From daaaff1c9d381aa50fe103451852aa42384c1be7 Mon Sep 17 00:00:00 2001 From: Alexander Narsudinov Date: Wed, 21 Jun 2023 08:58:09 +0200 Subject: [PATCH] refactor: Replace lib/pq with pgx in a PostgreSQL scaler (#4705) Signed-off-by: Alexander Narsudinov --- CHANGELOG.md | 1 + go.mod | 4 +- go.sum | 8 +- pkg/scalers/postgresql_scaler.go | 4 +- pkg/scalers/postgresql_scaler_test.go | 2 + .../postgresql/helper/postgresql_helper.go | 219 + .../postgresql_ha_test.go | 220 + .../postgresql_standalone/postgresql_test.go | 154 + tests/scalers/postgresql/postgresql_test.go | 332 -- .../github.com/jackc/pgpassfile/.travis.yml | 9 + vendor/github.com/jackc/pgpassfile/LICENSE | 22 + vendor/github.com/jackc/pgpassfile/README.md | 8 + vendor/github.com/jackc/pgpassfile/pgpass.go | 110 + .../jackc/pgservicefile/.travis.yml | 9 + vendor/github.com/jackc/pgservicefile/LICENSE | 22 + .../github.com/jackc/pgservicefile/README.md | 6 + .../jackc/pgservicefile/pgservicefile.go | 79 + vendor/github.com/jackc/pgx/v5/.gitignore | 27 + vendor/github.com/jackc/pgx/v5/CHANGELOG.md | 285 ++ .../github.com/jackc/pgx/v5/CONTRIBUTING.md | 134 + vendor/github.com/jackc/pgx/v5/LICENSE | 22 + vendor/github.com/jackc/pgx/v5/README.md | 168 + vendor/github.com/jackc/pgx/v5/Rakefile | 18 + vendor/github.com/jackc/pgx/v5/batch.go | 431 ++ vendor/github.com/jackc/pgx/v5/conn.go | 1346 ++++++ vendor/github.com/jackc/pgx/v5/copy_from.go | 249 + vendor/github.com/jackc/pgx/v5/doc.go | 193 + .../jackc/pgx/v5/extended_query_builder.go | 218 + .../jackc/pgx/v5/internal/anynil/anynil.go | 36 + .../pgx/v5/internal/iobufpool/iobufpool.go | 70 + .../jackc/pgx/v5/internal/pgio/README.md | 6 + .../jackc/pgx/v5/internal/pgio/doc.go | 6 + .../jackc/pgx/v5/internal/pgio/write.go | 40 + .../pgx/v5/internal/sanitize/sanitize.go | 322 ++ .../pgx/v5/internal/stmtcache/lru_cache.go | 98 + .../pgx/v5/internal/stmtcache/stmtcache.go | 57 + .../v5/internal/stmtcache/unlimited_cache.go | 71 + .../github.com/jackc/pgx/v5/large_objects.go | 121 + vendor/github.com/jackc/pgx/v5/named_args.go | 266 ++ .../github.com/jackc/pgx/v5/pgconn/README.md | 29 + .../jackc/pgx/v5/pgconn/auth_scram.go | 272 ++ .../github.com/jackc/pgx/v5/pgconn/config.go | 885 ++++ .../jackc/pgx/v5/pgconn/defaults.go | 63 + .../jackc/pgx/v5/pgconn/defaults_windows.go | 57 + vendor/github.com/jackc/pgx/v5/pgconn/doc.go | 34 + .../github.com/jackc/pgx/v5/pgconn/errors.go | 226 + .../v5/pgconn/internal/bgreader/bgreader.go | 132 + .../internal/ctxwatch/context_watcher.go | 73 + vendor/github.com/jackc/pgx/v5/pgconn/krb5.go | 100 + .../github.com/jackc/pgx/v5/pgconn/pgconn.go | 2072 ++++++++ .../jackc/pgx/v5/pgproto3/README.md | 7 + .../authentication_cleartext_password.go | 52 + .../pgx/v5/pgproto3/authentication_gss.go | 59 + .../pgproto3/authentication_gss_continue.go | 68 + .../pgproto3/authentication_md5_password.go | 77 + .../pgx/v5/pgproto3/authentication_ok.go | 52 + .../pgx/v5/pgproto3/authentication_sasl.go | 76 + .../pgproto3/authentication_sasl_continue.go | 81 + .../v5/pgproto3/authentication_sasl_final.go | 81 + .../jackc/pgx/v5/pgproto3/backend.go | 262 ++ .../jackc/pgx/v5/pgproto3/backend_key_data.go | 51 + .../jackc/pgx/v5/pgproto3/big_endian.go | 37 + .../github.com/jackc/pgx/v5/pgproto3/bind.go | 216 + .../jackc/pgx/v5/pgproto3/bind_complete.go | 34 + .../jackc/pgx/v5/pgproto3/cancel_request.go | 58 + .../jackc/pgx/v5/pgproto3/chunkreader.go | 90 + .../github.com/jackc/pgx/v5/pgproto3/close.go | 89 + .../jackc/pgx/v5/pgproto3/close_complete.go | 34 + .../jackc/pgx/v5/pgproto3/command_complete.go | 74 + .../pgx/v5/pgproto3/copy_both_response.go | 95 + .../jackc/pgx/v5/pgproto3/copy_data.go | 62 + .../jackc/pgx/v5/pgproto3/copy_done.go | 38 + .../jackc/pgx/v5/pgproto3/copy_fail.go | 53 + .../jackc/pgx/v5/pgproto3/copy_in_response.go | 96 + .../pgx/v5/pgproto3/copy_out_response.go | 96 + .../jackc/pgx/v5/pgproto3/data_row.go | 142 + .../jackc/pgx/v5/pgproto3/describe.go | 88 + .../github.com/jackc/pgx/v5/pgproto3/doc.go | 11 + .../pgx/v5/pgproto3/empty_query_response.go | 34 + .../jackc/pgx/v5/pgproto3/error_response.go | 333 ++ .../jackc/pgx/v5/pgproto3/execute.go | 65 + .../github.com/jackc/pgx/v5/pgproto3/flush.go | 34 + .../jackc/pgx/v5/pgproto3/frontend.go | 363 ++ .../jackc/pgx/v5/pgproto3/function_call.go | 95 + .../pgx/v5/pgproto3/function_call_response.go | 101 + .../jackc/pgx/v5/pgproto3/gss_enc_request.go | 49 + .../jackc/pgx/v5/pgproto3/gss_response.go | 49 + .../jackc/pgx/v5/pgproto3/no_data.go | 34 + .../jackc/pgx/v5/pgproto3/notice_response.go | 17 + .../pgx/v5/pgproto3/notification_response.go | 77 + .../pgx/v5/pgproto3/parameter_description.go | 66 + .../jackc/pgx/v5/pgproto3/parameter_status.go | 66 + .../github.com/jackc/pgx/v5/pgproto3/parse.go | 88 + .../jackc/pgx/v5/pgproto3/parse_complete.go | 34 + .../jackc/pgx/v5/pgproto3/password_message.go | 54 + .../jackc/pgx/v5/pgproto3/pgproto3.go | 85 + .../jackc/pgx/v5/pgproto3/portal_suspended.go | 34 + .../github.com/jackc/pgx/v5/pgproto3/query.go | 50 + .../jackc/pgx/v5/pgproto3/ready_for_query.go | 61 + .../jackc/pgx/v5/pgproto3/row_description.go | 165 + .../pgx/v5/pgproto3/sasl_initial_response.go | 94 + .../jackc/pgx/v5/pgproto3/sasl_response.go | 61 + .../jackc/pgx/v5/pgproto3/ssl_request.go | 49 + .../jackc/pgx/v5/pgproto3/startup_message.go | 96 + .../github.com/jackc/pgx/v5/pgproto3/sync.go | 34 + .../jackc/pgx/v5/pgproto3/terminate.go | 34 + .../github.com/jackc/pgx/v5/pgproto3/trace.go | 440 ++ .../github.com/jackc/pgx/v5/pgtype/array.go | 481 ++ .../jackc/pgx/v5/pgtype/array_codec.go | 406 ++ vendor/github.com/jackc/pgx/v5/pgtype/bits.go | 208 + vendor/github.com/jackc/pgx/v5/pgtype/bool.go | 343 ++ vendor/github.com/jackc/pgx/v5/pgtype/box.go | 238 + .../jackc/pgx/v5/pgtype/builtin_wrappers.go | 952 ++++ .../github.com/jackc/pgx/v5/pgtype/bytea.go | 255 + .../github.com/jackc/pgx/v5/pgtype/circle.go | 222 + .../jackc/pgx/v5/pgtype/composite.go | 602 +++ .../github.com/jackc/pgx/v5/pgtype/convert.go | 479 ++ vendor/github.com/jackc/pgx/v5/pgtype/date.go | 351 ++ vendor/github.com/jackc/pgx/v5/pgtype/doc.go | 178 + .../jackc/pgx/v5/pgtype/enum_codec.go | 109 + .../github.com/jackc/pgx/v5/pgtype/float4.go | 295 ++ .../github.com/jackc/pgx/v5/pgtype/float8.go | 349 ++ .../github.com/jackc/pgx/v5/pgtype/hstore.go | 467 ++ vendor/github.com/jackc/pgx/v5/pgtype/inet.go | 200 + vendor/github.com/jackc/pgx/v5/pgtype/int.go | 1980 ++++++++ .../github.com/jackc/pgx/v5/pgtype/int.go.erb | 548 +++ .../jackc/pgx/v5/pgtype/int_test.go.erb | 93 + .../pgtype/integration_benchmark_test.go.erb | 62 + .../pgtype/integration_benchmark_test_gen.sh | 2 + .../jackc/pgx/v5/pgtype/interval.go | 292 ++ vendor/github.com/jackc/pgx/v5/pgtype/json.go | 186 + .../github.com/jackc/pgx/v5/pgtype/jsonb.go | 127 + vendor/github.com/jackc/pgx/v5/pgtype/line.go | 225 + vendor/github.com/jackc/pgx/v5/pgtype/lseg.go | 238 + .../github.com/jackc/pgx/v5/pgtype/macaddr.go | 162 + .../jackc/pgx/v5/pgtype/multirange.go | 443 ++ .../github.com/jackc/pgx/v5/pgtype/numeric.go | 820 ++++ vendor/github.com/jackc/pgx/v5/pgtype/path.go | 272 ++ .../github.com/jackc/pgx/v5/pgtype/pgtype.go | 1975 ++++++++ .../jackc/pgx/v5/pgtype/pgtype_default.go | 221 + .../github.com/jackc/pgx/v5/pgtype/point.go | 266 ++ .../github.com/jackc/pgx/v5/pgtype/polygon.go | 253 + .../github.com/jackc/pgx/v5/pgtype/qchar.go | 141 + .../github.com/jackc/pgx/v5/pgtype/range.go | 322 ++ .../jackc/pgx/v5/pgtype/range_codec.go | 379 ++ .../jackc/pgx/v5/pgtype/record_codec.go | 125 + .../v5/pgtype/register_default_pg_types.go | 35 + .../register_default_pg_types_disabled.go | 6 + vendor/github.com/jackc/pgx/v5/pgtype/text.go | 223 + .../pgx/v5/pgtype/text_format_only_codec.go | 13 + vendor/github.com/jackc/pgx/v5/pgtype/tid.go | 241 + vendor/github.com/jackc/pgx/v5/pgtype/time.go | 233 + .../jackc/pgx/v5/pgtype/timestamp.go | 345 ++ .../jackc/pgx/v5/pgtype/timestamptz.go | 355 ++ .../github.com/jackc/pgx/v5/pgtype/uint32.go | 303 ++ vendor/github.com/jackc/pgx/v5/pgtype/uuid.go | 269 ++ vendor/github.com/jackc/pgx/v5/rows.go | 676 +++ vendor/github.com/jackc/pgx/v5/stdlib/sql.go | 797 ++++ vendor/github.com/jackc/pgx/v5/tracer.go | 107 + vendor/github.com/jackc/pgx/v5/tx.go | 425 ++ vendor/github.com/jackc/pgx/v5/values.go | 68 + vendor/github.com/lib/pq/.gitignore | 6 - vendor/github.com/lib/pq/LICENSE.md | 8 - vendor/github.com/lib/pq/README.md | 36 - vendor/github.com/lib/pq/TESTS.md | 33 - vendor/github.com/lib/pq/array.go | 895 ---- vendor/github.com/lib/pq/buf.go | 91 - vendor/github.com/lib/pq/conn.go | 2112 --------- vendor/github.com/lib/pq/conn_go115.go | 8 - vendor/github.com/lib/pq/conn_go18.go | 247 - vendor/github.com/lib/pq/connector.go | 120 - vendor/github.com/lib/pq/copy.go | 348 -- vendor/github.com/lib/pq/doc.go | 268 -- vendor/github.com/lib/pq/encode.go | 632 --- vendor/github.com/lib/pq/error.go | 523 --- vendor/github.com/lib/pq/krb.go | 27 - vendor/github.com/lib/pq/notice.go | 72 - vendor/github.com/lib/pq/notify.go | 858 ---- vendor/github.com/lib/pq/oid/doc.go | 6 - vendor/github.com/lib/pq/oid/types.go | 343 -- vendor/github.com/lib/pq/rows.go | 93 - vendor/github.com/lib/pq/scram/scram.go | 264 -- vendor/github.com/lib/pq/ssl.go | 204 - vendor/github.com/lib/pq/ssl_permissions.go | 93 - vendor/github.com/lib/pq/ssl_windows.go | 10 - vendor/github.com/lib/pq/url.go | 76 - vendor/github.com/lib/pq/user_other.go | 10 - vendor/github.com/lib/pq/user_posix.go | 25 - vendor/github.com/lib/pq/user_windows.go | 27 - vendor/github.com/lib/pq/uuid.go | 23 - .../golang.org/x/text/secure/precis/class.go | 36 + .../x/text/secure/precis/context.go | 139 + vendor/golang.org/x/text/secure/precis/doc.go | 14 + .../x/text/secure/precis/nickname.go | 72 + .../x/text/secure/precis/options.go | 157 + .../x/text/secure/precis/profile.go | 412 ++ .../x/text/secure/precis/profiles.go | 78 + .../x/text/secure/precis/tables10.0.0.go | 3890 +++++++++++++++ .../x/text/secure/precis/tables11.0.0.go | 4017 ++++++++++++++++ .../x/text/secure/precis/tables12.0.0.go | 4119 ++++++++++++++++ .../x/text/secure/precis/tables13.0.0.go | 4153 +++++++++++++++++ .../x/text/secure/precis/tables9.0.0.go | 3791 +++++++++++++++ .../x/text/secure/precis/transformer.go | 32 + .../x/text/secure/precis/trieval.go | 64 + vendor/modules.txt | 26 +- 205 files changed, 54298 insertions(+), 7800 deletions(-) create mode 100644 tests/scalers/postgresql/helper/postgresql_helper.go create mode 100644 tests/scalers/postgresql/postgresql_high_available/postgresql_ha_test.go create mode 100644 tests/scalers/postgresql/postgresql_standalone/postgresql_test.go delete mode 100644 tests/scalers/postgresql/postgresql_test.go create mode 100644 vendor/github.com/jackc/pgpassfile/.travis.yml create mode 100644 vendor/github.com/jackc/pgpassfile/LICENSE create mode 100644 vendor/github.com/jackc/pgpassfile/README.md create mode 100644 vendor/github.com/jackc/pgpassfile/pgpass.go create mode 100644 vendor/github.com/jackc/pgservicefile/.travis.yml create mode 100644 vendor/github.com/jackc/pgservicefile/LICENSE create mode 100644 vendor/github.com/jackc/pgservicefile/README.md create mode 100644 vendor/github.com/jackc/pgservicefile/pgservicefile.go create mode 100644 vendor/github.com/jackc/pgx/v5/.gitignore create mode 100644 vendor/github.com/jackc/pgx/v5/CHANGELOG.md create mode 100644 vendor/github.com/jackc/pgx/v5/CONTRIBUTING.md create mode 100644 vendor/github.com/jackc/pgx/v5/LICENSE create mode 100644 vendor/github.com/jackc/pgx/v5/README.md create mode 100644 vendor/github.com/jackc/pgx/v5/Rakefile create mode 100644 vendor/github.com/jackc/pgx/v5/batch.go create mode 100644 vendor/github.com/jackc/pgx/v5/conn.go create mode 100644 vendor/github.com/jackc/pgx/v5/copy_from.go create mode 100644 vendor/github.com/jackc/pgx/v5/doc.go create mode 100644 vendor/github.com/jackc/pgx/v5/extended_query_builder.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/anynil/anynil.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/iobufpool/iobufpool.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/pgio/README.md create mode 100644 vendor/github.com/jackc/pgx/v5/internal/pgio/doc.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/pgio/write.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/sanitize/sanitize.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/stmtcache/lru_cache.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/stmtcache/stmtcache.go create mode 100644 vendor/github.com/jackc/pgx/v5/internal/stmtcache/unlimited_cache.go create mode 100644 vendor/github.com/jackc/pgx/v5/large_objects.go create mode 100644 vendor/github.com/jackc/pgx/v5/named_args.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/README.md create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/auth_scram.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/config.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/defaults.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/defaults_windows.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/doc.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/errors.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/internal/bgreader/bgreader.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/internal/ctxwatch/context_watcher.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/krb5.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgconn/pgconn.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/README.md create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/backend.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/bind.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/close.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/describe.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/doc.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/execute.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/flush.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/parse.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/query.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/sync.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgproto3/trace.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/array.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/array_codec.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/bits.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/bool.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/box.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/builtin_wrappers.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/bytea.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/circle.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/composite.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/convert.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/date.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/doc.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/enum_codec.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/float4.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/float8.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/hstore.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/inet.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/int.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/int.go.erb create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/int_test.go.erb create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test.go.erb create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test_gen.sh create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/interval.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/json.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/jsonb.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/line.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/lseg.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/macaddr.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/multirange.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/numeric.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/path.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/point.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/polygon.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/qchar.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/range.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/range_codec.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/record_codec.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types_disabled.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/text.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/text_format_only_codec.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/tid.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/time.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/timestamp.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/timestamptz.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/uint32.go create mode 100644 vendor/github.com/jackc/pgx/v5/pgtype/uuid.go create mode 100644 vendor/github.com/jackc/pgx/v5/rows.go create mode 100644 vendor/github.com/jackc/pgx/v5/stdlib/sql.go create mode 100644 vendor/github.com/jackc/pgx/v5/tracer.go create mode 100644 vendor/github.com/jackc/pgx/v5/tx.go create mode 100644 vendor/github.com/jackc/pgx/v5/values.go delete mode 100644 vendor/github.com/lib/pq/.gitignore delete mode 100644 vendor/github.com/lib/pq/LICENSE.md delete mode 100644 vendor/github.com/lib/pq/README.md delete mode 100644 vendor/github.com/lib/pq/TESTS.md delete mode 100644 vendor/github.com/lib/pq/array.go delete mode 100644 vendor/github.com/lib/pq/buf.go delete mode 100644 vendor/github.com/lib/pq/conn.go delete mode 100644 vendor/github.com/lib/pq/conn_go115.go delete mode 100644 vendor/github.com/lib/pq/conn_go18.go delete mode 100644 vendor/github.com/lib/pq/connector.go delete mode 100644 vendor/github.com/lib/pq/copy.go delete mode 100644 vendor/github.com/lib/pq/doc.go delete mode 100644 vendor/github.com/lib/pq/encode.go delete mode 100644 vendor/github.com/lib/pq/error.go delete mode 100644 vendor/github.com/lib/pq/krb.go delete mode 100644 vendor/github.com/lib/pq/notice.go delete mode 100644 vendor/github.com/lib/pq/notify.go delete mode 100644 vendor/github.com/lib/pq/oid/doc.go delete mode 100644 vendor/github.com/lib/pq/oid/types.go delete mode 100644 vendor/github.com/lib/pq/rows.go delete mode 100644 vendor/github.com/lib/pq/scram/scram.go delete mode 100644 vendor/github.com/lib/pq/ssl.go delete mode 100644 vendor/github.com/lib/pq/ssl_permissions.go delete mode 100644 vendor/github.com/lib/pq/ssl_windows.go delete mode 100644 vendor/github.com/lib/pq/url.go delete mode 100644 vendor/github.com/lib/pq/user_other.go delete mode 100644 vendor/github.com/lib/pq/user_posix.go delete mode 100644 vendor/github.com/lib/pq/user_windows.go delete mode 100644 vendor/github.com/lib/pq/uuid.go create mode 100644 vendor/golang.org/x/text/secure/precis/class.go create mode 100644 vendor/golang.org/x/text/secure/precis/context.go create mode 100644 vendor/golang.org/x/text/secure/precis/doc.go create mode 100644 vendor/golang.org/x/text/secure/precis/nickname.go create mode 100644 vendor/golang.org/x/text/secure/precis/options.go create mode 100644 vendor/golang.org/x/text/secure/precis/profile.go create mode 100644 vendor/golang.org/x/text/secure/precis/profiles.go create mode 100644 vendor/golang.org/x/text/secure/precis/tables10.0.0.go create mode 100644 vendor/golang.org/x/text/secure/precis/tables11.0.0.go create mode 100644 vendor/golang.org/x/text/secure/precis/tables12.0.0.go create mode 100644 vendor/golang.org/x/text/secure/precis/tables13.0.0.go create mode 100644 vendor/golang.org/x/text/secure/precis/tables9.0.0.go create mode 100644 vendor/golang.org/x/text/secure/precis/transformer.go create mode 100644 vendor/golang.org/x/text/secure/precis/trieval.go diff --git a/CHANGELOG.md b/CHANGELOG.md index ed513c0e5f9..17f87ca3162 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -64,6 +64,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio - **Pulsar Scaler**: Improve error messages for unsuccessful connections ([#4563](https://github.com/kedacore/keda/issues/4563)) - **Security**: Enable secret scanning in GitHub repo - **RabbitMQ Scaler**: Add support for `unsafeSsl` in trigger metadata ([#4448](https://github.com/kedacore/keda/issues/4448)) +- **PostgreSQL Scaler**: Replace `lib/pq` with `pgx` ([#4704](https://github.com/kedacore/keda/issues/4704)) - **Prometheus Metrics**: Add new metric with KEDA build info ([#4647](https://github.com/kedacore/keda/issues/4647)) - **Prometheus Scaler**: Add support for Google Managed Prometheus ([#4675](https://github.com/kedacore/keda/pull/4675)) - **Solace Scaler**: Add new `messageReceiveRateTarget` metric to Solace Scaler ([#4665](https://github.com/kedacore/keda/issues/4665)) diff --git a/go.mod b/go.mod index 7cb2106feb5..ae55b70588b 100644 --- a/go.mod +++ b/go.mod @@ -42,8 +42,8 @@ require ( github.com/hashicorp/vault/api v1.9.2 github.com/imdario/mergo v0.3.16 github.com/influxdata/influxdb-client-go/v2 v2.12.3 + github.com/jackc/pgx/v5 v5.4.0 github.com/joho/godotenv v1.5.1 - github.com/lib/pq v1.10.9 github.com/microsoft/ApplicationInsights-Go v0.4.4 github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 github.com/mitchellh/hashstructure v1.1.0 @@ -212,6 +212,8 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect github.com/jcmturner/gofork v1.7.6 // indirect diff --git a/go.sum b/go.sum index 2acdb8f2883..025e5754ddc 100644 --- a/go.sum +++ b/go.sum @@ -471,6 +471,12 @@ github.com/influxdata/influxdb-client-go/v2 v2.12.3 h1:28nRlNMRIV4QbtIUvxhWqaxn0 github.com/influxdata/influxdb-client-go/v2 v2.12.3/go.mod h1:IrrLUbCjjfkmRuaCiGQg4m2GbkaeJDcuWoxiWdQEbA0= github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf h1:7JTmneyiNEwVBOHSjoMxiWAqB992atOeepeFYegn5RU= github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgx/v5 v5.4.0 h1:BSr+GCm4N6QcgIwv0DyTFHK9ugfEFF9DzSbbzxOiXU0= +github.com/jackc/pgx/v5 v5.4.0/go.mod h1:q6iHT8uDNXWiFNOlRqJzBTaSH3+2xCXkokxHZC5qWFY= github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= @@ -525,8 +531,6 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= -github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= diff --git a/pkg/scalers/postgresql_scaler.go b/pkg/scalers/postgresql_scaler.go index dc5a9e0c71c..789817641ae 100644 --- a/pkg/scalers/postgresql_scaler.go +++ b/pkg/scalers/postgresql_scaler.go @@ -9,7 +9,7 @@ import ( "github.com/go-logr/logr" // PostreSQL drive required for this scaler - _ "github.com/lib/pq" + _ "github.com/jackc/pgx/v5/stdlib" v2 "k8s.io/api/autoscaling/v2" "k8s.io/metrics/pkg/apis/external_metrics" @@ -146,7 +146,7 @@ func parsePostgreSQLMetadata(config *ScalerConfig) (*postgreSQLMetadata, error) } func getConnection(meta *postgreSQLMetadata, logger logr.Logger) (*sql.DB, error) { - db, err := sql.Open("postgres", meta.connection) + db, err := sql.Open("pgx", meta.connection) if err != nil { logger.Error(err, fmt.Sprintf("Found error opening postgreSQL: %s", err)) return nil, err diff --git a/pkg/scalers/postgresql_scaler_test.go b/pkg/scalers/postgresql_scaler_test.go index 5feb3509dd6..f719c1b0d6a 100644 --- a/pkg/scalers/postgresql_scaler_test.go +++ b/pkg/scalers/postgresql_scaler_test.go @@ -71,6 +71,8 @@ var testPostgreSQLConnectionstring = []postgreSQLConnectionStringTestData{ {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5"}, authParam: map[string]string{"connection": "test_connection_from_auth"}, connectionString: "test_connection_from_auth"}, // from meta {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5", "host": "localhost", "port": "1234", "dbName": "testDb", "userName": "user", "sslmode": "required"}, connectionString: "host=localhost port=1234 user=user dbname=testDb sslmode=required password="}, + // from meta, multiple hosts + {metadata: map[string]string{"query": "test_query", "targetQueryValue": "5", "host": "host1,host2", "port": "1234", "dbName": "testDb", "userName": "user", "sslmode": "required"}, connectionString: "host=host1,host2 port=1234 user=user dbname=testDb sslmode=required password="}, } func TestPosgresSQLConnectionStringGeneration(t *testing.T) { diff --git a/tests/scalers/postgresql/helper/postgresql_helper.go b/tests/scalers/postgresql/helper/postgresql_helper.go new file mode 100644 index 00000000000..acfd0a49f51 --- /dev/null +++ b/tests/scalers/postgresql/helper/postgresql_helper.go @@ -0,0 +1,219 @@ +//go:build e2e +// +build e2e + +package helper + +import ( + "fmt" + "strings" +) + +const ( + PostgresqlImage = "postgres:10.5" +) + +const ( + DeploymentTemplate = `apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: postgresql-update-worker + name: {{.DeploymentName}} + namespace: {{.TestNamespace}} +spec: + replicas: 0 + selector: + matchLabels: + app: postgresql-update-worker + template: + metadata: + labels: + app: postgresql-update-worker + spec: + containers: + - image: ghcr.io/kedacore/tests-postgresql + imagePullPolicy: Always + name: postgresql-processor-test + command: + - /app + - update + env: + - name: TASK_INSTANCES_COUNT + value: "6000" + - name: CONNECTION_STRING + valueFrom: + secretKeyRef: + name: {{.SecretName}} + key: postgresql_conn_str +` + ScaledObjectTemplate = `apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{.ScaledObjectName}} + namespace: {{.TestNamespace}} +spec: + scaleTargetRef: + name: {{.DeploymentName}} + pollingInterval: 5 + cooldownPeriod: 10 + minReplicaCount: {{.MinReplicaCount}} + maxReplicaCount: {{.MaxReplicaCount}} + triggers: + - type: postgresql + metadata: + targetQueryValue: "4" + activationTargetQueryValue: "5" + query: "SELECT CEIL(COUNT(*) / 5) FROM task_instance WHERE state='running' OR state='queued'" + authenticationRef: + name: {{.TriggerAuthenticationName}} +` + LowLevelRecordsJobTemplate = `apiVersion: batch/v1 +kind: Job +metadata: + labels: + app: postgresql-insert-low-level-job + name: postgresql-insert-low-level-job + namespace: {{.TestNamespace}} +spec: + template: + metadata: + labels: + app: postgresql-insert-low-level-job + spec: + containers: + - image: ghcr.io/kedacore/tests-postgresql + imagePullPolicy: Always + name: postgresql-processor-test + command: + - /app + - insert + env: + - name: TASK_INSTANCES_COUNT + value: "20" + - name: CONNECTION_STRING + valueFrom: + secretKeyRef: + name: {{.SecretName}} + key: postgresql_conn_str + restartPolicy: Never + backoffLimit: 4 +` + InsertRecordsJobTemplate = `apiVersion: batch/v1 +kind: Job +metadata: + labels: + app: postgresql-insert-job + name: postgresql-insert-job + namespace: {{.TestNamespace}} +spec: + template: + metadata: + labels: + app: postgresql-insert-job + spec: + containers: + - image: ghcr.io/kedacore/tests-postgresql + imagePullPolicy: Always + name: postgresql-processor-test + command: + - /app + - insert + env: + - name: TASK_INSTANCES_COUNT + value: "10000" + - name: CONNECTION_STRING + valueFrom: + secretKeyRef: + name: {{.SecretName}} + key: postgresql_conn_str + restartPolicy: Never + backoffLimit: 4 +` + TriggerAuthenticationTemplate = `apiVersion: keda.sh/v1alpha1 +kind: TriggerAuthentication +metadata: + name: {{.TriggerAuthenticationName}} + namespace: {{.TestNamespace}} +spec: + secretTargetRef: + - parameter: connection + name: {{.SecretName}} + key: {{.SecretKey}} +` + PostgreSQLStatefulSetTemplate = `apiVersion: apps/v1 +kind: StatefulSet +metadata: + labels: + app: {{.PostgreSQLStatefulSetName}} + name: {{.PostgreSQLStatefulSetName}} + namespace: {{.TestNamespace}} +spec: + replicas: 1 + serviceName: {{.PostgreSQLStatefulSetName}} + selector: + matchLabels: + app: {{.PostgreSQLStatefulSetName}} + template: + metadata: + labels: + app: {{.PostgreSQLStatefulSetName}} + spec: + containers: + - name: postgresql + image: {{.PostgreSQLImage}} + env: + - name: POSTGRES_USER + value: {{.PostgreSQLUsername}} + - name: POSTGRES_PASSWORD + value: {{.PostgreSQLPassword}} + - name: POSTGRES_DB + value: {{.PostgreSQLDatabase}} + ports: + - name: postgresql + protocol: TCP + containerPort: 5432 + readinessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 5 + livenessProbe: + tcpSocket: + port: 5432 + initialDelaySeconds: 5 + timeoutSeconds: 5 + volumeMounts: + - name: init-scripts + mountPath: /docker-entrypoint-initdb.d + volumes: + - name: init-scripts + configMap: + name: master-slave-config + optional: true +` + PostgreSQLServiceTemplate = `apiVersion: v1 +kind: Service +metadata: + labels: + app: {{.PostgreSQLStatefulSetName}} + name: {{.PostgreSQLStatefulSetName}} + namespace: {{.TestNamespace}} +spec: + ports: + - port: 5432 + protocol: TCP + targetPort: 5432 + selector: + app: {{.PostgreSQLStatefulSetName}} + type: ClusterIP +` +) + +func GetConnectionString(username string, password string, svcNames []string, namespace string, database string) string { + svcFQDNs := make([]string, 0, len(svcNames)) + for _, svcName := range svcNames { + svcFQDNs = append(svcFQDNs, fmt.Sprintf("%s.%s.svc.cluster.local", svcName, namespace)) + } + fqdns := strings.Join(svcFQDNs, ",") + return fmt.Sprintf("postgresql://%s:%s@%s:5432/%s?sslmode=disable", username, password, fqdns, database) +} diff --git a/tests/scalers/postgresql/postgresql_high_available/postgresql_ha_test.go b/tests/scalers/postgresql/postgresql_high_available/postgresql_ha_test.go new file mode 100644 index 00000000000..543336350ef --- /dev/null +++ b/tests/scalers/postgresql/postgresql_high_available/postgresql_ha_test.go @@ -0,0 +1,220 @@ +//go:build e2e +// +build e2e + +package postgresql_standalone_test + +import ( + "encoding/base64" + "fmt" + "strings" + "testing" + + "github.com/joho/godotenv" + "github.com/stretchr/testify/assert" + "k8s.io/client-go/kubernetes" + + . "github.com/kedacore/keda/v2/tests/helper" + pg "github.com/kedacore/keda/v2/tests/scalers/postgresql/helper" +) + +// Load environment variables from .env file +var _ = godotenv.Load("../../.env") + +const ( + testName = "postgresql-ha-test" +) + +var ( + testNamespace = fmt.Sprintf("%s-ns", testName) + deploymentName = fmt.Sprintf("%s-deployment", testName) + scaledObjectName = fmt.Sprintf("%s-so", testName) + triggerAuthenticationName = fmt.Sprintf("%s-ta", testName) + secretName = fmt.Sprintf("%s-secret", testName) + secretKey = "postgresql_multihost_conn_str" + postgreSQLImage = pg.PostgresqlImage + postgreSQLStatefulSetName = "postgresql-master" + postgreSQLReplicaStatefulSetName = "postgresql-replica" + postgresqlMasterPodName = fmt.Sprintf("%s-0", postgreSQLStatefulSetName) + postgresqlReplicaPodName = fmt.Sprintf("%s-0", postgreSQLReplicaStatefulSetName) + postgreSQLUsername = "test-user" + postgreSQLPassword = "test-password" + postgreSQLDatabase = "test_db" + postgreSQLConnectionString = pg.GetConnectionString(postgreSQLUsername, postgreSQLPassword, + []string{postgreSQLStatefulSetName}, testNamespace, postgreSQLDatabase) + postgreSQLMultihostConnectionString = pg.GetConnectionString(postgreSQLUsername, postgreSQLPassword, + []string{postgreSQLStatefulSetName, postgreSQLReplicaStatefulSetName}, testNamespace, postgreSQLDatabase) + minReplicaCount = 0 + maxReplicaCount = 2 +) + +type templateData struct { + TestNamespace string + DeploymentName string + ScaledObjectName string + TriggerAuthenticationName string + SecretName string + SecretKey string + PostgreSQLImage string + PostgreSQLStatefulSetName string + PostgreSQLReplicaStatefulSetName string + PostgreSQLConnectionStringBase64 string + PostgreSQLMultihostConnectionStringBase64 string + PostgreSQLUsername string + PostgreSQLPassword string + PostgreSQLDatabase string + MinReplicaCount int + MaxReplicaCount int +} + +const ( + postgresqlInitScriptsConfigMapTemplate = `apiVersion: v1 +kind: ConfigMap +metadata: + name: master-slave-config + namespace: {{.TestNamespace}} +data: + master-slave-config.sh: |- + HOST=$(hostname -s) + HOST_TEMPLATE=${HOST%-*} + case $HOST_TEMPLATE in + *master*) + echo "host replication all all md5" >> /var/lib/postgresql/data/pg_hba.conf + echo "archive_mode = on" >> /etc/postgresql/postgresql.conf + echo "archive_mode = on" >> /etc/postgresql/postgresql.conf + echo "archive_command = '/bin/true'" >> /etc/postgresql/postgresql.conf + echo "archive_timeout = 0" >> /etc/postgresql/postgresql.conf + echo "max_wal_senders = 8" >> /etc/postgresql/postgresql.conf + echo "wal_keep_segments = 32" >> /etc/postgresql/postgresql.conf + echo "wal_level = hot_standby" >> /etc/postgresql/postgresql.conf + ;; + *replica*) + # stop initial server to copy data + pg_ctl -D /var/lib/postgresql/data/ -m fast -w stop + rm -rf /var/lib/postgresql/data/* + # add service name for DNS resolution + PGPASSWORD=postgresql-ha pg_basebackup -h {{.PostgreSQLStatefulSetName}} -w -U replicator -p 5432 -D /var/lib/postgresql/data -Fp -Xs -P -R + # start server to keep container's screep happy + pg_ctl -D /var/lib/postgresql/data/ -w start + ;; + esac + + + create-replication-role.sql: |- + CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'postgresql-ha'; +` + secretTemplate = `apiVersion: v1 +kind: Secret +metadata: + name: {{.SecretName}} + namespace: {{.TestNamespace}} +type: Opaque +data: + postgresql_conn_str: {{.PostgreSQLConnectionStringBase64}} + postgresql_multihost_conn_str: {{.PostgreSQLMultihostConnectionStringBase64}} +` +) + +func TestPostreSQLScaler(t *testing.T) { + // Create kubernetes resources for PostgreSQL server + kc := GetKubernetesClient(t) + data, postgreSQLtemplates := getPostgreSQLTemplateData() + CreateKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates) + + assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, postgreSQLStatefulSetName, testNamespace, 1, 60, 3), + "replica count should be %d after 3 minutes", 1) + assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, postgreSQLReplicaStatefulSetName, testNamespace, 1, 60, 3), + "replica count should be %d after 3 minutes", 1) + + createTableSQL := "CREATE TABLE task_instance (id serial PRIMARY KEY,state VARCHAR(10));" + ok, out, errOut, err := WaitForSuccessfulExecCommandOnSpecificPod(t, postgresqlMasterPodName, testNamespace, + fmt.Sprintf("psql -U %s -d %s -c \"%s\"", postgreSQLUsername, postgreSQLDatabase, createTableSQL), 60, 3) + assert.True(t, ok, "executing a command on PostreSQL Master Pod should work; Output: %s, ErrorOutput: %s, Error: %s", out, errOut, err) + + checkTableExists := "SELECT * from task_instance;" + ok, out, errOut, err = WaitForSuccessfulExecCommandOnSpecificPod(t, postgresqlReplicaPodName, testNamespace, + fmt.Sprintf("psql -U %s -d %s -c \"%s\"", postgreSQLUsername, postgreSQLDatabase, checkTableExists), 60, 3) + + assert.True(t, ok, "executing a command on PostreSQL Replica Pod should work; Output: %s, ErrorOutput: %s, Error: %s", out, errOut, err) + + // Create kubernetes resources for testing + data, templates := getTemplateData() + KubectlApplyMultipleWithTemplate(t, data, templates) + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) + + testActivation(t, kc, data) + testScaleOut(t, kc, data) + testScaleIn(t, kc) + + // cleanup + KubectlDeleteMultipleWithTemplate(t, data, templates) + DeleteKubernetesResources(t, testNamespace, data, postgreSQLtemplates) +} + +func testActivation(t *testing.T, kc *kubernetes.Clientset, data templateData) { + t.Log("--- testing activation ---") + KubectlApplyWithTemplate(t, data, "lowLevelRecordsJobTemplate", pg.LowLevelRecordsJobTemplate) + + AssertReplicaCountNotChangeDuringTimePeriod(t, kc, deploymentName, testNamespace, minReplicaCount, 60) +} + +func testScaleOut(t *testing.T, kc *kubernetes.Clientset, data templateData) { + t.Log("--- testing scale out ---") + KubectlApplyWithTemplate(t, data, "insertRecordsJobTemplate", pg.InsertRecordsJobTemplate) + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", maxReplicaCount) +} + +func testScaleIn(t *testing.T, kc *kubernetes.Clientset) { + t.Log("--- testing scale in ---") + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) +} + +var data = templateData{ + TestNamespace: testNamespace, + PostgreSQLStatefulSetName: postgreSQLStatefulSetName, + PostgreSQLReplicaStatefulSetName: postgreSQLReplicaStatefulSetName, + DeploymentName: deploymentName, + ScaledObjectName: scaledObjectName, + MinReplicaCount: minReplicaCount, + MaxReplicaCount: maxReplicaCount, + TriggerAuthenticationName: triggerAuthenticationName, + SecretName: secretName, + SecretKey: secretKey, + PostgreSQLImage: postgreSQLImage, + PostgreSQLUsername: postgreSQLUsername, + PostgreSQLPassword: postgreSQLPassword, + PostgreSQLDatabase: postgreSQLDatabase, + PostgreSQLConnectionStringBase64: base64.StdEncoding.EncodeToString([]byte(postgreSQLConnectionString)), + PostgreSQLMultihostConnectionStringBase64: base64.StdEncoding.EncodeToString([]byte(postgreSQLMultihostConnectionString)), +} + +func getPostgreSQLTemplateData() (templateData, []Template) { + return data, []Template{ + {Name: "postgresqlInitScriptsConfigMapTemplate", Config: postgresqlInitScriptsConfigMapTemplate}, + {Name: "postgresqlMasterStatefulSetTemplate", Config: pg.PostgreSQLStatefulSetTemplate}, + {Name: "postgresqlReplicaStatefulSetTemplate", Config: postgreSQLReplicaStatefulSetTemplate()}, + {Name: "postgreSQLMasterServiceTemplate", Config: pg.PostgreSQLServiceTemplate}, + {Name: "postgreSQLReplicaServiceTemplate", Config: postgreSQLReplicaServiceTemplate()}, + } +} + +func postgreSQLReplicaStatefulSetTemplate() string { + return strings.ReplaceAll(pg.PostgreSQLStatefulSetTemplate, ".PostgreSQLStatefulSetName", ".PostgreSQLReplicaStatefulSetName") +} + +func postgreSQLReplicaServiceTemplate() string { + return strings.ReplaceAll(pg.PostgreSQLServiceTemplate, ".PostgreSQLStatefulSetName", ".PostgreSQLReplicaStatefulSetName") +} + +func getTemplateData() (templateData, []Template) { + return data, []Template{ + {Name: "secretTemplate", Config: secretTemplate}, + {Name: "deploymentTemplate", Config: pg.DeploymentTemplate}, + {Name: "triggerAuthenticationTemplate", Config: pg.TriggerAuthenticationTemplate}, + {Name: "scaledObjectTemplate", Config: pg.ScaledObjectTemplate}, + } +} diff --git a/tests/scalers/postgresql/postgresql_standalone/postgresql_test.go b/tests/scalers/postgresql/postgresql_standalone/postgresql_test.go new file mode 100644 index 00000000000..9b17a405aec --- /dev/null +++ b/tests/scalers/postgresql/postgresql_standalone/postgresql_test.go @@ -0,0 +1,154 @@ +//go:build e2e +// +build e2e + +package postgresql_standalone_test + +import ( + "encoding/base64" + "fmt" + "testing" + + "github.com/joho/godotenv" + "github.com/stretchr/testify/assert" + "k8s.io/client-go/kubernetes" + + . "github.com/kedacore/keda/v2/tests/helper" + pg "github.com/kedacore/keda/v2/tests/scalers/postgresql/helper" +) + +// Load environment variables from .env file +var _ = godotenv.Load("../../.env") + +const ( + testName = "postgresql-test" +) + +var ( + testNamespace = fmt.Sprintf("%s-ns", testName) + deploymentName = fmt.Sprintf("%s-deployment", testName) + scaledObjectName = fmt.Sprintf("%s-so", testName) + triggerAuthenticationName = fmt.Sprintf("%s-ta", testName) + secretName = fmt.Sprintf("%s-secret", testName) + secretKey = "postgresql_conn_str" + postgreSQLStatefulSetName = "postgresql" + postgresqlPodName = fmt.Sprintf("%s-0", postgreSQLStatefulSetName) + postgreSQLUsername = "test-user" + postgreSQLPassword = "test-password" + postgreSQLDatabase = "test_db" + postgreSQLConnectionString = pg.GetConnectionString(postgreSQLUsername, postgreSQLPassword, []string{postgreSQLStatefulSetName}, testNamespace, postgreSQLDatabase) + minReplicaCount = 0 + maxReplicaCount = 2 +) + +type templateData struct { + TestNamespace string + DeploymentName string + ScaledObjectName string + TriggerAuthenticationName string + SecretName string + SecretKey string + PostgreSQLImage string + PostgreSQLStatefulSetName string + PostgreSQLConnectionStringBase64 string + PostgreSQLUsername string + PostgreSQLPassword string + PostgreSQLDatabase string + MinReplicaCount int + MaxReplicaCount int +} + +const ( + secretTemplate = `apiVersion: v1 +kind: Secret +metadata: + name: {{.SecretName}} + namespace: {{.TestNamespace}} +type: Opaque +data: + postgresql_conn_str: {{.PostgreSQLConnectionStringBase64}} +` +) + +func TestPostreSQLScaler(t *testing.T) { + // Create kubernetes resources for PostgreSQL server + kc := GetKubernetesClient(t) + data, postgreSQLtemplates := getPostgreSQLTemplateData() + CreateKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates) + + assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, postgreSQLStatefulSetName, testNamespace, 1, 60, 3), + "replica count should be %d after 3 minutes", 1) + + createTableSQL := "CREATE TABLE task_instance (id serial PRIMARY KEY,state VARCHAR(10));" + ok, out, errOut, err := WaitForSuccessfulExecCommandOnSpecificPod(t, postgresqlPodName, testNamespace, + fmt.Sprintf("psql -U %s -d %s -c \"%s\"", postgreSQLUsername, postgreSQLDatabase, createTableSQL), 60, 3) + assert.True(t, ok, "executing a command on PostreSQL Pod should work; Output: %s, ErrorOutput: %s, Error: %s", out, errOut, err) + + // Create kubernetes resources for testing + data, templates := getTemplateData() + KubectlApplyMultipleWithTemplate(t, data, templates) + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) + + testActivation(t, kc, data) + testScaleOut(t, kc, data) + testScaleIn(t, kc) + + // cleanup + KubectlDeleteMultipleWithTemplate(t, data, templates) + DeleteKubernetesResources(t, testNamespace, data, postgreSQLtemplates) +} + +func testActivation(t *testing.T, kc *kubernetes.Clientset, data templateData) { + t.Log("--- testing activation ---") + KubectlApplyWithTemplate(t, data, "lowLevelRecordsJobTemplate", pg.LowLevelRecordsJobTemplate) + + AssertReplicaCountNotChangeDuringTimePeriod(t, kc, deploymentName, testNamespace, minReplicaCount, 60) +} + +func testScaleOut(t *testing.T, kc *kubernetes.Clientset, data templateData) { + t.Log("--- testing scale out ---") + KubectlApplyWithTemplate(t, data, "insertRecordsJobTemplate", pg.InsertRecordsJobTemplate) + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", maxReplicaCount) +} + +func testScaleIn(t *testing.T, kc *kubernetes.Clientset) { + t.Log("--- testing scale in ---") + + assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), + "replica count should be %d after 3 minutes", minReplicaCount) +} + +var data = templateData{ + TestNamespace: testNamespace, + PostgreSQLStatefulSetName: postgreSQLStatefulSetName, + DeploymentName: deploymentName, + ScaledObjectName: scaledObjectName, + MinReplicaCount: minReplicaCount, + MaxReplicaCount: maxReplicaCount, + TriggerAuthenticationName: triggerAuthenticationName, + SecretName: secretName, + SecretKey: secretKey, + PostgreSQLImage: pg.PostgresqlImage, + PostgreSQLUsername: postgreSQLUsername, + PostgreSQLPassword: postgreSQLPassword, + PostgreSQLDatabase: postgreSQLDatabase, + PostgreSQLConnectionStringBase64: base64.StdEncoding.EncodeToString([]byte(postgreSQLConnectionString)), +} + +func getPostgreSQLTemplateData() (templateData, []Template) { + return data, []Template{ + {Name: "postgreSQLStatefulSetTemplate", Config: pg.PostgreSQLStatefulSetTemplate}, + {Name: "postgreSQLServiceTemplate", Config: pg.PostgreSQLServiceTemplate}, + } +} + +func getTemplateData() (templateData, []Template) { + return data, []Template{ + {Name: "secretTemplate", Config: secretTemplate}, + {Name: "deploymentTemplate", Config: pg.DeploymentTemplate}, + {Name: "triggerAuthenticationTemplate", Config: pg.TriggerAuthenticationTemplate}, + {Name: "scaledObjectTemplate", Config: pg.ScaledObjectTemplate}, + } +} diff --git a/tests/scalers/postgresql/postgresql_test.go b/tests/scalers/postgresql/postgresql_test.go deleted file mode 100644 index 57e9d63576f..00000000000 --- a/tests/scalers/postgresql/postgresql_test.go +++ /dev/null @@ -1,332 +0,0 @@ -//go:build e2e -// +build e2e - -package postgresql_test - -import ( - "encoding/base64" - "fmt" - "testing" - - "github.com/joho/godotenv" - "github.com/stretchr/testify/assert" - "k8s.io/client-go/kubernetes" - - . "github.com/kedacore/keda/v2/tests/helper" -) - -// Load environment variables from .env file -var _ = godotenv.Load("../../.env") - -const ( - testName = "postgresql-test" -) - -var ( - testNamespace = fmt.Sprintf("%s-ns", testName) - deploymentName = fmt.Sprintf("%s-deployment", testName) - scaledObjectName = fmt.Sprintf("%s-so", testName) - triggerAuthenticationName = fmt.Sprintf("%s-ta", testName) - secretName = fmt.Sprintf("%s-secret", testName) - postgreSQLStatefulSetName = "postgresql" - postgresqlPodName = fmt.Sprintf("%s-0", postgreSQLStatefulSetName) - postgreSQLUsername = "test-user" - postgreSQLPassword = "test-password" - postgreSQLDatabase = "test_db" - postgreSQLConnectionString = fmt.Sprintf("postgresql://%s:%s@postgresql.%s.svc.cluster.local:5432/%s?sslmode=disable", - postgreSQLUsername, postgreSQLPassword, testNamespace, postgreSQLDatabase) - minReplicaCount = 0 - maxReplicaCount = 2 -) - -type templateData struct { - TestNamespace string - DeploymentName string - ScaledObjectName string - TriggerAuthenticationName string - SecretName string - PostgreSQLStatefulSetName string - PostgreSQLConnectionStringBase64 string - PostgreSQLUsername string - PostgreSQLPassword string - PostgreSQLDatabase string - MinReplicaCount int - MaxReplicaCount int -} - -const ( - deploymentTemplate = `apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: postgresql-update-worker - name: {{.DeploymentName}} - namespace: {{.TestNamespace}} -spec: - replicas: 0 - selector: - matchLabels: - app: postgresql-update-worker - template: - metadata: - labels: - app: postgresql-update-worker - spec: - containers: - - image: ghcr.io/kedacore/tests-postgresql - imagePullPolicy: Always - name: postgresql-processor-test - command: - - /app - - update - env: - - name: TASK_INSTANCES_COUNT - value: "6000" - - name: CONNECTION_STRING - valueFrom: - secretKeyRef: - name: {{.SecretName}} - key: postgresql_conn_str -` - - secretTemplate = `apiVersion: v1 -kind: Secret -metadata: - name: {{.SecretName}} - namespace: {{.TestNamespace}} -type: Opaque -data: - postgresql_conn_str: {{.PostgreSQLConnectionStringBase64}} -` - - triggerAuthenticationTemplate = `apiVersion: keda.sh/v1alpha1 -kind: TriggerAuthentication -metadata: - name: {{.TriggerAuthenticationName}} - namespace: {{.TestNamespace}} -spec: - secretTargetRef: - - parameter: connection - name: {{.SecretName}} - key: postgresql_conn_str -` - - scaledObjectTemplate = `apiVersion: keda.sh/v1alpha1 -kind: ScaledObject -metadata: - name: {{.ScaledObjectName}} - namespace: {{.TestNamespace}} -spec: - scaleTargetRef: - name: {{.DeploymentName}} - pollingInterval: 5 - cooldownPeriod: 10 - minReplicaCount: {{.MinReplicaCount}} - maxReplicaCount: {{.MaxReplicaCount}} - triggers: - - type: postgresql - metadata: - targetQueryValue: "4" - activationTargetQueryValue: "5" - query: "SELECT CEIL(COUNT(*) / 5) FROM task_instance WHERE state='running' OR state='queued'" - authenticationRef: - name: {{.TriggerAuthenticationName}} -` - - postgreSQLStatefulSetTemplate = `apiVersion: apps/v1 -kind: StatefulSet -metadata: - labels: - app: {{.PostgreSQLStatefulSetName}} - name: {{.PostgreSQLStatefulSetName}} - namespace: {{.TestNamespace}} -spec: - replicas: 1 - serviceName: {{.PostgreSQLStatefulSetName}} - selector: - matchLabels: - app: {{.PostgreSQLStatefulSetName}} - template: - metadata: - labels: - app: {{.PostgreSQLStatefulSetName}} - spec: - containers: - - image: postgres:10.5 - name: postgresql - env: - - name: POSTGRES_USER - value: {{.PostgreSQLUsername}} - - name: POSTGRES_PASSWORD - value: {{.PostgreSQLPassword}} - - name: POSTGRES_DB - value: {{.PostgreSQLDatabase}} - ports: - - name: postgresql - protocol: TCP - containerPort: 5432 -` - - postgreSQLServiceTemplate = `apiVersion: v1 -kind: Service -metadata: - labels: - app: {{.PostgreSQLStatefulSetName}} - name: {{.PostgreSQLStatefulSetName}} - namespace: {{.TestNamespace}} -spec: - ports: - - port: 5432 - protocol: TCP - targetPort: 5432 - selector: - app: {{.PostgreSQLStatefulSetName}} - type: ClusterIP -` - - lowLevelRecordsJobTemplate = `apiVersion: batch/v1 -kind: Job -metadata: - labels: - app: postgresql-insert-low-level-job - name: postgresql-insert-low-level-job - namespace: {{.TestNamespace}} -spec: - template: - metadata: - labels: - app: postgresql-insert-low-level-job - spec: - containers: - - image: ghcr.io/kedacore/tests-postgresql - imagePullPolicy: Always - name: postgresql-processor-test - command: - - /app - - insert - env: - - name: TASK_INSTANCES_COUNT - value: "20" - - name: CONNECTION_STRING - valueFrom: - secretKeyRef: - name: {{.SecretName}} - key: postgresql_conn_str - restartPolicy: Never - backoffLimit: 4 -` - - insertRecordsJobTemplate = `apiVersion: batch/v1 -kind: Job -metadata: - labels: - app: postgresql-insert-job - name: postgresql-insert-job - namespace: {{.TestNamespace}} -spec: - template: - metadata: - labels: - app: postgresql-insert-job - spec: - containers: - - image: ghcr.io/kedacore/tests-postgresql - imagePullPolicy: Always - name: postgresql-processor-test - command: - - /app - - insert - env: - - name: TASK_INSTANCES_COUNT - value: "10000" - - name: CONNECTION_STRING - valueFrom: - secretKeyRef: - name: {{.SecretName}} - key: postgresql_conn_str - restartPolicy: Never - backoffLimit: 4 -` -) - -func TestPostreSQLScaler(t *testing.T) { - // Create kubernetes resources for PostgreSQL server - kc := GetKubernetesClient(t) - data, postgreSQLtemplates := getPostgreSQLTemplateData() - CreateKubernetesResources(t, kc, testNamespace, data, postgreSQLtemplates) - - assert.True(t, WaitForStatefulsetReplicaReadyCount(t, kc, postgreSQLStatefulSetName, testNamespace, 1, 60, 3), - "replica count should be %d after 3 minutes", 1) - - createTableSQL := "CREATE TABLE task_instance (id serial PRIMARY KEY,state VARCHAR(10));" - ok, out, errOut, err := WaitForSuccessfulExecCommandOnSpecificPod(t, postgresqlPodName, testNamespace, - fmt.Sprintf("psql -U %s -d %s -c \"%s\"", postgreSQLUsername, postgreSQLDatabase, createTableSQL), 60, 3) - assert.True(t, ok, "executing a command on PostreSQL Pod should work; Output: %s, ErrorOutput: %s, Error: %s", out, errOut, err) - - // Create kubernetes resources for testing - data, templates := getTemplateData() - KubectlApplyMultipleWithTemplate(t, data, templates) - assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), - "replica count should be %d after 3 minutes", minReplicaCount) - - testActivation(t, kc, data) - testScaleOut(t, kc, data) - testScaleIn(t, kc) - - // cleanup - KubectlDeleteMultipleWithTemplate(t, data, templates) - DeleteKubernetesResources(t, testNamespace, data, postgreSQLtemplates) -} - -func testActivation(t *testing.T, kc *kubernetes.Clientset, data templateData) { - t.Log("--- testing activation ---") - KubectlApplyWithTemplate(t, data, "lowLevelRecordsJobTemplate", lowLevelRecordsJobTemplate) - - AssertReplicaCountNotChangeDuringTimePeriod(t, kc, deploymentName, testNamespace, minReplicaCount, 60) -} - -func testScaleOut(t *testing.T, kc *kubernetes.Clientset, data templateData) { - t.Log("--- testing scale out ---") - KubectlApplyWithTemplate(t, data, "insertRecordsJobTemplate", insertRecordsJobTemplate) - - assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, maxReplicaCount, 60, 3), - "replica count should be %d after 3 minutes", maxReplicaCount) -} - -func testScaleIn(t *testing.T, kc *kubernetes.Clientset) { - t.Log("--- testing scale in ---") - - assert.True(t, WaitForDeploymentReplicaReadyCount(t, kc, deploymentName, testNamespace, minReplicaCount, 60, 3), - "replica count should be %d after 3 minutes", minReplicaCount) -} - -var data = templateData{ - TestNamespace: testNamespace, - PostgreSQLStatefulSetName: postgreSQLStatefulSetName, - DeploymentName: deploymentName, - ScaledObjectName: scaledObjectName, - MinReplicaCount: minReplicaCount, - MaxReplicaCount: maxReplicaCount, - TriggerAuthenticationName: triggerAuthenticationName, - SecretName: secretName, - PostgreSQLUsername: postgreSQLUsername, - PostgreSQLPassword: postgreSQLPassword, - PostgreSQLDatabase: postgreSQLDatabase, - PostgreSQLConnectionStringBase64: base64.StdEncoding.EncodeToString([]byte(postgreSQLConnectionString)), -} - -func getPostgreSQLTemplateData() (templateData, []Template) { - return data, []Template{ - {Name: "postgreSQLStatefulSetTemplate", Config: postgreSQLStatefulSetTemplate}, - {Name: "postgreSQLServiceTemplate", Config: postgreSQLServiceTemplate}, - } -} - -func getTemplateData() (templateData, []Template) { - return data, []Template{ - {Name: "secretTemplate", Config: secretTemplate}, - {Name: "deploymentTemplate", Config: deploymentTemplate}, - {Name: "triggerAuthenticationTemplate", Config: triggerAuthenticationTemplate}, - {Name: "scaledObjectTemplate", Config: scaledObjectTemplate}, - } -} diff --git a/vendor/github.com/jackc/pgpassfile/.travis.yml b/vendor/github.com/jackc/pgpassfile/.travis.yml new file mode 100644 index 00000000000..e176228e8e3 --- /dev/null +++ b/vendor/github.com/jackc/pgpassfile/.travis.yml @@ -0,0 +1,9 @@ +language: go + +go: + - 1.x + - tip + +matrix: + allow_failures: + - go: tip diff --git a/vendor/github.com/jackc/pgpassfile/LICENSE b/vendor/github.com/jackc/pgpassfile/LICENSE new file mode 100644 index 00000000000..c1c4f50fc66 --- /dev/null +++ b/vendor/github.com/jackc/pgpassfile/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2019 Jack Christensen + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/jackc/pgpassfile/README.md b/vendor/github.com/jackc/pgpassfile/README.md new file mode 100644 index 00000000000..661289ed88f --- /dev/null +++ b/vendor/github.com/jackc/pgpassfile/README.md @@ -0,0 +1,8 @@ +[![](https://godoc.org/github.com/jackc/pgpassfile?status.svg)](https://godoc.org/github.com/jackc/pgpassfile) +[![Build Status](https://travis-ci.org/jackc/pgpassfile.svg)](https://travis-ci.org/jackc/pgpassfile) + +# pgpassfile + +Package pgpassfile is a parser PostgreSQL .pgpass files. + +Extracted and rewritten from original implementation in https://github.com/jackc/pgx. diff --git a/vendor/github.com/jackc/pgpassfile/pgpass.go b/vendor/github.com/jackc/pgpassfile/pgpass.go new file mode 100644 index 00000000000..f7eed3c8415 --- /dev/null +++ b/vendor/github.com/jackc/pgpassfile/pgpass.go @@ -0,0 +1,110 @@ +// Package pgpassfile is a parser PostgreSQL .pgpass files. +package pgpassfile + +import ( + "bufio" + "io" + "os" + "regexp" + "strings" +) + +// Entry represents a line in a PG passfile. +type Entry struct { + Hostname string + Port string + Database string + Username string + Password string +} + +// Passfile is the in memory data structure representing a PG passfile. +type Passfile struct { + Entries []*Entry +} + +// ReadPassfile reads the file at path and parses it into a Passfile. +func ReadPassfile(path string) (*Passfile, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + + return ParsePassfile(f) +} + +// ParsePassfile reads r and parses it into a Passfile. +func ParsePassfile(r io.Reader) (*Passfile, error) { + passfile := &Passfile{} + + scanner := bufio.NewScanner(r) + for scanner.Scan() { + entry := parseLine(scanner.Text()) + if entry != nil { + passfile.Entries = append(passfile.Entries, entry) + } + } + + return passfile, scanner.Err() +} + +// Match (not colons or escaped colon or escaped backslash)+. Essentially gives a split on unescaped +// colon. +var colonSplitterRegexp = regexp.MustCompile("(([^:]|(\\:)))+") + +// var colonSplitterRegexp = regexp.MustCompile("((?:[^:]|(?:\\:)|(?:\\\\))+)") + +// parseLine parses a line into an *Entry. It returns nil on comment lines or any other unparsable +// line. +func parseLine(line string) *Entry { + const ( + tmpBackslash = "\r" + tmpColon = "\n" + ) + + line = strings.TrimSpace(line) + + if strings.HasPrefix(line, "#") { + return nil + } + + line = strings.Replace(line, `\\`, tmpBackslash, -1) + line = strings.Replace(line, `\:`, tmpColon, -1) + + parts := strings.Split(line, ":") + if len(parts) != 5 { + return nil + } + + // Unescape escaped colons and backslashes + for i := range parts { + parts[i] = strings.Replace(parts[i], tmpBackslash, `\`, -1) + parts[i] = strings.Replace(parts[i], tmpColon, `:`, -1) + } + + return &Entry{ + Hostname: parts[0], + Port: parts[1], + Database: parts[2], + Username: parts[3], + Password: parts[4], + } +} + +// FindPassword finds the password for the provided hostname, port, database, and username. For a +// Unix domain socket hostname must be set to "localhost". An empty string will be returned if no +// match is found. +// +// See https://www.postgresql.org/docs/current/libpq-pgpass.html for more password file information. +func (pf *Passfile) FindPassword(hostname, port, database, username string) (password string) { + for _, e := range pf.Entries { + if (e.Hostname == "*" || e.Hostname == hostname) && + (e.Port == "*" || e.Port == port) && + (e.Database == "*" || e.Database == database) && + (e.Username == "*" || e.Username == username) { + return e.Password + } + } + return "" +} diff --git a/vendor/github.com/jackc/pgservicefile/.travis.yml b/vendor/github.com/jackc/pgservicefile/.travis.yml new file mode 100644 index 00000000000..e176228e8e3 --- /dev/null +++ b/vendor/github.com/jackc/pgservicefile/.travis.yml @@ -0,0 +1,9 @@ +language: go + +go: + - 1.x + - tip + +matrix: + allow_failures: + - go: tip diff --git a/vendor/github.com/jackc/pgservicefile/LICENSE b/vendor/github.com/jackc/pgservicefile/LICENSE new file mode 100644 index 00000000000..f1b4c289233 --- /dev/null +++ b/vendor/github.com/jackc/pgservicefile/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2020 Jack Christensen + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/jackc/pgservicefile/README.md b/vendor/github.com/jackc/pgservicefile/README.md new file mode 100644 index 00000000000..e50ca12627f --- /dev/null +++ b/vendor/github.com/jackc/pgservicefile/README.md @@ -0,0 +1,6 @@ +[![](https://godoc.org/github.com/jackc/pgservicefile?status.svg)](https://godoc.org/github.com/jackc/pgservicefile) +[![Build Status](https://travis-ci.org/jackc/pgservicefile.svg)](https://travis-ci.org/jackc/pgservicefile) + +# pgservicefile + +Package pgservicefile is a parser for PostgreSQL service files (e.g. `.pg_service.conf`). diff --git a/vendor/github.com/jackc/pgservicefile/pgservicefile.go b/vendor/github.com/jackc/pgservicefile/pgservicefile.go new file mode 100644 index 00000000000..797bbab9e78 --- /dev/null +++ b/vendor/github.com/jackc/pgservicefile/pgservicefile.go @@ -0,0 +1,79 @@ +// Package pgservicefile is a parser for PostgreSQL service files (e.g. .pg_service.conf). +package pgservicefile + +import ( + "bufio" + "errors" + "fmt" + "io" + "os" + "strings" +) + +type Service struct { + Name string + Settings map[string]string +} + +type Servicefile struct { + Services []*Service + servicesByName map[string]*Service +} + +// GetService returns the named service. +func (sf *Servicefile) GetService(name string) (*Service, error) { + service, present := sf.servicesByName[name] + if !present { + return nil, errors.New("not found") + } + return service, nil +} + +// ReadServicefile reads the file at path and parses it into a Servicefile. +func ReadServicefile(path string) (*Servicefile, error) { + f, err := os.Open(path) + if err != nil { + return nil, err + } + defer f.Close() + + return ParseServicefile(f) +} + +// ParseServicefile reads r and parses it into a Servicefile. +func ParseServicefile(r io.Reader) (*Servicefile, error) { + servicefile := &Servicefile{} + + var service *Service + scanner := bufio.NewScanner(r) + lineNum := 0 + for scanner.Scan() { + lineNum += 1 + line := scanner.Text() + line = strings.TrimSpace(line) + + if line == "" || strings.HasPrefix(line, "#") { + // ignore comments and empty lines + } else if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") { + service = &Service{Name: line[1 : len(line)-1], Settings: make(map[string]string)} + servicefile.Services = append(servicefile.Services, service) + } else { + parts := strings.SplitN(line, "=", 2) + if len(parts) != 2 { + return nil, fmt.Errorf("unable to parse line %d", lineNum) + } + + key := strings.TrimSpace(parts[0]) + value := strings.TrimSpace(parts[1]) + + service.Settings[key] = value + } + } + + servicefile.servicesByName = make(map[string]*Service, len(servicefile.Services)) + for _, service := range servicefile.Services { + servicefile.servicesByName[service.Name] = service + } + + return servicefile, scanner.Err() +} diff --git a/vendor/github.com/jackc/pgx/v5/.gitignore b/vendor/github.com/jackc/pgx/v5/.gitignore new file mode 100644 index 00000000000..a2ebbe9c60e --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/.gitignore @@ -0,0 +1,27 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe + +.envrc +/.testdb + +.DS_Store diff --git a/vendor/github.com/jackc/pgx/v5/CHANGELOG.md b/vendor/github.com/jackc/pgx/v5/CHANGELOG.md new file mode 100644 index 00000000000..f923fd8ca4d --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/CHANGELOG.md @@ -0,0 +1,285 @@ +# 5.4.0 (June 14, 2023) + +* Replace platform specific syscalls for non-blocking IO with more traditional goroutines and deadlines. This returns to the v4 approach with some additional improvements and fixes. This restores the ability to use a pgx.Conn over an ssh.Conn as well as other non-TCP or Unix socket connections. In addition, it is a significantly simpler implementation that is less likely to have cross platform issues. +* Optimization: The default type registrations are now shared among all connections. This saves about 100KB of memory per connection. `pgtype.Type` and `pgtype.Codec` values are now required to be immutable after registration. This was already necessary in most cases but wasn't documented until now. (Lev Zakharov) +* Fix: Ensure pgxpool.Pool.QueryRow.Scan releases connection on panic +* CancelRequest: don't try to read the reply (Nicola Murino) +* Fix: correctly handle bool type aliases (Wichert Akkerman) +* Fix: pgconn.CancelRequest: Fix unix sockets: don't use RemoteAddr() +* Fix: pgx.Conn memory leak with prepared statement caching (Evan Jones) +* Add BeforeClose to pgxpool.Pool (Evan Cordell) +* Fix: various hstore fixes and optimizations (Evan Jones) +* Fix: RowToStructByPos with embedded unexported struct +* Support different bool string representations (Lev Zakharov) +* Fix: error when using BatchResults.Exec on a select that returns an error after some rows. +* Fix: pipelineBatchResults.Exec() not returning error from ResultReader +* Fix: pipeline batch results not closing pipeline when error occurs while reading directly from results instead of using + a callback. +* Fix: scanning a table type into a struct +* Fix: scan array of record to pointer to slice of struct +* Fix: handle null for json (Cemre Mengu) +* Batch Query callback is called even when there is an error +* Add RowTo(AddrOf)StructByNameLax (Audi P. Risa P) + +# 5.3.1 (February 27, 2023) + +* Fix: Support v4 and v5 stdlib in same program (Tomáš Procházka) +* Fix: sql.Scanner not being used in certain cases +* Add text format jsonpath support +* Fix: fake non-blocking read adaptive wait time + +# 5.3.0 (February 11, 2023) + +* Fix: json values work with sql.Scanner +* Fixed / improved error messages (Mark Chambers and Yevgeny Pats) +* Fix: support scan into single dimensional arrays +* Fix: MaxConnLifetimeJitter setting actually jitter (Ben Weintraub) +* Fix: driver.Value representation of bytea should be []byte not string +* Fix: better handling of unregistered OIDs +* CopyFrom can use query cache to avoid extra round trip to get OIDs (Alejandro Do Nascimento Mora) +* Fix: encode to json ignoring driver.Valuer +* Support sql.Scanner on renamed base type +* Fix: pgtype.Numeric text encoding of negative numbers (Mark Chambers) +* Fix: connect with multiple hostnames when one can't be resolved +* Upgrade puddle to remove dependency on uber/atomic and fix alignment issue on 32-bit platform +* Fix: scanning json column into **string +* Multiple reductions in memory allocations +* Fake non-blocking read adapts its max wait time +* Improve CopyFrom performance and reduce memory usage +* Fix: encode []any to array +* Fix: LoadType for composite with dropped attributes (Felix Röhrich) +* Support v4 and v5 stdlib in same program +* Fix: text format array decoding with string of "NULL" +* Prefer binary format for arrays + +# 5.2.0 (December 5, 2022) + +* `tracelog.TraceLog` implements the pgx.PrepareTracer interface. (Vitalii Solodilov) +* Optimize creating begin transaction SQL string (Petr Evdokimov and ksco) +* `Conn.LoadType` supports range and multirange types (Vitalii Solodilov) +* Fix scan `uint` and `uint64` `ScanNumeric`. This resolves a PostgreSQL `numeric` being incorrectly scanned into `uint` and `uint64`. + +# 5.1.1 (November 17, 2022) + +* Fix simple query sanitizer where query text contains a Unicode replacement character. +* Remove erroneous `name` argument from `DeallocateAll()`. Technically, this is a breaking change, but given that method was only added 5 days ago this change was accepted. (Bodo Kaiser) + +# 5.1.0 (November 12, 2022) + +* Update puddle to v2.1.2. This resolves a race condition and a deadlock in pgxpool. +* `QueryRewriter.RewriteQuery` now returns an error. Technically, this is a breaking change for any external implementers, but given the minimal likelihood that there are actually any external implementers this change was accepted. +* Expose `GetSSLPassword` support to pgx. +* Fix encode `ErrorResponse` unknown field handling. This would only affect pgproto3 being used directly as a proxy with a non-PostgreSQL server that included additional error fields. +* Fix date text format encoding with 5 digit years. +* Fix date values passed to a `sql.Scanner` as `string` instead of `time.Time`. +* DateCodec.DecodeValue can return `pgtype.InfinityModifier` instead of `string` for infinite values. This now matches the behavior of the timestamp types. +* Add domain type support to `Conn.LoadType()`. +* Add `RowToStructByName` and `RowToAddrOfStructByName`. (Pavlo Golub) +* Add `Conn.DeallocateAll()` to clear all prepared statements including the statement cache. (Bodo Kaiser) + +# 5.0.4 (October 24, 2022) + +* Fix: CollectOneRow prefers PostgreSQL error over pgx.ErrorNoRows +* Fix: some reflect Kind checks to first check for nil +* Bump golang.org/x/text dependency to placate snyk +* Fix: RowToStructByPos on structs with multiple anonymous sub-structs (Baptiste Fontaine) +* Fix: Exec checks if tx is closed + +# 5.0.3 (October 14, 2022) + +* Fix `driver.Valuer` handling edge cases that could cause infinite loop or crash + +# v5.0.2 (October 8, 2022) + +* Fix date encoding in text format to always use 2 digits for month and day +* Prefer driver.Valuer over wrap plans when encoding +* Fix scan to pointer to pointer to renamed type +* Allow scanning NULL even if PG and Go types are incompatible + +# v5.0.1 (September 24, 2022) + +* Fix 32-bit atomic usage +* Add MarshalJSON for Float8 (yogipristiawan) +* Add `[` and `]` to text encoding of `Lseg` +* Fix sqlScannerWrapper NULL handling + +# v5.0.0 (September 17, 2022) + +## Merged Packages + +`github.com/jackc/pgtype`, `github.com/jackc/pgconn`, and `github.com/jackc/pgproto3` are now included in the main +`github.com/jackc/pgx` repository. Previously there was confusion as to where issues should be reported, additional +release work due to releasing multiple packages, and less clear changelogs. + +## pgconn + +`CommandTag` is now an opaque type instead of directly exposing an underlying `[]byte`. + +The return value `ResultReader.Values()` is no longer safe to retain a reference to after a subsequent call to `NextRow()` or `Close()`. + +`Trace()` method adds low level message tracing similar to the `PQtrace` function in `libpq`. + +pgconn now uses non-blocking IO. This is a significant internal restructuring, but it should not cause any visible changes on its own. However, it is important in implementing other new features. + +`CheckConn()` checks a connection's liveness by doing a non-blocking read. This can be used to detect database restarts or network interruptions without executing a query or a ping. + +pgconn now supports pipeline mode. + +`*PgConn.ReceiveResults` removed. Use pipeline mode instead. + +`Timeout()` no longer considers `context.Canceled` as a timeout error. `context.DeadlineExceeded` still is considered a timeout error. + +## pgxpool + +`Connect` and `ConnectConfig` have been renamed to `New` and `NewWithConfig` respectively. The `LazyConnect` option has been removed. Pools always lazily connect. + +## pgtype + +The `pgtype` package has been significantly changed. + +### NULL Representation + +Previously, types had a `Status` field that could be `Undefined`, `Null`, or `Present`. This has been changed to a +`Valid` `bool` field to harmonize with how `database/sql` represents `NULL` and to make the zero value useable. + +Previously, a type that implemented `driver.Valuer` would have the `Value` method called even on a nil pointer. All nils +whether typed or untyped now represent `NULL`. + +### Codec and Value Split + +Previously, the type system combined decoding and encoding values with the value types. e.g. Type `Int8` both handled +encoding and decoding the PostgreSQL representation and acted as a value object. This caused some difficulties when +there was not an exact 1 to 1 relationship between the Go types and the PostgreSQL types For example, scanning a +PostgreSQL binary `numeric` into a Go `float64` was awkward (see https://github.com/jackc/pgtype/issues/147). This +concepts have been separated. A `Codec` only has responsibility for encoding and decoding values. Value types are +generally defined by implementing an interface that a particular `Codec` understands (e.g. `PointScanner` and +`PointValuer` for the PostgreSQL `point` type). + +### Array Types + +All array types are now handled by `ArrayCodec` instead of using code generation for each new array type. This also +means that less common array types such as `point[]` are now supported. `Array[T]` supports PostgreSQL multi-dimensional +arrays. + +### Composite Types + +Composite types must be registered before use. `CompositeFields` may still be used to construct and destruct composite +values, but any type may now implement `CompositeIndexGetter` and `CompositeIndexScanner` to be used as a composite. + +### Range Types + +Range types are now handled with types `RangeCodec` and `Range[T]`. This allows additional user defined range types to +easily be handled. Multirange types are handled similarly with `MultirangeCodec` and `Multirange[T]`. + +### pgxtype + +`LoadDataType` moved to `*Conn` as `LoadType`. + +### Bytea + +The `Bytea` and `GenericBinary` types have been replaced. Use the following instead: + +* `[]byte` - For normal usage directly use `[]byte`. +* `DriverBytes` - Uses driver memory only available until next database method call. Avoids a copy and an allocation. +* `PreallocBytes` - Uses preallocated byte slice to avoid an allocation. +* `UndecodedBytes` - Avoids any decoding. Allows working with raw bytes. + +### Dropped lib/pq Support + +`pgtype` previously supported and was tested against [lib/pq](https://github.com/lib/pq). While it will continue to work +in most cases this is no longer supported. + +### database/sql Scan + +Previously, most `Scan` implementations would convert `[]byte` to `string` automatically to decode a text value. Now +only `string` is handled. This is to allow the possibility of future binary support in `database/sql` mode by +considering `[]byte` to be binary format and `string` text format. This change should have no effect for any use with +`pgx`. The previous behavior was only necessary for `lib/pq` compatibility. + +Added `*Map.SQLScanner` to create a `sql.Scanner` for types such as `[]int32` and `Range[T]` that do not implement +`sql.Scanner` directly. + +### Number Type Fields Include Bit size + +`Int2`, `Int4`, `Int8`, `Float4`, `Float8`, and `Uint32` fields now include bit size. e.g. `Int` is renamed to `Int64`. +This matches the convention set by `database/sql`. In addition, for comparable types like `pgtype.Int8` and +`sql.NullInt64` the structures are identical. This means they can be directly converted one to another. + +### 3rd Party Type Integrations + +* Extracted integrations with https://github.com/shopspring/decimal and https://github.com/gofrs/uuid to + https://github.com/jackc/pgx-shopspring-decimal and https://github.com/jackc/pgx-gofrs-uuid respectively. This trims + the pgx dependency tree. + +### Other Changes + +* `Bit` and `Varbit` are both replaced by the `Bits` type. +* `CID`, `OID`, `OIDValue`, and `XID` are replaced by the `Uint32` type. +* `Hstore` is now defined as `map[string]*string`. +* `JSON` and `JSONB` types removed. Use `[]byte` or `string` directly. +* `QChar` type removed. Use `rune` or `byte` directly. +* `Inet` and `Cidr` types removed. Use `netip.Addr` and `netip.Prefix` directly. These types are more memory efficient than the previous `net.IPNet`. +* `Macaddr` type removed. Use `net.HardwareAddr` directly. +* Renamed `pgtype.ConnInfo` to `pgtype.Map`. +* Renamed `pgtype.DataType` to `pgtype.Type`. +* Renamed `pgtype.None` to `pgtype.Finite`. +* `RegisterType` now accepts a `*Type` instead of `Type`. +* Assorted array helper methods and types made private. + +## stdlib + +* Removed `AcquireConn` and `ReleaseConn` as that functionality has been built in since Go 1.13. + +## Reduced Memory Usage by Reusing Read Buffers + +Previously, the connection read buffer would allocate large chunks of memory and never reuse them. This allowed +transferring ownership to anything such as scanned values without incurring an additional allocation and memory copy. +However, this came at the cost of overall increased memory allocation size. But worse it was also possible to pin large +chunks of memory by retaining a reference to a small value that originally came directly from the read buffer. Now +ownership remains with the read buffer and anything needing to retain a value must make a copy. + +## Query Execution Modes + +Control over automatic prepared statement caching and simple protocol use are now combined into query execution mode. +See documentation for `QueryExecMode`. + +## QueryRewriter Interface and NamedArgs + +pgx now supports named arguments with the `NamedArgs` type. This is implemented via the new `QueryRewriter` interface which +allows arbitrary rewriting of query SQL and arguments. + +## RowScanner Interface + +The `RowScanner` interface allows a single argument to Rows.Scan to scan the entire row. + +## Rows Result Helpers + +* `CollectRows` and `RowTo*` functions simplify collecting results into a slice. +* `CollectOneRow` collects one row using `RowTo*` functions. +* `ForEachRow` simplifies scanning each row and executing code using the scanned values. `ForEachRow` replaces `QueryFunc`. + +## Tx Helpers + +Rather than every type that implemented `Begin` or `BeginTx` methods also needing to implement `BeginFunc` and +`BeginTxFunc` these methods have been converted to functions that take a db that implements `Begin` or `BeginTx`. + +## Improved Batch Query Ergonomics + +Previously, the code for building a batch went in one place before the call to `SendBatch`, and the code for reading the +results went in one place after the call to `SendBatch`. This could make it difficult to match up the query and the code +to handle the results. Now `Queue` returns a `QueuedQuery` which has methods `Query`, `QueryRow`, and `Exec` which can +be used to register a callback function that will handle the result. Callback functions are called automatically when +`BatchResults.Close` is called. + +## SendBatch Uses Pipeline Mode When Appropriate + +Previously, a batch with 10 unique parameterized statements executed 100 times would entail 11 network round trips. 1 +for each prepare / describe and 1 for executing them all. Now pipeline mode is used to prepare / describe all statements +in a single network round trip. So it would only take 2 round trips. + +## Tracing and Logging + +Internal logging support has been replaced with tracing hooks. This allows custom tracing integration with tools like OpenTelemetry. Package tracelog provides an adapter for pgx v4 loggers to act as a tracer. + +All integrations with 3rd party loggers have been extracted to separate repositories. This trims the pgx dependency +tree. diff --git a/vendor/github.com/jackc/pgx/v5/CONTRIBUTING.md b/vendor/github.com/jackc/pgx/v5/CONTRIBUTING.md new file mode 100644 index 00000000000..3eb0da5b925 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/CONTRIBUTING.md @@ -0,0 +1,134 @@ +# Contributing + +## Discuss Significant Changes + +Before you invest a significant amount of time on a change, please create a discussion or issue describing your +proposal. This will help to ensure your proposed change has a reasonable chance of being merged. + +## Avoid Dependencies + +Adding a dependency is a big deal. While on occasion a new dependency may be accepted, the default answer to any change +that adds a dependency is no. + +## Development Environment Setup + +pgx tests naturally require a PostgreSQL database. It will connect to the database specified in the `PGX_TEST_DATABASE` +environment variable. The `PGX_TEST_DATABASE` environment variable can either be a URL or key-value pairs. In addition, +the standard `PG*` environment variables will be respected. Consider using [direnv](https://github.com/direnv/direnv) to +simplify environment variable handling. + +### Using an Existing PostgreSQL Cluster + +If you already have a PostgreSQL development server this is the quickest way to start and run the majority of the pgx +test suite. Some tests will be skipped that require server configuration changes (e.g. those testing different +authentication methods). + +Create and setup a test database: + +``` +export PGDATABASE=pgx_test +createdb +psql -c 'create extension hstore;' +psql -c 'create domain uint64 as numeric(20,0);' +``` + +Ensure a `postgres` user exists. This happens by default in normal PostgreSQL installs, but some installation methods +such as Homebrew do not. + +``` +createuser -s postgres +``` + +Ensure your `PGX_TEST_DATABASE` environment variable points to the database you just created and run the tests. + +``` +export PGX_TEST_DATABASE="host=/private/tmp database=pgx_test" +go test ./... +``` + +This will run the vast majority of the tests, but some tests will be skipped (e.g. those testing different connection methods). + +### Creating a New PostgreSQL Cluster Exclusively for Testing + +The following environment variables need to be set both for initial setup and whenever the tests are run. (direnv is +highly recommended). Depending on your platform, you may need to change the host for `PGX_TEST_UNIX_SOCKET_CONN_STRING`. + +``` +export PGPORT=5015 +export PGUSER=postgres +export PGDATABASE=pgx_test +export POSTGRESQL_DATA_DIR=postgresql + +export PGX_TEST_DATABASE="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret" +export PGX_TEST_UNIX_SOCKET_CONN_STRING="host=/private/tmp database=pgx_test" +export PGX_TEST_TCP_CONN_STRING="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret" +export PGX_TEST_SCRAM_PASSWORD_CONN_STRING="host=127.0.0.1 user=pgx_scram password=secret database=pgx_test" +export PGX_TEST_MD5_PASSWORD_CONN_STRING="host=127.0.0.1 database=pgx_test user=pgx_md5 password=secret" +export PGX_TEST_PLAIN_PASSWORD_CONN_STRING="host=127.0.0.1 user=pgx_pw password=secret" +export PGX_TEST_TLS_CONN_STRING="host=localhost user=pgx_ssl password=secret sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem" +export PGX_SSL_PASSWORD=certpw +export PGX_TEST_TLS_CLIENT_CONN_STRING="host=localhost user=pgx_sslcert sslmode=verify-full sslrootcert=`pwd`/.testdb/ca.pem database=pgx_test sslcert=`pwd`/.testdb/pgx_sslcert.crt sslkey=`pwd`/.testdb/pgx_sslcert.key" +``` + +Create a new database cluster. + +``` +initdb --locale=en_US -E UTF-8 --username=postgres .testdb/$POSTGRESQL_DATA_DIR + +echo "listen_addresses = '127.0.0.1'" >> .testdb/$POSTGRESQL_DATA_DIR/postgresql.conf +echo "port = $PGPORT" >> .testdb/$POSTGRESQL_DATA_DIR/postgresql.conf +cat testsetup/postgresql_ssl.conf >> .testdb/$POSTGRESQL_DATA_DIR/postgresql.conf +cp testsetup/pg_hba.conf .testdb/$POSTGRESQL_DATA_DIR/pg_hba.conf +cp testsetup/ca.cnf .testdb +cp testsetup/localhost.cnf .testdb +cp testsetup/pgx_sslcert.cnf .testdb + +cd .testdb + +# Generate a CA public / private key pair. +openssl genrsa -out ca.key 4096 +openssl req -x509 -config ca.cnf -new -nodes -key ca.key -sha256 -days 365 -subj '/O=pgx-test-root' -out ca.pem + +# Generate the certificate for localhost (the server). +openssl genrsa -out localhost.key 2048 +openssl req -new -config localhost.cnf -key localhost.key -out localhost.csr +openssl x509 -req -in localhost.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out localhost.crt -days 364 -sha256 -extfile localhost.cnf -extensions v3_req + +# Copy certificates to server directory and set permissions. +cp ca.pem $POSTGRESQL_DATA_DIR/root.crt +cp localhost.key $POSTGRESQL_DATA_DIR/server.key +chmod 600 $POSTGRESQL_DATA_DIR/server.key +cp localhost.crt $POSTGRESQL_DATA_DIR/server.crt + +# Generate the certificate for client authentication. +openssl genrsa -des3 -out pgx_sslcert.key -passout pass:certpw 2048 +openssl req -new -config pgx_sslcert.cnf -key pgx_sslcert.key -passin pass:certpw -out pgx_sslcert.csr +openssl x509 -req -in pgx_sslcert.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out pgx_sslcert.crt -days 363 -sha256 -extfile pgx_sslcert.cnf -extensions v3_req + +cd .. +``` + + +Start the new cluster. This will be necessary whenever you are running pgx tests. + +``` +postgres -D .testdb/$POSTGRESQL_DATA_DIR +``` + +Setup the test database in the new cluster. + +``` +createdb +psql --no-psqlrc -f testsetup/postgresql_setup.sql +``` + +### PgBouncer + +There are tests specific for PgBouncer that will be executed if `PGX_TEST_PGBOUNCER_CONN_STRING` is set. + +### Optional Tests + +pgx supports multiple connection types and means of authentication. These tests are optional. They will only run if the +appropriate environment variables are set. In addition, there may be tests specific to particular PostgreSQL versions, +non-PostgreSQL servers (e.g. CockroachDB), or connection poolers (e.g. PgBouncer). `go test ./... -v | grep SKIP` to see +if any tests are being skipped. diff --git a/vendor/github.com/jackc/pgx/v5/LICENSE b/vendor/github.com/jackc/pgx/v5/LICENSE new file mode 100644 index 00000000000..5c486c39a22 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2013-2021 Jack Christensen + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/jackc/pgx/v5/README.md b/vendor/github.com/jackc/pgx/v5/README.md new file mode 100644 index 00000000000..14327f2c654 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/README.md @@ -0,0 +1,168 @@ +[![Go Reference](https://pkg.go.dev/badge/github.com/jackc/pgx/v5.svg)](https://pkg.go.dev/github.com/jackc/pgx/v5) +![Build Status](https://github.com/jackc/pgx/actions/workflows/ci.yml/badge.svg) + +# pgx - PostgreSQL Driver and Toolkit + +pgx is a pure Go driver and toolkit for PostgreSQL. + +The pgx driver is a low-level, high performance interface that exposes PostgreSQL-specific features such as `LISTEN` / +`NOTIFY` and `COPY`. It also includes an adapter for the standard `database/sql` interface. + +The toolkit component is a related set of packages that implement PostgreSQL functionality such as parsing the wire protocol +and type mapping between PostgreSQL and Go. These underlying packages can be used to implement alternative drivers, +proxies, load balancers, logical replication clients, etc. + +## Example Usage + +```go +package main + +import ( + "context" + "fmt" + "os" + + "github.com/jackc/pgx/v5" +) + +func main() { + // urlExample := "postgres://username:password@localhost:5432/database_name" + conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL")) + if err != nil { + fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err) + os.Exit(1) + } + defer conn.Close(context.Background()) + + var name string + var weight int64 + err = conn.QueryRow(context.Background(), "select name, weight from widgets where id=$1", 42).Scan(&name, &weight) + if err != nil { + fmt.Fprintf(os.Stderr, "QueryRow failed: %v\n", err) + os.Exit(1) + } + + fmt.Println(name, weight) +} +``` + +See the [getting started guide](https://github.com/jackc/pgx/wiki/Getting-started-with-pgx) for more information. + +## Features + +* Support for approximately 70 different PostgreSQL types +* Automatic statement preparation and caching +* Batch queries +* Single-round trip query mode +* Full TLS connection control +* Binary format support for custom types (allows for much quicker encoding/decoding) +* `COPY` protocol support for faster bulk data loads +* Tracing and logging support +* Connection pool with after-connect hook for arbitrary connection setup +* `LISTEN` / `NOTIFY` +* Conversion of PostgreSQL arrays to Go slice mappings for integers, floats, and strings +* `hstore` support +* `json` and `jsonb` support +* Maps `inet` and `cidr` PostgreSQL types to `netip.Addr` and `netip.Prefix` +* Large object support +* NULL mapping to pointer to pointer +* Supports `database/sql.Scanner` and `database/sql/driver.Valuer` interfaces for custom types +* Notice response handling +* Simulated nested transactions with savepoints + +## Choosing Between the pgx and database/sql Interfaces + +The pgx interface is faster. Many PostgreSQL specific features such as `LISTEN` / `NOTIFY` and `COPY` are not available +through the `database/sql` interface. + +The pgx interface is recommended when: + +1. The application only targets PostgreSQL. +2. No other libraries that require `database/sql` are in use. + +It is also possible to use the `database/sql` interface and convert a connection to the lower-level pgx interface as needed. + +## Testing + +See CONTRIBUTING.md for setup instructions. + +## Supported Go and PostgreSQL Versions + +pgx supports the same versions of Go and PostgreSQL that are supported by their respective teams. For [Go](https://golang.org/doc/devel/release.html#policy) that is the two most recent major releases and for [PostgreSQL](https://www.postgresql.org/support/versioning/) the major releases in the last 5 years. This means pgx supports Go 1.19 and higher and PostgreSQL 11 and higher. pgx also is tested against the latest version of [CockroachDB](https://www.cockroachlabs.com/product/). + +## Version Policy + +pgx follows semantic versioning for the documented public API on stable releases. `v5` is the latest stable major version. + +## PGX Family Libraries + +### [github.com/jackc/pglogrepl](https://github.com/jackc/pglogrepl) + +pglogrepl provides functionality to act as a client for PostgreSQL logical replication. + +### [github.com/jackc/pgmock](https://github.com/jackc/pgmock) + +pgmock offers the ability to create a server that mocks the PostgreSQL wire protocol. This is used internally to test pgx by purposely inducing unusual errors. pgproto3 and pgmock together provide most of the foundational tooling required to implement a PostgreSQL proxy or MitM (such as for a custom connection pooler). + +### [github.com/jackc/tern](https://github.com/jackc/tern) + +tern is a stand-alone SQL migration system. + +### [github.com/jackc/pgerrcode](https://github.com/jackc/pgerrcode) + +pgerrcode contains constants for the PostgreSQL error codes. + +## Adapters for 3rd Party Types + +* [github.com/jackc/pgx-gofrs-uuid](https://github.com/jackc/pgx-gofrs-uuid) +* [github.com/jackc/pgx-shopspring-decimal](https://github.com/jackc/pgx-shopspring-decimal) +* [github.com/vgarvardt/pgx-google-uuid](https://github.com/vgarvardt/pgx-google-uuid) + + +## Adapters for 3rd Party Tracers + +* [https://github.com/jackhopner/pgx-xray-tracer](https://github.com/jackhopner/pgx-xray-tracer) + +## Adapters for 3rd Party Loggers + +These adapters can be used with the tracelog package. + +* [github.com/jackc/pgx-go-kit-log](https://github.com/jackc/pgx-go-kit-log) +* [github.com/jackc/pgx-log15](https://github.com/jackc/pgx-log15) +* [github.com/jackc/pgx-logrus](https://github.com/jackc/pgx-logrus) +* [github.com/jackc/pgx-zap](https://github.com/jackc/pgx-zap) +* [github.com/jackc/pgx-zerolog](https://github.com/jackc/pgx-zerolog) +* [github.com/mcosta74/pgx-slog](https://github.com/mcosta74/pgx-slog) + +## 3rd Party Libraries with PGX Support + +### [github.com/pashagolub/pgxmock](https://github.com/pashagolub/pgxmock) + +pgxmock is a mock library implementing pgx interfaces. +pgxmock has one and only purpose - to simulate pgx behavior in tests, without needing a real database connection. + +### [github.com/georgysavva/scany](https://github.com/georgysavva/scany) + +Library for scanning data from a database into Go structs and more. + +### [github.com/vingarcia/ksql](https://github.com/vingarcia/ksql) + +A carefully designed SQL client for making using SQL easier, +more productive, and less error-prone on Golang. + +### [https://github.com/otan/gopgkrb5](https://github.com/otan/gopgkrb5) + +Adds GSSAPI / Kerberos authentication support. + +### [github.com/wcamarao/pmx](https://github.com/wcamarao/pmx) + +Explicit data mapping and scanning library for Go structs and slices. + +### [github.com/stephenafamo/scan](https://github.com/stephenafamo/scan) + +Type safe and flexible package for scanning database data into Go types. +Supports, structs, maps, slices and custom mapping functions. + +### [https://github.com/z0ne-dev/mgx](https://github.com/z0ne-dev/mgx) + +Code first migration library for native pgx (no database/sql abstraction). diff --git a/vendor/github.com/jackc/pgx/v5/Rakefile b/vendor/github.com/jackc/pgx/v5/Rakefile new file mode 100644 index 00000000000..d957573e954 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/Rakefile @@ -0,0 +1,18 @@ +require "erb" + +rule '.go' => '.go.erb' do |task| + erb = ERB.new(File.read(task.source)) + File.write(task.name, "// Do not edit. Generated from #{task.source}\n" + erb.result(binding)) + sh "goimports", "-w", task.name +end + +generated_code_files = [ + "pgtype/int.go", + "pgtype/int_test.go", + "pgtype/integration_benchmark_test.go", + "pgtype/zeronull/int.go", + "pgtype/zeronull/int_test.go" +] + +desc "Generate code" +task generate: generated_code_files diff --git a/vendor/github.com/jackc/pgx/v5/batch.go b/vendor/github.com/jackc/pgx/v5/batch.go new file mode 100644 index 00000000000..8f6ea4f0d5c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/batch.go @@ -0,0 +1,431 @@ +package pgx + +import ( + "context" + "errors" + "fmt" + + "github.com/jackc/pgx/v5/pgconn" +) + +// QueuedQuery is a query that has been queued for execution via a Batch. +type QueuedQuery struct { + query string + arguments []any + fn batchItemFunc + sd *pgconn.StatementDescription +} + +type batchItemFunc func(br BatchResults) error + +// Query sets fn to be called when the response to qq is received. +func (qq *QueuedQuery) Query(fn func(rows Rows) error) { + qq.fn = func(br BatchResults) error { + rows, _ := br.Query() + defer rows.Close() + + err := fn(rows) + if err != nil { + return err + } + rows.Close() + + return rows.Err() + } +} + +// Query sets fn to be called when the response to qq is received. +func (qq *QueuedQuery) QueryRow(fn func(row Row) error) { + qq.fn = func(br BatchResults) error { + row := br.QueryRow() + return fn(row) + } +} + +// Exec sets fn to be called when the response to qq is received. +func (qq *QueuedQuery) Exec(fn func(ct pgconn.CommandTag) error) { + qq.fn = func(br BatchResults) error { + ct, err := br.Exec() + if err != nil { + return err + } + + return fn(ct) + } +} + +// Batch queries are a way of bundling multiple queries together to avoid +// unnecessary network round trips. A Batch must only be sent once. +type Batch struct { + queuedQueries []*QueuedQuery +} + +// Queue queues a query to batch b. query can be an SQL query or the name of a prepared statement. +func (b *Batch) Queue(query string, arguments ...any) *QueuedQuery { + qq := &QueuedQuery{ + query: query, + arguments: arguments, + } + b.queuedQueries = append(b.queuedQueries, qq) + return qq +} + +// Len returns number of queries that have been queued so far. +func (b *Batch) Len() int { + return len(b.queuedQueries) +} + +type BatchResults interface { + // Exec reads the results from the next query in the batch as if the query has been sent with Conn.Exec. Prefer + // calling Exec on the QueuedQuery. + Exec() (pgconn.CommandTag, error) + + // Query reads the results from the next query in the batch as if the query has been sent with Conn.Query. Prefer + // calling Query on the QueuedQuery. + Query() (Rows, error) + + // QueryRow reads the results from the next query in the batch as if the query has been sent with Conn.QueryRow. + // Prefer calling QueryRow on the QueuedQuery. + QueryRow() Row + + // Close closes the batch operation. All unread results are read and any callback functions registered with + // QueuedQuery.Query, QueuedQuery.QueryRow, or QueuedQuery.Exec will be called. If a callback function returns an + // error or the batch encounters an error subsequent callback functions will not be called. + // + // Close must be called before the underlying connection can be used again. Any error that occurred during a batch + // operation may have made it impossible to resyncronize the connection with the server. In this case the underlying + // connection will have been closed. + // + // Close is safe to call multiple times. If it returns an error subsequent calls will return the same error. Callback + // functions will not be rerun. + Close() error +} + +type batchResults struct { + ctx context.Context + conn *Conn + mrr *pgconn.MultiResultReader + err error + b *Batch + qqIdx int + closed bool + endTraced bool +} + +// Exec reads the results from the next query in the batch as if the query has been sent with Exec. +func (br *batchResults) Exec() (pgconn.CommandTag, error) { + if br.err != nil { + return pgconn.CommandTag{}, br.err + } + if br.closed { + return pgconn.CommandTag{}, fmt.Errorf("batch already closed") + } + + query, arguments, _ := br.nextQueryAndArgs() + + if !br.mrr.NextResult() { + err := br.mrr.Close() + if err == nil { + err = errors.New("no result") + } + if br.conn.batchTracer != nil { + br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{ + SQL: query, + Args: arguments, + Err: err, + }) + } + return pgconn.CommandTag{}, err + } + + commandTag, err := br.mrr.ResultReader().Close() + if err != nil { + br.err = err + br.mrr.Close() + } + + if br.conn.batchTracer != nil { + br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{ + SQL: query, + Args: arguments, + CommandTag: commandTag, + Err: br.err, + }) + } + + return commandTag, br.err +} + +// Query reads the results from the next query in the batch as if the query has been sent with Query. +func (br *batchResults) Query() (Rows, error) { + query, arguments, ok := br.nextQueryAndArgs() + if !ok { + query = "batch query" + } + + if br.err != nil { + return &baseRows{err: br.err, closed: true}, br.err + } + + if br.closed { + alreadyClosedErr := fmt.Errorf("batch already closed") + return &baseRows{err: alreadyClosedErr, closed: true}, alreadyClosedErr + } + + rows := br.conn.getRows(br.ctx, query, arguments) + rows.batchTracer = br.conn.batchTracer + + if !br.mrr.NextResult() { + rows.err = br.mrr.Close() + if rows.err == nil { + rows.err = errors.New("no result") + } + rows.closed = true + + if br.conn.batchTracer != nil { + br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{ + SQL: query, + Args: arguments, + Err: rows.err, + }) + } + + return rows, rows.err + } + + rows.resultReader = br.mrr.ResultReader() + return rows, nil +} + +// QueryRow reads the results from the next query in the batch as if the query has been sent with QueryRow. +func (br *batchResults) QueryRow() Row { + rows, _ := br.Query() + return (*connRow)(rows.(*baseRows)) + +} + +// Close closes the batch operation. Any error that occurred during a batch operation may have made it impossible to +// resyncronize the connection with the server. In this case the underlying connection will have been closed. +func (br *batchResults) Close() error { + defer func() { + if !br.endTraced { + if br.conn != nil && br.conn.batchTracer != nil { + br.conn.batchTracer.TraceBatchEnd(br.ctx, br.conn, TraceBatchEndData{Err: br.err}) + } + br.endTraced = true + } + }() + + if br.err != nil { + return br.err + } + + if br.closed { + return nil + } + + // Read and run fn for all remaining items + for br.err == nil && !br.closed && br.b != nil && br.qqIdx < len(br.b.queuedQueries) { + if br.b.queuedQueries[br.qqIdx].fn != nil { + err := br.b.queuedQueries[br.qqIdx].fn(br) + if err != nil { + br.err = err + } + } else { + br.Exec() + } + } + + br.closed = true + + err := br.mrr.Close() + if br.err == nil { + br.err = err + } + + return br.err +} + +func (br *batchResults) earlyError() error { + return br.err +} + +func (br *batchResults) nextQueryAndArgs() (query string, args []any, ok bool) { + if br.b != nil && br.qqIdx < len(br.b.queuedQueries) { + bi := br.b.queuedQueries[br.qqIdx] + query = bi.query + args = bi.arguments + ok = true + br.qqIdx++ + } + return +} + +type pipelineBatchResults struct { + ctx context.Context + conn *Conn + pipeline *pgconn.Pipeline + lastRows *baseRows + err error + b *Batch + qqIdx int + closed bool + endTraced bool +} + +// Exec reads the results from the next query in the batch as if the query has been sent with Exec. +func (br *pipelineBatchResults) Exec() (pgconn.CommandTag, error) { + if br.err != nil { + return pgconn.CommandTag{}, br.err + } + if br.closed { + return pgconn.CommandTag{}, fmt.Errorf("batch already closed") + } + if br.lastRows != nil && br.lastRows.err != nil { + return pgconn.CommandTag{}, br.err + } + + query, arguments, _ := br.nextQueryAndArgs() + + results, err := br.pipeline.GetResults() + if err != nil { + br.err = err + return pgconn.CommandTag{}, br.err + } + var commandTag pgconn.CommandTag + switch results := results.(type) { + case *pgconn.ResultReader: + commandTag, br.err = results.Close() + default: + return pgconn.CommandTag{}, fmt.Errorf("unexpected pipeline result: %T", results) + } + + if br.conn.batchTracer != nil { + br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{ + SQL: query, + Args: arguments, + CommandTag: commandTag, + Err: br.err, + }) + } + + return commandTag, br.err +} + +// Query reads the results from the next query in the batch as if the query has been sent with Query. +func (br *pipelineBatchResults) Query() (Rows, error) { + if br.err != nil { + return &baseRows{err: br.err, closed: true}, br.err + } + + if br.closed { + alreadyClosedErr := fmt.Errorf("batch already closed") + return &baseRows{err: alreadyClosedErr, closed: true}, alreadyClosedErr + } + + if br.lastRows != nil && br.lastRows.err != nil { + br.err = br.lastRows.err + return &baseRows{err: br.err, closed: true}, br.err + } + + query, arguments, ok := br.nextQueryAndArgs() + if !ok { + query = "batch query" + } + + rows := br.conn.getRows(br.ctx, query, arguments) + rows.batchTracer = br.conn.batchTracer + br.lastRows = rows + + results, err := br.pipeline.GetResults() + if err != nil { + br.err = err + rows.err = err + rows.closed = true + + if br.conn.batchTracer != nil { + br.conn.batchTracer.TraceBatchQuery(br.ctx, br.conn, TraceBatchQueryData{ + SQL: query, + Args: arguments, + Err: err, + }) + } + } else { + switch results := results.(type) { + case *pgconn.ResultReader: + rows.resultReader = results + default: + err = fmt.Errorf("unexpected pipeline result: %T", results) + br.err = err + rows.err = err + rows.closed = true + } + } + + return rows, rows.err +} + +// QueryRow reads the results from the next query in the batch as if the query has been sent with QueryRow. +func (br *pipelineBatchResults) QueryRow() Row { + rows, _ := br.Query() + return (*connRow)(rows.(*baseRows)) + +} + +// Close closes the batch operation. Any error that occurred during a batch operation may have made it impossible to +// resyncronize the connection with the server. In this case the underlying connection will have been closed. +func (br *pipelineBatchResults) Close() error { + defer func() { + if !br.endTraced { + if br.conn.batchTracer != nil { + br.conn.batchTracer.TraceBatchEnd(br.ctx, br.conn, TraceBatchEndData{Err: br.err}) + } + br.endTraced = true + } + }() + + if br.err == nil && br.lastRows != nil && br.lastRows.err != nil { + br.err = br.lastRows.err + return br.err + } + + if br.closed { + return br.err + } + + // Read and run fn for all remaining items + for br.err == nil && !br.closed && br.b != nil && br.qqIdx < len(br.b.queuedQueries) { + if br.b.queuedQueries[br.qqIdx].fn != nil { + err := br.b.queuedQueries[br.qqIdx].fn(br) + if err != nil { + br.err = err + } + } else { + br.Exec() + } + } + + br.closed = true + + err := br.pipeline.Close() + if br.err == nil { + br.err = err + } + + return br.err +} + +func (br *pipelineBatchResults) earlyError() error { + return br.err +} + +func (br *pipelineBatchResults) nextQueryAndArgs() (query string, args []any, ok bool) { + if br.b != nil && br.qqIdx < len(br.b.queuedQueries) { + bi := br.b.queuedQueries[br.qqIdx] + query = bi.query + args = bi.arguments + ok = true + br.qqIdx++ + } + return +} diff --git a/vendor/github.com/jackc/pgx/v5/conn.go b/vendor/github.com/jackc/pgx/v5/conn.go new file mode 100644 index 00000000000..a609d100203 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/conn.go @@ -0,0 +1,1346 @@ +package pgx + +import ( + "context" + "errors" + "fmt" + "strconv" + "strings" + "time" + + "github.com/jackc/pgx/v5/internal/anynil" + "github.com/jackc/pgx/v5/internal/sanitize" + "github.com/jackc/pgx/v5/internal/stmtcache" + "github.com/jackc/pgx/v5/pgconn" + "github.com/jackc/pgx/v5/pgtype" +) + +// ConnConfig contains all the options used to establish a connection. It must be created by ParseConfig and +// then it can be modified. A manually initialized ConnConfig will cause ConnectConfig to panic. +type ConnConfig struct { + pgconn.Config + + Tracer QueryTracer + + // Original connection string that was parsed into config. + connString string + + // StatementCacheCapacity is maximum size of the statement cache used when executing a query with "cache_statement" + // query exec mode. + StatementCacheCapacity int + + // DescriptionCacheCapacity is the maximum size of the description cache used when executing a query with + // "cache_describe" query exec mode. + DescriptionCacheCapacity int + + // DefaultQueryExecMode controls the default mode for executing queries. By default pgx uses the extended protocol + // and automatically prepares and caches prepared statements. However, this may be incompatible with proxies such as + // PGBouncer. In this case it may be preferrable to use QueryExecModeExec or QueryExecModeSimpleProtocol. The same + // functionality can be controlled on a per query basis by passing a QueryExecMode as the first query argument. + DefaultQueryExecMode QueryExecMode + + createdByParseConfig bool // Used to enforce created by ParseConfig rule. +} + +// ParseConfigOptions contains options that control how a config is built such as getsslpassword. +type ParseConfigOptions struct { + pgconn.ParseConfigOptions +} + +// Copy returns a deep copy of the config that is safe to use and modify. +// The only exception is the tls.Config: +// according to the tls.Config docs it must not be modified after creation. +func (cc *ConnConfig) Copy() *ConnConfig { + newConfig := new(ConnConfig) + *newConfig = *cc + newConfig.Config = *newConfig.Config.Copy() + return newConfig +} + +// ConnString returns the connection string as parsed by pgx.ParseConfig into pgx.ConnConfig. +func (cc *ConnConfig) ConnString() string { return cc.connString } + +// Conn is a PostgreSQL connection handle. It is not safe for concurrent usage. Use a connection pool to manage access +// to multiple database connections from multiple goroutines. +type Conn struct { + pgConn *pgconn.PgConn + config *ConnConfig // config used when establishing this connection + preparedStatements map[string]*pgconn.StatementDescription + statementCache stmtcache.Cache + descriptionCache stmtcache.Cache + + queryTracer QueryTracer + batchTracer BatchTracer + copyFromTracer CopyFromTracer + prepareTracer PrepareTracer + + notifications []*pgconn.Notification + + doneChan chan struct{} + closedChan chan error + + typeMap *pgtype.Map + + wbuf []byte + eqb ExtendedQueryBuilder +} + +// Identifier a PostgreSQL identifier or name. Identifiers can be composed of +// multiple parts such as ["schema", "table"] or ["table", "column"]. +type Identifier []string + +// Sanitize returns a sanitized string safe for SQL interpolation. +func (ident Identifier) Sanitize() string { + parts := make([]string, len(ident)) + for i := range ident { + s := strings.ReplaceAll(ident[i], string([]byte{0}), "") + parts[i] = `"` + strings.ReplaceAll(s, `"`, `""`) + `"` + } + return strings.Join(parts, ".") +} + +// ErrNoRows occurs when rows are expected but none are returned. +var ErrNoRows = errors.New("no rows in result set") + +var errDisabledStatementCache = fmt.Errorf("cannot use QueryExecModeCacheStatement with disabled statement cache") +var errDisabledDescriptionCache = fmt.Errorf("cannot use QueryExecModeCacheDescribe with disabled description cache") + +// Connect establishes a connection with a PostgreSQL server with a connection string. See +// pgconn.Connect for details. +func Connect(ctx context.Context, connString string) (*Conn, error) { + connConfig, err := ParseConfig(connString) + if err != nil { + return nil, err + } + return connect(ctx, connConfig) +} + +// ConnectWithOptions behaves exactly like Connect with the addition of options. At the present options is only used to +// provide a GetSSLPassword function. +func ConnectWithOptions(ctx context.Context, connString string, options ParseConfigOptions) (*Conn, error) { + connConfig, err := ParseConfigWithOptions(connString, options) + if err != nil { + return nil, err + } + return connect(ctx, connConfig) +} + +// ConnectConfig establishes a connection with a PostgreSQL server with a configuration struct. +// connConfig must have been created by ParseConfig. +func ConnectConfig(ctx context.Context, connConfig *ConnConfig) (*Conn, error) { + // In general this improves safety. In particular avoid the config.Config.OnNotification mutation from affecting other + // connections with the same config. See https://github.com/jackc/pgx/issues/618. + connConfig = connConfig.Copy() + + return connect(ctx, connConfig) +} + +// ParseConfigWithOptions behaves exactly as ParseConfig does with the addition of options. At the present options is +// only used to provide a GetSSLPassword function. +func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*ConnConfig, error) { + config, err := pgconn.ParseConfigWithOptions(connString, options.ParseConfigOptions) + if err != nil { + return nil, err + } + + statementCacheCapacity := 512 + if s, ok := config.RuntimeParams["statement_cache_capacity"]; ok { + delete(config.RuntimeParams, "statement_cache_capacity") + n, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return nil, fmt.Errorf("cannot parse statement_cache_capacity: %w", err) + } + statementCacheCapacity = int(n) + } + + descriptionCacheCapacity := 512 + if s, ok := config.RuntimeParams["description_cache_capacity"]; ok { + delete(config.RuntimeParams, "description_cache_capacity") + n, err := strconv.ParseInt(s, 10, 32) + if err != nil { + return nil, fmt.Errorf("cannot parse description_cache_capacity: %w", err) + } + descriptionCacheCapacity = int(n) + } + + defaultQueryExecMode := QueryExecModeCacheStatement + if s, ok := config.RuntimeParams["default_query_exec_mode"]; ok { + delete(config.RuntimeParams, "default_query_exec_mode") + switch s { + case "cache_statement": + defaultQueryExecMode = QueryExecModeCacheStatement + case "cache_describe": + defaultQueryExecMode = QueryExecModeCacheDescribe + case "describe_exec": + defaultQueryExecMode = QueryExecModeDescribeExec + case "exec": + defaultQueryExecMode = QueryExecModeExec + case "simple_protocol": + defaultQueryExecMode = QueryExecModeSimpleProtocol + default: + return nil, fmt.Errorf("invalid default_query_exec_mode: %s", s) + } + } + + connConfig := &ConnConfig{ + Config: *config, + createdByParseConfig: true, + StatementCacheCapacity: statementCacheCapacity, + DescriptionCacheCapacity: descriptionCacheCapacity, + DefaultQueryExecMode: defaultQueryExecMode, + connString: connString, + } + + return connConfig, nil +} + +// ParseConfig creates a ConnConfig from a connection string. ParseConfig handles all options that pgconn.ParseConfig +// does. In addition, it accepts the following options: +// +// - default_query_exec_mode. +// Possible values: "cache_statement", "cache_describe", "describe_exec", "exec", and "simple_protocol". See +// QueryExecMode constant documentation for the meaning of these values. Default: "cache_statement". +// +// - statement_cache_capacity. +// The maximum size of the statement cache used when executing a query with "cache_statement" query exec mode. +// Default: 512. +// +// - description_cache_capacity. +// The maximum size of the description cache used when executing a query with "cache_describe" query exec mode. +// Default: 512. +func ParseConfig(connString string) (*ConnConfig, error) { + return ParseConfigWithOptions(connString, ParseConfigOptions{}) +} + +// connect connects to a database. connect takes ownership of config. The caller must not use or access it again. +func connect(ctx context.Context, config *ConnConfig) (c *Conn, err error) { + if connectTracer, ok := config.Tracer.(ConnectTracer); ok { + ctx = connectTracer.TraceConnectStart(ctx, TraceConnectStartData{ConnConfig: config}) + defer func() { + connectTracer.TraceConnectEnd(ctx, TraceConnectEndData{Conn: c, Err: err}) + }() + } + + // Default values are set in ParseConfig. Enforce initial creation by ParseConfig rather than setting defaults from + // zero values. + if !config.createdByParseConfig { + panic("config must be created by ParseConfig") + } + + c = &Conn{ + config: config, + typeMap: pgtype.NewMap(), + queryTracer: config.Tracer, + } + + if t, ok := c.queryTracer.(BatchTracer); ok { + c.batchTracer = t + } + if t, ok := c.queryTracer.(CopyFromTracer); ok { + c.copyFromTracer = t + } + if t, ok := c.queryTracer.(PrepareTracer); ok { + c.prepareTracer = t + } + + // Only install pgx notification system if no other callback handler is present. + if config.Config.OnNotification == nil { + config.Config.OnNotification = c.bufferNotifications + } + + c.pgConn, err = pgconn.ConnectConfig(ctx, &config.Config) + if err != nil { + return nil, err + } + + c.preparedStatements = make(map[string]*pgconn.StatementDescription) + c.doneChan = make(chan struct{}) + c.closedChan = make(chan error) + c.wbuf = make([]byte, 0, 1024) + + if c.config.StatementCacheCapacity > 0 { + c.statementCache = stmtcache.NewLRUCache(c.config.StatementCacheCapacity) + } + + if c.config.DescriptionCacheCapacity > 0 { + c.descriptionCache = stmtcache.NewLRUCache(c.config.DescriptionCacheCapacity) + } + + return c, nil +} + +// Close closes a connection. It is safe to call Close on a already closed +// connection. +func (c *Conn) Close(ctx context.Context) error { + if c.IsClosed() { + return nil + } + + err := c.pgConn.Close(ctx) + return err +} + +// Prepare creates a prepared statement with name and sql. sql can contain placeholders +// for bound parameters. These placeholders are referenced positional as $1, $2, etc. +// +// Prepare is idempotent; i.e. it is safe to call Prepare multiple times with the same +// name and sql arguments. This allows a code path to Prepare and Query/Exec without +// concern for if the statement has already been prepared. +func (c *Conn) Prepare(ctx context.Context, name, sql string) (sd *pgconn.StatementDescription, err error) { + if c.prepareTracer != nil { + ctx = c.prepareTracer.TracePrepareStart(ctx, c, TracePrepareStartData{Name: name, SQL: sql}) + } + + if name != "" { + var ok bool + if sd, ok = c.preparedStatements[name]; ok && sd.SQL == sql { + if c.prepareTracer != nil { + c.prepareTracer.TracePrepareEnd(ctx, c, TracePrepareEndData{AlreadyPrepared: true}) + } + return sd, nil + } + } + + if c.prepareTracer != nil { + defer func() { + c.prepareTracer.TracePrepareEnd(ctx, c, TracePrepareEndData{Err: err}) + }() + } + + sd, err = c.pgConn.Prepare(ctx, name, sql, nil) + if err != nil { + return nil, err + } + + if name != "" { + c.preparedStatements[name] = sd + } + + return sd, nil +} + +// Deallocate released a prepared statement +func (c *Conn) Deallocate(ctx context.Context, name string) error { + delete(c.preparedStatements, name) + _, err := c.pgConn.Exec(ctx, "deallocate "+quoteIdentifier(name)).ReadAll() + return err +} + +// DeallocateAll releases all previously prepared statements from the server and client, where it also resets the statement and description cache. +func (c *Conn) DeallocateAll(ctx context.Context) error { + c.preparedStatements = map[string]*pgconn.StatementDescription{} + if c.config.StatementCacheCapacity > 0 { + c.statementCache = stmtcache.NewLRUCache(c.config.StatementCacheCapacity) + } + if c.config.DescriptionCacheCapacity > 0 { + c.descriptionCache = stmtcache.NewLRUCache(c.config.DescriptionCacheCapacity) + } + _, err := c.pgConn.Exec(ctx, "deallocate all").ReadAll() + return err +} + +func (c *Conn) bufferNotifications(_ *pgconn.PgConn, n *pgconn.Notification) { + c.notifications = append(c.notifications, n) +} + +// WaitForNotification waits for a PostgreSQL notification. It wraps the underlying pgconn notification system in a +// slightly more convenient form. +func (c *Conn) WaitForNotification(ctx context.Context) (*pgconn.Notification, error) { + var n *pgconn.Notification + + // Return already received notification immediately + if len(c.notifications) > 0 { + n = c.notifications[0] + c.notifications = c.notifications[1:] + return n, nil + } + + err := c.pgConn.WaitForNotification(ctx) + if len(c.notifications) > 0 { + n = c.notifications[0] + c.notifications = c.notifications[1:] + } + return n, err +} + +// IsClosed reports if the connection has been closed. +func (c *Conn) IsClosed() bool { + return c.pgConn.IsClosed() +} + +func (c *Conn) die(err error) { + if c.IsClosed() { + return + } + + ctx, cancel := context.WithCancel(context.Background()) + cancel() // force immediate hard cancel + c.pgConn.Close(ctx) +} + +func quoteIdentifier(s string) string { + return `"` + strings.ReplaceAll(s, `"`, `""`) + `"` +} + +// Ping delegates to the underlying *pgconn.PgConn.Ping. +func (c *Conn) Ping(ctx context.Context) error { + return c.pgConn.Ping(ctx) +} + +// PgConn returns the underlying *pgconn.PgConn. This is an escape hatch method that allows lower level access to the +// PostgreSQL connection than pgx exposes. +// +// It is strongly recommended that the connection be idle (no in-progress queries) before the underlying *pgconn.PgConn +// is used and the connection must be returned to the same state before any *pgx.Conn methods are again used. +func (c *Conn) PgConn() *pgconn.PgConn { return c.pgConn } + +// TypeMap returns the connection info used for this connection. +func (c *Conn) TypeMap() *pgtype.Map { return c.typeMap } + +// Config returns a copy of config that was used to establish this connection. +func (c *Conn) Config() *ConnConfig { return c.config.Copy() } + +// Exec executes sql. sql can be either a prepared statement name or an SQL string. arguments should be referenced +// positionally from the sql string as $1, $2, etc. +func (c *Conn) Exec(ctx context.Context, sql string, arguments ...any) (pgconn.CommandTag, error) { + if c.queryTracer != nil { + ctx = c.queryTracer.TraceQueryStart(ctx, c, TraceQueryStartData{SQL: sql, Args: arguments}) + } + + if err := c.deallocateInvalidatedCachedStatements(ctx); err != nil { + return pgconn.CommandTag{}, err + } + + commandTag, err := c.exec(ctx, sql, arguments...) + + if c.queryTracer != nil { + c.queryTracer.TraceQueryEnd(ctx, c, TraceQueryEndData{CommandTag: commandTag, Err: err}) + } + + return commandTag, err +} + +func (c *Conn) exec(ctx context.Context, sql string, arguments ...any) (commandTag pgconn.CommandTag, err error) { + mode := c.config.DefaultQueryExecMode + var queryRewriter QueryRewriter + +optionLoop: + for len(arguments) > 0 { + switch arg := arguments[0].(type) { + case QueryExecMode: + mode = arg + arguments = arguments[1:] + case QueryRewriter: + queryRewriter = arg + arguments = arguments[1:] + default: + break optionLoop + } + } + + if queryRewriter != nil { + sql, arguments, err = queryRewriter.RewriteQuery(ctx, c, sql, arguments) + if err != nil { + return pgconn.CommandTag{}, fmt.Errorf("rewrite query failed: %v", err) + } + } + + // Always use simple protocol when there are no arguments. + if len(arguments) == 0 { + mode = QueryExecModeSimpleProtocol + } + + if sd, ok := c.preparedStatements[sql]; ok { + return c.execPrepared(ctx, sd, arguments) + } + + switch mode { + case QueryExecModeCacheStatement: + if c.statementCache == nil { + return pgconn.CommandTag{}, errDisabledStatementCache + } + sd := c.statementCache.Get(sql) + if sd == nil { + sd, err = c.Prepare(ctx, stmtcache.NextStatementName(), sql) + if err != nil { + return pgconn.CommandTag{}, err + } + c.statementCache.Put(sd) + } + + return c.execPrepared(ctx, sd, arguments) + case QueryExecModeCacheDescribe: + if c.descriptionCache == nil { + return pgconn.CommandTag{}, errDisabledDescriptionCache + } + sd := c.descriptionCache.Get(sql) + if sd == nil { + sd, err = c.Prepare(ctx, "", sql) + if err != nil { + return pgconn.CommandTag{}, err + } + } + + return c.execParams(ctx, sd, arguments) + case QueryExecModeDescribeExec: + sd, err := c.Prepare(ctx, "", sql) + if err != nil { + return pgconn.CommandTag{}, err + } + return c.execPrepared(ctx, sd, arguments) + case QueryExecModeExec: + return c.execSQLParams(ctx, sql, arguments) + case QueryExecModeSimpleProtocol: + return c.execSimpleProtocol(ctx, sql, arguments) + default: + return pgconn.CommandTag{}, fmt.Errorf("unknown QueryExecMode: %v", mode) + } +} + +func (c *Conn) execSimpleProtocol(ctx context.Context, sql string, arguments []any) (commandTag pgconn.CommandTag, err error) { + if len(arguments) > 0 { + sql, err = c.sanitizeForSimpleQuery(sql, arguments...) + if err != nil { + return pgconn.CommandTag{}, err + } + } + + mrr := c.pgConn.Exec(ctx, sql) + for mrr.NextResult() { + commandTag, err = mrr.ResultReader().Close() + } + err = mrr.Close() + return commandTag, err +} + +func (c *Conn) execParams(ctx context.Context, sd *pgconn.StatementDescription, arguments []any) (pgconn.CommandTag, error) { + err := c.eqb.Build(c.typeMap, sd, arguments) + if err != nil { + return pgconn.CommandTag{}, err + } + + result := c.pgConn.ExecParams(ctx, sd.SQL, c.eqb.ParamValues, sd.ParamOIDs, c.eqb.ParamFormats, c.eqb.ResultFormats).Read() + c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible. + return result.CommandTag, result.Err +} + +func (c *Conn) execPrepared(ctx context.Context, sd *pgconn.StatementDescription, arguments []any) (pgconn.CommandTag, error) { + err := c.eqb.Build(c.typeMap, sd, arguments) + if err != nil { + return pgconn.CommandTag{}, err + } + + result := c.pgConn.ExecPrepared(ctx, sd.Name, c.eqb.ParamValues, c.eqb.ParamFormats, c.eqb.ResultFormats).Read() + c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible. + return result.CommandTag, result.Err +} + +type unknownArgumentTypeQueryExecModeExecError struct { + arg any +} + +func (e *unknownArgumentTypeQueryExecModeExecError) Error() string { + return fmt.Sprintf("cannot use unregistered type %T as query argument in QueryExecModeExec", e.arg) +} + +func (c *Conn) execSQLParams(ctx context.Context, sql string, args []any) (pgconn.CommandTag, error) { + err := c.eqb.Build(c.typeMap, nil, args) + if err != nil { + return pgconn.CommandTag{}, err + } + + result := c.pgConn.ExecParams(ctx, sql, c.eqb.ParamValues, nil, c.eqb.ParamFormats, c.eqb.ResultFormats).Read() + c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible. + return result.CommandTag, result.Err +} + +func (c *Conn) getRows(ctx context.Context, sql string, args []any) *baseRows { + r := &baseRows{} + + r.ctx = ctx + r.queryTracer = c.queryTracer + r.typeMap = c.typeMap + r.startTime = time.Now() + r.sql = sql + r.args = args + r.conn = c + + return r +} + +type QueryExecMode int32 + +const ( + _ QueryExecMode = iota + + // Automatically prepare and cache statements. This uses the extended protocol. Queries are executed in a single + // round trip after the statement is cached. This is the default. + QueryExecModeCacheStatement + + // Cache statement descriptions (i.e. argument and result types) and assume they do not change. This uses the + // extended protocol. Queries are executed in a single round trip after the description is cached. If the database + // schema is modified or the search_path is changed this may result in undetected result decoding errors. + QueryExecModeCacheDescribe + + // Get the statement description on every execution. This uses the extended protocol. Queries require two round trips + // to execute. It does not use named prepared statements. But it does use the unnamed prepared statement to get the + // statement description on the first round trip and then uses it to execute the query on the second round trip. This + // may cause problems with connection poolers that switch the underlying connection between round trips. It is safe + // even when the the database schema is modified concurrently. + QueryExecModeDescribeExec + + // Assume the PostgreSQL query parameter types based on the Go type of the arguments. This uses the extended protocol + // with text formatted parameters and results. Queries are executed in a single round trip. Type mappings can be + // registered with pgtype.Map.RegisterDefaultPgType. Queries will be rejected that have arguments that are + // unregistered or ambigious. e.g. A map[string]string may have the PostgreSQL type json or hstore. Modes that know + // the PostgreSQL type can use a map[string]string directly as an argument. This mode cannot. + QueryExecModeExec + + // Use the simple protocol. Assume the PostgreSQL query parameter types based on the Go type of the arguments. + // Queries are executed in a single round trip. Type mappings can be registered with + // pgtype.Map.RegisterDefaultPgType. Queries will be rejected that have arguments that are unregistered or ambigious. + // e.g. A map[string]string may have the PostgreSQL type json or hstore. Modes that know the PostgreSQL type can use + // a map[string]string directly as an argument. This mode cannot. + // + // QueryExecModeSimpleProtocol should have the user application visible behavior as QueryExecModeExec with minor + // exceptions such as behavior when multiple result returning queries are erroneously sent in a single string. + // + // QueryExecModeSimpleProtocol uses client side parameter interpolation. All values are quoted and escaped. Prefer + // QueryExecModeExec over QueryExecModeSimpleProtocol whenever possible. In general QueryExecModeSimpleProtocol + // should only be used if connecting to a proxy server, connection pool server, or non-PostgreSQL server that does + // not support the extended protocol. + QueryExecModeSimpleProtocol +) + +func (m QueryExecMode) String() string { + switch m { + case QueryExecModeCacheStatement: + return "cache statement" + case QueryExecModeCacheDescribe: + return "cache describe" + case QueryExecModeDescribeExec: + return "describe exec" + case QueryExecModeExec: + return "exec" + case QueryExecModeSimpleProtocol: + return "simple protocol" + default: + return "invalid" + } +} + +// QueryResultFormats controls the result format (text=0, binary=1) of a query by result column position. +type QueryResultFormats []int16 + +// QueryResultFormatsByOID controls the result format (text=0, binary=1) of a query by the result column OID. +type QueryResultFormatsByOID map[uint32]int16 + +// QueryRewriter rewrites a query when used as the first arguments to a query method. +type QueryRewriter interface { + RewriteQuery(ctx context.Context, conn *Conn, sql string, args []any) (newSQL string, newArgs []any, err error) +} + +// Query sends a query to the server and returns a Rows to read the results. Only errors encountered sending the query +// and initializing Rows will be returned. Err() on the returned Rows must be checked after the Rows is closed to +// determine if the query executed successfully. +// +// The returned Rows must be closed before the connection can be used again. It is safe to attempt to read from the +// returned Rows even if an error is returned. The error will be the available in rows.Err() after rows are closed. It +// is allowed to ignore the error returned from Query and handle it in Rows. +// +// It is possible for a call of FieldDescriptions on the returned Rows to return nil even if the Query call did not +// return an error. +// +// It is possible for a query to return one or more rows before encountering an error. In most cases the rows should be +// collected before processing rather than processed while receiving each row. This avoids the possibility of the +// application processing rows from a query that the server rejected. The CollectRows function is useful here. +// +// An implementor of QueryRewriter may be passed as the first element of args. It can rewrite the sql and change or +// replace args. For example, NamedArgs is QueryRewriter that implements named arguments. +// +// For extra control over how the query is executed, the types QueryExecMode, QueryResultFormats, and +// QueryResultFormatsByOID may be used as the first args to control exactly how the query is executed. This is rarely +// needed. See the documentation for those types for details. +func (c *Conn) Query(ctx context.Context, sql string, args ...any) (Rows, error) { + if c.queryTracer != nil { + ctx = c.queryTracer.TraceQueryStart(ctx, c, TraceQueryStartData{SQL: sql, Args: args}) + } + + if err := c.deallocateInvalidatedCachedStatements(ctx); err != nil { + if c.queryTracer != nil { + c.queryTracer.TraceQueryEnd(ctx, c, TraceQueryEndData{Err: err}) + } + return &baseRows{err: err, closed: true}, err + } + + var resultFormats QueryResultFormats + var resultFormatsByOID QueryResultFormatsByOID + mode := c.config.DefaultQueryExecMode + var queryRewriter QueryRewriter + +optionLoop: + for len(args) > 0 { + switch arg := args[0].(type) { + case QueryResultFormats: + resultFormats = arg + args = args[1:] + case QueryResultFormatsByOID: + resultFormatsByOID = arg + args = args[1:] + case QueryExecMode: + mode = arg + args = args[1:] + case QueryRewriter: + queryRewriter = arg + args = args[1:] + default: + break optionLoop + } + } + + if queryRewriter != nil { + var err error + originalSQL := sql + originalArgs := args + sql, args, err = queryRewriter.RewriteQuery(ctx, c, sql, args) + if err != nil { + rows := c.getRows(ctx, originalSQL, originalArgs) + err = fmt.Errorf("rewrite query failed: %v", err) + rows.fatal(err) + return rows, err + } + } + + // Bypass any statement caching. + if sql == "" { + mode = QueryExecModeSimpleProtocol + } + + c.eqb.reset() + anynil.NormalizeSlice(args) + rows := c.getRows(ctx, sql, args) + + var err error + sd, explicitPreparedStatement := c.preparedStatements[sql] + if sd != nil || mode == QueryExecModeCacheStatement || mode == QueryExecModeCacheDescribe || mode == QueryExecModeDescribeExec { + if sd == nil { + sd, err = c.getStatementDescription(ctx, mode, sql) + if err != nil { + rows.fatal(err) + return rows, err + } + } + + if len(sd.ParamOIDs) != len(args) { + rows.fatal(fmt.Errorf("expected %d arguments, got %d", len(sd.ParamOIDs), len(args))) + return rows, rows.err + } + + rows.sql = sd.SQL + + err = c.eqb.Build(c.typeMap, sd, args) + if err != nil { + rows.fatal(err) + return rows, rows.err + } + + if resultFormatsByOID != nil { + resultFormats = make([]int16, len(sd.Fields)) + for i := range resultFormats { + resultFormats[i] = resultFormatsByOID[uint32(sd.Fields[i].DataTypeOID)] + } + } + + if resultFormats == nil { + resultFormats = c.eqb.ResultFormats + } + + if !explicitPreparedStatement && mode == QueryExecModeCacheDescribe { + rows.resultReader = c.pgConn.ExecParams(ctx, sql, c.eqb.ParamValues, sd.ParamOIDs, c.eqb.ParamFormats, resultFormats) + } else { + rows.resultReader = c.pgConn.ExecPrepared(ctx, sd.Name, c.eqb.ParamValues, c.eqb.ParamFormats, resultFormats) + } + } else if mode == QueryExecModeExec { + err := c.eqb.Build(c.typeMap, nil, args) + if err != nil { + rows.fatal(err) + return rows, rows.err + } + + rows.resultReader = c.pgConn.ExecParams(ctx, sql, c.eqb.ParamValues, nil, c.eqb.ParamFormats, c.eqb.ResultFormats) + } else if mode == QueryExecModeSimpleProtocol { + sql, err = c.sanitizeForSimpleQuery(sql, args...) + if err != nil { + rows.fatal(err) + return rows, err + } + + mrr := c.pgConn.Exec(ctx, sql) + if mrr.NextResult() { + rows.resultReader = mrr.ResultReader() + rows.multiResultReader = mrr + } else { + err = mrr.Close() + rows.fatal(err) + return rows, err + } + + return rows, nil + } else { + err = fmt.Errorf("unknown QueryExecMode: %v", mode) + rows.fatal(err) + return rows, rows.err + } + + c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible. + + return rows, rows.err +} + +// getStatementDescription returns the statement description of the sql query +// according to the given mode. +// +// If the mode is one that doesn't require to know the param and result OIDs +// then nil is returned without error. +func (c *Conn) getStatementDescription( + ctx context.Context, + mode QueryExecMode, + sql string, +) (sd *pgconn.StatementDescription, err error) { + + switch mode { + case QueryExecModeCacheStatement: + if c.statementCache == nil { + return nil, errDisabledStatementCache + } + sd = c.statementCache.Get(sql) + if sd == nil { + sd, err = c.Prepare(ctx, stmtcache.NextStatementName(), sql) + if err != nil { + return nil, err + } + c.statementCache.Put(sd) + } + case QueryExecModeCacheDescribe: + if c.descriptionCache == nil { + return nil, errDisabledDescriptionCache + } + sd = c.descriptionCache.Get(sql) + if sd == nil { + sd, err = c.Prepare(ctx, "", sql) + if err != nil { + return nil, err + } + c.descriptionCache.Put(sd) + } + case QueryExecModeDescribeExec: + return c.Prepare(ctx, "", sql) + } + return sd, err +} + +// QueryRow is a convenience wrapper over Query. Any error that occurs while +// querying is deferred until calling Scan on the returned Row. That Row will +// error with ErrNoRows if no rows are returned. +func (c *Conn) QueryRow(ctx context.Context, sql string, args ...any) Row { + rows, _ := c.Query(ctx, sql, args...) + return (*connRow)(rows.(*baseRows)) +} + +// SendBatch sends all queued queries to the server at once. All queries are run in an implicit transaction unless +// explicit transaction control statements are executed. The returned BatchResults must be closed before the connection +// is used again. +func (c *Conn) SendBatch(ctx context.Context, b *Batch) (br BatchResults) { + if c.batchTracer != nil { + ctx = c.batchTracer.TraceBatchStart(ctx, c, TraceBatchStartData{Batch: b}) + defer func() { + err := br.(interface{ earlyError() error }).earlyError() + if err != nil { + c.batchTracer.TraceBatchEnd(ctx, c, TraceBatchEndData{Err: err}) + } + }() + } + + if err := c.deallocateInvalidatedCachedStatements(ctx); err != nil { + return &batchResults{ctx: ctx, conn: c, err: err} + } + + mode := c.config.DefaultQueryExecMode + + for _, bi := range b.queuedQueries { + var queryRewriter QueryRewriter + sql := bi.query + arguments := bi.arguments + + optionLoop: + for len(arguments) > 0 { + switch arg := arguments[0].(type) { + case QueryRewriter: + queryRewriter = arg + arguments = arguments[1:] + default: + break optionLoop + } + } + + if queryRewriter != nil { + var err error + sql, arguments, err = queryRewriter.RewriteQuery(ctx, c, sql, arguments) + if err != nil { + return &batchResults{ctx: ctx, conn: c, err: fmt.Errorf("rewrite query failed: %v", err)} + } + } + + bi.query = sql + bi.arguments = arguments + } + + if mode == QueryExecModeSimpleProtocol { + return c.sendBatchQueryExecModeSimpleProtocol(ctx, b) + } + + // All other modes use extended protocol and thus can use prepared statements. + for _, bi := range b.queuedQueries { + if sd, ok := c.preparedStatements[bi.query]; ok { + bi.sd = sd + } + } + + switch mode { + case QueryExecModeExec: + return c.sendBatchQueryExecModeExec(ctx, b) + case QueryExecModeCacheStatement: + return c.sendBatchQueryExecModeCacheStatement(ctx, b) + case QueryExecModeCacheDescribe: + return c.sendBatchQueryExecModeCacheDescribe(ctx, b) + case QueryExecModeDescribeExec: + return c.sendBatchQueryExecModeDescribeExec(ctx, b) + default: + panic("unknown QueryExecMode") + } +} + +func (c *Conn) sendBatchQueryExecModeSimpleProtocol(ctx context.Context, b *Batch) *batchResults { + var sb strings.Builder + for i, bi := range b.queuedQueries { + if i > 0 { + sb.WriteByte(';') + } + sql, err := c.sanitizeForSimpleQuery(bi.query, bi.arguments...) + if err != nil { + return &batchResults{ctx: ctx, conn: c, err: err} + } + sb.WriteString(sql) + } + mrr := c.pgConn.Exec(ctx, sb.String()) + return &batchResults{ + ctx: ctx, + conn: c, + mrr: mrr, + b: b, + qqIdx: 0, + } +} + +func (c *Conn) sendBatchQueryExecModeExec(ctx context.Context, b *Batch) *batchResults { + batch := &pgconn.Batch{} + + for _, bi := range b.queuedQueries { + sd := bi.sd + if sd != nil { + err := c.eqb.Build(c.typeMap, sd, bi.arguments) + if err != nil { + return &batchResults{ctx: ctx, conn: c, err: err} + } + + batch.ExecPrepared(sd.Name, c.eqb.ParamValues, c.eqb.ParamFormats, c.eqb.ResultFormats) + } else { + err := c.eqb.Build(c.typeMap, nil, bi.arguments) + if err != nil { + return &batchResults{ctx: ctx, conn: c, err: err} + } + batch.ExecParams(bi.query, c.eqb.ParamValues, nil, c.eqb.ParamFormats, c.eqb.ResultFormats) + } + } + + c.eqb.reset() // Allow c.eqb internal memory to be GC'ed as soon as possible. + + mrr := c.pgConn.ExecBatch(ctx, batch) + + return &batchResults{ + ctx: ctx, + conn: c, + mrr: mrr, + b: b, + qqIdx: 0, + } +} + +func (c *Conn) sendBatchQueryExecModeCacheStatement(ctx context.Context, b *Batch) (pbr *pipelineBatchResults) { + if c.statementCache == nil { + return &pipelineBatchResults{ctx: ctx, conn: c, err: errDisabledStatementCache, closed: true} + } + + distinctNewQueries := []*pgconn.StatementDescription{} + distinctNewQueriesIdxMap := make(map[string]int) + + for _, bi := range b.queuedQueries { + if bi.sd == nil { + sd := c.statementCache.Get(bi.query) + if sd != nil { + bi.sd = sd + } else { + if idx, present := distinctNewQueriesIdxMap[bi.query]; present { + bi.sd = distinctNewQueries[idx] + } else { + sd = &pgconn.StatementDescription{ + Name: stmtcache.NextStatementName(), + SQL: bi.query, + } + distinctNewQueriesIdxMap[sd.SQL] = len(distinctNewQueries) + distinctNewQueries = append(distinctNewQueries, sd) + bi.sd = sd + } + } + } + } + + return c.sendBatchExtendedWithDescription(ctx, b, distinctNewQueries, c.statementCache) +} + +func (c *Conn) sendBatchQueryExecModeCacheDescribe(ctx context.Context, b *Batch) (pbr *pipelineBatchResults) { + if c.descriptionCache == nil { + return &pipelineBatchResults{ctx: ctx, conn: c, err: errDisabledDescriptionCache, closed: true} + } + + distinctNewQueries := []*pgconn.StatementDescription{} + distinctNewQueriesIdxMap := make(map[string]int) + + for _, bi := range b.queuedQueries { + if bi.sd == nil { + sd := c.descriptionCache.Get(bi.query) + if sd != nil { + bi.sd = sd + } else { + if idx, present := distinctNewQueriesIdxMap[bi.query]; present { + bi.sd = distinctNewQueries[idx] + } else { + sd = &pgconn.StatementDescription{ + SQL: bi.query, + } + distinctNewQueriesIdxMap[sd.SQL] = len(distinctNewQueries) + distinctNewQueries = append(distinctNewQueries, sd) + bi.sd = sd + } + } + } + } + + return c.sendBatchExtendedWithDescription(ctx, b, distinctNewQueries, c.descriptionCache) +} + +func (c *Conn) sendBatchQueryExecModeDescribeExec(ctx context.Context, b *Batch) (pbr *pipelineBatchResults) { + distinctNewQueries := []*pgconn.StatementDescription{} + distinctNewQueriesIdxMap := make(map[string]int) + + for _, bi := range b.queuedQueries { + if bi.sd == nil { + if idx, present := distinctNewQueriesIdxMap[bi.query]; present { + bi.sd = distinctNewQueries[idx] + } else { + sd := &pgconn.StatementDescription{ + SQL: bi.query, + } + distinctNewQueriesIdxMap[sd.SQL] = len(distinctNewQueries) + distinctNewQueries = append(distinctNewQueries, sd) + bi.sd = sd + } + } + } + + return c.sendBatchExtendedWithDescription(ctx, b, distinctNewQueries, nil) +} + +func (c *Conn) sendBatchExtendedWithDescription(ctx context.Context, b *Batch, distinctNewQueries []*pgconn.StatementDescription, sdCache stmtcache.Cache) (pbr *pipelineBatchResults) { + pipeline := c.pgConn.StartPipeline(context.Background()) + defer func() { + if pbr.err != nil { + pipeline.Close() + } + }() + + // Prepare any needed queries + if len(distinctNewQueries) > 0 { + for _, sd := range distinctNewQueries { + pipeline.SendPrepare(sd.Name, sd.SQL, nil) + } + + err := pipeline.Sync() + if err != nil { + return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true} + } + + for _, sd := range distinctNewQueries { + results, err := pipeline.GetResults() + if err != nil { + return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true} + } + + resultSD, ok := results.(*pgconn.StatementDescription) + if !ok { + return &pipelineBatchResults{ctx: ctx, conn: c, err: fmt.Errorf("expected statement description, got %T", results), closed: true} + } + + // Fill in the previously empty / pending statement descriptions. + sd.ParamOIDs = resultSD.ParamOIDs + sd.Fields = resultSD.Fields + } + + results, err := pipeline.GetResults() + if err != nil { + return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true} + } + + _, ok := results.(*pgconn.PipelineSync) + if !ok { + return &pipelineBatchResults{ctx: ctx, conn: c, err: fmt.Errorf("expected sync, got %T", results), closed: true} + } + } + + // Put all statements into the cache. It's fine if it overflows because HandleInvalidated will clean them up later. + if sdCache != nil { + for _, sd := range distinctNewQueries { + sdCache.Put(sd) + } + } + + // Queue the queries. + for _, bi := range b.queuedQueries { + err := c.eqb.Build(c.typeMap, bi.sd, bi.arguments) + if err != nil { + // we wrap the error so we the user can understand which query failed inside the batch + err = fmt.Errorf("error building query %s: %w", bi.query, err) + return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true} + } + + if bi.sd.Name == "" { + pipeline.SendQueryParams(bi.sd.SQL, c.eqb.ParamValues, bi.sd.ParamOIDs, c.eqb.ParamFormats, c.eqb.ResultFormats) + } else { + pipeline.SendQueryPrepared(bi.sd.Name, c.eqb.ParamValues, c.eqb.ParamFormats, c.eqb.ResultFormats) + } + } + + err := pipeline.Sync() + if err != nil { + return &pipelineBatchResults{ctx: ctx, conn: c, err: err, closed: true} + } + + return &pipelineBatchResults{ + ctx: ctx, + conn: c, + pipeline: pipeline, + b: b, + } +} + +func (c *Conn) sanitizeForSimpleQuery(sql string, args ...any) (string, error) { + if c.pgConn.ParameterStatus("standard_conforming_strings") != "on" { + return "", errors.New("simple protocol queries must be run with standard_conforming_strings=on") + } + + if c.pgConn.ParameterStatus("client_encoding") != "UTF8" { + return "", errors.New("simple protocol queries must be run with client_encoding=UTF8") + } + + var err error + valueArgs := make([]any, len(args)) + for i, a := range args { + valueArgs[i], err = convertSimpleArgument(c.typeMap, a) + if err != nil { + return "", err + } + } + + return sanitize.SanitizeSQL(sql, valueArgs...) +} + +// LoadType inspects the database for typeName and produces a pgtype.Type suitable for registration. +func (c *Conn) LoadType(ctx context.Context, typeName string) (*pgtype.Type, error) { + var oid uint32 + + err := c.QueryRow(ctx, "select $1::text::regtype::oid;", typeName).Scan(&oid) + if err != nil { + return nil, err + } + + var typtype string + var typbasetype uint32 + + err = c.QueryRow(ctx, "select typtype::text, typbasetype from pg_type where oid=$1", oid).Scan(&typtype, &typbasetype) + if err != nil { + return nil, err + } + + switch typtype { + case "b": // array + elementOID, err := c.getArrayElementOID(ctx, oid) + if err != nil { + return nil, err + } + + dt, ok := c.TypeMap().TypeForOID(elementOID) + if !ok { + return nil, errors.New("array element OID not registered") + } + + return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.ArrayCodec{ElementType: dt}}, nil + case "c": // composite + fields, err := c.getCompositeFields(ctx, oid) + if err != nil { + return nil, err + } + + return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.CompositeCodec{Fields: fields}}, nil + case "d": // domain + dt, ok := c.TypeMap().TypeForOID(typbasetype) + if !ok { + return nil, errors.New("domain base type OID not registered") + } + + return &pgtype.Type{Name: typeName, OID: oid, Codec: dt.Codec}, nil + case "e": // enum + return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.EnumCodec{}}, nil + case "r": // range + elementOID, err := c.getRangeElementOID(ctx, oid) + if err != nil { + return nil, err + } + + dt, ok := c.TypeMap().TypeForOID(elementOID) + if !ok { + return nil, errors.New("range element OID not registered") + } + + return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.RangeCodec{ElementType: dt}}, nil + case "m": // multirange + elementOID, err := c.getMultiRangeElementOID(ctx, oid) + if err != nil { + return nil, err + } + + dt, ok := c.TypeMap().TypeForOID(elementOID) + if !ok { + return nil, errors.New("multirange element OID not registered") + } + + return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.MultirangeCodec{ElementType: dt}}, nil + default: + return &pgtype.Type{}, errors.New("unknown typtype") + } +} + +func (c *Conn) getArrayElementOID(ctx context.Context, oid uint32) (uint32, error) { + var typelem uint32 + + err := c.QueryRow(ctx, "select typelem from pg_type where oid=$1", oid).Scan(&typelem) + if err != nil { + return 0, err + } + + return typelem, nil +} + +func (c *Conn) getRangeElementOID(ctx context.Context, oid uint32) (uint32, error) { + var typelem uint32 + + err := c.QueryRow(ctx, "select rngsubtype from pg_range where rngtypid=$1", oid).Scan(&typelem) + if err != nil { + return 0, err + } + + return typelem, nil +} + +func (c *Conn) getMultiRangeElementOID(ctx context.Context, oid uint32) (uint32, error) { + var typelem uint32 + + err := c.QueryRow(ctx, "select rngtypid from pg_range where rngmultitypid=$1", oid).Scan(&typelem) + if err != nil { + return 0, err + } + + return typelem, nil +} + +func (c *Conn) getCompositeFields(ctx context.Context, oid uint32) ([]pgtype.CompositeCodecField, error) { + var typrelid uint32 + + err := c.QueryRow(ctx, "select typrelid from pg_type where oid=$1", oid).Scan(&typrelid) + if err != nil { + return nil, err + } + + var fields []pgtype.CompositeCodecField + var fieldName string + var fieldOID uint32 + rows, _ := c.Query(ctx, `select attname, atttypid +from pg_attribute +where attrelid=$1 + and not attisdropped + and attnum > 0 +order by attnum`, + typrelid, + ) + _, err = ForEachRow(rows, []any{&fieldName, &fieldOID}, func() error { + dt, ok := c.TypeMap().TypeForOID(fieldOID) + if !ok { + return fmt.Errorf("unknown composite type field OID: %v", fieldOID) + } + fields = append(fields, pgtype.CompositeCodecField{Name: fieldName, Type: dt}) + return nil + }) + if err != nil { + return nil, err + } + + return fields, nil +} + +func (c *Conn) deallocateInvalidatedCachedStatements(ctx context.Context) error { + if c.pgConn.TxStatus() != 'I' { + return nil + } + + if c.descriptionCache != nil { + c.descriptionCache.HandleInvalidated() + } + + var invalidatedStatements []*pgconn.StatementDescription + if c.statementCache != nil { + invalidatedStatements = c.statementCache.HandleInvalidated() + } + + if len(invalidatedStatements) == 0 { + return nil + } + + pipeline := c.pgConn.StartPipeline(ctx) + defer pipeline.Close() + + for _, sd := range invalidatedStatements { + pipeline.SendDeallocate(sd.Name) + delete(c.preparedStatements, sd.Name) + } + + err := pipeline.Sync() + if err != nil { + return fmt.Errorf("failed to deallocate cached statement(s): %w", err) + } + + err = pipeline.Close() + if err != nil { + return fmt.Errorf("failed to deallocate cached statement(s): %w", err) + } + + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/copy_from.go b/vendor/github.com/jackc/pgx/v5/copy_from.go new file mode 100644 index 00000000000..a2c227fd447 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/copy_from.go @@ -0,0 +1,249 @@ +package pgx + +import ( + "bytes" + "context" + "fmt" + "io" + + "github.com/jackc/pgx/v5/internal/pgio" + "github.com/jackc/pgx/v5/pgconn" +) + +// CopyFromRows returns a CopyFromSource interface over the provided rows slice +// making it usable by *Conn.CopyFrom. +func CopyFromRows(rows [][]any) CopyFromSource { + return ©FromRows{rows: rows, idx: -1} +} + +type copyFromRows struct { + rows [][]any + idx int +} + +func (ctr *copyFromRows) Next() bool { + ctr.idx++ + return ctr.idx < len(ctr.rows) +} + +func (ctr *copyFromRows) Values() ([]any, error) { + return ctr.rows[ctr.idx], nil +} + +func (ctr *copyFromRows) Err() error { + return nil +} + +// CopyFromSlice returns a CopyFromSource interface over a dynamic func +// making it usable by *Conn.CopyFrom. +func CopyFromSlice(length int, next func(int) ([]any, error)) CopyFromSource { + return ©FromSlice{next: next, idx: -1, len: length} +} + +type copyFromSlice struct { + next func(int) ([]any, error) + idx int + len int + err error +} + +func (cts *copyFromSlice) Next() bool { + cts.idx++ + return cts.idx < cts.len +} + +func (cts *copyFromSlice) Values() ([]any, error) { + values, err := cts.next(cts.idx) + if err != nil { + cts.err = err + } + return values, err +} + +func (cts *copyFromSlice) Err() error { + return cts.err +} + +// CopyFromSource is the interface used by *Conn.CopyFrom as the source for copy data. +type CopyFromSource interface { + // Next returns true if there is another row and makes the next row data + // available to Values(). When there are no more rows available or an error + // has occurred it returns false. + Next() bool + + // Values returns the values for the current row. + Values() ([]any, error) + + // Err returns any error that has been encountered by the CopyFromSource. If + // this is not nil *Conn.CopyFrom will abort the copy. + Err() error +} + +type copyFrom struct { + conn *Conn + tableName Identifier + columnNames []string + rowSrc CopyFromSource + readerErrChan chan error + mode QueryExecMode +} + +func (ct *copyFrom) run(ctx context.Context) (int64, error) { + if ct.conn.copyFromTracer != nil { + ctx = ct.conn.copyFromTracer.TraceCopyFromStart(ctx, ct.conn, TraceCopyFromStartData{ + TableName: ct.tableName, + ColumnNames: ct.columnNames, + }) + } + + quotedTableName := ct.tableName.Sanitize() + cbuf := &bytes.Buffer{} + for i, cn := range ct.columnNames { + if i != 0 { + cbuf.WriteString(", ") + } + cbuf.WriteString(quoteIdentifier(cn)) + } + quotedColumnNames := cbuf.String() + + var sd *pgconn.StatementDescription + switch ct.mode { + case QueryExecModeExec, QueryExecModeSimpleProtocol: + // These modes don't support the binary format. Before the inclusion of the + // QueryExecModes, Conn.Prepare was called on every COPY operation to get + // the OIDs. These prepared statements were not cached. + // + // Since that's the same behavior provided by QueryExecModeDescribeExec, + // we'll default to that mode. + ct.mode = QueryExecModeDescribeExec + fallthrough + case QueryExecModeCacheStatement, QueryExecModeCacheDescribe, QueryExecModeDescribeExec: + var err error + sd, err = ct.conn.getStatementDescription( + ctx, + ct.mode, + fmt.Sprintf("select %s from %s", quotedColumnNames, quotedTableName), + ) + if err != nil { + return 0, fmt.Errorf("statement description failed: %w", err) + } + default: + return 0, fmt.Errorf("unknown QueryExecMode: %v", ct.mode) + } + + r, w := io.Pipe() + doneChan := make(chan struct{}) + + go func() { + defer close(doneChan) + + // Purposely NOT using defer w.Close(). See https://github.com/golang/go/issues/24283. + buf := ct.conn.wbuf + + buf = append(buf, "PGCOPY\n\377\r\n\000"...) + buf = pgio.AppendInt32(buf, 0) + buf = pgio.AppendInt32(buf, 0) + + moreRows := true + for moreRows { + var err error + moreRows, buf, err = ct.buildCopyBuf(buf, sd) + if err != nil { + w.CloseWithError(err) + return + } + + if ct.rowSrc.Err() != nil { + w.CloseWithError(ct.rowSrc.Err()) + return + } + + if len(buf) > 0 { + _, err = w.Write(buf) + if err != nil { + w.Close() + return + } + } + + buf = buf[:0] + } + + w.Close() + }() + + commandTag, err := ct.conn.pgConn.CopyFrom(ctx, r, fmt.Sprintf("copy %s ( %s ) from stdin binary;", quotedTableName, quotedColumnNames)) + + r.Close() + <-doneChan + + if ct.conn.copyFromTracer != nil { + ct.conn.copyFromTracer.TraceCopyFromEnd(ctx, ct.conn, TraceCopyFromEndData{ + CommandTag: commandTag, + Err: err, + }) + } + + return commandTag.RowsAffected(), err +} + +func (ct *copyFrom) buildCopyBuf(buf []byte, sd *pgconn.StatementDescription) (bool, []byte, error) { + const sendBufSize = 65536 - 5 // The packet has a 5-byte header + lastBufLen := 0 + largestRowLen := 0 + + for ct.rowSrc.Next() { + lastBufLen = len(buf) + + values, err := ct.rowSrc.Values() + if err != nil { + return false, nil, err + } + if len(values) != len(ct.columnNames) { + return false, nil, fmt.Errorf("expected %d values, got %d values", len(ct.columnNames), len(values)) + } + + buf = pgio.AppendInt16(buf, int16(len(ct.columnNames))) + for i, val := range values { + buf, err = encodeCopyValue(ct.conn.typeMap, buf, sd.Fields[i].DataTypeOID, val) + if err != nil { + return false, nil, err + } + } + + rowLen := len(buf) - lastBufLen + if rowLen > largestRowLen { + largestRowLen = rowLen + } + + // Try not to overflow size of the buffer PgConn.CopyFrom will be reading into. If that happens then the nature of + // io.Pipe means that the next Read will be short. This can lead to pathological send sizes such as 65531, 13, 65531 + // 13, 65531, 13, 65531, 13. + if len(buf) > sendBufSize-largestRowLen { + return true, buf, nil + } + } + + return false, buf, nil +} + +// CopyFrom uses the PostgreSQL copy protocol to perform bulk data insertion. It returns the number of rows copied and +// an error. +// +// CopyFrom requires all values use the binary format. A pgtype.Type that supports the binary format must be registered +// for the type of each column. Almost all types implemented by pgx support the binary format. +// +// Even though enum types appear to be strings they still must be registered to use with CopyFrom. This can be done with +// Conn.LoadType and pgtype.Map.RegisterType. +func (c *Conn) CopyFrom(ctx context.Context, tableName Identifier, columnNames []string, rowSrc CopyFromSource) (int64, error) { + ct := ©From{ + conn: c, + tableName: tableName, + columnNames: columnNames, + rowSrc: rowSrc, + readerErrChan: make(chan error), + mode: c.config.DefaultQueryExecMode, + } + + return ct.run(ctx) +} diff --git a/vendor/github.com/jackc/pgx/v5/doc.go b/vendor/github.com/jackc/pgx/v5/doc.go new file mode 100644 index 00000000000..0db8cbb1402 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/doc.go @@ -0,0 +1,193 @@ +// Package pgx is a PostgreSQL database driver. +/* +pgx provides a native PostgreSQL driver and can act as a database/sql driver. The native PostgreSQL interface is similar +to the database/sql interface while providing better speed and access to PostgreSQL specific features. Use +github.com/jackc/pgx/v5/stdlib to use pgx as a database/sql compatible driver. See that package's documentation for +details. + +Establishing a Connection + +The primary way of establishing a connection is with `pgx.Connect`. + + conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL")) + +The database connection string can be in URL or DSN format. Both PostgreSQL settings and pgx settings can be specified +here. In addition, a config struct can be created by `ParseConfig` and modified before establishing the connection with +`ConnectConfig` to configure settings such as tracing that cannot be configured with a connection string. + +Connection Pool + +`*pgx.Conn` represents a single connection to the database and is not concurrency safe. Use package +github.com/jackc/pgx/v5/pgxpool for a concurrency safe connection pool. + +Query Interface + +pgx implements Query in the familiar database/sql style. However, pgx provides generic functions such as CollectRows and +ForEachRow that are a simpler and safer way of processing rows than manually calling rows.Next(), rows.Scan, and +rows.Err(). + +CollectRows can be used collect all returned rows into a slice. + + rows, _ := conn.Query(context.Background(), "select generate_series(1,$1)", 5) + numbers, err := pgx.CollectRows(rows, pgx.RowTo[int32]) + if err != nil { + return err + } + // numbers => [1 2 3 4 5] + +ForEachRow can be used to execute a callback function for every row. This is often easier than iterating over rows +directly. + + var sum, n int32 + rows, _ := conn.Query(context.Background(), "select generate_series(1,$1)", 10) + _, err := pgx.ForEachRow(rows, []any{&n}, func() error { + sum += n + return nil + }) + if err != nil { + return err + } + +pgx also implements QueryRow in the same style as database/sql. + + var name string + var weight int64 + err := conn.QueryRow(context.Background(), "select name, weight from widgets where id=$1", 42).Scan(&name, &weight) + if err != nil { + return err + } + +Use Exec to execute a query that does not return a result set. + + commandTag, err := conn.Exec(context.Background(), "delete from widgets where id=$1", 42) + if err != nil { + return err + } + if commandTag.RowsAffected() != 1 { + return errors.New("No row found to delete") + } + +PostgreSQL Data Types + +pgx uses the pgtype package to converting Go values to and from PostgreSQL values. It supports many PostgreSQL types +directly and is customizable and extendable. User defined data types such as enums, domains, and composite types may +require type registration. See that package's documentation for details. + +Transactions + +Transactions are started by calling Begin. + + tx, err := conn.Begin(context.Background()) + if err != nil { + return err + } + // Rollback is safe to call even if the tx is already closed, so if + // the tx commits successfully, this is a no-op + defer tx.Rollback(context.Background()) + + _, err = tx.Exec(context.Background(), "insert into foo(id) values (1)") + if err != nil { + return err + } + + err = tx.Commit(context.Background()) + if err != nil { + return err + } + +The Tx returned from Begin also implements the Begin method. This can be used to implement pseudo nested transactions. +These are internally implemented with savepoints. + +Use BeginTx to control the transaction mode. BeginTx also can be used to ensure a new transaction is created instead of +a pseudo nested transaction. + +BeginFunc and BeginTxFunc are functions that begin a transaction, execute a function, and commit or rollback the +transaction depending on the return value of the function. These can be simpler and less error prone to use. + + err = pgx.BeginFunc(context.Background(), conn, func(tx pgx.Tx) error { + _, err := tx.Exec(context.Background(), "insert into foo(id) values (1)") + return err + }) + if err != nil { + return err + } + +Prepared Statements + +Prepared statements can be manually created with the Prepare method. However, this is rarely necessary because pgx +includes an automatic statement cache by default. Queries run through the normal Query, QueryRow, and Exec functions are +automatically prepared on first execution and the prepared statement is reused on subsequent executions. See ParseConfig +for information on how to customize or disable the statement cache. + +Copy Protocol + +Use CopyFrom to efficiently insert multiple rows at a time using the PostgreSQL copy protocol. CopyFrom accepts a +CopyFromSource interface. If the data is already in a [][]any use CopyFromRows to wrap it in a CopyFromSource interface. +Or implement CopyFromSource to avoid buffering the entire data set in memory. + + rows := [][]any{ + {"John", "Smith", int32(36)}, + {"Jane", "Doe", int32(29)}, + } + + copyCount, err := conn.CopyFrom( + context.Background(), + pgx.Identifier{"people"}, + []string{"first_name", "last_name", "age"}, + pgx.CopyFromRows(rows), + ) + +When you already have a typed array using CopyFromSlice can be more convenient. + + rows := []User{ + {"John", "Smith", 36}, + {"Jane", "Doe", 29}, + } + + copyCount, err := conn.CopyFrom( + context.Background(), + pgx.Identifier{"people"}, + []string{"first_name", "last_name", "age"}, + pgx.CopyFromSlice(len(rows), func(i int) ([]any, error) { + return []any{rows[i].FirstName, rows[i].LastName, rows[i].Age}, nil + }), + ) + +CopyFrom can be faster than an insert with as few as 5 rows. + +Listen and Notify + +pgx can listen to the PostgreSQL notification system with the `Conn.WaitForNotification` method. It blocks until a +notification is received or the context is canceled. + + _, err := conn.Exec(context.Background(), "listen channelname") + if err != nil { + return err + } + + notification, err := conn.WaitForNotification(context.Background()) + if err != nil { + return err + } + // do something with notification + + +Tracing and Logging + +pgx supports tracing by setting ConnConfig.Tracer. + +In addition, the tracelog package provides the TraceLog type which lets a traditional logger act as a Tracer. + +For debug tracing of the actual PostgreSQL wire protocol messages see github.com/jackc/pgx/v5/pgproto3. + +Lower Level PostgreSQL Functionality + +github.com/jackc/pgx/v5/pgconn contains a lower level PostgreSQL driver roughly at the level of libpq. pgx.Conn in +implemented on top of pgconn. The Conn.PgConn() method can be used to access this lower layer. + +PgBouncer + +By default pgx automatically uses prepared statements. Prepared statements are incompaptible with PgBouncer. This can be +disabled by setting a different QueryExecMode in ConnConfig.DefaultQueryExecMode. +*/ +package pgx diff --git a/vendor/github.com/jackc/pgx/v5/extended_query_builder.go b/vendor/github.com/jackc/pgx/v5/extended_query_builder.go new file mode 100644 index 00000000000..0bbdfbb57b4 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/extended_query_builder.go @@ -0,0 +1,218 @@ +package pgx + +import ( + "database/sql/driver" + "fmt" + + "github.com/jackc/pgx/v5/internal/anynil" + "github.com/jackc/pgx/v5/pgconn" + "github.com/jackc/pgx/v5/pgtype" +) + +// ExtendedQueryBuilder is used to choose the parameter formats, to format the parameters and to choose the result +// formats for an extended query. +type ExtendedQueryBuilder struct { + ParamValues [][]byte + paramValueBytes []byte + ParamFormats []int16 + ResultFormats []int16 +} + +// Build sets ParamValues, ParamFormats, and ResultFormats for use with *PgConn.ExecParams or *PgConn.ExecPrepared. If +// sd is nil then QueryExecModeExec behavior will be used. +func (eqb *ExtendedQueryBuilder) Build(m *pgtype.Map, sd *pgconn.StatementDescription, args []any) error { + eqb.reset() + + anynil.NormalizeSlice(args) + + if sd == nil { + return eqb.appendParamsForQueryExecModeExec(m, args) + } + + if len(sd.ParamOIDs) != len(args) { + return fmt.Errorf("mismatched param and argument count") + } + + for i := range args { + err := eqb.appendParam(m, sd.ParamOIDs[i], -1, args[i]) + if err != nil { + err = fmt.Errorf("failed to encode args[%d]: %v", i, err) + return err + } + } + + for i := range sd.Fields { + eqb.appendResultFormat(m.FormatCodeForOID(sd.Fields[i].DataTypeOID)) + } + + return nil +} + +// appendParam appends a parameter to the query. format may be -1 to automatically choose the format. If arg is nil it +// must be an untyped nil. +func (eqb *ExtendedQueryBuilder) appendParam(m *pgtype.Map, oid uint32, format int16, arg any) error { + if format == -1 { + preferredFormat := eqb.chooseParameterFormatCode(m, oid, arg) + preferredErr := eqb.appendParam(m, oid, preferredFormat, arg) + if preferredErr == nil { + return nil + } + + var otherFormat int16 + if preferredFormat == TextFormatCode { + otherFormat = BinaryFormatCode + } else { + otherFormat = TextFormatCode + } + + otherErr := eqb.appendParam(m, oid, otherFormat, arg) + if otherErr == nil { + return nil + } + + return preferredErr // return the error from the preferred format + } + + v, err := eqb.encodeExtendedParamValue(m, oid, format, arg) + if err != nil { + return err + } + + eqb.ParamFormats = append(eqb.ParamFormats, format) + eqb.ParamValues = append(eqb.ParamValues, v) + + return nil +} + +// appendResultFormat appends a result format to the query. +func (eqb *ExtendedQueryBuilder) appendResultFormat(format int16) { + eqb.ResultFormats = append(eqb.ResultFormats, format) +} + +// reset readies eqb to build another query. +func (eqb *ExtendedQueryBuilder) reset() { + eqb.ParamValues = eqb.ParamValues[0:0] + eqb.paramValueBytes = eqb.paramValueBytes[0:0] + eqb.ParamFormats = eqb.ParamFormats[0:0] + eqb.ResultFormats = eqb.ResultFormats[0:0] + + if cap(eqb.ParamValues) > 64 { + eqb.ParamValues = make([][]byte, 0, 64) + } + + if cap(eqb.paramValueBytes) > 256 { + eqb.paramValueBytes = make([]byte, 0, 256) + } + + if cap(eqb.ParamFormats) > 64 { + eqb.ParamFormats = make([]int16, 0, 64) + } + if cap(eqb.ResultFormats) > 64 { + eqb.ResultFormats = make([]int16, 0, 64) + } +} + +func (eqb *ExtendedQueryBuilder) encodeExtendedParamValue(m *pgtype.Map, oid uint32, formatCode int16, arg any) ([]byte, error) { + if anynil.Is(arg) { + return nil, nil + } + + if eqb.paramValueBytes == nil { + eqb.paramValueBytes = make([]byte, 0, 128) + } + + pos := len(eqb.paramValueBytes) + + buf, err := m.Encode(oid, formatCode, arg, eqb.paramValueBytes) + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + eqb.paramValueBytes = buf + return eqb.paramValueBytes[pos:], nil +} + +// chooseParameterFormatCode determines the correct format code for an +// argument to a prepared statement. It defaults to TextFormatCode if no +// determination can be made. +func (eqb *ExtendedQueryBuilder) chooseParameterFormatCode(m *pgtype.Map, oid uint32, arg any) int16 { + switch arg.(type) { + case string, *string: + return TextFormatCode + } + + return m.FormatCodeForOID(oid) +} + +// appendParamsForQueryExecModeExec appends the args to eqb. +// +// Parameters must be encoded in the text format because of differences in type conversion between timestamps and +// dates. In QueryExecModeExec we don't know what the actual PostgreSQL type is. To determine the type we use the +// Go type to OID type mapping registered by RegisterDefaultPgType. However, the Go time.Time represents both +// PostgreSQL timestamp[tz] and date. To use the binary format we would need to also specify what the PostgreSQL +// type OID is. But that would mean telling PostgreSQL that we have sent a timestamp[tz] when what is needed is a date. +// This means that the value is converted from text to timestamp[tz] to date. This means it does a time zone conversion +// before converting it to date. This means that dates can be shifted by one day. In text format without that double +// type conversion it takes the date directly and ignores time zone (i.e. it works). +// +// Given that the whole point of QueryExecModeExec is to operate without having to know the PostgreSQL types there is +// no way to safely use binary or to specify the parameter OIDs. +func (eqb *ExtendedQueryBuilder) appendParamsForQueryExecModeExec(m *pgtype.Map, args []any) error { + for _, arg := range args { + if arg == nil { + err := eqb.appendParam(m, 0, TextFormatCode, arg) + if err != nil { + return err + } + } else { + dt, ok := m.TypeForValue(arg) + if !ok { + var tv pgtype.TextValuer + if tv, ok = arg.(pgtype.TextValuer); ok { + t, err := tv.TextValue() + if err != nil { + return err + } + + dt, ok = m.TypeForOID(pgtype.TextOID) + if ok { + arg = t + } + } + } + if !ok { + var dv driver.Valuer + if dv, ok = arg.(driver.Valuer); ok { + v, err := dv.Value() + if err != nil { + return err + } + dt, ok = m.TypeForValue(v) + if ok { + arg = v + } + } + } + if !ok { + var str fmt.Stringer + if str, ok = arg.(fmt.Stringer); ok { + dt, ok = m.TypeForOID(pgtype.TextOID) + if ok { + arg = str.String() + } + } + } + if !ok { + return &unknownArgumentTypeQueryExecModeExecError{arg: arg} + } + err := eqb.appendParam(m, dt.OID, TextFormatCode, arg) + if err != nil { + return err + } + } + } + + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/internal/anynil/anynil.go b/vendor/github.com/jackc/pgx/v5/internal/anynil/anynil.go new file mode 100644 index 00000000000..9a48c1a844c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/internal/anynil/anynil.go @@ -0,0 +1,36 @@ +package anynil + +import "reflect" + +// Is returns true if value is any type of nil. e.g. nil or []byte(nil). +func Is(value any) bool { + if value == nil { + return true + } + + refVal := reflect.ValueOf(value) + switch refVal.Kind() { + case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.UnsafePointer, reflect.Interface, reflect.Slice: + return refVal.IsNil() + default: + return false + } +} + +// Normalize converts typed nils (e.g. []byte(nil)) into untyped nil. Other values are returned unmodified. +func Normalize(v any) any { + if Is(v) { + return nil + } + return v +} + +// NormalizeSlice converts all typed nils (e.g. []byte(nil)) in s into untyped nils. Other values are unmodified. s is +// mutated in place. +func NormalizeSlice(s []any) { + for i := range s { + if Is(s[i]) { + s[i] = nil + } + } +} diff --git a/vendor/github.com/jackc/pgx/v5/internal/iobufpool/iobufpool.go b/vendor/github.com/jackc/pgx/v5/internal/iobufpool/iobufpool.go new file mode 100644 index 00000000000..89e0c22738d --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/internal/iobufpool/iobufpool.go @@ -0,0 +1,70 @@ +// Package iobufpool implements a global segregated-fit pool of buffers for IO. +// +// It uses *[]byte instead of []byte to avoid the sync.Pool allocation with Put. Unfortunately, using a pointer to avoid +// an allocation is purposely not documented. https://github.com/golang/go/issues/16323 +package iobufpool + +import "sync" + +const minPoolExpOf2 = 8 + +var pools [18]*sync.Pool + +func init() { + for i := range pools { + bufLen := 1 << (minPoolExpOf2 + i) + pools[i] = &sync.Pool{ + New: func() any { + buf := make([]byte, bufLen) + return &buf + }, + } + } +} + +// Get gets a []byte of len size with cap <= size*2. +func Get(size int) *[]byte { + i := getPoolIdx(size) + if i >= len(pools) { + buf := make([]byte, size) + return &buf + } + + ptrBuf := (pools[i].Get().(*[]byte)) + *ptrBuf = (*ptrBuf)[:size] + + return ptrBuf +} + +func getPoolIdx(size int) int { + size-- + size >>= minPoolExpOf2 + i := 0 + for size > 0 { + size >>= 1 + i++ + } + + return i +} + +// Put returns buf to the pool. +func Put(buf *[]byte) { + i := putPoolIdx(cap(*buf)) + if i < 0 { + return + } + + pools[i].Put(buf) +} + +func putPoolIdx(size int) int { + minPoolSize := 1 << minPoolExpOf2 + for i := range pools { + if size == minPoolSize<= len(args) { + return "", fmt.Errorf("insufficient arguments") + } + arg := args[argIdx] + switch arg := arg.(type) { + case nil: + str = "null" + case int64: + str = strconv.FormatInt(arg, 10) + case float64: + str = strconv.FormatFloat(arg, 'f', -1, 64) + case bool: + str = strconv.FormatBool(arg) + case []byte: + str = QuoteBytes(arg) + case string: + str = QuoteString(arg) + case time.Time: + str = arg.Truncate(time.Microsecond).Format("'2006-01-02 15:04:05.999999999Z07:00:00'") + default: + return "", fmt.Errorf("invalid arg type: %T", arg) + } + argUse[argIdx] = true + default: + return "", fmt.Errorf("invalid Part type: %T", part) + } + buf.WriteString(str) + } + + for i, used := range argUse { + if !used { + return "", fmt.Errorf("unused argument: %d", i) + } + } + return buf.String(), nil +} + +func NewQuery(sql string) (*Query, error) { + l := &sqlLexer{ + src: sql, + stateFn: rawState, + } + + for l.stateFn != nil { + l.stateFn = l.stateFn(l) + } + + query := &Query{Parts: l.parts} + + return query, nil +} + +func QuoteString(str string) string { + return "'" + strings.ReplaceAll(str, "'", "''") + "'" +} + +func QuoteBytes(buf []byte) string { + return `'\x` + hex.EncodeToString(buf) + "'" +} + +type sqlLexer struct { + src string + start int + pos int + nested int // multiline comment nesting level. + stateFn stateFn + parts []Part +} + +type stateFn func(*sqlLexer) stateFn + +func rawState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case 'e', 'E': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '\'' { + l.pos += width + return escapeStringState + } + case '\'': + return singleQuoteState + case '"': + return doubleQuoteState + case '$': + nextRune, _ := utf8.DecodeRuneInString(l.src[l.pos:]) + if '0' <= nextRune && nextRune <= '9' { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos-width]) + } + l.start = l.pos + return placeholderState + } + case '-': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '-' { + l.pos += width + return oneLineCommentState + } + case '/': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '*' { + l.pos += width + return multilineCommentState + } + case utf8.RuneError: + if width != replacementcharacterwidth { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } + } +} + +func singleQuoteState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '\'': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '\'' { + return rawState + } + l.pos += width + case utf8.RuneError: + if width != replacementcharacterwidth { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } + } +} + +func doubleQuoteState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '"': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '"' { + return rawState + } + l.pos += width + case utf8.RuneError: + if width != replacementcharacterwidth { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } + } +} + +// placeholderState consumes a placeholder value. The $ must have already has +// already been consumed. The first rune must be a digit. +func placeholderState(l *sqlLexer) stateFn { + num := 0 + + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + if '0' <= r && r <= '9' { + num *= 10 + num += int(r - '0') + } else { + l.parts = append(l.parts, num) + l.pos -= width + l.start = l.pos + return rawState + } + } +} + +func escapeStringState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '\\': + _, width = utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + case '\'': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '\'' { + return rawState + } + l.pos += width + case utf8.RuneError: + if width != replacementcharacterwidth { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } + } +} + +func oneLineCommentState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '\\': + _, width = utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + case '\n', '\r': + return rawState + case utf8.RuneError: + if width != replacementcharacterwidth { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } + } +} + +func multilineCommentState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '/': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '*' { + l.pos += width + l.nested++ + } + case '*': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '/' { + continue + } + + l.pos += width + if l.nested == 0 { + return rawState + } + l.nested-- + + case utf8.RuneError: + if width != replacementcharacterwidth { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } + } +} + +// SanitizeSQL replaces placeholder values with args. It quotes and escapes args +// as necessary. This function is only safe when standard_conforming_strings is +// on. +func SanitizeSQL(sql string, args ...any) (string, error) { + query, err := NewQuery(sql) + if err != nil { + return "", err + } + return query.Sanitize(args...) +} diff --git a/vendor/github.com/jackc/pgx/v5/internal/stmtcache/lru_cache.go b/vendor/github.com/jackc/pgx/v5/internal/stmtcache/lru_cache.go new file mode 100644 index 00000000000..a25cc8b1c40 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/internal/stmtcache/lru_cache.go @@ -0,0 +1,98 @@ +package stmtcache + +import ( + "container/list" + + "github.com/jackc/pgx/v5/pgconn" +) + +// LRUCache implements Cache with a Least Recently Used (LRU) cache. +type LRUCache struct { + cap int + m map[string]*list.Element + l *list.List + invalidStmts []*pgconn.StatementDescription +} + +// NewLRUCache creates a new LRUCache. cap is the maximum size of the cache. +func NewLRUCache(cap int) *LRUCache { + return &LRUCache{ + cap: cap, + m: make(map[string]*list.Element), + l: list.New(), + } +} + +// Get returns the statement description for sql. Returns nil if not found. +func (c *LRUCache) Get(key string) *pgconn.StatementDescription { + if el, ok := c.m[key]; ok { + c.l.MoveToFront(el) + return el.Value.(*pgconn.StatementDescription) + } + + return nil + +} + +// Put stores sd in the cache. Put panics if sd.SQL is "". Put does nothing if sd.SQL already exists in the cache. +func (c *LRUCache) Put(sd *pgconn.StatementDescription) { + if sd.SQL == "" { + panic("cannot store statement description with empty SQL") + } + + if _, present := c.m[sd.SQL]; present { + return + } + + if c.l.Len() == c.cap { + c.invalidateOldest() + } + + el := c.l.PushFront(sd) + c.m[sd.SQL] = el +} + +// Invalidate invalidates statement description identified by sql. Does nothing if not found. +func (c *LRUCache) Invalidate(sql string) { + if el, ok := c.m[sql]; ok { + delete(c.m, sql) + c.invalidStmts = append(c.invalidStmts, el.Value.(*pgconn.StatementDescription)) + c.l.Remove(el) + } +} + +// InvalidateAll invalidates all statement descriptions. +func (c *LRUCache) InvalidateAll() { + el := c.l.Front() + for el != nil { + c.invalidStmts = append(c.invalidStmts, el.Value.(*pgconn.StatementDescription)) + el = el.Next() + } + + c.m = make(map[string]*list.Element) + c.l = list.New() +} + +func (c *LRUCache) HandleInvalidated() []*pgconn.StatementDescription { + invalidStmts := c.invalidStmts + c.invalidStmts = nil + return invalidStmts +} + +// Len returns the number of cached prepared statement descriptions. +func (c *LRUCache) Len() int { + return c.l.Len() +} + +// Cap returns the maximum number of cached prepared statement descriptions. +func (c *LRUCache) Cap() int { + return c.cap +} + +func (c *LRUCache) invalidateOldest() { + oldest := c.l.Back() + sd := oldest.Value.(*pgconn.StatementDescription) + c.invalidStmts = append(c.invalidStmts, sd) + delete(c.m, sd.SQL) + c.l.Remove(oldest) +} diff --git a/vendor/github.com/jackc/pgx/v5/internal/stmtcache/stmtcache.go b/vendor/github.com/jackc/pgx/v5/internal/stmtcache/stmtcache.go new file mode 100644 index 00000000000..e1bdcba574c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/internal/stmtcache/stmtcache.go @@ -0,0 +1,57 @@ +// Package stmtcache is a cache for statement descriptions. +package stmtcache + +import ( + "strconv" + "sync/atomic" + + "github.com/jackc/pgx/v5/pgconn" +) + +var stmtCounter int64 + +// NextStatementName returns a statement name that will be unique for the lifetime of the program. +func NextStatementName() string { + n := atomic.AddInt64(&stmtCounter, 1) + return "stmtcache_" + strconv.FormatInt(n, 10) +} + +// Cache caches statement descriptions. +type Cache interface { + // Get returns the statement description for sql. Returns nil if not found. + Get(sql string) *pgconn.StatementDescription + + // Put stores sd in the cache. Put panics if sd.SQL is "". Put does nothing if sd.SQL already exists in the cache. + Put(sd *pgconn.StatementDescription) + + // Invalidate invalidates statement description identified by sql. Does nothing if not found. + Invalidate(sql string) + + // InvalidateAll invalidates all statement descriptions. + InvalidateAll() + + // HandleInvalidated returns a slice of all statement descriptions invalidated since the last call to HandleInvalidated. + HandleInvalidated() []*pgconn.StatementDescription + + // Len returns the number of cached prepared statement descriptions. + Len() int + + // Cap returns the maximum number of cached prepared statement descriptions. + Cap() int +} + +func IsStatementInvalid(err error) bool { + pgErr, ok := err.(*pgconn.PgError) + if !ok { + return false + } + + // https://github.com/jackc/pgx/issues/1162 + // + // We used to look for the message "cached plan must not change result type". However, that message can be localized. + // Unfortunately, error code "0A000" - "FEATURE NOT SUPPORTED" is used for many different errors and the only way to + // tell the difference is by the message. But all that happens is we clear a statement that we otherwise wouldn't + // have so it should be safe. + possibleInvalidCachedPlanError := pgErr.Code == "0A000" + return possibleInvalidCachedPlanError +} diff --git a/vendor/github.com/jackc/pgx/v5/internal/stmtcache/unlimited_cache.go b/vendor/github.com/jackc/pgx/v5/internal/stmtcache/unlimited_cache.go new file mode 100644 index 00000000000..f5f59396e4f --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/internal/stmtcache/unlimited_cache.go @@ -0,0 +1,71 @@ +package stmtcache + +import ( + "math" + + "github.com/jackc/pgx/v5/pgconn" +) + +// UnlimitedCache implements Cache with no capacity limit. +type UnlimitedCache struct { + m map[string]*pgconn.StatementDescription + invalidStmts []*pgconn.StatementDescription +} + +// NewUnlimitedCache creates a new UnlimitedCache. +func NewUnlimitedCache() *UnlimitedCache { + return &UnlimitedCache{ + m: make(map[string]*pgconn.StatementDescription), + } +} + +// Get returns the statement description for sql. Returns nil if not found. +func (c *UnlimitedCache) Get(sql string) *pgconn.StatementDescription { + return c.m[sql] +} + +// Put stores sd in the cache. Put panics if sd.SQL is "". Put does nothing if sd.SQL already exists in the cache. +func (c *UnlimitedCache) Put(sd *pgconn.StatementDescription) { + if sd.SQL == "" { + panic("cannot store statement description with empty SQL") + } + + if _, present := c.m[sd.SQL]; present { + return + } + + c.m[sd.SQL] = sd +} + +// Invalidate invalidates statement description identified by sql. Does nothing if not found. +func (c *UnlimitedCache) Invalidate(sql string) { + if sd, ok := c.m[sql]; ok { + delete(c.m, sql) + c.invalidStmts = append(c.invalidStmts, sd) + } +} + +// InvalidateAll invalidates all statement descriptions. +func (c *UnlimitedCache) InvalidateAll() { + for _, sd := range c.m { + c.invalidStmts = append(c.invalidStmts, sd) + } + + c.m = make(map[string]*pgconn.StatementDescription) +} + +func (c *UnlimitedCache) HandleInvalidated() []*pgconn.StatementDescription { + invalidStmts := c.invalidStmts + c.invalidStmts = nil + return invalidStmts +} + +// Len returns the number of cached prepared statement descriptions. +func (c *UnlimitedCache) Len() int { + return len(c.m) +} + +// Cap returns the maximum number of cached prepared statement descriptions. +func (c *UnlimitedCache) Cap() int { + return math.MaxInt +} diff --git a/vendor/github.com/jackc/pgx/v5/large_objects.go b/vendor/github.com/jackc/pgx/v5/large_objects.go new file mode 100644 index 00000000000..c238ab9c220 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/large_objects.go @@ -0,0 +1,121 @@ +package pgx + +import ( + "context" + "errors" + "io" +) + +// LargeObjects is a structure used to access the large objects API. It is only valid within the transaction where it +// was created. +// +// For more details see: http://www.postgresql.org/docs/current/static/largeobjects.html +type LargeObjects struct { + tx Tx +} + +type LargeObjectMode int32 + +const ( + LargeObjectModeWrite LargeObjectMode = 0x20000 + LargeObjectModeRead LargeObjectMode = 0x40000 +) + +// Create creates a new large object. If oid is zero, the server assigns an unused OID. +func (o *LargeObjects) Create(ctx context.Context, oid uint32) (uint32, error) { + err := o.tx.QueryRow(ctx, "select lo_create($1)", oid).Scan(&oid) + return oid, err +} + +// Open opens an existing large object with the given mode. ctx will also be used for all operations on the opened large +// object. +func (o *LargeObjects) Open(ctx context.Context, oid uint32, mode LargeObjectMode) (*LargeObject, error) { + var fd int32 + err := o.tx.QueryRow(ctx, "select lo_open($1, $2)", oid, mode).Scan(&fd) + if err != nil { + return nil, err + } + return &LargeObject{fd: fd, tx: o.tx, ctx: ctx}, nil +} + +// Unlink removes a large object from the database. +func (o *LargeObjects) Unlink(ctx context.Context, oid uint32) error { + var result int32 + err := o.tx.QueryRow(ctx, "select lo_unlink($1)", oid).Scan(&result) + if err != nil { + return err + } + + if result != 1 { + return errors.New("failed to remove large object") + } + + return nil +} + +// A LargeObject is a large object stored on the server. It is only valid within the transaction that it was initialized +// in. It uses the context it was initialized with for all operations. It implements these interfaces: +// +// io.Writer +// io.Reader +// io.Seeker +// io.Closer +type LargeObject struct { + ctx context.Context + tx Tx + fd int32 +} + +// Write writes p to the large object and returns the number of bytes written and an error if not all of p was written. +func (o *LargeObject) Write(p []byte) (int, error) { + var n int + err := o.tx.QueryRow(o.ctx, "select lowrite($1, $2)", o.fd, p).Scan(&n) + if err != nil { + return n, err + } + + if n < 0 { + return 0, errors.New("failed to write to large object") + } + + return n, nil +} + +// Read reads up to len(p) bytes into p returning the number of bytes read. +func (o *LargeObject) Read(p []byte) (int, error) { + var res []byte + err := o.tx.QueryRow(o.ctx, "select loread($1, $2)", o.fd, len(p)).Scan(&res) + copy(p, res) + if err != nil { + return len(res), err + } + + if len(res) < len(p) { + err = io.EOF + } + return len(res), err +} + +// Seek moves the current location pointer to the new location specified by offset. +func (o *LargeObject) Seek(offset int64, whence int) (n int64, err error) { + err = o.tx.QueryRow(o.ctx, "select lo_lseek64($1, $2, $3)", o.fd, offset, whence).Scan(&n) + return n, err +} + +// Tell returns the current read or write location of the large object descriptor. +func (o *LargeObject) Tell() (n int64, err error) { + err = o.tx.QueryRow(o.ctx, "select lo_tell64($1)", o.fd).Scan(&n) + return n, err +} + +// Truncate the large object to size. +func (o *LargeObject) Truncate(size int64) (err error) { + _, err = o.tx.Exec(o.ctx, "select lo_truncate64($1, $2)", o.fd, size) + return err +} + +// Close the large object descriptor. +func (o *LargeObject) Close() error { + _, err := o.tx.Exec(o.ctx, "select lo_close($1)", o.fd) + return err +} diff --git a/vendor/github.com/jackc/pgx/v5/named_args.go b/vendor/github.com/jackc/pgx/v5/named_args.go new file mode 100644 index 00000000000..1bc32337aa1 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/named_args.go @@ -0,0 +1,266 @@ +package pgx + +import ( + "context" + "strconv" + "strings" + "unicode/utf8" +) + +// NamedArgs can be used as the first argument to a query method. It will replace every '@' named placeholder with a '$' +// ordinal placeholder and construct the appropriate arguments. +// +// For example, the following two queries are equivalent: +// +// conn.Query(ctx, "select * from widgets where foo = @foo and bar = @bar", pgx.NamedArgs{"foo": 1, "bar": 2}) +// conn.Query(ctx, "select * from widgets where foo = $1 and bar = $2", 1, 2) +type NamedArgs map[string]any + +// RewriteQuery implements the QueryRewriter interface. +func (na NamedArgs) RewriteQuery(ctx context.Context, conn *Conn, sql string, args []any) (newSQL string, newArgs []any, err error) { + l := &sqlLexer{ + src: sql, + stateFn: rawState, + nameToOrdinal: make(map[namedArg]int, len(na)), + } + + for l.stateFn != nil { + l.stateFn = l.stateFn(l) + } + + sb := strings.Builder{} + for _, p := range l.parts { + switch p := p.(type) { + case string: + sb.WriteString(p) + case namedArg: + sb.WriteRune('$') + sb.WriteString(strconv.Itoa(l.nameToOrdinal[p])) + } + } + + newArgs = make([]any, len(l.nameToOrdinal)) + for name, ordinal := range l.nameToOrdinal { + newArgs[ordinal-1] = na[string(name)] + } + + return sb.String(), newArgs, nil +} + +type namedArg string + +type sqlLexer struct { + src string + start int + pos int + nested int // multiline comment nesting level. + stateFn stateFn + parts []any + + nameToOrdinal map[namedArg]int +} + +type stateFn func(*sqlLexer) stateFn + +func rawState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case 'e', 'E': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '\'' { + l.pos += width + return escapeStringState + } + case '\'': + return singleQuoteState + case '"': + return doubleQuoteState + case '@': + nextRune, _ := utf8.DecodeRuneInString(l.src[l.pos:]) + if isLetter(nextRune) { + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos-width]) + } + l.start = l.pos + return namedArgState + } + case '-': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '-' { + l.pos += width + return oneLineCommentState + } + case '/': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '*' { + l.pos += width + return multilineCommentState + } + case utf8.RuneError: + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } +} + +func isLetter(r rune) bool { + return (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') +} + +func namedArgState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + if r == utf8.RuneError { + if l.pos-l.start > 0 { + na := namedArg(l.src[l.start:l.pos]) + if _, found := l.nameToOrdinal[na]; !found { + l.nameToOrdinal[na] = len(l.nameToOrdinal) + 1 + } + l.parts = append(l.parts, na) + l.start = l.pos + } + return nil + } else if !(isLetter(r) || (r >= '0' && r <= '9') || r == '_') { + l.pos -= width + na := namedArg(l.src[l.start:l.pos]) + if _, found := l.nameToOrdinal[na]; !found { + l.nameToOrdinal[na] = len(l.nameToOrdinal) + 1 + } + l.parts = append(l.parts, namedArg(na)) + l.start = l.pos + return rawState + } + } +} + +func singleQuoteState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '\'': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '\'' { + return rawState + } + l.pos += width + case utf8.RuneError: + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } +} + +func doubleQuoteState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '"': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '"' { + return rawState + } + l.pos += width + case utf8.RuneError: + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } +} + +func escapeStringState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '\\': + _, width = utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + case '\'': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '\'' { + return rawState + } + l.pos += width + case utf8.RuneError: + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } +} + +func oneLineCommentState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '\\': + _, width = utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + case '\n', '\r': + return rawState + case utf8.RuneError: + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } +} + +func multilineCommentState(l *sqlLexer) stateFn { + for { + r, width := utf8.DecodeRuneInString(l.src[l.pos:]) + l.pos += width + + switch r { + case '/': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune == '*' { + l.pos += width + l.nested++ + } + case '*': + nextRune, width := utf8.DecodeRuneInString(l.src[l.pos:]) + if nextRune != '/' { + continue + } + + l.pos += width + if l.nested == 0 { + return rawState + } + l.nested-- + + case utf8.RuneError: + if l.pos-l.start > 0 { + l.parts = append(l.parts, l.src[l.start:l.pos]) + l.start = l.pos + } + return nil + } + } +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/README.md b/vendor/github.com/jackc/pgx/v5/pgconn/README.md new file mode 100644 index 00000000000..1fe15c2686c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/README.md @@ -0,0 +1,29 @@ +# pgconn + +Package pgconn is a low-level PostgreSQL database driver. It operates at nearly the same level as the C library libpq. +It is primarily intended to serve as the foundation for higher level libraries such as https://github.com/jackc/pgx. +Applications should handle normal queries with a higher level library and only use pgconn directly when required for +low-level access to PostgreSQL functionality. + +## Example Usage + +```go +pgConn, err := pgconn.Connect(context.Background(), os.Getenv("DATABASE_URL")) +if err != nil { + log.Fatalln("pgconn failed to connect:", err) +} +defer pgConn.Close(context.Background()) + +result := pgConn.ExecParams(context.Background(), "SELECT email FROM users WHERE id=$1", [][]byte{[]byte("123")}, nil, nil, nil) +for result.NextRow() { + fmt.Println("User 123 has email:", string(result.Values()[0])) +} +_, err = result.Close() +if err != nil { + log.Fatalln("failed reading result:", err) +} +``` + +## Testing + +See CONTRIBUTING.md for setup instructions. diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/auth_scram.go b/vendor/github.com/jackc/pgx/v5/pgconn/auth_scram.go new file mode 100644 index 00000000000..8c4b2de3cbe --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/auth_scram.go @@ -0,0 +1,272 @@ +// SCRAM-SHA-256 authentication +// +// Resources: +// https://tools.ietf.org/html/rfc5802 +// https://tools.ietf.org/html/rfc8265 +// https://www.postgresql.org/docs/current/sasl-authentication.html +// +// Inspiration drawn from other implementations: +// https://github.com/lib/pq/pull/608 +// https://github.com/lib/pq/pull/788 +// https://github.com/lib/pq/pull/833 + +package pgconn + +import ( + "bytes" + "crypto/hmac" + "crypto/rand" + "crypto/sha256" + "encoding/base64" + "errors" + "fmt" + "strconv" + + "github.com/jackc/pgx/v5/pgproto3" + "golang.org/x/crypto/pbkdf2" + "golang.org/x/text/secure/precis" +) + +const clientNonceLen = 18 + +// Perform SCRAM authentication. +func (c *PgConn) scramAuth(serverAuthMechanisms []string) error { + sc, err := newScramClient(serverAuthMechanisms, c.config.Password) + if err != nil { + return err + } + + // Send client-first-message in a SASLInitialResponse + saslInitialResponse := &pgproto3.SASLInitialResponse{ + AuthMechanism: "SCRAM-SHA-256", + Data: sc.clientFirstMessage(), + } + c.frontend.Send(saslInitialResponse) + err = c.flushWithPotentialWriteReadDeadlock() + if err != nil { + return err + } + + // Receive server-first-message payload in a AuthenticationSASLContinue. + saslContinue, err := c.rxSASLContinue() + if err != nil { + return err + } + err = sc.recvServerFirstMessage(saslContinue.Data) + if err != nil { + return err + } + + // Send client-final-message in a SASLResponse + saslResponse := &pgproto3.SASLResponse{ + Data: []byte(sc.clientFinalMessage()), + } + c.frontend.Send(saslResponse) + err = c.flushWithPotentialWriteReadDeadlock() + if err != nil { + return err + } + + // Receive server-final-message payload in a AuthenticationSASLFinal. + saslFinal, err := c.rxSASLFinal() + if err != nil { + return err + } + return sc.recvServerFinalMessage(saslFinal.Data) +} + +func (c *PgConn) rxSASLContinue() (*pgproto3.AuthenticationSASLContinue, error) { + msg, err := c.receiveMessage() + if err != nil { + return nil, err + } + switch m := msg.(type) { + case *pgproto3.AuthenticationSASLContinue: + return m, nil + case *pgproto3.ErrorResponse: + return nil, ErrorResponseToPgError(m) + } + + return nil, fmt.Errorf("expected AuthenticationSASLContinue message but received unexpected message %T", msg) +} + +func (c *PgConn) rxSASLFinal() (*pgproto3.AuthenticationSASLFinal, error) { + msg, err := c.receiveMessage() + if err != nil { + return nil, err + } + switch m := msg.(type) { + case *pgproto3.AuthenticationSASLFinal: + return m, nil + case *pgproto3.ErrorResponse: + return nil, ErrorResponseToPgError(m) + } + + return nil, fmt.Errorf("expected AuthenticationSASLFinal message but received unexpected message %T", msg) +} + +type scramClient struct { + serverAuthMechanisms []string + password []byte + clientNonce []byte + + clientFirstMessageBare []byte + + serverFirstMessage []byte + clientAndServerNonce []byte + salt []byte + iterations int + + saltedPassword []byte + authMessage []byte +} + +func newScramClient(serverAuthMechanisms []string, password string) (*scramClient, error) { + sc := &scramClient{ + serverAuthMechanisms: serverAuthMechanisms, + } + + // Ensure server supports SCRAM-SHA-256 + hasScramSHA256 := false + for _, mech := range sc.serverAuthMechanisms { + if mech == "SCRAM-SHA-256" { + hasScramSHA256 = true + break + } + } + if !hasScramSHA256 { + return nil, errors.New("server does not support SCRAM-SHA-256") + } + + // precis.OpaqueString is equivalent to SASLprep for password. + var err error + sc.password, err = precis.OpaqueString.Bytes([]byte(password)) + if err != nil { + // PostgreSQL allows passwords invalid according to SCRAM / SASLprep. + sc.password = []byte(password) + } + + buf := make([]byte, clientNonceLen) + _, err = rand.Read(buf) + if err != nil { + return nil, err + } + sc.clientNonce = make([]byte, base64.RawStdEncoding.EncodedLen(len(buf))) + base64.RawStdEncoding.Encode(sc.clientNonce, buf) + + return sc, nil +} + +func (sc *scramClient) clientFirstMessage() []byte { + sc.clientFirstMessageBare = []byte(fmt.Sprintf("n=,r=%s", sc.clientNonce)) + return []byte(fmt.Sprintf("n,,%s", sc.clientFirstMessageBare)) +} + +func (sc *scramClient) recvServerFirstMessage(serverFirstMessage []byte) error { + sc.serverFirstMessage = serverFirstMessage + buf := serverFirstMessage + if !bytes.HasPrefix(buf, []byte("r=")) { + return errors.New("invalid SCRAM server-first-message received from server: did not include r=") + } + buf = buf[2:] + + idx := bytes.IndexByte(buf, ',') + if idx == -1 { + return errors.New("invalid SCRAM server-first-message received from server: did not include s=") + } + sc.clientAndServerNonce = buf[:idx] + buf = buf[idx+1:] + + if !bytes.HasPrefix(buf, []byte("s=")) { + return errors.New("invalid SCRAM server-first-message received from server: did not include s=") + } + buf = buf[2:] + + idx = bytes.IndexByte(buf, ',') + if idx == -1 { + return errors.New("invalid SCRAM server-first-message received from server: did not include i=") + } + saltStr := buf[:idx] + buf = buf[idx+1:] + + if !bytes.HasPrefix(buf, []byte("i=")) { + return errors.New("invalid SCRAM server-first-message received from server: did not include i=") + } + buf = buf[2:] + iterationsStr := buf + + var err error + sc.salt, err = base64.StdEncoding.DecodeString(string(saltStr)) + if err != nil { + return fmt.Errorf("invalid SCRAM salt received from server: %w", err) + } + + sc.iterations, err = strconv.Atoi(string(iterationsStr)) + if err != nil || sc.iterations <= 0 { + return fmt.Errorf("invalid SCRAM iteration count received from server: %w", err) + } + + if !bytes.HasPrefix(sc.clientAndServerNonce, sc.clientNonce) { + return errors.New("invalid SCRAM nonce: did not start with client nonce") + } + + if len(sc.clientAndServerNonce) <= len(sc.clientNonce) { + return errors.New("invalid SCRAM nonce: did not include server nonce") + } + + return nil +} + +func (sc *scramClient) clientFinalMessage() string { + clientFinalMessageWithoutProof := []byte(fmt.Sprintf("c=biws,r=%s", sc.clientAndServerNonce)) + + sc.saltedPassword = pbkdf2.Key([]byte(sc.password), sc.salt, sc.iterations, 32, sha256.New) + sc.authMessage = bytes.Join([][]byte{sc.clientFirstMessageBare, sc.serverFirstMessage, clientFinalMessageWithoutProof}, []byte(",")) + + clientProof := computeClientProof(sc.saltedPassword, sc.authMessage) + + return fmt.Sprintf("%s,p=%s", clientFinalMessageWithoutProof, clientProof) +} + +func (sc *scramClient) recvServerFinalMessage(serverFinalMessage []byte) error { + if !bytes.HasPrefix(serverFinalMessage, []byte("v=")) { + return errors.New("invalid SCRAM server-final-message received from server") + } + + serverSignature := serverFinalMessage[2:] + + if !hmac.Equal(serverSignature, computeServerSignature(sc.saltedPassword, sc.authMessage)) { + return errors.New("invalid SCRAM ServerSignature received from server") + } + + return nil +} + +func computeHMAC(key, msg []byte) []byte { + mac := hmac.New(sha256.New, key) + mac.Write(msg) + return mac.Sum(nil) +} + +func computeClientProof(saltedPassword, authMessage []byte) []byte { + clientKey := computeHMAC(saltedPassword, []byte("Client Key")) + storedKey := sha256.Sum256(clientKey) + clientSignature := computeHMAC(storedKey[:], authMessage) + + clientProof := make([]byte, len(clientSignature)) + for i := 0; i < len(clientSignature); i++ { + clientProof[i] = clientKey[i] ^ clientSignature[i] + } + + buf := make([]byte, base64.StdEncoding.EncodedLen(len(clientProof))) + base64.StdEncoding.Encode(buf, clientProof) + return buf +} + +func computeServerSignature(saltedPassword []byte, authMessage []byte) []byte { + serverKey := computeHMAC(saltedPassword, []byte("Server Key")) + serverSignature := computeHMAC(serverKey, authMessage) + buf := make([]byte, base64.StdEncoding.EncodedLen(len(serverSignature))) + base64.StdEncoding.Encode(buf, serverSignature) + return buf +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/config.go b/vendor/github.com/jackc/pgx/v5/pgconn/config.go new file mode 100644 index 00000000000..24bf837ce12 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/config.go @@ -0,0 +1,885 @@ +package pgconn + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "errors" + "fmt" + "io" + "math" + "net" + "net/url" + "os" + "path/filepath" + "strconv" + "strings" + "time" + + "github.com/jackc/pgpassfile" + "github.com/jackc/pgservicefile" + "github.com/jackc/pgx/v5/pgproto3" +) + +type AfterConnectFunc func(ctx context.Context, pgconn *PgConn) error +type ValidateConnectFunc func(ctx context.Context, pgconn *PgConn) error +type GetSSLPasswordFunc func(ctx context.Context) string + +// Config is the settings used to establish a connection to a PostgreSQL server. It must be created by ParseConfig. A +// manually initialized Config will cause ConnectConfig to panic. +type Config struct { + Host string // host (e.g. localhost) or absolute path to unix domain socket directory (e.g. /private/tmp) + Port uint16 + Database string + User string + Password string + TLSConfig *tls.Config // nil disables TLS + ConnectTimeout time.Duration + DialFunc DialFunc // e.g. net.Dialer.DialContext + LookupFunc LookupFunc // e.g. net.Resolver.LookupHost + BuildFrontend BuildFrontendFunc + RuntimeParams map[string]string // Run-time parameters to set on connection as session default values (e.g. search_path or application_name) + + KerberosSrvName string + KerberosSpn string + Fallbacks []*FallbackConfig + + // ValidateConnect is called during a connection attempt after a successful authentication with the PostgreSQL server. + // It can be used to validate that the server is acceptable. If this returns an error the connection is closed and the next + // fallback config is tried. This allows implementing high availability behavior such as libpq does with target_session_attrs. + ValidateConnect ValidateConnectFunc + + // AfterConnect is called after ValidateConnect. It can be used to set up the connection (e.g. Set session variables + // or prepare statements). If this returns an error the connection attempt fails. + AfterConnect AfterConnectFunc + + // OnNotice is a callback function called when a notice response is received. + OnNotice NoticeHandler + + // OnNotification is a callback function called when a notification from the LISTEN/NOTIFY system is received. + OnNotification NotificationHandler + + createdByParseConfig bool // Used to enforce created by ParseConfig rule. +} + +// ParseConfigOptions contains options that control how a config is built such as GetSSLPassword. +type ParseConfigOptions struct { + // GetSSLPassword gets the password to decrypt a SSL client certificate. This is analogous to the the libpq function + // PQsetSSLKeyPassHook_OpenSSL. + GetSSLPassword GetSSLPasswordFunc +} + +// Copy returns a deep copy of the config that is safe to use and modify. +// The only exception is the TLSConfig field: +// according to the tls.Config docs it must not be modified after creation. +func (c *Config) Copy() *Config { + newConf := new(Config) + *newConf = *c + if newConf.TLSConfig != nil { + newConf.TLSConfig = c.TLSConfig.Clone() + } + if newConf.RuntimeParams != nil { + newConf.RuntimeParams = make(map[string]string, len(c.RuntimeParams)) + for k, v := range c.RuntimeParams { + newConf.RuntimeParams[k] = v + } + } + if newConf.Fallbacks != nil { + newConf.Fallbacks = make([]*FallbackConfig, len(c.Fallbacks)) + for i, fallback := range c.Fallbacks { + newFallback := new(FallbackConfig) + *newFallback = *fallback + if newFallback.TLSConfig != nil { + newFallback.TLSConfig = fallback.TLSConfig.Clone() + } + newConf.Fallbacks[i] = newFallback + } + } + return newConf +} + +// FallbackConfig is additional settings to attempt a connection with when the primary Config fails to establish a +// network connection. It is used for TLS fallback such as sslmode=prefer and high availability (HA) connections. +type FallbackConfig struct { + Host string // host (e.g. localhost) or path to unix domain socket directory (e.g. /private/tmp) + Port uint16 + TLSConfig *tls.Config // nil disables TLS +} + +// isAbsolutePath checks if the provided value is an absolute path either +// beginning with a forward slash (as on Linux-based systems) or with a capital +// letter A-Z followed by a colon and a backslash, e.g., "C:\", (as on Windows). +func isAbsolutePath(path string) bool { + isWindowsPath := func(p string) bool { + if len(p) < 3 { + return false + } + drive := p[0] + colon := p[1] + backslash := p[2] + if drive >= 'A' && drive <= 'Z' && colon == ':' && backslash == '\\' { + return true + } + return false + } + return strings.HasPrefix(path, "/") || isWindowsPath(path) +} + +// NetworkAddress converts a PostgreSQL host and port into network and address suitable for use with +// net.Dial. +func NetworkAddress(host string, port uint16) (network, address string) { + if isAbsolutePath(host) { + network = "unix" + address = filepath.Join(host, ".s.PGSQL.") + strconv.FormatInt(int64(port), 10) + } else { + network = "tcp" + address = net.JoinHostPort(host, strconv.Itoa(int(port))) + } + return network, address +} + +// ParseConfig builds a *Config from connString with similar behavior to the PostgreSQL standard C library libpq. It +// uses the same defaults as libpq (e.g. port=5432) and understands most PG* environment variables. ParseConfig closely +// matches the parsing behavior of libpq. connString may either be in URL format or keyword = value format (DSN style). +// See https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING for details. connString also may be +// empty to only read from the environment. If a password is not supplied it will attempt to read the .pgpass file. +// +// # Example DSN +// user=jack password=secret host=pg.example.com port=5432 dbname=mydb sslmode=verify-ca +// +// # Example URL +// postgres://jack:secret@pg.example.com:5432/mydb?sslmode=verify-ca +// +// The returned *Config may be modified. However, it is strongly recommended that any configuration that can be done +// through the connection string be done there. In particular the fields Host, Port, TLSConfig, and Fallbacks can be +// interdependent (e.g. TLSConfig needs knowledge of the host to validate the server certificate). These fields should +// not be modified individually. They should all be modified or all left unchanged. +// +// ParseConfig supports specifying multiple hosts in similar manner to libpq. Host and port may include comma separated +// values that will be tried in order. This can be used as part of a high availability system. See +// https://www.postgresql.org/docs/11/libpq-connect.html#LIBPQ-MULTIPLE-HOSTS for more information. +// +// # Example URL +// postgres://jack:secret@foo.example.com:5432,bar.example.com:5432/mydb +// +// ParseConfig currently recognizes the following environment variable and their parameter key word equivalents passed +// via database URL or DSN: +// +// PGHOST +// PGPORT +// PGDATABASE +// PGUSER +// PGPASSWORD +// PGPASSFILE +// PGSERVICE +// PGSERVICEFILE +// PGSSLMODE +// PGSSLCERT +// PGSSLKEY +// PGSSLROOTCERT +// PGSSLPASSWORD +// PGAPPNAME +// PGCONNECT_TIMEOUT +// PGTARGETSESSIONATTRS +// +// See http://www.postgresql.org/docs/11/static/libpq-envars.html for details on the meaning of environment variables. +// +// See https://www.postgresql.org/docs/11/libpq-connect.html#LIBPQ-PARAMKEYWORDS for parameter key word names. They are +// usually but not always the environment variable name downcased and without the "PG" prefix. +// +// Important Security Notes: +// +// ParseConfig tries to match libpq behavior with regard to PGSSLMODE. This includes defaulting to "prefer" behavior if +// not set. +// +// See http://www.postgresql.org/docs/11/static/libpq-ssl.html#LIBPQ-SSL-PROTECTION for details on what level of +// security each sslmode provides. +// +// The sslmode "prefer" (the default), sslmode "allow", and multiple hosts are implemented via the Fallbacks field of +// the Config struct. If TLSConfig is manually changed it will not affect the fallbacks. For example, in the case of +// sslmode "prefer" this means it will first try the main Config settings which use TLS, then it will try the fallback +// which does not use TLS. This can lead to an unexpected unencrypted connection if the main TLS config is manually +// changed later but the unencrypted fallback is present. Ensure there are no stale fallbacks when manually setting +// TLSConfig. +// +// Other known differences with libpq: +// +// When multiple hosts are specified, libpq allows them to have different passwords set via the .pgpass file. pgconn +// does not. +// +// In addition, ParseConfig accepts the following options: +// +// - servicefile. +// libpq only reads servicefile from the PGSERVICEFILE environment variable. ParseConfig accepts servicefile as a +// part of the connection string. +func ParseConfig(connString string) (*Config, error) { + var parseConfigOptions ParseConfigOptions + return ParseConfigWithOptions(connString, parseConfigOptions) +} + +// ParseConfigWithOptions builds a *Config from connString and options with similar behavior to the PostgreSQL standard +// C library libpq. options contains settings that cannot be specified in a connString such as providing a function to +// get the SSL password. +func ParseConfigWithOptions(connString string, options ParseConfigOptions) (*Config, error) { + defaultSettings := defaultSettings() + envSettings := parseEnvSettings() + + connStringSettings := make(map[string]string) + if connString != "" { + var err error + // connString may be a database URL or a DSN + if strings.HasPrefix(connString, "postgres://") || strings.HasPrefix(connString, "postgresql://") { + connStringSettings, err = parseURLSettings(connString) + if err != nil { + return nil, &parseConfigError{connString: connString, msg: "failed to parse as URL", err: err} + } + } else { + connStringSettings, err = parseDSNSettings(connString) + if err != nil { + return nil, &parseConfigError{connString: connString, msg: "failed to parse as DSN", err: err} + } + } + } + + settings := mergeSettings(defaultSettings, envSettings, connStringSettings) + if service, present := settings["service"]; present { + serviceSettings, err := parseServiceSettings(settings["servicefile"], service) + if err != nil { + return nil, &parseConfigError{connString: connString, msg: "failed to read service", err: err} + } + + settings = mergeSettings(defaultSettings, envSettings, serviceSettings, connStringSettings) + } + + config := &Config{ + createdByParseConfig: true, + Database: settings["database"], + User: settings["user"], + Password: settings["password"], + RuntimeParams: make(map[string]string), + BuildFrontend: func(r io.Reader, w io.Writer) *pgproto3.Frontend { + return pgproto3.NewFrontend(r, w) + }, + } + + if connectTimeoutSetting, present := settings["connect_timeout"]; present { + connectTimeout, err := parseConnectTimeoutSetting(connectTimeoutSetting) + if err != nil { + return nil, &parseConfigError{connString: connString, msg: "invalid connect_timeout", err: err} + } + config.ConnectTimeout = connectTimeout + config.DialFunc = makeConnectTimeoutDialFunc(connectTimeout) + } else { + defaultDialer := makeDefaultDialer() + config.DialFunc = defaultDialer.DialContext + } + + config.LookupFunc = makeDefaultResolver().LookupHost + + notRuntimeParams := map[string]struct{}{ + "host": {}, + "port": {}, + "database": {}, + "user": {}, + "password": {}, + "passfile": {}, + "connect_timeout": {}, + "sslmode": {}, + "sslkey": {}, + "sslcert": {}, + "sslrootcert": {}, + "sslpassword": {}, + "sslsni": {}, + "krbspn": {}, + "krbsrvname": {}, + "target_session_attrs": {}, + "service": {}, + "servicefile": {}, + } + + // Adding kerberos configuration + if _, present := settings["krbsrvname"]; present { + config.KerberosSrvName = settings["krbsrvname"] + } + if _, present := settings["krbspn"]; present { + config.KerberosSpn = settings["krbspn"] + } + + for k, v := range settings { + if _, present := notRuntimeParams[k]; present { + continue + } + config.RuntimeParams[k] = v + } + + fallbacks := []*FallbackConfig{} + + hosts := strings.Split(settings["host"], ",") + ports := strings.Split(settings["port"], ",") + + for i, host := range hosts { + var portStr string + if i < len(ports) { + portStr = ports[i] + } else { + portStr = ports[0] + } + + port, err := parsePort(portStr) + if err != nil { + return nil, &parseConfigError{connString: connString, msg: "invalid port", err: err} + } + + var tlsConfigs []*tls.Config + + // Ignore TLS settings if Unix domain socket like libpq + if network, _ := NetworkAddress(host, port); network == "unix" { + tlsConfigs = append(tlsConfigs, nil) + } else { + var err error + tlsConfigs, err = configTLS(settings, host, options) + if err != nil { + return nil, &parseConfigError{connString: connString, msg: "failed to configure TLS", err: err} + } + } + + for _, tlsConfig := range tlsConfigs { + fallbacks = append(fallbacks, &FallbackConfig{ + Host: host, + Port: port, + TLSConfig: tlsConfig, + }) + } + } + + config.Host = fallbacks[0].Host + config.Port = fallbacks[0].Port + config.TLSConfig = fallbacks[0].TLSConfig + config.Fallbacks = fallbacks[1:] + + passfile, err := pgpassfile.ReadPassfile(settings["passfile"]) + if err == nil { + if config.Password == "" { + host := config.Host + if network, _ := NetworkAddress(config.Host, config.Port); network == "unix" { + host = "localhost" + } + + config.Password = passfile.FindPassword(host, strconv.Itoa(int(config.Port)), config.Database, config.User) + } + } + + switch tsa := settings["target_session_attrs"]; tsa { + case "read-write": + config.ValidateConnect = ValidateConnectTargetSessionAttrsReadWrite + case "read-only": + config.ValidateConnect = ValidateConnectTargetSessionAttrsReadOnly + case "primary": + config.ValidateConnect = ValidateConnectTargetSessionAttrsPrimary + case "standby": + config.ValidateConnect = ValidateConnectTargetSessionAttrsStandby + case "prefer-standby": + config.ValidateConnect = ValidateConnectTargetSessionAttrsPreferStandby + case "any": + // do nothing + default: + return nil, &parseConfigError{connString: connString, msg: fmt.Sprintf("unknown target_session_attrs value: %v", tsa)} + } + + return config, nil +} + +func mergeSettings(settingSets ...map[string]string) map[string]string { + settings := make(map[string]string) + + for _, s2 := range settingSets { + for k, v := range s2 { + settings[k] = v + } + } + + return settings +} + +func parseEnvSettings() map[string]string { + settings := make(map[string]string) + + nameMap := map[string]string{ + "PGHOST": "host", + "PGPORT": "port", + "PGDATABASE": "database", + "PGUSER": "user", + "PGPASSWORD": "password", + "PGPASSFILE": "passfile", + "PGAPPNAME": "application_name", + "PGCONNECT_TIMEOUT": "connect_timeout", + "PGSSLMODE": "sslmode", + "PGSSLKEY": "sslkey", + "PGSSLCERT": "sslcert", + "PGSSLSNI": "sslsni", + "PGSSLROOTCERT": "sslrootcert", + "PGSSLPASSWORD": "sslpassword", + "PGTARGETSESSIONATTRS": "target_session_attrs", + "PGSERVICE": "service", + "PGSERVICEFILE": "servicefile", + } + + for envname, realname := range nameMap { + value := os.Getenv(envname) + if value != "" { + settings[realname] = value + } + } + + return settings +} + +func parseURLSettings(connString string) (map[string]string, error) { + settings := make(map[string]string) + + url, err := url.Parse(connString) + if err != nil { + return nil, err + } + + if url.User != nil { + settings["user"] = url.User.Username() + if password, present := url.User.Password(); present { + settings["password"] = password + } + } + + // Handle multiple host:port's in url.Host by splitting them into host,host,host and port,port,port. + var hosts []string + var ports []string + for _, host := range strings.Split(url.Host, ",") { + if host == "" { + continue + } + if isIPOnly(host) { + hosts = append(hosts, strings.Trim(host, "[]")) + continue + } + h, p, err := net.SplitHostPort(host) + if err != nil { + return nil, fmt.Errorf("failed to split host:port in '%s', err: %w", host, err) + } + if h != "" { + hosts = append(hosts, h) + } + if p != "" { + ports = append(ports, p) + } + } + if len(hosts) > 0 { + settings["host"] = strings.Join(hosts, ",") + } + if len(ports) > 0 { + settings["port"] = strings.Join(ports, ",") + } + + database := strings.TrimLeft(url.Path, "/") + if database != "" { + settings["database"] = database + } + + nameMap := map[string]string{ + "dbname": "database", + } + + for k, v := range url.Query() { + if k2, present := nameMap[k]; present { + k = k2 + } + + settings[k] = v[0] + } + + return settings, nil +} + +func isIPOnly(host string) bool { + return net.ParseIP(strings.Trim(host, "[]")) != nil || !strings.Contains(host, ":") +} + +var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1} + +func parseDSNSettings(s string) (map[string]string, error) { + settings := make(map[string]string) + + nameMap := map[string]string{ + "dbname": "database", + } + + for len(s) > 0 { + var key, val string + eqIdx := strings.IndexRune(s, '=') + if eqIdx < 0 { + return nil, errors.New("invalid dsn") + } + + key = strings.Trim(s[:eqIdx], " \t\n\r\v\f") + s = strings.TrimLeft(s[eqIdx+1:], " \t\n\r\v\f") + if len(s) == 0 { + } else if s[0] != '\'' { + end := 0 + for ; end < len(s); end++ { + if asciiSpace[s[end]] == 1 { + break + } + if s[end] == '\\' { + end++ + if end == len(s) { + return nil, errors.New("invalid backslash") + } + } + } + val = strings.Replace(strings.Replace(s[:end], "\\\\", "\\", -1), "\\'", "'", -1) + if end == len(s) { + s = "" + } else { + s = s[end+1:] + } + } else { // quoted string + s = s[1:] + end := 0 + for ; end < len(s); end++ { + if s[end] == '\'' { + break + } + if s[end] == '\\' { + end++ + } + } + if end == len(s) { + return nil, errors.New("unterminated quoted string in connection info string") + } + val = strings.Replace(strings.Replace(s[:end], "\\\\", "\\", -1), "\\'", "'", -1) + if end == len(s) { + s = "" + } else { + s = s[end+1:] + } + } + + if k, ok := nameMap[key]; ok { + key = k + } + + if key == "" { + return nil, errors.New("invalid dsn") + } + + settings[key] = val + } + + return settings, nil +} + +func parseServiceSettings(servicefilePath, serviceName string) (map[string]string, error) { + servicefile, err := pgservicefile.ReadServicefile(servicefilePath) + if err != nil { + return nil, fmt.Errorf("failed to read service file: %v", servicefilePath) + } + + service, err := servicefile.GetService(serviceName) + if err != nil { + return nil, fmt.Errorf("unable to find service: %v", serviceName) + } + + nameMap := map[string]string{ + "dbname": "database", + } + + settings := make(map[string]string, len(service.Settings)) + for k, v := range service.Settings { + if k2, present := nameMap[k]; present { + k = k2 + } + settings[k] = v + } + + return settings, nil +} + +// configTLS uses libpq's TLS parameters to construct []*tls.Config. It is +// necessary to allow returning multiple TLS configs as sslmode "allow" and +// "prefer" allow fallback. +func configTLS(settings map[string]string, thisHost string, parseConfigOptions ParseConfigOptions) ([]*tls.Config, error) { + host := thisHost + sslmode := settings["sslmode"] + sslrootcert := settings["sslrootcert"] + sslcert := settings["sslcert"] + sslkey := settings["sslkey"] + sslpassword := settings["sslpassword"] + sslsni := settings["sslsni"] + + // Match libpq default behavior + if sslmode == "" { + sslmode = "prefer" + } + if sslsni == "" { + sslsni = "1" + } + + tlsConfig := &tls.Config{} + + switch sslmode { + case "disable": + return []*tls.Config{nil}, nil + case "allow", "prefer": + tlsConfig.InsecureSkipVerify = true + case "require": + // According to PostgreSQL documentation, if a root CA file exists, + // the behavior of sslmode=require should be the same as that of verify-ca + // + // See https://www.postgresql.org/docs/12/libpq-ssl.html + if sslrootcert != "" { + goto nextCase + } + tlsConfig.InsecureSkipVerify = true + break + nextCase: + fallthrough + case "verify-ca": + // Don't perform the default certificate verification because it + // will verify the hostname. Instead, verify the server's + // certificate chain ourselves in VerifyPeerCertificate and + // ignore the server name. This emulates libpq's verify-ca + // behavior. + // + // See https://github.com/golang/go/issues/21971#issuecomment-332693931 + // and https://pkg.go.dev/crypto/tls?tab=doc#example-Config-VerifyPeerCertificate + // for more info. + tlsConfig.InsecureSkipVerify = true + tlsConfig.VerifyPeerCertificate = func(certificates [][]byte, _ [][]*x509.Certificate) error { + certs := make([]*x509.Certificate, len(certificates)) + for i, asn1Data := range certificates { + cert, err := x509.ParseCertificate(asn1Data) + if err != nil { + return errors.New("failed to parse certificate from server: " + err.Error()) + } + certs[i] = cert + } + + // Leave DNSName empty to skip hostname verification. + opts := x509.VerifyOptions{ + Roots: tlsConfig.RootCAs, + Intermediates: x509.NewCertPool(), + } + // Skip the first cert because it's the leaf. All others + // are intermediates. + for _, cert := range certs[1:] { + opts.Intermediates.AddCert(cert) + } + _, err := certs[0].Verify(opts) + return err + } + case "verify-full": + tlsConfig.ServerName = host + default: + return nil, errors.New("sslmode is invalid") + } + + if sslrootcert != "" { + caCertPool := x509.NewCertPool() + + caPath := sslrootcert + caCert, err := os.ReadFile(caPath) + if err != nil { + return nil, fmt.Errorf("unable to read CA file: %w", err) + } + + if !caCertPool.AppendCertsFromPEM(caCert) { + return nil, errors.New("unable to add CA to cert pool") + } + + tlsConfig.RootCAs = caCertPool + tlsConfig.ClientCAs = caCertPool + } + + if (sslcert != "" && sslkey == "") || (sslcert == "" && sslkey != "") { + return nil, errors.New(`both "sslcert" and "sslkey" are required`) + } + + if sslcert != "" && sslkey != "" { + buf, err := os.ReadFile(sslkey) + if err != nil { + return nil, fmt.Errorf("unable to read sslkey: %w", err) + } + block, _ := pem.Decode(buf) + var pemKey []byte + var decryptedKey []byte + var decryptedError error + // If PEM is encrypted, attempt to decrypt using pass phrase + if x509.IsEncryptedPEMBlock(block) { + // Attempt decryption with pass phrase + // NOTE: only supports RSA (PKCS#1) + if sslpassword != "" { + decryptedKey, decryptedError = x509.DecryptPEMBlock(block, []byte(sslpassword)) + } + //if sslpassword not provided or has decryption error when use it + //try to find sslpassword with callback function + if sslpassword == "" || decryptedError != nil { + if parseConfigOptions.GetSSLPassword != nil { + sslpassword = parseConfigOptions.GetSSLPassword(context.Background()) + } + if sslpassword == "" { + return nil, fmt.Errorf("unable to find sslpassword") + } + } + decryptedKey, decryptedError = x509.DecryptPEMBlock(block, []byte(sslpassword)) + // Should we also provide warning for PKCS#1 needed? + if decryptedError != nil { + return nil, fmt.Errorf("unable to decrypt key: %w", err) + } + + pemBytes := pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: decryptedKey, + } + pemKey = pem.EncodeToMemory(&pemBytes) + } else { + pemKey = pem.EncodeToMemory(block) + } + certfile, err := os.ReadFile(sslcert) + if err != nil { + return nil, fmt.Errorf("unable to read cert: %w", err) + } + cert, err := tls.X509KeyPair(certfile, pemKey) + if err != nil { + return nil, fmt.Errorf("unable to load cert: %w", err) + } + tlsConfig.Certificates = []tls.Certificate{cert} + } + + // Set Server Name Indication (SNI), if enabled by connection parameters. + // Per RFC 6066, do not set it if the host is a literal IP address (IPv4 + // or IPv6). + if sslsni == "1" && net.ParseIP(host) == nil { + tlsConfig.ServerName = host + } + + switch sslmode { + case "allow": + return []*tls.Config{nil, tlsConfig}, nil + case "prefer": + return []*tls.Config{tlsConfig, nil}, nil + case "require", "verify-ca", "verify-full": + return []*tls.Config{tlsConfig}, nil + default: + panic("BUG: bad sslmode should already have been caught") + } +} + +func parsePort(s string) (uint16, error) { + port, err := strconv.ParseUint(s, 10, 16) + if err != nil { + return 0, err + } + if port < 1 || port > math.MaxUint16 { + return 0, errors.New("outside range") + } + return uint16(port), nil +} + +func makeDefaultDialer() *net.Dialer { + return &net.Dialer{KeepAlive: 5 * time.Minute} +} + +func makeDefaultResolver() *net.Resolver { + return net.DefaultResolver +} + +func parseConnectTimeoutSetting(s string) (time.Duration, error) { + timeout, err := strconv.ParseInt(s, 10, 64) + if err != nil { + return 0, err + } + if timeout < 0 { + return 0, errors.New("negative timeout") + } + return time.Duration(timeout) * time.Second, nil +} + +func makeConnectTimeoutDialFunc(timeout time.Duration) DialFunc { + d := makeDefaultDialer() + d.Timeout = timeout + return d.DialContext +} + +// ValidateConnectTargetSessionAttrsReadWrite is an ValidateConnectFunc that implements libpq compatible +// target_session_attrs=read-write. +func ValidateConnectTargetSessionAttrsReadWrite(ctx context.Context, pgConn *PgConn) error { + result := pgConn.ExecParams(ctx, "show transaction_read_only", nil, nil, nil, nil).Read() + if result.Err != nil { + return result.Err + } + + if string(result.Rows[0][0]) == "on" { + return errors.New("read only connection") + } + + return nil +} + +// ValidateConnectTargetSessionAttrsReadOnly is an ValidateConnectFunc that implements libpq compatible +// target_session_attrs=read-only. +func ValidateConnectTargetSessionAttrsReadOnly(ctx context.Context, pgConn *PgConn) error { + result := pgConn.ExecParams(ctx, "show transaction_read_only", nil, nil, nil, nil).Read() + if result.Err != nil { + return result.Err + } + + if string(result.Rows[0][0]) != "on" { + return errors.New("connection is not read only") + } + + return nil +} + +// ValidateConnectTargetSessionAttrsStandby is an ValidateConnectFunc that implements libpq compatible +// target_session_attrs=standby. +func ValidateConnectTargetSessionAttrsStandby(ctx context.Context, pgConn *PgConn) error { + result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read() + if result.Err != nil { + return result.Err + } + + if string(result.Rows[0][0]) != "t" { + return errors.New("server is not in hot standby mode") + } + + return nil +} + +// ValidateConnectTargetSessionAttrsPrimary is an ValidateConnectFunc that implements libpq compatible +// target_session_attrs=primary. +func ValidateConnectTargetSessionAttrsPrimary(ctx context.Context, pgConn *PgConn) error { + result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read() + if result.Err != nil { + return result.Err + } + + if string(result.Rows[0][0]) == "t" { + return errors.New("server is in standby mode") + } + + return nil +} + +// ValidateConnectTargetSessionAttrsPreferStandby is an ValidateConnectFunc that implements libpq compatible +// target_session_attrs=prefer-standby. +func ValidateConnectTargetSessionAttrsPreferStandby(ctx context.Context, pgConn *PgConn) error { + result := pgConn.ExecParams(ctx, "select pg_is_in_recovery()", nil, nil, nil, nil).Read() + if result.Err != nil { + return result.Err + } + + if string(result.Rows[0][0]) != "t" { + return &NotPreferredError{err: errors.New("server is not in hot standby mode")} + } + + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/defaults.go b/vendor/github.com/jackc/pgx/v5/pgconn/defaults.go new file mode 100644 index 00000000000..1dd514ff44c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/defaults.go @@ -0,0 +1,63 @@ +//go:build !windows +// +build !windows + +package pgconn + +import ( + "os" + "os/user" + "path/filepath" +) + +func defaultSettings() map[string]string { + settings := make(map[string]string) + + settings["host"] = defaultHost() + settings["port"] = "5432" + + // Default to the OS user name. Purposely ignoring err getting user name from + // OS. The client application will simply have to specify the user in that + // case (which they typically will be doing anyway). + user, err := user.Current() + if err == nil { + settings["user"] = user.Username + settings["passfile"] = filepath.Join(user.HomeDir, ".pgpass") + settings["servicefile"] = filepath.Join(user.HomeDir, ".pg_service.conf") + sslcert := filepath.Join(user.HomeDir, ".postgresql", "postgresql.crt") + sslkey := filepath.Join(user.HomeDir, ".postgresql", "postgresql.key") + if _, err := os.Stat(sslcert); err == nil { + if _, err := os.Stat(sslkey); err == nil { + // Both the cert and key must be present to use them, or do not use either + settings["sslcert"] = sslcert + settings["sslkey"] = sslkey + } + } + sslrootcert := filepath.Join(user.HomeDir, ".postgresql", "root.crt") + if _, err := os.Stat(sslrootcert); err == nil { + settings["sslrootcert"] = sslrootcert + } + } + + settings["target_session_attrs"] = "any" + + return settings +} + +// defaultHost attempts to mimic libpq's default host. libpq uses the default unix socket location on *nix and localhost +// on Windows. The default socket location is compiled into libpq. Since pgx does not have access to that default it +// checks the existence of common locations. +func defaultHost() string { + candidatePaths := []string{ + "/var/run/postgresql", // Debian + "/private/tmp", // OSX - homebrew + "/tmp", // standard PostgreSQL + } + + for _, path := range candidatePaths { + if _, err := os.Stat(path); err == nil { + return path + } + } + + return "localhost" +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/defaults_windows.go b/vendor/github.com/jackc/pgx/v5/pgconn/defaults_windows.go new file mode 100644 index 00000000000..33b4a1ff852 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/defaults_windows.go @@ -0,0 +1,57 @@ +package pgconn + +import ( + "os" + "os/user" + "path/filepath" + "strings" +) + +func defaultSettings() map[string]string { + settings := make(map[string]string) + + settings["host"] = defaultHost() + settings["port"] = "5432" + + // Default to the OS user name. Purposely ignoring err getting user name from + // OS. The client application will simply have to specify the user in that + // case (which they typically will be doing anyway). + user, err := user.Current() + appData := os.Getenv("APPDATA") + if err == nil { + // Windows gives us the username here as `DOMAIN\user` or `LOCALPCNAME\user`, + // but the libpq default is just the `user` portion, so we strip off the first part. + username := user.Username + if strings.Contains(username, "\\") { + username = username[strings.LastIndex(username, "\\")+1:] + } + + settings["user"] = username + settings["passfile"] = filepath.Join(appData, "postgresql", "pgpass.conf") + settings["servicefile"] = filepath.Join(user.HomeDir, ".pg_service.conf") + sslcert := filepath.Join(appData, "postgresql", "postgresql.crt") + sslkey := filepath.Join(appData, "postgresql", "postgresql.key") + if _, err := os.Stat(sslcert); err == nil { + if _, err := os.Stat(sslkey); err == nil { + // Both the cert and key must be present to use them, or do not use either + settings["sslcert"] = sslcert + settings["sslkey"] = sslkey + } + } + sslrootcert := filepath.Join(appData, "postgresql", "root.crt") + if _, err := os.Stat(sslrootcert); err == nil { + settings["sslrootcert"] = sslrootcert + } + } + + settings["target_session_attrs"] = "any" + + return settings +} + +// defaultHost attempts to mimic libpq's default host. libpq uses the default unix socket location on *nix and localhost +// on Windows. The default socket location is compiled into libpq. Since pgx does not have access to that default it +// checks the existence of common locations. +func defaultHost() string { + return "localhost" +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/doc.go b/vendor/github.com/jackc/pgx/v5/pgconn/doc.go new file mode 100644 index 00000000000..e3242cf4e15 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/doc.go @@ -0,0 +1,34 @@ +// Package pgconn is a low-level PostgreSQL database driver. +/* +pgconn provides lower level access to a PostgreSQL connection than a database/sql or pgx connection. It operates at +nearly the same level is the C library libpq. + +Establishing a Connection + +Use Connect to establish a connection. It accepts a connection string in URL or DSN and will read the environment for +libpq style environment variables. + +Executing a Query + +ExecParams and ExecPrepared execute a single query. They return readers that iterate over each row. The Read method +reads all rows into memory. + +Executing Multiple Queries in a Single Round Trip + +Exec and ExecBatch can execute multiple queries in a single round trip. They return readers that iterate over each query +result. The ReadAll method reads all query results into memory. + +Pipeline Mode + +Pipeline mode allows sending queries without having read the results of previously sent queries. It allows +control of exactly how many and when network round trips occur. + +Context Support + +All potentially blocking operations take a context.Context. If a context is canceled while the method is in progress the +method immediately returns. In most circumstances, this will close the underlying connection. + +The CancelRequest method may be used to request the PostgreSQL server cancel an in-progress query without forcing the +client to abort. +*/ +package pgconn diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/errors.go b/vendor/github.com/jackc/pgx/v5/pgconn/errors.go new file mode 100644 index 00000000000..3c54bbec05b --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/errors.go @@ -0,0 +1,226 @@ +package pgconn + +import ( + "context" + "errors" + "fmt" + "net" + "net/url" + "regexp" + "strings" +) + +// SafeToRetry checks if the err is guaranteed to have occurred before sending any data to the server. +func SafeToRetry(err error) bool { + if e, ok := err.(interface{ SafeToRetry() bool }); ok { + return e.SafeToRetry() + } + return false +} + +// Timeout checks if err was was caused by a timeout. To be specific, it is true if err was caused within pgconn by a +// context.DeadlineExceeded or an implementer of net.Error where Timeout() is true. +func Timeout(err error) bool { + var timeoutErr *errTimeout + return errors.As(err, &timeoutErr) +} + +// PgError represents an error reported by the PostgreSQL server. See +// http://www.postgresql.org/docs/11/static/protocol-error-fields.html for +// detailed field description. +type PgError struct { + Severity string + Code string + Message string + Detail string + Hint string + Position int32 + InternalPosition int32 + InternalQuery string + Where string + SchemaName string + TableName string + ColumnName string + DataTypeName string + ConstraintName string + File string + Line int32 + Routine string +} + +func (pe *PgError) Error() string { + return pe.Severity + ": " + pe.Message + " (SQLSTATE " + pe.Code + ")" +} + +// SQLState returns the SQLState of the error. +func (pe *PgError) SQLState() string { + return pe.Code +} + +type connectError struct { + config *Config + msg string + err error +} + +func (e *connectError) Error() string { + sb := &strings.Builder{} + fmt.Fprintf(sb, "failed to connect to `host=%s user=%s database=%s`: %s", e.config.Host, e.config.User, e.config.Database, e.msg) + if e.err != nil { + fmt.Fprintf(sb, " (%s)", e.err.Error()) + } + return sb.String() +} + +func (e *connectError) Unwrap() error { + return e.err +} + +type connLockError struct { + status string +} + +func (e *connLockError) SafeToRetry() bool { + return true // a lock failure by definition happens before the connection is used. +} + +func (e *connLockError) Error() string { + return e.status +} + +type parseConfigError struct { + connString string + msg string + err error +} + +func (e *parseConfigError) Error() string { + connString := redactPW(e.connString) + if e.err == nil { + return fmt.Sprintf("cannot parse `%s`: %s", connString, e.msg) + } + return fmt.Sprintf("cannot parse `%s`: %s (%s)", connString, e.msg, e.err.Error()) +} + +func (e *parseConfigError) Unwrap() error { + return e.err +} + +func normalizeTimeoutError(ctx context.Context, err error) error { + if err, ok := err.(net.Error); ok && err.Timeout() { + if ctx.Err() == context.Canceled { + // Since the timeout was caused by a context cancellation, the actual error is context.Canceled not the timeout error. + return context.Canceled + } else if ctx.Err() == context.DeadlineExceeded { + return &errTimeout{err: ctx.Err()} + } else { + return &errTimeout{err: err} + } + } + return err +} + +type pgconnError struct { + msg string + err error + safeToRetry bool +} + +func (e *pgconnError) Error() string { + if e.msg == "" { + return e.err.Error() + } + if e.err == nil { + return e.msg + } + return fmt.Sprintf("%s: %s", e.msg, e.err.Error()) +} + +func (e *pgconnError) SafeToRetry() bool { + return e.safeToRetry +} + +func (e *pgconnError) Unwrap() error { + return e.err +} + +// errTimeout occurs when an error was caused by a timeout. Specifically, it wraps an error which is +// context.Canceled, context.DeadlineExceeded, or an implementer of net.Error where Timeout() is true. +type errTimeout struct { + err error +} + +func (e *errTimeout) Error() string { + return fmt.Sprintf("timeout: %s", e.err.Error()) +} + +func (e *errTimeout) SafeToRetry() bool { + return SafeToRetry(e.err) +} + +func (e *errTimeout) Unwrap() error { + return e.err +} + +type contextAlreadyDoneError struct { + err error +} + +func (e *contextAlreadyDoneError) Error() string { + return fmt.Sprintf("context already done: %s", e.err.Error()) +} + +func (e *contextAlreadyDoneError) SafeToRetry() bool { + return true +} + +func (e *contextAlreadyDoneError) Unwrap() error { + return e.err +} + +// newContextAlreadyDoneError double-wraps a context error in `contextAlreadyDoneError` and `errTimeout`. +func newContextAlreadyDoneError(ctx context.Context) (err error) { + return &errTimeout{&contextAlreadyDoneError{err: ctx.Err()}} +} + +func redactPW(connString string) string { + if strings.HasPrefix(connString, "postgres://") || strings.HasPrefix(connString, "postgresql://") { + if u, err := url.Parse(connString); err == nil { + return redactURL(u) + } + } + quotedDSN := regexp.MustCompile(`password='[^']*'`) + connString = quotedDSN.ReplaceAllLiteralString(connString, "password=xxxxx") + plainDSN := regexp.MustCompile(`password=[^ ]*`) + connString = plainDSN.ReplaceAllLiteralString(connString, "password=xxxxx") + brokenURL := regexp.MustCompile(`:[^:@]+?@`) + connString = brokenURL.ReplaceAllLiteralString(connString, ":xxxxxx@") + return connString +} + +func redactURL(u *url.URL) string { + if u == nil { + return "" + } + if _, pwSet := u.User.Password(); pwSet { + u.User = url.UserPassword(u.User.Username(), "xxxxx") + } + return u.String() +} + +type NotPreferredError struct { + err error + safeToRetry bool +} + +func (e *NotPreferredError) Error() string { + return fmt.Sprintf("standby server not found: %s", e.err.Error()) +} + +func (e *NotPreferredError) SafeToRetry() bool { + return e.safeToRetry +} + +func (e *NotPreferredError) Unwrap() error { + return e.err +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/internal/bgreader/bgreader.go b/vendor/github.com/jackc/pgx/v5/pgconn/internal/bgreader/bgreader.go new file mode 100644 index 00000000000..aa1a3d39c80 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/internal/bgreader/bgreader.go @@ -0,0 +1,132 @@ +// Package bgreader provides a io.Reader that can optionally buffer reads in the background. +package bgreader + +import ( + "io" + "sync" + + "github.com/jackc/pgx/v5/internal/iobufpool" +) + +const ( + bgReaderStatusStopped = iota + bgReaderStatusRunning + bgReaderStatusStopping +) + +// BGReader is an io.Reader that can optionally buffer reads in the background. It is safe for concurrent use. +type BGReader struct { + r io.Reader + + cond *sync.Cond + bgReaderStatus int32 + readResults []readResult +} + +type readResult struct { + buf *[]byte + err error +} + +// Start starts the backgrounder reader. If the background reader is already running this is a no-op. The background +// reader will stop automatically when the underlying reader returns an error. +func (r *BGReader) Start() { + r.cond.L.Lock() + defer r.cond.L.Unlock() + + switch r.bgReaderStatus { + case bgReaderStatusStopped: + r.bgReaderStatus = bgReaderStatusRunning + go r.bgRead() + case bgReaderStatusRunning: + // no-op + case bgReaderStatusStopping: + r.bgReaderStatus = bgReaderStatusRunning + } +} + +// Stop tells the background reader to stop after the in progress Read returns. It is safe to call Stop when the +// background reader is not running. +func (r *BGReader) Stop() { + r.cond.L.Lock() + defer r.cond.L.Unlock() + + switch r.bgReaderStatus { + case bgReaderStatusStopped: + // no-op + case bgReaderStatusRunning: + r.bgReaderStatus = bgReaderStatusStopping + case bgReaderStatusStopping: + // no-op + } +} + +func (r *BGReader) bgRead() { + keepReading := true + for keepReading { + buf := iobufpool.Get(8192) + n, err := r.r.Read(*buf) + *buf = (*buf)[:n] + + r.cond.L.Lock() + r.readResults = append(r.readResults, readResult{buf: buf, err: err}) + if r.bgReaderStatus == bgReaderStatusStopping || err != nil { + r.bgReaderStatus = bgReaderStatusStopped + keepReading = false + } + r.cond.L.Unlock() + r.cond.Broadcast() + } +} + +// Read implements the io.Reader interface. +func (r *BGReader) Read(p []byte) (int, error) { + r.cond.L.Lock() + defer r.cond.L.Unlock() + + if len(r.readResults) > 0 { + return r.readFromReadResults(p) + } + + // There are no unread background read results and the background reader is stopped. + if r.bgReaderStatus == bgReaderStatusStopped { + return r.r.Read(p) + } + + // Wait for results from the background reader + for len(r.readResults) == 0 { + r.cond.Wait() + } + return r.readFromReadResults(p) +} + +// readBackgroundResults reads a result previously read by the background reader. r.cond.L must be held. +func (r *BGReader) readFromReadResults(p []byte) (int, error) { + buf := r.readResults[0].buf + var err error + + n := copy(p, *buf) + if n == len(*buf) { + err = r.readResults[0].err + iobufpool.Put(buf) + if len(r.readResults) == 1 { + r.readResults = nil + } else { + r.readResults = r.readResults[1:] + } + } else { + *buf = (*buf)[n:] + r.readResults[0].buf = buf + } + + return n, err +} + +func New(r io.Reader) *BGReader { + return &BGReader{ + r: r, + cond: &sync.Cond{ + L: &sync.Mutex{}, + }, + } +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/internal/ctxwatch/context_watcher.go b/vendor/github.com/jackc/pgx/v5/pgconn/internal/ctxwatch/context_watcher.go new file mode 100644 index 00000000000..b39cb3ee57a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/internal/ctxwatch/context_watcher.go @@ -0,0 +1,73 @@ +package ctxwatch + +import ( + "context" + "sync" +) + +// ContextWatcher watches a context and performs an action when the context is canceled. It can watch one context at a +// time. +type ContextWatcher struct { + onCancel func() + onUnwatchAfterCancel func() + unwatchChan chan struct{} + + lock sync.Mutex + watchInProgress bool + onCancelWasCalled bool +} + +// NewContextWatcher returns a ContextWatcher. onCancel will be called when a watched context is canceled. +// OnUnwatchAfterCancel will be called when Unwatch is called and the watched context had already been canceled and +// onCancel called. +func NewContextWatcher(onCancel func(), onUnwatchAfterCancel func()) *ContextWatcher { + cw := &ContextWatcher{ + onCancel: onCancel, + onUnwatchAfterCancel: onUnwatchAfterCancel, + unwatchChan: make(chan struct{}), + } + + return cw +} + +// Watch starts watching ctx. If ctx is canceled then the onCancel function passed to NewContextWatcher will be called. +func (cw *ContextWatcher) Watch(ctx context.Context) { + cw.lock.Lock() + defer cw.lock.Unlock() + + if cw.watchInProgress { + panic("Watch already in progress") + } + + cw.onCancelWasCalled = false + + if ctx.Done() != nil { + cw.watchInProgress = true + go func() { + select { + case <-ctx.Done(): + cw.onCancel() + cw.onCancelWasCalled = true + <-cw.unwatchChan + case <-cw.unwatchChan: + } + }() + } else { + cw.watchInProgress = false + } +} + +// Unwatch stops watching the previously watched context. If the onCancel function passed to NewContextWatcher was +// called then onUnwatchAfterCancel will also be called. +func (cw *ContextWatcher) Unwatch() { + cw.lock.Lock() + defer cw.lock.Unlock() + + if cw.watchInProgress { + cw.unwatchChan <- struct{}{} + if cw.onCancelWasCalled { + cw.onUnwatchAfterCancel() + } + cw.watchInProgress = false + } +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/krb5.go b/vendor/github.com/jackc/pgx/v5/pgconn/krb5.go new file mode 100644 index 00000000000..3c1af347730 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/krb5.go @@ -0,0 +1,100 @@ +package pgconn + +import ( + "errors" + "fmt" + + "github.com/jackc/pgx/v5/pgproto3" +) + +// NewGSSFunc creates a GSS authentication provider, for use with +// RegisterGSSProvider. +type NewGSSFunc func() (GSS, error) + +var newGSS NewGSSFunc + +// RegisterGSSProvider registers a GSS authentication provider. For example, if +// you need to use Kerberos to authenticate with your server, add this to your +// main package: +// +// import "github.com/otan/gopgkrb5" +// +// func init() { +// pgconn.RegisterGSSProvider(func() (pgconn.GSS, error) { return gopgkrb5.NewGSS() }) +// } +func RegisterGSSProvider(newGSSArg NewGSSFunc) { + newGSS = newGSSArg +} + +// GSS provides GSSAPI authentication (e.g., Kerberos). +type GSS interface { + GetInitToken(host string, service string) ([]byte, error) + GetInitTokenFromSPN(spn string) ([]byte, error) + Continue(inToken []byte) (done bool, outToken []byte, err error) +} + +func (c *PgConn) gssAuth() error { + if newGSS == nil { + return errors.New("kerberos error: no GSSAPI provider registered, see https://github.com/otan/gopgkrb5") + } + cli, err := newGSS() + if err != nil { + return err + } + + var nextData []byte + if c.config.KerberosSpn != "" { + // Use the supplied SPN if provided. + nextData, err = cli.GetInitTokenFromSPN(c.config.KerberosSpn) + } else { + // Allow the kerberos service name to be overridden + service := "postgres" + if c.config.KerberosSrvName != "" { + service = c.config.KerberosSrvName + } + nextData, err = cli.GetInitToken(c.config.Host, service) + } + if err != nil { + return err + } + + for { + gssResponse := &pgproto3.GSSResponse{ + Data: nextData, + } + c.frontend.Send(gssResponse) + err = c.flushWithPotentialWriteReadDeadlock() + if err != nil { + return err + } + resp, err := c.rxGSSContinue() + if err != nil { + return err + } + var done bool + done, nextData, err = cli.Continue(resp.Data) + if err != nil { + return err + } + if done { + break + } + } + return nil +} + +func (c *PgConn) rxGSSContinue() (*pgproto3.AuthenticationGSSContinue, error) { + msg, err := c.receiveMessage() + if err != nil { + return nil, err + } + + switch m := msg.(type) { + case *pgproto3.AuthenticationGSSContinue: + return m, nil + case *pgproto3.ErrorResponse: + return nil, ErrorResponseToPgError(m) + } + + return nil, fmt.Errorf("expected AuthenticationGSSContinue message but received unexpected message %T", msg) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgconn/pgconn.go b/vendor/github.com/jackc/pgx/v5/pgconn/pgconn.go new file mode 100644 index 00000000000..9f84605fefe --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgconn/pgconn.go @@ -0,0 +1,2072 @@ +package pgconn + +import ( + "context" + "crypto/md5" + "crypto/tls" + "encoding/binary" + "encoding/hex" + "errors" + "fmt" + "io" + "math" + "net" + "strconv" + "strings" + "sync" + "time" + + "github.com/jackc/pgx/v5/internal/iobufpool" + "github.com/jackc/pgx/v5/internal/pgio" + "github.com/jackc/pgx/v5/pgconn/internal/bgreader" + "github.com/jackc/pgx/v5/pgconn/internal/ctxwatch" + "github.com/jackc/pgx/v5/pgproto3" +) + +const ( + connStatusUninitialized = iota + connStatusConnecting + connStatusClosed + connStatusIdle + connStatusBusy +) + +// Notice represents a notice response message reported by the PostgreSQL server. Be aware that this is distinct from +// LISTEN/NOTIFY notification. +type Notice PgError + +// Notification is a message received from the PostgreSQL LISTEN/NOTIFY system +type Notification struct { + PID uint32 // backend pid that sent the notification + Channel string // channel from which notification was received + Payload string +} + +// DialFunc is a function that can be used to connect to a PostgreSQL server. +type DialFunc func(ctx context.Context, network, addr string) (net.Conn, error) + +// LookupFunc is a function that can be used to lookup IPs addrs from host. Optionally an ip:port combination can be +// returned in order to override the connection string's port. +type LookupFunc func(ctx context.Context, host string) (addrs []string, err error) + +// BuildFrontendFunc is a function that can be used to create Frontend implementation for connection. +type BuildFrontendFunc func(r io.Reader, w io.Writer) *pgproto3.Frontend + +// NoticeHandler is a function that can handle notices received from the PostgreSQL server. Notices can be received at +// any time, usually during handling of a query response. The *PgConn is provided so the handler is aware of the origin +// of the notice, but it must not invoke any query method. Be aware that this is distinct from LISTEN/NOTIFY +// notification. +type NoticeHandler func(*PgConn, *Notice) + +// NotificationHandler is a function that can handle notifications received from the PostgreSQL server. Notifications +// can be received at any time, usually during handling of a query response. The *PgConn is provided so the handler is +// aware of the origin of the notice, but it must not invoke any query method. Be aware that this is distinct from a +// notice event. +type NotificationHandler func(*PgConn, *Notification) + +// PgConn is a low-level PostgreSQL connection handle. It is not safe for concurrent usage. +type PgConn struct { + conn net.Conn + pid uint32 // backend pid + secretKey uint32 // key to use to send a cancel query message to the server + parameterStatuses map[string]string // parameters that have been reported by the server + txStatus byte + frontend *pgproto3.Frontend + bgReader *bgreader.BGReader + slowWriteTimer *time.Timer + + config *Config + + status byte // One of connStatus* constants + + bufferingReceive bool + bufferingReceiveMux sync.Mutex + bufferingReceiveMsg pgproto3.BackendMessage + bufferingReceiveErr error + + peekedMsg pgproto3.BackendMessage + + // Reusable / preallocated resources + resultReader ResultReader + multiResultReader MultiResultReader + pipeline Pipeline + contextWatcher *ctxwatch.ContextWatcher + fieldDescriptions [16]FieldDescription + + cleanupDone chan struct{} +} + +// Connect establishes a connection to a PostgreSQL server using the environment and connString (in URL or DSN format) +// to provide configuration. See documentation for ParseConfig for details. ctx can be used to cancel a connect attempt. +func Connect(ctx context.Context, connString string) (*PgConn, error) { + config, err := ParseConfig(connString) + if err != nil { + return nil, err + } + + return ConnectConfig(ctx, config) +} + +// Connect establishes a connection to a PostgreSQL server using the environment and connString (in URL or DSN format) +// and ParseConfigOptions to provide additional configuration. See documentation for ParseConfig for details. ctx can be +// used to cancel a connect attempt. +func ConnectWithOptions(ctx context.Context, connString string, parseConfigOptions ParseConfigOptions) (*PgConn, error) { + config, err := ParseConfigWithOptions(connString, parseConfigOptions) + if err != nil { + return nil, err + } + + return ConnectConfig(ctx, config) +} + +// Connect establishes a connection to a PostgreSQL server using config. config must have been constructed with +// ParseConfig. ctx can be used to cancel a connect attempt. +// +// If config.Fallbacks are present they will sequentially be tried in case of error establishing network connection. An +// authentication error will terminate the chain of attempts (like libpq: +// https://www.postgresql.org/docs/11/libpq-connect.html#LIBPQ-MULTIPLE-HOSTS) and be returned as the error. Otherwise, +// if all attempts fail the last error is returned. +func ConnectConfig(octx context.Context, config *Config) (pgConn *PgConn, err error) { + // Default values are set in ParseConfig. Enforce initial creation by ParseConfig rather than setting defaults from + // zero values. + if !config.createdByParseConfig { + panic("config must be created by ParseConfig") + } + + // Simplify usage by treating primary config and fallbacks the same. + fallbackConfigs := []*FallbackConfig{ + { + Host: config.Host, + Port: config.Port, + TLSConfig: config.TLSConfig, + }, + } + fallbackConfigs = append(fallbackConfigs, config.Fallbacks...) + ctx := octx + fallbackConfigs, err = expandWithIPs(ctx, config.LookupFunc, fallbackConfigs) + if err != nil { + return nil, &connectError{config: config, msg: "hostname resolving error", err: err} + } + + if len(fallbackConfigs) == 0 { + return nil, &connectError{config: config, msg: "hostname resolving error", err: errors.New("ip addr wasn't found")} + } + + foundBestServer := false + var fallbackConfig *FallbackConfig + for _, fc := range fallbackConfigs { + // ConnectTimeout restricts the whole connection process. + if config.ConnectTimeout != 0 { + var cancel context.CancelFunc + ctx, cancel = context.WithTimeout(octx, config.ConnectTimeout) + defer cancel() + } else { + ctx = octx + } + pgConn, err = connect(ctx, config, fc, false) + if err == nil { + foundBestServer = true + break + } else if pgerr, ok := err.(*PgError); ok { + err = &connectError{config: config, msg: "server error", err: pgerr} + const ERRCODE_INVALID_PASSWORD = "28P01" // wrong password + const ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION = "28000" // wrong password or bad pg_hba.conf settings + const ERRCODE_INVALID_CATALOG_NAME = "3D000" // db does not exist + const ERRCODE_INSUFFICIENT_PRIVILEGE = "42501" // missing connect privilege + if pgerr.Code == ERRCODE_INVALID_PASSWORD || + pgerr.Code == ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION || + pgerr.Code == ERRCODE_INVALID_CATALOG_NAME || + pgerr.Code == ERRCODE_INSUFFICIENT_PRIVILEGE { + break + } + } else if cerr, ok := err.(*connectError); ok { + if _, ok := cerr.err.(*NotPreferredError); ok { + fallbackConfig = fc + } + } + } + + if !foundBestServer && fallbackConfig != nil { + pgConn, err = connect(ctx, config, fallbackConfig, true) + if pgerr, ok := err.(*PgError); ok { + err = &connectError{config: config, msg: "server error", err: pgerr} + } + } + + if err != nil { + return nil, err // no need to wrap in connectError because it will already be wrapped in all cases except PgError + } + + if config.AfterConnect != nil { + err := config.AfterConnect(ctx, pgConn) + if err != nil { + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "AfterConnect error", err: err} + } + } + + return pgConn, nil +} + +func expandWithIPs(ctx context.Context, lookupFn LookupFunc, fallbacks []*FallbackConfig) ([]*FallbackConfig, error) { + var configs []*FallbackConfig + + var lookupErrors []error + + for _, fb := range fallbacks { + // skip resolve for unix sockets + if isAbsolutePath(fb.Host) { + configs = append(configs, &FallbackConfig{ + Host: fb.Host, + Port: fb.Port, + TLSConfig: fb.TLSConfig, + }) + + continue + } + + ips, err := lookupFn(ctx, fb.Host) + if err != nil { + lookupErrors = append(lookupErrors, err) + continue + } + + for _, ip := range ips { + splitIP, splitPort, err := net.SplitHostPort(ip) + if err == nil { + port, err := strconv.ParseUint(splitPort, 10, 16) + if err != nil { + return nil, fmt.Errorf("error parsing port (%s) from lookup: %w", splitPort, err) + } + configs = append(configs, &FallbackConfig{ + Host: splitIP, + Port: uint16(port), + TLSConfig: fb.TLSConfig, + }) + } else { + configs = append(configs, &FallbackConfig{ + Host: ip, + Port: fb.Port, + TLSConfig: fb.TLSConfig, + }) + } + } + } + + // See https://github.com/jackc/pgx/issues/1464. When Go 1.20 can be used in pgx consider using errors.Join so all + // errors are reported. + if len(configs) == 0 && len(lookupErrors) > 0 { + return nil, lookupErrors[0] + } + + return configs, nil +} + +func connect(ctx context.Context, config *Config, fallbackConfig *FallbackConfig, + ignoreNotPreferredErr bool) (*PgConn, error) { + pgConn := new(PgConn) + pgConn.config = config + pgConn.cleanupDone = make(chan struct{}) + + var err error + network, address := NetworkAddress(fallbackConfig.Host, fallbackConfig.Port) + netConn, err := config.DialFunc(ctx, network, address) + if err != nil { + return nil, &connectError{config: config, msg: "dial error", err: normalizeTimeoutError(ctx, err)} + } + + pgConn.conn = netConn + pgConn.contextWatcher = newContextWatcher(netConn) + pgConn.contextWatcher.Watch(ctx) + + if fallbackConfig.TLSConfig != nil { + nbTLSConn, err := startTLS(netConn, fallbackConfig.TLSConfig) + pgConn.contextWatcher.Unwatch() // Always unwatch `netConn` after TLS. + if err != nil { + netConn.Close() + return nil, &connectError{config: config, msg: "tls error", err: err} + } + + pgConn.conn = nbTLSConn + pgConn.contextWatcher = newContextWatcher(nbTLSConn) + pgConn.contextWatcher.Watch(ctx) + } + + defer pgConn.contextWatcher.Unwatch() + + pgConn.parameterStatuses = make(map[string]string) + pgConn.status = connStatusConnecting + pgConn.bgReader = bgreader.New(pgConn.conn) + pgConn.slowWriteTimer = time.AfterFunc(time.Duration(math.MaxInt64), pgConn.bgReader.Start) + pgConn.frontend = config.BuildFrontend(pgConn.bgReader, pgConn.conn) + + startupMsg := pgproto3.StartupMessage{ + ProtocolVersion: pgproto3.ProtocolVersionNumber, + Parameters: make(map[string]string), + } + + // Copy default run-time params + for k, v := range config.RuntimeParams { + startupMsg.Parameters[k] = v + } + + startupMsg.Parameters["user"] = config.User + if config.Database != "" { + startupMsg.Parameters["database"] = config.Database + } + + pgConn.frontend.Send(&startupMsg) + if err := pgConn.flushWithPotentialWriteReadDeadlock(); err != nil { + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "failed to write startup message", err: normalizeTimeoutError(ctx, err)} + } + + for { + msg, err := pgConn.receiveMessage() + if err != nil { + pgConn.conn.Close() + if err, ok := err.(*PgError); ok { + return nil, err + } + return nil, &connectError{config: config, msg: "failed to receive message", err: normalizeTimeoutError(ctx, err)} + } + + switch msg := msg.(type) { + case *pgproto3.BackendKeyData: + pgConn.pid = msg.ProcessID + pgConn.secretKey = msg.SecretKey + + case *pgproto3.AuthenticationOk: + case *pgproto3.AuthenticationCleartextPassword: + err = pgConn.txPasswordMessage(pgConn.config.Password) + if err != nil { + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "failed to write password message", err: err} + } + case *pgproto3.AuthenticationMD5Password: + digestedPassword := "md5" + hexMD5(hexMD5(pgConn.config.Password+pgConn.config.User)+string(msg.Salt[:])) + err = pgConn.txPasswordMessage(digestedPassword) + if err != nil { + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "failed to write password message", err: err} + } + case *pgproto3.AuthenticationSASL: + err = pgConn.scramAuth(msg.AuthMechanisms) + if err != nil { + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "failed SASL auth", err: err} + } + case *pgproto3.AuthenticationGSS: + err = pgConn.gssAuth() + if err != nil { + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "failed GSS auth", err: err} + } + case *pgproto3.ReadyForQuery: + pgConn.status = connStatusIdle + if config.ValidateConnect != nil { + // ValidateConnect may execute commands that cause the context to be watched again. Unwatch first to avoid + // the watch already in progress panic. This is that last thing done by this method so there is no need to + // restart the watch after ValidateConnect returns. + // + // See https://github.com/jackc/pgconn/issues/40. + pgConn.contextWatcher.Unwatch() + + err := config.ValidateConnect(ctx, pgConn) + if err != nil { + if _, ok := err.(*NotPreferredError); ignoreNotPreferredErr && ok { + return pgConn, nil + } + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "ValidateConnect failed", err: err} + } + } + return pgConn, nil + case *pgproto3.ParameterStatus, *pgproto3.NoticeResponse: + // handled by ReceiveMessage + case *pgproto3.ErrorResponse: + pgConn.conn.Close() + return nil, ErrorResponseToPgError(msg) + default: + pgConn.conn.Close() + return nil, &connectError{config: config, msg: "received unexpected message", err: err} + } + } +} + +func newContextWatcher(conn net.Conn) *ctxwatch.ContextWatcher { + return ctxwatch.NewContextWatcher( + func() { conn.SetDeadline(time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC)) }, + func() { conn.SetDeadline(time.Time{}) }, + ) +} + +func startTLS(conn net.Conn, tlsConfig *tls.Config) (net.Conn, error) { + err := binary.Write(conn, binary.BigEndian, []int32{8, 80877103}) + if err != nil { + return nil, err + } + + response := make([]byte, 1) + if _, err = io.ReadFull(conn, response); err != nil { + return nil, err + } + + if response[0] != 'S' { + return nil, errors.New("server refused TLS connection") + } + + return tls.Client(conn, tlsConfig), nil +} + +func (pgConn *PgConn) txPasswordMessage(password string) (err error) { + pgConn.frontend.Send(&pgproto3.PasswordMessage{Password: password}) + return pgConn.flushWithPotentialWriteReadDeadlock() +} + +func hexMD5(s string) string { + hash := md5.New() + io.WriteString(hash, s) + return hex.EncodeToString(hash.Sum(nil)) +} + +func (pgConn *PgConn) signalMessage() chan struct{} { + if pgConn.bufferingReceive { + panic("BUG: signalMessage when already in progress") + } + + pgConn.bufferingReceive = true + pgConn.bufferingReceiveMux.Lock() + + ch := make(chan struct{}) + go func() { + pgConn.bufferingReceiveMsg, pgConn.bufferingReceiveErr = pgConn.frontend.Receive() + pgConn.bufferingReceiveMux.Unlock() + close(ch) + }() + + return ch +} + +// ReceiveMessage receives one wire protocol message from the PostgreSQL server. It must only be used when the +// connection is not busy. e.g. It is an error to call ReceiveMessage while reading the result of a query. The messages +// are still handled by the core pgconn message handling system so receiving a NotificationResponse will still trigger +// the OnNotification callback. +// +// This is a very low level method that requires deep understanding of the PostgreSQL wire protocol to use correctly. +// See https://www.postgresql.org/docs/current/protocol.html. +func (pgConn *PgConn) ReceiveMessage(ctx context.Context) (pgproto3.BackendMessage, error) { + if err := pgConn.lock(); err != nil { + return nil, err + } + defer pgConn.unlock() + + if ctx != context.Background() { + select { + case <-ctx.Done(): + return nil, newContextAlreadyDoneError(ctx) + default: + } + pgConn.contextWatcher.Watch(ctx) + defer pgConn.contextWatcher.Unwatch() + } + + msg, err := pgConn.receiveMessage() + if err != nil { + err = &pgconnError{ + msg: "receive message failed", + err: normalizeTimeoutError(ctx, err), + safeToRetry: true} + } + return msg, err +} + +// peekMessage peeks at the next message without setting up context cancellation. +func (pgConn *PgConn) peekMessage() (pgproto3.BackendMessage, error) { + if pgConn.peekedMsg != nil { + return pgConn.peekedMsg, nil + } + + var msg pgproto3.BackendMessage + var err error + if pgConn.bufferingReceive { + pgConn.bufferingReceiveMux.Lock() + msg = pgConn.bufferingReceiveMsg + err = pgConn.bufferingReceiveErr + pgConn.bufferingReceiveMux.Unlock() + pgConn.bufferingReceive = false + + // If a timeout error happened in the background try the read again. + var netErr net.Error + if errors.As(err, &netErr) && netErr.Timeout() { + msg, err = pgConn.frontend.Receive() + } + } else { + msg, err = pgConn.frontend.Receive() + } + + if err != nil { + // Close on anything other than timeout error - everything else is fatal + var netErr net.Error + isNetErr := errors.As(err, &netErr) + if !(isNetErr && netErr.Timeout()) { + pgConn.asyncClose() + } + + return nil, err + } + + pgConn.peekedMsg = msg + return msg, nil +} + +// receiveMessage receives a message without setting up context cancellation +func (pgConn *PgConn) receiveMessage() (pgproto3.BackendMessage, error) { + msg, err := pgConn.peekMessage() + if err != nil { + return nil, err + } + pgConn.peekedMsg = nil + + switch msg := msg.(type) { + case *pgproto3.ReadyForQuery: + pgConn.txStatus = msg.TxStatus + case *pgproto3.ParameterStatus: + pgConn.parameterStatuses[msg.Name] = msg.Value + case *pgproto3.ErrorResponse: + if msg.Severity == "FATAL" { + pgConn.status = connStatusClosed + pgConn.conn.Close() // Ignore error as the connection is already broken and there is already an error to return. + close(pgConn.cleanupDone) + return nil, ErrorResponseToPgError(msg) + } + case *pgproto3.NoticeResponse: + if pgConn.config.OnNotice != nil { + pgConn.config.OnNotice(pgConn, noticeResponseToNotice(msg)) + } + case *pgproto3.NotificationResponse: + if pgConn.config.OnNotification != nil { + pgConn.config.OnNotification(pgConn, &Notification{PID: msg.PID, Channel: msg.Channel, Payload: msg.Payload}) + } + } + + return msg, nil +} + +// Conn returns the underlying net.Conn. This rarely necessary. +func (pgConn *PgConn) Conn() net.Conn { + return pgConn.conn +} + +// PID returns the backend PID. +func (pgConn *PgConn) PID() uint32 { + return pgConn.pid +} + +// TxStatus returns the current TxStatus as reported by the server in the ReadyForQuery message. +// +// Possible return values: +// +// 'I' - idle / not in transaction +// 'T' - in a transaction +// 'E' - in a failed transaction +// +// See https://www.postgresql.org/docs/current/protocol-message-formats.html. +func (pgConn *PgConn) TxStatus() byte { + return pgConn.txStatus +} + +// SecretKey returns the backend secret key used to send a cancel query message to the server. +func (pgConn *PgConn) SecretKey() uint32 { + return pgConn.secretKey +} + +// Frontend returns the underlying *pgproto3.Frontend. This rarely necessary. +func (pgConn *PgConn) Frontend() *pgproto3.Frontend { + return pgConn.frontend +} + +// Close closes a connection. It is safe to call Close on a already closed connection. Close attempts a clean close by +// sending the exit message to PostgreSQL. However, this could block so ctx is available to limit the time to wait. The +// underlying net.Conn.Close() will always be called regardless of any other errors. +func (pgConn *PgConn) Close(ctx context.Context) error { + if pgConn.status == connStatusClosed { + return nil + } + pgConn.status = connStatusClosed + + defer close(pgConn.cleanupDone) + defer pgConn.conn.Close() + + if ctx != context.Background() { + // Close may be called while a cancellable query is in progress. This will most often be triggered by panic when + // a defer closes the connection (possibly indirectly via a transaction or a connection pool). Unwatch to end any + // previous watch. It is safe to Unwatch regardless of whether a watch is already is progress. + // + // See https://github.com/jackc/pgconn/issues/29 + pgConn.contextWatcher.Unwatch() + + pgConn.contextWatcher.Watch(ctx) + defer pgConn.contextWatcher.Unwatch() + } + + // Ignore any errors sending Terminate message and waiting for server to close connection. + // This mimics the behavior of libpq PQfinish. It calls closePGconn which calls sendTerminateConn which purposefully + // ignores errors. + // + // See https://github.com/jackc/pgx/issues/637 + pgConn.frontend.Send(&pgproto3.Terminate{}) + pgConn.flushWithPotentialWriteReadDeadlock() + + return pgConn.conn.Close() +} + +// asyncClose marks the connection as closed and asynchronously sends a cancel query message and closes the underlying +// connection. +func (pgConn *PgConn) asyncClose() { + if pgConn.status == connStatusClosed { + return + } + pgConn.status = connStatusClosed + + go func() { + defer close(pgConn.cleanupDone) + defer pgConn.conn.Close() + + deadline := time.Now().Add(time.Second * 15) + + ctx, cancel := context.WithDeadline(context.Background(), deadline) + defer cancel() + + pgConn.CancelRequest(ctx) + + pgConn.conn.SetDeadline(deadline) + + pgConn.frontend.Send(&pgproto3.Terminate{}) + pgConn.flushWithPotentialWriteReadDeadlock() + }() +} + +// CleanupDone returns a channel that will be closed after all underlying resources have been cleaned up. A closed +// connection is no longer usable, but underlying resources, in particular the net.Conn, may not have finished closing +// yet. This is because certain errors such as a context cancellation require that the interrupted function call return +// immediately, but the error may also cause the connection to be closed. In these cases the underlying resources are +// closed asynchronously. +// +// This is only likely to be useful to connection pools. It gives them a way avoid establishing a new connection while +// an old connection is still being cleaned up and thereby exceeding the maximum pool size. +func (pgConn *PgConn) CleanupDone() chan (struct{}) { + return pgConn.cleanupDone +} + +// IsClosed reports if the connection has been closed. +// +// CleanupDone() can be used to determine if all cleanup has been completed. +func (pgConn *PgConn) IsClosed() bool { + return pgConn.status < connStatusIdle +} + +// IsBusy reports if the connection is busy. +func (pgConn *PgConn) IsBusy() bool { + return pgConn.status == connStatusBusy +} + +// lock locks the connection. +func (pgConn *PgConn) lock() error { + switch pgConn.status { + case connStatusBusy: + return &connLockError{status: "conn busy"} // This only should be possible in case of an application bug. + case connStatusClosed: + return &connLockError{status: "conn closed"} + case connStatusUninitialized: + return &connLockError{status: "conn uninitialized"} + } + pgConn.status = connStatusBusy + return nil +} + +func (pgConn *PgConn) unlock() { + switch pgConn.status { + case connStatusBusy: + pgConn.status = connStatusIdle + case connStatusClosed: + default: + panic("BUG: cannot unlock unlocked connection") // This should only be possible if there is a bug in this package. + } +} + +// ParameterStatus returns the value of a parameter reported by the server (e.g. +// server_version). Returns an empty string for unknown parameters. +func (pgConn *PgConn) ParameterStatus(key string) string { + return pgConn.parameterStatuses[key] +} + +// CommandTag is the status text returned by PostgreSQL for a query. +type CommandTag struct { + s string +} + +// NewCommandTag makes a CommandTag from s. +func NewCommandTag(s string) CommandTag { + return CommandTag{s: s} +} + +// RowsAffected returns the number of rows affected. If the CommandTag was not +// for a row affecting command (e.g. "CREATE TABLE") then it returns 0. +func (ct CommandTag) RowsAffected() int64 { + // Find last non-digit + idx := -1 + for i := len(ct.s) - 1; i >= 0; i-- { + if ct.s[i] >= '0' && ct.s[i] <= '9' { + idx = i + } else { + break + } + } + + if idx == -1 { + return 0 + } + + var n int64 + for _, b := range ct.s[idx:] { + n = n*10 + int64(b-'0') + } + + return n +} + +func (ct CommandTag) String() string { + return ct.s +} + +// Insert is true if the command tag starts with "INSERT". +func (ct CommandTag) Insert() bool { + return strings.HasPrefix(ct.s, "INSERT") +} + +// Update is true if the command tag starts with "UPDATE". +func (ct CommandTag) Update() bool { + return strings.HasPrefix(ct.s, "UPDATE") +} + +// Delete is true if the command tag starts with "DELETE". +func (ct CommandTag) Delete() bool { + return strings.HasPrefix(ct.s, "DELETE") +} + +// Select is true if the command tag starts with "SELECT". +func (ct CommandTag) Select() bool { + return strings.HasPrefix(ct.s, "SELECT") +} + +type FieldDescription struct { + Name string + TableOID uint32 + TableAttributeNumber uint16 + DataTypeOID uint32 + DataTypeSize int16 + TypeModifier int32 + Format int16 +} + +func (pgConn *PgConn) convertRowDescription(dst []FieldDescription, rd *pgproto3.RowDescription) []FieldDescription { + if cap(dst) >= len(rd.Fields) { + dst = dst[:len(rd.Fields):len(rd.Fields)] + } else { + dst = make([]FieldDescription, len(rd.Fields)) + } + + for i := range rd.Fields { + dst[i].Name = string(rd.Fields[i].Name) + dst[i].TableOID = rd.Fields[i].TableOID + dst[i].TableAttributeNumber = rd.Fields[i].TableAttributeNumber + dst[i].DataTypeOID = rd.Fields[i].DataTypeOID + dst[i].DataTypeSize = rd.Fields[i].DataTypeSize + dst[i].TypeModifier = rd.Fields[i].TypeModifier + dst[i].Format = rd.Fields[i].Format + } + + return dst +} + +type StatementDescription struct { + Name string + SQL string + ParamOIDs []uint32 + Fields []FieldDescription +} + +// Prepare creates a prepared statement. If the name is empty, the anonymous prepared statement will be used. This +// allows Prepare to also to describe statements without creating a server-side prepared statement. +func (pgConn *PgConn) Prepare(ctx context.Context, name, sql string, paramOIDs []uint32) (*StatementDescription, error) { + if err := pgConn.lock(); err != nil { + return nil, err + } + defer pgConn.unlock() + + if ctx != context.Background() { + select { + case <-ctx.Done(): + return nil, newContextAlreadyDoneError(ctx) + default: + } + pgConn.contextWatcher.Watch(ctx) + defer pgConn.contextWatcher.Unwatch() + } + + pgConn.frontend.SendParse(&pgproto3.Parse{Name: name, Query: sql, ParameterOIDs: paramOIDs}) + pgConn.frontend.SendDescribe(&pgproto3.Describe{ObjectType: 'S', Name: name}) + pgConn.frontend.SendSync(&pgproto3.Sync{}) + err := pgConn.flushWithPotentialWriteReadDeadlock() + if err != nil { + pgConn.asyncClose() + return nil, err + } + + psd := &StatementDescription{Name: name, SQL: sql} + + var parseErr error + +readloop: + for { + msg, err := pgConn.receiveMessage() + if err != nil { + pgConn.asyncClose() + return nil, normalizeTimeoutError(ctx, err) + } + + switch msg := msg.(type) { + case *pgproto3.ParameterDescription: + psd.ParamOIDs = make([]uint32, len(msg.ParameterOIDs)) + copy(psd.ParamOIDs, msg.ParameterOIDs) + case *pgproto3.RowDescription: + psd.Fields = pgConn.convertRowDescription(nil, msg) + case *pgproto3.ErrorResponse: + parseErr = ErrorResponseToPgError(msg) + case *pgproto3.ReadyForQuery: + break readloop + } + } + + if parseErr != nil { + return nil, parseErr + } + return psd, nil +} + +// ErrorResponseToPgError converts a wire protocol error message to a *PgError. +func ErrorResponseToPgError(msg *pgproto3.ErrorResponse) *PgError { + return &PgError{ + Severity: msg.Severity, + Code: string(msg.Code), + Message: string(msg.Message), + Detail: string(msg.Detail), + Hint: msg.Hint, + Position: msg.Position, + InternalPosition: msg.InternalPosition, + InternalQuery: string(msg.InternalQuery), + Where: string(msg.Where), + SchemaName: string(msg.SchemaName), + TableName: string(msg.TableName), + ColumnName: string(msg.ColumnName), + DataTypeName: string(msg.DataTypeName), + ConstraintName: msg.ConstraintName, + File: string(msg.File), + Line: msg.Line, + Routine: string(msg.Routine), + } +} + +func noticeResponseToNotice(msg *pgproto3.NoticeResponse) *Notice { + pgerr := ErrorResponseToPgError((*pgproto3.ErrorResponse)(msg)) + return (*Notice)(pgerr) +} + +// CancelRequest sends a cancel request to the PostgreSQL server. It returns an error if unable to deliver the cancel +// request, but lack of an error does not ensure that the query was canceled. As specified in the documentation, there +// is no way to be sure a query was canceled. See https://www.postgresql.org/docs/11/protocol-flow.html#id-1.10.5.7.9 +func (pgConn *PgConn) CancelRequest(ctx context.Context) error { + // Open a cancellation request to the same server. The address is taken from the net.Conn directly instead of reusing + // the connection config. This is important in high availability configurations where fallback connections may be + // specified or DNS may be used to load balance. + serverAddr := pgConn.conn.RemoteAddr() + var serverNetwork string + var serverAddress string + if serverAddr.Network() == "unix" { + // for unix sockets, RemoteAddr() calls getpeername() which returns the name the + // server passed to bind(). For Postgres, this is always a relative path "./.s.PGSQL.5432" + // so connecting to it will fail. Fall back to the config's value + serverNetwork, serverAddress = NetworkAddress(pgConn.config.Host, pgConn.config.Port) + } else { + serverNetwork, serverAddress = serverAddr.Network(), serverAddr.String() + } + cancelConn, err := pgConn.config.DialFunc(ctx, serverNetwork, serverAddress) + if err != nil { + // In case of unix sockets, RemoteAddr() returns only the file part of the path. If the + // first connect failed, try the config. + if serverAddr.Network() != "unix" { + return err + } + serverNetwork, serverAddr := NetworkAddress(pgConn.config.Host, pgConn.config.Port) + cancelConn, err = pgConn.config.DialFunc(ctx, serverNetwork, serverAddr) + if err != nil { + return err + } + } + defer cancelConn.Close() + + if ctx != context.Background() { + contextWatcher := ctxwatch.NewContextWatcher( + func() { cancelConn.SetDeadline(time.Date(1, 1, 1, 1, 1, 1, 1, time.UTC)) }, + func() { cancelConn.SetDeadline(time.Time{}) }, + ) + contextWatcher.Watch(ctx) + defer contextWatcher.Unwatch() + } + + buf := make([]byte, 16) + binary.BigEndian.PutUint32(buf[0:4], 16) + binary.BigEndian.PutUint32(buf[4:8], 80877102) + binary.BigEndian.PutUint32(buf[8:12], uint32(pgConn.pid)) + binary.BigEndian.PutUint32(buf[12:16], uint32(pgConn.secretKey)) + // Postgres will process the request and close the connection + // so when don't need to read the reply + // https://www.postgresql.org/docs/current/protocol-flow.html#id-1.10.6.7.10 + _, err = cancelConn.Write(buf) + return err +} + +// WaitForNotification waits for a LISTON/NOTIFY message to be received. It returns an error if a notification was not +// received. +func (pgConn *PgConn) WaitForNotification(ctx context.Context) error { + if err := pgConn.lock(); err != nil { + return err + } + defer pgConn.unlock() + + if ctx != context.Background() { + select { + case <-ctx.Done(): + return newContextAlreadyDoneError(ctx) + default: + } + + pgConn.contextWatcher.Watch(ctx) + defer pgConn.contextWatcher.Unwatch() + } + + for { + msg, err := pgConn.receiveMessage() + if err != nil { + return normalizeTimeoutError(ctx, err) + } + + switch msg.(type) { + case *pgproto3.NotificationResponse: + return nil + } + } +} + +// Exec executes SQL via the PostgreSQL simple query protocol. SQL may contain multiple queries. Execution is +// implicitly wrapped in a transaction unless a transaction is already in progress or SQL contains transaction control +// statements. +// +// Prefer ExecParams unless executing arbitrary SQL that may contain multiple queries. +func (pgConn *PgConn) Exec(ctx context.Context, sql string) *MultiResultReader { + if err := pgConn.lock(); err != nil { + return &MultiResultReader{ + closed: true, + err: err, + } + } + + pgConn.multiResultReader = MultiResultReader{ + pgConn: pgConn, + ctx: ctx, + } + multiResult := &pgConn.multiResultReader + if ctx != context.Background() { + select { + case <-ctx.Done(): + multiResult.closed = true + multiResult.err = newContextAlreadyDoneError(ctx) + pgConn.unlock() + return multiResult + default: + } + pgConn.contextWatcher.Watch(ctx) + } + + pgConn.frontend.SendQuery(&pgproto3.Query{String: sql}) + err := pgConn.flushWithPotentialWriteReadDeadlock() + if err != nil { + pgConn.asyncClose() + pgConn.contextWatcher.Unwatch() + multiResult.closed = true + multiResult.err = err + pgConn.unlock() + return multiResult + } + + return multiResult +} + +// ExecParams executes a command via the PostgreSQL extended query protocol. +// +// sql is a SQL command string. It may only contain one query. Parameter substitution is positional using $1, $2, $3, +// etc. +// +// paramValues are the parameter values. It must be encoded in the format given by paramFormats. +// +// paramOIDs is a slice of data type OIDs for paramValues. If paramOIDs is nil, the server will infer the data type for +// all parameters. Any paramOID element that is 0 that will cause the server to infer the data type for that parameter. +// ExecParams will panic if len(paramOIDs) is not 0, 1, or len(paramValues). +// +// paramFormats is a slice of format codes determining for each paramValue column whether it is encoded in text or +// binary format. If paramFormats is nil all params are text format. ExecParams will panic if +// len(paramFormats) is not 0, 1, or len(paramValues). +// +// resultFormats is a slice of format codes determining for each result column whether it is encoded in text or +// binary format. If resultFormats is nil all results will be in text format. +// +// ResultReader must be closed before PgConn can be used again. +func (pgConn *PgConn) ExecParams(ctx context.Context, sql string, paramValues [][]byte, paramOIDs []uint32, paramFormats []int16, resultFormats []int16) *ResultReader { + result := pgConn.execExtendedPrefix(ctx, paramValues) + if result.closed { + return result + } + + pgConn.frontend.SendParse(&pgproto3.Parse{Query: sql, ParameterOIDs: paramOIDs}) + pgConn.frontend.SendBind(&pgproto3.Bind{ParameterFormatCodes: paramFormats, Parameters: paramValues, ResultFormatCodes: resultFormats}) + + pgConn.execExtendedSuffix(result) + + return result +} + +// ExecPrepared enqueues the execution of a prepared statement via the PostgreSQL extended query protocol. +// +// paramValues are the parameter values. It must be encoded in the format given by paramFormats. +// +// paramFormats is a slice of format codes determining for each paramValue column whether it is encoded in text or +// binary format. If paramFormats is nil all params are text format. ExecPrepared will panic if +// len(paramFormats) is not 0, 1, or len(paramValues). +// +// resultFormats is a slice of format codes determining for each result column whether it is encoded in text or +// binary format. If resultFormats is nil all results will be in text format. +// +// ResultReader must be closed before PgConn can be used again. +func (pgConn *PgConn) ExecPrepared(ctx context.Context, stmtName string, paramValues [][]byte, paramFormats []int16, resultFormats []int16) *ResultReader { + result := pgConn.execExtendedPrefix(ctx, paramValues) + if result.closed { + return result + } + + pgConn.frontend.SendBind(&pgproto3.Bind{PreparedStatement: stmtName, ParameterFormatCodes: paramFormats, Parameters: paramValues, ResultFormatCodes: resultFormats}) + + pgConn.execExtendedSuffix(result) + + return result +} + +func (pgConn *PgConn) execExtendedPrefix(ctx context.Context, paramValues [][]byte) *ResultReader { + pgConn.resultReader = ResultReader{ + pgConn: pgConn, + ctx: ctx, + } + result := &pgConn.resultReader + + if err := pgConn.lock(); err != nil { + result.concludeCommand(CommandTag{}, err) + result.closed = true + return result + } + + if len(paramValues) > math.MaxUint16 { + result.concludeCommand(CommandTag{}, fmt.Errorf("extended protocol limited to %v parameters", math.MaxUint16)) + result.closed = true + pgConn.unlock() + return result + } + + if ctx != context.Background() { + select { + case <-ctx.Done(): + result.concludeCommand(CommandTag{}, newContextAlreadyDoneError(ctx)) + result.closed = true + pgConn.unlock() + return result + default: + } + pgConn.contextWatcher.Watch(ctx) + } + + return result +} + +func (pgConn *PgConn) execExtendedSuffix(result *ResultReader) { + pgConn.frontend.SendDescribe(&pgproto3.Describe{ObjectType: 'P'}) + pgConn.frontend.SendExecute(&pgproto3.Execute{}) + pgConn.frontend.SendSync(&pgproto3.Sync{}) + + err := pgConn.flushWithPotentialWriteReadDeadlock() + if err != nil { + pgConn.asyncClose() + result.concludeCommand(CommandTag{}, err) + pgConn.contextWatcher.Unwatch() + result.closed = true + pgConn.unlock() + return + } + + result.readUntilRowDescription() +} + +// CopyTo executes the copy command sql and copies the results to w. +func (pgConn *PgConn) CopyTo(ctx context.Context, w io.Writer, sql string) (CommandTag, error) { + if err := pgConn.lock(); err != nil { + return CommandTag{}, err + } + + if ctx != context.Background() { + select { + case <-ctx.Done(): + pgConn.unlock() + return CommandTag{}, newContextAlreadyDoneError(ctx) + default: + } + pgConn.contextWatcher.Watch(ctx) + defer pgConn.contextWatcher.Unwatch() + } + + // Send copy to command + pgConn.frontend.SendQuery(&pgproto3.Query{String: sql}) + + err := pgConn.flushWithPotentialWriteReadDeadlock() + if err != nil { + pgConn.asyncClose() + pgConn.unlock() + return CommandTag{}, err + } + + // Read results + var commandTag CommandTag + var pgErr error + for { + msg, err := pgConn.receiveMessage() + if err != nil { + pgConn.asyncClose() + return CommandTag{}, normalizeTimeoutError(ctx, err) + } + + switch msg := msg.(type) { + case *pgproto3.CopyDone: + case *pgproto3.CopyData: + _, err := w.Write(msg.Data) + if err != nil { + pgConn.asyncClose() + return CommandTag{}, err + } + case *pgproto3.ReadyForQuery: + pgConn.unlock() + return commandTag, pgErr + case *pgproto3.CommandComplete: + commandTag = pgConn.makeCommandTag(msg.CommandTag) + case *pgproto3.ErrorResponse: + pgErr = ErrorResponseToPgError(msg) + } + } +} + +// CopyFrom executes the copy command sql and copies all of r to the PostgreSQL server. +// +// Note: context cancellation will only interrupt operations on the underlying PostgreSQL network connection. Reads on r +// could still block. +func (pgConn *PgConn) CopyFrom(ctx context.Context, r io.Reader, sql string) (CommandTag, error) { + if err := pgConn.lock(); err != nil { + return CommandTag{}, err + } + defer pgConn.unlock() + + if ctx != context.Background() { + select { + case <-ctx.Done(): + return CommandTag{}, newContextAlreadyDoneError(ctx) + default: + } + pgConn.contextWatcher.Watch(ctx) + defer pgConn.contextWatcher.Unwatch() + } + + // Send copy from query + pgConn.frontend.SendQuery(&pgproto3.Query{String: sql}) + err := pgConn.flushWithPotentialWriteReadDeadlock() + if err != nil { + pgConn.asyncClose() + return CommandTag{}, err + } + + // Send copy data + abortCopyChan := make(chan struct{}) + copyErrChan := make(chan error, 1) + signalMessageChan := pgConn.signalMessage() + var wg sync.WaitGroup + wg.Add(1) + + go func() { + defer wg.Done() + buf := iobufpool.Get(65536) + defer iobufpool.Put(buf) + (*buf)[0] = 'd' + + for { + n, readErr := r.Read((*buf)[5:cap(*buf)]) + if n > 0 { + *buf = (*buf)[0 : n+5] + pgio.SetInt32((*buf)[1:], int32(n+4)) + + writeErr := pgConn.frontend.SendUnbufferedEncodedCopyData(*buf) + if writeErr != nil { + // Write errors are always fatal, but we can't use asyncClose because we are in a different goroutine. Not + // setting pgConn.status or closing pgConn.cleanupDone for the same reason. + pgConn.conn.Close() + + copyErrChan <- writeErr + return + } + } + if readErr != nil { + copyErrChan <- readErr + return + } + + select { + case <-abortCopyChan: + return + default: + } + } + }() + + var pgErr error + var copyErr error + for copyErr == nil && pgErr == nil { + select { + case copyErr = <-copyErrChan: + case <-signalMessageChan: + // If pgConn.receiveMessage encounters an error it will call pgConn.asyncClose. But that is a race condition with + // the goroutine. So instead check pgConn.bufferingReceiveErr which will have been set by the signalMessage. If an + // error is found then forcibly close the connection without sending the Terminate message. + if err := pgConn.bufferingReceiveErr; err != nil { + pgConn.status = connStatusClosed + pgConn.conn.Close() + close(pgConn.cleanupDone) + return CommandTag{}, normalizeTimeoutError(ctx, err) + } + msg, _ := pgConn.receiveMessage() + + switch msg := msg.(type) { + case *pgproto3.ErrorResponse: + pgErr = ErrorResponseToPgError(msg) + default: + signalMessageChan = pgConn.signalMessage() + } + } + } + close(abortCopyChan) + // Make sure io goroutine finishes before writing. + wg.Wait() + + if copyErr == io.EOF || pgErr != nil { + pgConn.frontend.Send(&pgproto3.CopyDone{}) + } else { + pgConn.frontend.Send(&pgproto3.CopyFail{Message: copyErr.Error()}) + } + err = pgConn.flushWithPotentialWriteReadDeadlock() + if err != nil { + pgConn.asyncClose() + return CommandTag{}, err + } + + // Read results + var commandTag CommandTag + for { + msg, err := pgConn.receiveMessage() + if err != nil { + pgConn.asyncClose() + return CommandTag{}, normalizeTimeoutError(ctx, err) + } + + switch msg := msg.(type) { + case *pgproto3.ReadyForQuery: + return commandTag, pgErr + case *pgproto3.CommandComplete: + commandTag = pgConn.makeCommandTag(msg.CommandTag) + case *pgproto3.ErrorResponse: + pgErr = ErrorResponseToPgError(msg) + } + } +} + +// MultiResultReader is a reader for a command that could return multiple results such as Exec or ExecBatch. +type MultiResultReader struct { + pgConn *PgConn + ctx context.Context + pipeline *Pipeline + + rr *ResultReader + + closed bool + err error +} + +// ReadAll reads all available results. Calling ReadAll is mutually exclusive with all other MultiResultReader methods. +func (mrr *MultiResultReader) ReadAll() ([]*Result, error) { + var results []*Result + + for mrr.NextResult() { + results = append(results, mrr.ResultReader().Read()) + } + err := mrr.Close() + + return results, err +} + +func (mrr *MultiResultReader) receiveMessage() (pgproto3.BackendMessage, error) { + msg, err := mrr.pgConn.receiveMessage() + + if err != nil { + mrr.pgConn.contextWatcher.Unwatch() + mrr.err = normalizeTimeoutError(mrr.ctx, err) + mrr.closed = true + mrr.pgConn.asyncClose() + return nil, mrr.err + } + + switch msg := msg.(type) { + case *pgproto3.ReadyForQuery: + mrr.closed = true + if mrr.pipeline != nil { + mrr.pipeline.expectedReadyForQueryCount-- + } else { + mrr.pgConn.contextWatcher.Unwatch() + mrr.pgConn.unlock() + } + case *pgproto3.ErrorResponse: + mrr.err = ErrorResponseToPgError(msg) + } + + return msg, nil +} + +// NextResult returns advances the MultiResultReader to the next result and returns true if a result is available. +func (mrr *MultiResultReader) NextResult() bool { + for !mrr.closed && mrr.err == nil { + msg, err := mrr.receiveMessage() + if err != nil { + return false + } + + switch msg := msg.(type) { + case *pgproto3.RowDescription: + mrr.pgConn.resultReader = ResultReader{ + pgConn: mrr.pgConn, + multiResultReader: mrr, + ctx: mrr.ctx, + fieldDescriptions: mrr.pgConn.convertRowDescription(mrr.pgConn.fieldDescriptions[:], msg), + } + + mrr.rr = &mrr.pgConn.resultReader + return true + case *pgproto3.CommandComplete: + mrr.pgConn.resultReader = ResultReader{ + commandTag: mrr.pgConn.makeCommandTag(msg.CommandTag), + commandConcluded: true, + closed: true, + } + mrr.rr = &mrr.pgConn.resultReader + return true + case *pgproto3.EmptyQueryResponse: + return false + } + } + + return false +} + +// ResultReader returns the current ResultReader. +func (mrr *MultiResultReader) ResultReader() *ResultReader { + return mrr.rr +} + +// Close closes the MultiResultReader and returns the first error that occurred during the MultiResultReader's use. +func (mrr *MultiResultReader) Close() error { + for !mrr.closed { + _, err := mrr.receiveMessage() + if err != nil { + return mrr.err + } + } + + return mrr.err +} + +// ResultReader is a reader for the result of a single query. +type ResultReader struct { + pgConn *PgConn + multiResultReader *MultiResultReader + pipeline *Pipeline + ctx context.Context + + fieldDescriptions []FieldDescription + rowValues [][]byte + commandTag CommandTag + commandConcluded bool + closed bool + err error +} + +// Result is the saved query response that is returned by calling Read on a ResultReader. +type Result struct { + FieldDescriptions []FieldDescription + Rows [][][]byte + CommandTag CommandTag + Err error +} + +// Read saves the query response to a Result. +func (rr *ResultReader) Read() *Result { + br := &Result{} + + for rr.NextRow() { + if br.FieldDescriptions == nil { + br.FieldDescriptions = make([]FieldDescription, len(rr.FieldDescriptions())) + copy(br.FieldDescriptions, rr.FieldDescriptions()) + } + + values := rr.Values() + row := make([][]byte, len(values)) + for i := range row { + row[i] = make([]byte, len(values[i])) + copy(row[i], values[i]) + } + br.Rows = append(br.Rows, row) + } + + br.CommandTag, br.Err = rr.Close() + + return br +} + +// NextRow advances the ResultReader to the next row and returns true if a row is available. +func (rr *ResultReader) NextRow() bool { + for !rr.commandConcluded { + msg, err := rr.receiveMessage() + if err != nil { + return false + } + + switch msg := msg.(type) { + case *pgproto3.DataRow: + rr.rowValues = msg.Values + return true + } + } + + return false +} + +// FieldDescriptions returns the field descriptions for the current result set. The returned slice is only valid until +// the ResultReader is closed. It may return nil (for example, if the query did not return a result set or an error was +// encountered.) +func (rr *ResultReader) FieldDescriptions() []FieldDescription { + return rr.fieldDescriptions +} + +// Values returns the current row data. NextRow must have been previously been called. The returned [][]byte is only +// valid until the next NextRow call or the ResultReader is closed. +func (rr *ResultReader) Values() [][]byte { + return rr.rowValues +} + +// Close consumes any remaining result data and returns the command tag or +// error. +func (rr *ResultReader) Close() (CommandTag, error) { + if rr.closed { + return rr.commandTag, rr.err + } + rr.closed = true + + for !rr.commandConcluded { + _, err := rr.receiveMessage() + if err != nil { + return CommandTag{}, rr.err + } + } + + if rr.multiResultReader == nil && rr.pipeline == nil { + for { + msg, err := rr.receiveMessage() + if err != nil { + return CommandTag{}, rr.err + } + + switch msg := msg.(type) { + // Detect a deferred constraint violation where the ErrorResponse is sent after CommandComplete. + case *pgproto3.ErrorResponse: + rr.err = ErrorResponseToPgError(msg) + case *pgproto3.ReadyForQuery: + rr.pgConn.contextWatcher.Unwatch() + rr.pgConn.unlock() + return rr.commandTag, rr.err + } + } + } + + return rr.commandTag, rr.err +} + +// readUntilRowDescription ensures the ResultReader's fieldDescriptions are loaded. It does not return an error as any +// error will be stored in the ResultReader. +func (rr *ResultReader) readUntilRowDescription() { + for !rr.commandConcluded { + // Peek before receive to avoid consuming a DataRow if the result set does not include a RowDescription method. + // This should never happen under normal pgconn usage, but it is possible if SendBytes and ReceiveResults are + // manually used to construct a query that does not issue a describe statement. + msg, _ := rr.pgConn.peekMessage() + if _, ok := msg.(*pgproto3.DataRow); ok { + return + } + + // Consume the message + msg, _ = rr.receiveMessage() + if _, ok := msg.(*pgproto3.RowDescription); ok { + return + } + } +} + +func (rr *ResultReader) receiveMessage() (msg pgproto3.BackendMessage, err error) { + if rr.multiResultReader == nil { + msg, err = rr.pgConn.receiveMessage() + } else { + msg, err = rr.multiResultReader.receiveMessage() + } + + if err != nil { + err = normalizeTimeoutError(rr.ctx, err) + rr.concludeCommand(CommandTag{}, err) + rr.pgConn.contextWatcher.Unwatch() + rr.closed = true + if rr.multiResultReader == nil { + rr.pgConn.asyncClose() + } + + return nil, rr.err + } + + switch msg := msg.(type) { + case *pgproto3.RowDescription: + rr.fieldDescriptions = rr.pgConn.convertRowDescription(rr.pgConn.fieldDescriptions[:], msg) + case *pgproto3.CommandComplete: + rr.concludeCommand(rr.pgConn.makeCommandTag(msg.CommandTag), nil) + case *pgproto3.EmptyQueryResponse: + rr.concludeCommand(CommandTag{}, nil) + case *pgproto3.ErrorResponse: + rr.concludeCommand(CommandTag{}, ErrorResponseToPgError(msg)) + } + + return msg, nil +} + +func (rr *ResultReader) concludeCommand(commandTag CommandTag, err error) { + // Keep the first error that is recorded. Store the error before checking if the command is already concluded to + // allow for receiving an error after CommandComplete but before ReadyForQuery. + if err != nil && rr.err == nil { + rr.err = err + } + + if rr.commandConcluded { + return + } + + rr.commandTag = commandTag + rr.rowValues = nil + rr.commandConcluded = true +} + +// Batch is a collection of queries that can be sent to the PostgreSQL server in a single round-trip. +type Batch struct { + buf []byte +} + +// ExecParams appends an ExecParams command to the batch. See PgConn.ExecParams for parameter descriptions. +func (batch *Batch) ExecParams(sql string, paramValues [][]byte, paramOIDs []uint32, paramFormats []int16, resultFormats []int16) { + batch.buf = (&pgproto3.Parse{Query: sql, ParameterOIDs: paramOIDs}).Encode(batch.buf) + batch.ExecPrepared("", paramValues, paramFormats, resultFormats) +} + +// ExecPrepared appends an ExecPrepared e command to the batch. See PgConn.ExecPrepared for parameter descriptions. +func (batch *Batch) ExecPrepared(stmtName string, paramValues [][]byte, paramFormats []int16, resultFormats []int16) { + batch.buf = (&pgproto3.Bind{PreparedStatement: stmtName, ParameterFormatCodes: paramFormats, Parameters: paramValues, ResultFormatCodes: resultFormats}).Encode(batch.buf) + batch.buf = (&pgproto3.Describe{ObjectType: 'P'}).Encode(batch.buf) + batch.buf = (&pgproto3.Execute{}).Encode(batch.buf) +} + +// ExecBatch executes all the queries in batch in a single round-trip. Execution is implicitly transactional unless a +// transaction is already in progress or SQL contains transaction control statements. This is a simpler way of executing +// multiple queries in a single round trip than using pipeline mode. +func (pgConn *PgConn) ExecBatch(ctx context.Context, batch *Batch) *MultiResultReader { + if err := pgConn.lock(); err != nil { + return &MultiResultReader{ + closed: true, + err: err, + } + } + + pgConn.multiResultReader = MultiResultReader{ + pgConn: pgConn, + ctx: ctx, + } + multiResult := &pgConn.multiResultReader + + if ctx != context.Background() { + select { + case <-ctx.Done(): + multiResult.closed = true + multiResult.err = newContextAlreadyDoneError(ctx) + pgConn.unlock() + return multiResult + default: + } + pgConn.contextWatcher.Watch(ctx) + } + + batch.buf = (&pgproto3.Sync{}).Encode(batch.buf) + + pgConn.enterPotentialWriteReadDeadlock() + _, err := pgConn.conn.Write(batch.buf) + pgConn.exitPotentialWriteReadDeadlock() + if err != nil { + multiResult.closed = true + multiResult.err = err + pgConn.unlock() + return multiResult + } + + return multiResult +} + +// EscapeString escapes a string such that it can safely be interpolated into a SQL command string. It does not include +// the surrounding single quotes. +// +// The current implementation requires that standard_conforming_strings=on and client_encoding="UTF8". If these +// conditions are not met an error will be returned. It is possible these restrictions will be lifted in the future. +func (pgConn *PgConn) EscapeString(s string) (string, error) { + if pgConn.ParameterStatus("standard_conforming_strings") != "on" { + return "", errors.New("EscapeString must be run with standard_conforming_strings=on") + } + + if pgConn.ParameterStatus("client_encoding") != "UTF8" { + return "", errors.New("EscapeString must be run with client_encoding=UTF8") + } + + return strings.Replace(s, "'", "''", -1), nil +} + +// CheckConn checks the underlying connection without writing any bytes. This is currently implemented by doing a read +// with a very short deadline. This can be useful because a TCP connection can be broken such that a write will appear +// to succeed even though it will never actually reach the server. Reading immediately before a write will detect this +// condition. If this is done immediately before sending a query it reduces the chances a query will be sent that fails +// without the client knowing whether the server received it or not. +// +// Deprecated: CheckConn is deprecated in favor of Ping. CheckConn cannot detect all types of broken connections where +// the write would still appear to succeed. Prefer Ping unless on a high latency connection. +func (pgConn *PgConn) CheckConn() error { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond) + defer cancel() + + _, err := pgConn.ReceiveMessage(ctx) + if err != nil { + if !Timeout(err) { + return err + } + } + + return nil +} + +// Ping pings the server. This can be useful because a TCP connection can be broken such that a write will appear to +// succeed even though it will never actually reach the server. Pinging immediately before sending a query reduces the +// chances a query will be sent that fails without the client knowing whether the server received it or not. +func (pgConn *PgConn) Ping(ctx context.Context) error { + return pgConn.Exec(ctx, "-- ping").Close() +} + +// makeCommandTag makes a CommandTag. It does not retain a reference to buf or buf's underlying memory. +func (pgConn *PgConn) makeCommandTag(buf []byte) CommandTag { + return CommandTag{s: string(buf)} +} + +// enterPotentialWriteReadDeadlock must be called before a write that could deadlock if the server is simultaneously +// blocked writing to us. +func (pgConn *PgConn) enterPotentialWriteReadDeadlock() { + // The time to wait is somewhat arbitrary. A Write should only take as long as the syscall and memcpy to the OS + // outbound network buffer unless the buffer is full (which potentially is a block). It needs to be long enough for + // the normal case, but short enough not to kill performance if a block occurs. + // + // In addition, on Windows the default timer resolution is 15.6ms. So setting the timer to less than that is + // ineffective. + pgConn.slowWriteTimer.Reset(15 * time.Millisecond) +} + +// exitPotentialWriteReadDeadlock must be called after a call to enterPotentialWriteReadDeadlock. +func (pgConn *PgConn) exitPotentialWriteReadDeadlock() { + if !pgConn.slowWriteTimer.Reset(time.Duration(math.MaxInt64)) { + pgConn.slowWriteTimer.Stop() + } +} + +func (pgConn *PgConn) flushWithPotentialWriteReadDeadlock() error { + pgConn.enterPotentialWriteReadDeadlock() + err := pgConn.frontend.Flush() + pgConn.exitPotentialWriteReadDeadlock() + return err +} + +// HijackedConn is the result of hijacking a connection. +// +// Due to the necessary exposure of internal implementation details, it is not covered by the semantic versioning +// compatibility. +type HijackedConn struct { + Conn net.Conn + PID uint32 // backend pid + SecretKey uint32 // key to use to send a cancel query message to the server + ParameterStatuses map[string]string // parameters that have been reported by the server + TxStatus byte + Frontend *pgproto3.Frontend + Config *Config +} + +// Hijack extracts the internal connection data. pgConn must be in an idle state. pgConn is unusable after hijacking. +// Hijacking is typically only useful when using pgconn to establish a connection, but taking complete control of the +// raw connection after that (e.g. a load balancer or proxy). +// +// Due to the necessary exposure of internal implementation details, it is not covered by the semantic versioning +// compatibility. +func (pgConn *PgConn) Hijack() (*HijackedConn, error) { + if err := pgConn.lock(); err != nil { + return nil, err + } + pgConn.status = connStatusClosed + + return &HijackedConn{ + Conn: pgConn.conn, + PID: pgConn.pid, + SecretKey: pgConn.secretKey, + ParameterStatuses: pgConn.parameterStatuses, + TxStatus: pgConn.txStatus, + Frontend: pgConn.frontend, + Config: pgConn.config, + }, nil +} + +// Construct created a PgConn from an already established connection to a PostgreSQL server. This is the inverse of +// PgConn.Hijack. The connection must be in an idle state. +// +// Due to the necessary exposure of internal implementation details, it is not covered by the semantic versioning +// compatibility. +func Construct(hc *HijackedConn) (*PgConn, error) { + pgConn := &PgConn{ + conn: hc.Conn, + pid: hc.PID, + secretKey: hc.SecretKey, + parameterStatuses: hc.ParameterStatuses, + txStatus: hc.TxStatus, + frontend: hc.Frontend, + config: hc.Config, + + status: connStatusIdle, + + cleanupDone: make(chan struct{}), + } + + pgConn.contextWatcher = newContextWatcher(pgConn.conn) + pgConn.bgReader = bgreader.New(pgConn.conn) + pgConn.slowWriteTimer = time.AfterFunc(time.Duration(math.MaxInt64), pgConn.bgReader.Start) + + return pgConn, nil +} + +// Pipeline represents a connection in pipeline mode. +// +// SendPrepare, SendQueryParams, and SendQueryPrepared queue requests to the server. These requests are not written until +// pipeline is flushed by Flush or Sync. Sync must be called after the last request is queued. Requests between +// synchronization points are implicitly transactional unless explicit transaction control statements have been issued. +// +// The context the pipeline was started with is in effect for the entire life of the Pipeline. +// +// For a deeper understanding of pipeline mode see the PostgreSQL documentation for the extended query protocol +// (https://www.postgresql.org/docs/current/protocol-flow.html#PROTOCOL-FLOW-EXT-QUERY) and the libpq pipeline mode +// (https://www.postgresql.org/docs/current/libpq-pipeline-mode.html). +type Pipeline struct { + conn *PgConn + ctx context.Context + + expectedReadyForQueryCount int + pendingSync bool + + err error + closed bool +} + +// PipelineSync is returned by GetResults when a ReadyForQuery message is received. +type PipelineSync struct{} + +// CloseComplete is returned by GetResults when a CloseComplete message is received. +type CloseComplete struct{} + +// StartPipeline switches the connection to pipeline mode and returns a *Pipeline. In pipeline mode requests can be sent +// to the server without waiting for a response. Close must be called on the returned *Pipeline to return the connection +// to normal mode. While in pipeline mode, no methods that communicate with the server may be called except +// CancelRequest and Close. ctx is in effect for entire life of the *Pipeline. +// +// Prefer ExecBatch when only sending one group of queries at once. +func (pgConn *PgConn) StartPipeline(ctx context.Context) *Pipeline { + if err := pgConn.lock(); err != nil { + return &Pipeline{ + closed: true, + err: err, + } + } + + pgConn.pipeline = Pipeline{ + conn: pgConn, + ctx: ctx, + } + pipeline := &pgConn.pipeline + + if ctx != context.Background() { + select { + case <-ctx.Done(): + pipeline.closed = true + pipeline.err = newContextAlreadyDoneError(ctx) + pgConn.unlock() + return pipeline + default: + } + pgConn.contextWatcher.Watch(ctx) + } + + return pipeline +} + +// SendPrepare is the pipeline version of *PgConn.Prepare. +func (p *Pipeline) SendPrepare(name, sql string, paramOIDs []uint32) { + if p.closed { + return + } + p.pendingSync = true + + p.conn.frontend.SendParse(&pgproto3.Parse{Name: name, Query: sql, ParameterOIDs: paramOIDs}) + p.conn.frontend.SendDescribe(&pgproto3.Describe{ObjectType: 'S', Name: name}) +} + +// SendDeallocate deallocates a prepared statement. +func (p *Pipeline) SendDeallocate(name string) { + if p.closed { + return + } + p.pendingSync = true + + p.conn.frontend.SendClose(&pgproto3.Close{ObjectType: 'S', Name: name}) +} + +// SendQueryParams is the pipeline version of *PgConn.QueryParams. +func (p *Pipeline) SendQueryParams(sql string, paramValues [][]byte, paramOIDs []uint32, paramFormats []int16, resultFormats []int16) { + if p.closed { + return + } + p.pendingSync = true + + p.conn.frontend.SendParse(&pgproto3.Parse{Query: sql, ParameterOIDs: paramOIDs}) + p.conn.frontend.SendBind(&pgproto3.Bind{ParameterFormatCodes: paramFormats, Parameters: paramValues, ResultFormatCodes: resultFormats}) + p.conn.frontend.SendDescribe(&pgproto3.Describe{ObjectType: 'P'}) + p.conn.frontend.SendExecute(&pgproto3.Execute{}) +} + +// SendQueryPrepared is the pipeline version of *PgConn.QueryPrepared. +func (p *Pipeline) SendQueryPrepared(stmtName string, paramValues [][]byte, paramFormats []int16, resultFormats []int16) { + if p.closed { + return + } + p.pendingSync = true + + p.conn.frontend.SendBind(&pgproto3.Bind{PreparedStatement: stmtName, ParameterFormatCodes: paramFormats, Parameters: paramValues, ResultFormatCodes: resultFormats}) + p.conn.frontend.SendDescribe(&pgproto3.Describe{ObjectType: 'P'}) + p.conn.frontend.SendExecute(&pgproto3.Execute{}) +} + +// Flush flushes the queued requests without establishing a synchronization point. +func (p *Pipeline) Flush() error { + if p.closed { + if p.err != nil { + return p.err + } + return errors.New("pipeline closed") + } + + err := p.conn.flushWithPotentialWriteReadDeadlock() + if err != nil { + err = normalizeTimeoutError(p.ctx, err) + + p.conn.asyncClose() + + p.conn.contextWatcher.Unwatch() + p.conn.unlock() + p.closed = true + p.err = err + return err + } + + return nil +} + +// Sync establishes a synchronization point and flushes the queued requests. +func (p *Pipeline) Sync() error { + p.conn.frontend.SendSync(&pgproto3.Sync{}) + err := p.Flush() + if err != nil { + return err + } + + p.pendingSync = false + p.expectedReadyForQueryCount++ + + return nil +} + +// GetResults gets the next results. If results are present, results may be a *ResultReader, *StatementDescription, or +// *PipelineSync. If an ErrorResponse is received from the server, results will be nil and err will be a *PgError. If no +// results are available, results and err will both be nil. +func (p *Pipeline) GetResults() (results any, err error) { + if p.expectedReadyForQueryCount == 0 { + return nil, nil + } + + for { + msg, err := p.conn.receiveMessage() + if err != nil { + return nil, err + } + + switch msg := msg.(type) { + case *pgproto3.RowDescription: + p.conn.resultReader = ResultReader{ + pgConn: p.conn, + pipeline: p, + ctx: p.ctx, + fieldDescriptions: p.conn.convertRowDescription(p.conn.fieldDescriptions[:], msg), + } + return &p.conn.resultReader, nil + case *pgproto3.CommandComplete: + p.conn.resultReader = ResultReader{ + commandTag: p.conn.makeCommandTag(msg.CommandTag), + commandConcluded: true, + closed: true, + } + return &p.conn.resultReader, nil + case *pgproto3.ParseComplete: + peekedMsg, err := p.conn.peekMessage() + if err != nil { + return nil, err + } + if _, ok := peekedMsg.(*pgproto3.ParameterDescription); ok { + return p.getResultsPrepare() + } + case *pgproto3.CloseComplete: + return &CloseComplete{}, nil + case *pgproto3.ReadyForQuery: + p.expectedReadyForQueryCount-- + return &PipelineSync{}, nil + case *pgproto3.ErrorResponse: + pgErr := ErrorResponseToPgError(msg) + return nil, pgErr + } + + } + +} + +func (p *Pipeline) getResultsPrepare() (*StatementDescription, error) { + psd := &StatementDescription{} + + for { + msg, err := p.conn.receiveMessage() + if err != nil { + p.conn.asyncClose() + return nil, normalizeTimeoutError(p.ctx, err) + } + + switch msg := msg.(type) { + case *pgproto3.ParameterDescription: + psd.ParamOIDs = make([]uint32, len(msg.ParameterOIDs)) + copy(psd.ParamOIDs, msg.ParameterOIDs) + case *pgproto3.RowDescription: + psd.Fields = p.conn.convertRowDescription(nil, msg) + return psd, nil + + // NoData is returned instead of RowDescription when there is no expected result. e.g. An INSERT without a RETURNING + // clause. + case *pgproto3.NoData: + return psd, nil + + // These should never happen here. But don't take chances that could lead to a deadlock. + case *pgproto3.ErrorResponse: + pgErr := ErrorResponseToPgError(msg) + return nil, pgErr + case *pgproto3.CommandComplete: + p.conn.asyncClose() + return nil, errors.New("BUG: received CommandComplete while handling Describe") + case *pgproto3.ReadyForQuery: + p.conn.asyncClose() + return nil, errors.New("BUG: received ReadyForQuery while handling Describe") + } + } +} + +// Close closes the pipeline and returns the connection to normal mode. +func (p *Pipeline) Close() error { + if p.closed { + return p.err + } + p.closed = true + + if p.pendingSync { + p.conn.asyncClose() + p.err = errors.New("pipeline has unsynced requests") + p.conn.contextWatcher.Unwatch() + p.conn.unlock() + + return p.err + } + + for p.expectedReadyForQueryCount > 0 { + _, err := p.GetResults() + if err != nil { + p.err = err + var pgErr *PgError + if !errors.As(err, &pgErr) { + p.conn.asyncClose() + break + } + } + } + + p.conn.contextWatcher.Unwatch() + p.conn.unlock() + + return p.err +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/README.md b/vendor/github.com/jackc/pgx/v5/pgproto3/README.md new file mode 100644 index 00000000000..79d3a68bbf0 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/README.md @@ -0,0 +1,7 @@ +# pgproto3 + +Package pgproto3 is a encoder and decoder of the PostgreSQL wire protocol version 3. + +pgproto3 can be used as a foundation for PostgreSQL drivers, proxies, mock servers, load balancers and more. + +See example/pgfortune for a playful example of a fake PostgreSQL server. diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go new file mode 100644 index 00000000000..d8f98b9af0c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_cleartext_password.go @@ -0,0 +1,52 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// AuthenticationCleartextPassword is a message sent from the backend indicating that a clear-text password is required. +type AuthenticationCleartextPassword struct { +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*AuthenticationCleartextPassword) Backend() {} + +// Backend identifies this message as an authentication response. +func (*AuthenticationCleartextPassword) AuthenticationResponse() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *AuthenticationCleartextPassword) Decode(src []byte) error { + if len(src) != 4 { + return errors.New("bad authentication message size") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeCleartextPassword { + return errors.New("bad auth type") + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *AuthenticationCleartextPassword) Encode(dst []byte) []byte { + dst = append(dst, 'R') + dst = pgio.AppendInt32(dst, 8) + dst = pgio.AppendUint32(dst, AuthTypeCleartextPassword) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src AuthenticationCleartextPassword) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "AuthenticationCleartextPassword", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go new file mode 100644 index 00000000000..0d234222fcb --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss.go @@ -0,0 +1,59 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type AuthenticationGSS struct{} + +func (a *AuthenticationGSS) Backend() {} + +func (a *AuthenticationGSS) AuthenticationResponse() {} + +func (a *AuthenticationGSS) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("authentication message too short") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeGSS { + return errors.New("bad auth type") + } + return nil +} + +func (a *AuthenticationGSS) Encode(dst []byte) []byte { + dst = append(dst, 'R') + dst = pgio.AppendInt32(dst, 4) + dst = pgio.AppendUint32(dst, AuthTypeGSS) + return dst +} + +func (a *AuthenticationGSS) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Data []byte + }{ + Type: "AuthenticationGSS", + }) +} + +func (a *AuthenticationGSS) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Type string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go new file mode 100644 index 00000000000..63789dc1a57 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_gss_continue.go @@ -0,0 +1,68 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type AuthenticationGSSContinue struct { + Data []byte +} + +func (a *AuthenticationGSSContinue) Backend() {} + +func (a *AuthenticationGSSContinue) AuthenticationResponse() {} + +func (a *AuthenticationGSSContinue) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("authentication message too short") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeGSSCont { + return errors.New("bad auth type") + } + + a.Data = src[4:] + return nil +} + +func (a *AuthenticationGSSContinue) Encode(dst []byte) []byte { + dst = append(dst, 'R') + dst = pgio.AppendInt32(dst, int32(len(a.Data))+8) + dst = pgio.AppendUint32(dst, AuthTypeGSSCont) + dst = append(dst, a.Data...) + return dst +} + +func (a *AuthenticationGSSContinue) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Data []byte + }{ + Type: "AuthenticationGSSContinue", + Data: a.Data, + }) +} + +func (a *AuthenticationGSSContinue) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Type string + Data []byte + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + a.Data = msg.Data + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go new file mode 100644 index 00000000000..5671c84c55a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_md5_password.go @@ -0,0 +1,77 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// AuthenticationMD5Password is a message sent from the backend indicating that an MD5 hashed password is required. +type AuthenticationMD5Password struct { + Salt [4]byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*AuthenticationMD5Password) Backend() {} + +// Backend identifies this message as an authentication response. +func (*AuthenticationMD5Password) AuthenticationResponse() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *AuthenticationMD5Password) Decode(src []byte) error { + if len(src) != 8 { + return errors.New("bad authentication message size") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeMD5Password { + return errors.New("bad auth type") + } + + copy(dst.Salt[:], src[4:8]) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *AuthenticationMD5Password) Encode(dst []byte) []byte { + dst = append(dst, 'R') + dst = pgio.AppendInt32(dst, 12) + dst = pgio.AppendUint32(dst, AuthTypeMD5Password) + dst = append(dst, src.Salt[:]...) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src AuthenticationMD5Password) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Salt [4]byte + }{ + Type: "AuthenticationMD5Password", + Salt: src.Salt, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *AuthenticationMD5Password) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Type string + Salt [4]byte + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + dst.Salt = msg.Salt + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go new file mode 100644 index 00000000000..88d648ae705 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_ok.go @@ -0,0 +1,52 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// AuthenticationOk is a message sent from the backend indicating that authentication was successful. +type AuthenticationOk struct { +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*AuthenticationOk) Backend() {} + +// Backend identifies this message as an authentication response. +func (*AuthenticationOk) AuthenticationResponse() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *AuthenticationOk) Decode(src []byte) error { + if len(src) != 4 { + return errors.New("bad authentication message size") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeOk { + return errors.New("bad auth type") + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *AuthenticationOk) Encode(dst []byte) []byte { + dst = append(dst, 'R') + dst = pgio.AppendInt32(dst, 8) + dst = pgio.AppendUint32(dst, AuthTypeOk) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src AuthenticationOk) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "AuthenticationOK", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go new file mode 100644 index 00000000000..59650d4cd07 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl.go @@ -0,0 +1,76 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// AuthenticationSASL is a message sent from the backend indicating that SASL authentication is required. +type AuthenticationSASL struct { + AuthMechanisms []string +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*AuthenticationSASL) Backend() {} + +// Backend identifies this message as an authentication response. +func (*AuthenticationSASL) AuthenticationResponse() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *AuthenticationSASL) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("authentication message too short") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeSASL { + return errors.New("bad auth type") + } + + authMechanisms := src[4:] + for len(authMechanisms) > 1 { + idx := bytes.IndexByte(authMechanisms, 0) + if idx == -1 { + return &invalidMessageFormatErr{messageType: "AuthenticationSASL", details: "unterminated string"} + } + dst.AuthMechanisms = append(dst.AuthMechanisms, string(authMechanisms[:idx])) + authMechanisms = authMechanisms[idx+1:] + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *AuthenticationSASL) Encode(dst []byte) []byte { + dst = append(dst, 'R') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + dst = pgio.AppendUint32(dst, AuthTypeSASL) + + for _, s := range src.AuthMechanisms { + dst = append(dst, []byte(s)...) + dst = append(dst, 0) + } + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src AuthenticationSASL) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + AuthMechanisms []string + }{ + Type: "AuthenticationSASL", + AuthMechanisms: src.AuthMechanisms, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go new file mode 100644 index 00000000000..2ce70a47786 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_continue.go @@ -0,0 +1,81 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// AuthenticationSASLContinue is a message sent from the backend containing a SASL challenge. +type AuthenticationSASLContinue struct { + Data []byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*AuthenticationSASLContinue) Backend() {} + +// Backend identifies this message as an authentication response. +func (*AuthenticationSASLContinue) AuthenticationResponse() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *AuthenticationSASLContinue) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("authentication message too short") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeSASLContinue { + return errors.New("bad auth type") + } + + dst.Data = src[4:] + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *AuthenticationSASLContinue) Encode(dst []byte) []byte { + dst = append(dst, 'R') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + dst = pgio.AppendUint32(dst, AuthTypeSASLContinue) + + dst = append(dst, src.Data...) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src AuthenticationSASLContinue) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Data string + }{ + Type: "AuthenticationSASLContinue", + Data: string(src.Data), + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *AuthenticationSASLContinue) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Data string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + dst.Data = []byte(msg.Data) + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go new file mode 100644 index 00000000000..a38a8b9129e --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/authentication_sasl_final.go @@ -0,0 +1,81 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// AuthenticationSASLFinal is a message sent from the backend indicating a SASL authentication has completed. +type AuthenticationSASLFinal struct { + Data []byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*AuthenticationSASLFinal) Backend() {} + +// Backend identifies this message as an authentication response. +func (*AuthenticationSASLFinal) AuthenticationResponse() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *AuthenticationSASLFinal) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("authentication message too short") + } + + authType := binary.BigEndian.Uint32(src) + + if authType != AuthTypeSASLFinal { + return errors.New("bad auth type") + } + + dst.Data = src[4:] + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *AuthenticationSASLFinal) Encode(dst []byte) []byte { + dst = append(dst, 'R') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + dst = pgio.AppendUint32(dst, AuthTypeSASLFinal) + + dst = append(dst, src.Data...) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Unmarshaler. +func (src AuthenticationSASLFinal) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Data string + }{ + Type: "AuthenticationSASLFinal", + Data: string(src.Data), + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *AuthenticationSASLFinal) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Data string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + dst.Data = []byte(msg.Data) + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/backend.go b/vendor/github.com/jackc/pgx/v5/pgproto3/backend.go new file mode 100644 index 00000000000..6db77e4a2f4 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/backend.go @@ -0,0 +1,262 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" +) + +// Backend acts as a server for the PostgreSQL wire protocol version 3. +type Backend struct { + cr *chunkReader + w io.Writer + + // tracer is used to trace messages when Send or Receive is called. This means an outbound message is traced + // before it is actually transmitted (i.e. before Flush). + tracer *tracer + + wbuf []byte + + // Frontend message flyweights + bind Bind + cancelRequest CancelRequest + _close Close + copyFail CopyFail + copyData CopyData + copyDone CopyDone + describe Describe + execute Execute + flush Flush + functionCall FunctionCall + gssEncRequest GSSEncRequest + parse Parse + query Query + sslRequest SSLRequest + startupMessage StartupMessage + sync Sync + terminate Terminate + + bodyLen int + msgType byte + partialMsg bool + authType uint32 +} + +const ( + minStartupPacketLen = 4 // minStartupPacketLen is a single 32-bit int version or code. + maxStartupPacketLen = 10000 // maxStartupPacketLen is MAX_STARTUP_PACKET_LENGTH from PG source. +) + +// NewBackend creates a new Backend. +func NewBackend(r io.Reader, w io.Writer) *Backend { + cr := newChunkReader(r, 0) + return &Backend{cr: cr, w: w} +} + +// Send sends a message to the frontend (i.e. the client). The message is not guaranteed to be written until Flush is +// called. +func (b *Backend) Send(msg BackendMessage) { + prevLen := len(b.wbuf) + b.wbuf = msg.Encode(b.wbuf) + if b.tracer != nil { + b.tracer.traceMessage('B', int32(len(b.wbuf)-prevLen), msg) + } +} + +// Flush writes any pending messages to the frontend (i.e. the client). +func (b *Backend) Flush() error { + n, err := b.w.Write(b.wbuf) + + const maxLen = 1024 + if len(b.wbuf) > maxLen { + b.wbuf = make([]byte, 0, maxLen) + } else { + b.wbuf = b.wbuf[:0] + } + + if err != nil { + return &writeError{err: err, safeToRetry: n == 0} + } + + return nil +} + +// Trace starts tracing the message traffic to w. It writes in a similar format to that produced by the libpq function +// PQtrace. +func (b *Backend) Trace(w io.Writer, options TracerOptions) { + b.tracer = &tracer{ + w: w, + buf: &bytes.Buffer{}, + TracerOptions: options, + } +} + +// Untrace stops tracing. +func (b *Backend) Untrace() { + b.tracer = nil +} + +// ReceiveStartupMessage receives the initial connection message. This method is used of the normal Receive method +// because the initial connection message is "special" and does not include the message type as the first byte. This +// will return either a StartupMessage, SSLRequest, GSSEncRequest, or CancelRequest. +func (b *Backend) ReceiveStartupMessage() (FrontendMessage, error) { + buf, err := b.cr.Next(4) + if err != nil { + return nil, err + } + msgSize := int(binary.BigEndian.Uint32(buf) - 4) + + if msgSize < minStartupPacketLen || msgSize > maxStartupPacketLen { + return nil, fmt.Errorf("invalid length of startup packet: %d", msgSize) + } + + buf, err = b.cr.Next(msgSize) + if err != nil { + return nil, translateEOFtoErrUnexpectedEOF(err) + } + + code := binary.BigEndian.Uint32(buf) + + switch code { + case ProtocolVersionNumber: + err = b.startupMessage.Decode(buf) + if err != nil { + return nil, err + } + return &b.startupMessage, nil + case sslRequestNumber: + err = b.sslRequest.Decode(buf) + if err != nil { + return nil, err + } + return &b.sslRequest, nil + case cancelRequestCode: + err = b.cancelRequest.Decode(buf) + if err != nil { + return nil, err + } + return &b.cancelRequest, nil + case gssEncReqNumber: + err = b.gssEncRequest.Decode(buf) + if err != nil { + return nil, err + } + return &b.gssEncRequest, nil + default: + return nil, fmt.Errorf("unknown startup message code: %d", code) + } +} + +// Receive receives a message from the frontend. The returned message is only valid until the next call to Receive. +func (b *Backend) Receive() (FrontendMessage, error) { + if !b.partialMsg { + header, err := b.cr.Next(5) + if err != nil { + return nil, translateEOFtoErrUnexpectedEOF(err) + } + + b.msgType = header[0] + b.bodyLen = int(binary.BigEndian.Uint32(header[1:])) - 4 + b.partialMsg = true + } + + var msg FrontendMessage + switch b.msgType { + case 'B': + msg = &b.bind + case 'C': + msg = &b._close + case 'D': + msg = &b.describe + case 'E': + msg = &b.execute + case 'F': + msg = &b.functionCall + case 'f': + msg = &b.copyFail + case 'd': + msg = &b.copyData + case 'c': + msg = &b.copyDone + case 'H': + msg = &b.flush + case 'P': + msg = &b.parse + case 'p': + switch b.authType { + case AuthTypeSASL: + msg = &SASLInitialResponse{} + case AuthTypeSASLContinue: + msg = &SASLResponse{} + case AuthTypeSASLFinal: + msg = &SASLResponse{} + case AuthTypeGSS, AuthTypeGSSCont: + msg = &GSSResponse{} + case AuthTypeCleartextPassword, AuthTypeMD5Password: + fallthrough + default: + // to maintain backwards compatibility + msg = &PasswordMessage{} + } + case 'Q': + msg = &b.query + case 'S': + msg = &b.sync + case 'X': + msg = &b.terminate + default: + return nil, fmt.Errorf("unknown message type: %c", b.msgType) + } + + msgBody, err := b.cr.Next(b.bodyLen) + if err != nil { + return nil, translateEOFtoErrUnexpectedEOF(err) + } + + b.partialMsg = false + + err = msg.Decode(msgBody) + if err != nil { + return nil, err + } + + if b.tracer != nil { + b.tracer.traceMessage('F', int32(5+len(msgBody)), msg) + } + + return msg, nil +} + +// SetAuthType sets the authentication type in the backend. +// Since multiple message types can start with 'p', SetAuthType allows +// contextual identification of FrontendMessages. For example, in the +// PG message flow documentation for PasswordMessage: +// +// Byte1('p') +// +// Identifies the message as a password response. Note that this is also used for +// GSSAPI, SSPI and SASL response messages. The exact message type can be deduced from +// the context. +// +// Since the Frontend does not know about the state of a backend, it is important +// to call SetAuthType() after an authentication request is received by the Frontend. +func (b *Backend) SetAuthType(authType uint32) error { + switch authType { + case AuthTypeOk, + AuthTypeCleartextPassword, + AuthTypeMD5Password, + AuthTypeSCMCreds, + AuthTypeGSS, + AuthTypeGSSCont, + AuthTypeSSPI, + AuthTypeSASL, + AuthTypeSASLContinue, + AuthTypeSASLFinal: + b.authType = authType + default: + return fmt.Errorf("authType not recognized: %d", authType) + } + + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go b/vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go new file mode 100644 index 00000000000..12c60817036 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/backend_key_data.go @@ -0,0 +1,51 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type BackendKeyData struct { + ProcessID uint32 + SecretKey uint32 +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*BackendKeyData) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *BackendKeyData) Decode(src []byte) error { + if len(src) != 8 { + return &invalidMessageLenErr{messageType: "BackendKeyData", expectedLen: 8, actualLen: len(src)} + } + + dst.ProcessID = binary.BigEndian.Uint32(src[:4]) + dst.SecretKey = binary.BigEndian.Uint32(src[4:]) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *BackendKeyData) Encode(dst []byte) []byte { + dst = append(dst, 'K') + dst = pgio.AppendUint32(dst, 12) + dst = pgio.AppendUint32(dst, src.ProcessID) + dst = pgio.AppendUint32(dst, src.SecretKey) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src BackendKeyData) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ProcessID uint32 + SecretKey uint32 + }{ + Type: "BackendKeyData", + ProcessID: src.ProcessID, + SecretKey: src.SecretKey, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go b/vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go new file mode 100644 index 00000000000..f7bdb97eb7a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/big_endian.go @@ -0,0 +1,37 @@ +package pgproto3 + +import ( + "encoding/binary" +) + +type BigEndianBuf [8]byte + +func (b BigEndianBuf) Int16(n int16) []byte { + buf := b[0:2] + binary.BigEndian.PutUint16(buf, uint16(n)) + return buf +} + +func (b BigEndianBuf) Uint16(n uint16) []byte { + buf := b[0:2] + binary.BigEndian.PutUint16(buf, n) + return buf +} + +func (b BigEndianBuf) Int32(n int32) []byte { + buf := b[0:4] + binary.BigEndian.PutUint32(buf, uint32(n)) + return buf +} + +func (b BigEndianBuf) Uint32(n uint32) []byte { + buf := b[0:4] + binary.BigEndian.PutUint32(buf, n) + return buf +} + +func (b BigEndianBuf) Int64(n int64) []byte { + buf := b[0:8] + binary.BigEndian.PutUint64(buf, uint64(n)) + return buf +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/bind.go b/vendor/github.com/jackc/pgx/v5/pgproto3/bind.go new file mode 100644 index 00000000000..fdd2d3b812e --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/bind.go @@ -0,0 +1,216 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/hex" + "encoding/json" + "fmt" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Bind struct { + DestinationPortal string + PreparedStatement string + ParameterFormatCodes []int16 + Parameters [][]byte + ResultFormatCodes []int16 +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Bind) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Bind) Decode(src []byte) error { + *dst = Bind{} + + idx := bytes.IndexByte(src, 0) + if idx < 0 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + dst.DestinationPortal = string(src[:idx]) + rp := idx + 1 + + idx = bytes.IndexByte(src[rp:], 0) + if idx < 0 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + dst.PreparedStatement = string(src[rp : rp+idx]) + rp += idx + 1 + + if len(src[rp:]) < 2 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + parameterFormatCodeCount := int(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + + if parameterFormatCodeCount > 0 { + dst.ParameterFormatCodes = make([]int16, parameterFormatCodeCount) + + if len(src[rp:]) < len(dst.ParameterFormatCodes)*2 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + for i := 0; i < parameterFormatCodeCount; i++ { + dst.ParameterFormatCodes[i] = int16(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + } + } + + if len(src[rp:]) < 2 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + parameterCount := int(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + + if parameterCount > 0 { + dst.Parameters = make([][]byte, parameterCount) + + for i := 0; i < parameterCount; i++ { + if len(src[rp:]) < 4 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + + msgSize := int(int32(binary.BigEndian.Uint32(src[rp:]))) + rp += 4 + + // null + if msgSize == -1 { + continue + } + + if len(src[rp:]) < msgSize { + return &invalidMessageFormatErr{messageType: "Bind"} + } + + dst.Parameters[i] = src[rp : rp+msgSize] + rp += msgSize + } + } + + if len(src[rp:]) < 2 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + resultFormatCodeCount := int(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + + dst.ResultFormatCodes = make([]int16, resultFormatCodeCount) + if len(src[rp:]) < len(dst.ResultFormatCodes)*2 { + return &invalidMessageFormatErr{messageType: "Bind"} + } + for i := 0; i < resultFormatCodeCount; i++ { + dst.ResultFormatCodes[i] = int16(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Bind) Encode(dst []byte) []byte { + dst = append(dst, 'B') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.DestinationPortal...) + dst = append(dst, 0) + dst = append(dst, src.PreparedStatement...) + dst = append(dst, 0) + + dst = pgio.AppendUint16(dst, uint16(len(src.ParameterFormatCodes))) + for _, fc := range src.ParameterFormatCodes { + dst = pgio.AppendInt16(dst, fc) + } + + dst = pgio.AppendUint16(dst, uint16(len(src.Parameters))) + for _, p := range src.Parameters { + if p == nil { + dst = pgio.AppendInt32(dst, -1) + continue + } + + dst = pgio.AppendInt32(dst, int32(len(p))) + dst = append(dst, p...) + } + + dst = pgio.AppendUint16(dst, uint16(len(src.ResultFormatCodes))) + for _, fc := range src.ResultFormatCodes { + dst = pgio.AppendInt16(dst, fc) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Bind) MarshalJSON() ([]byte, error) { + formattedParameters := make([]map[string]string, len(src.Parameters)) + for i, p := range src.Parameters { + if p == nil { + continue + } + + textFormat := true + if len(src.ParameterFormatCodes) == 1 { + textFormat = src.ParameterFormatCodes[0] == 0 + } else if len(src.ParameterFormatCodes) > 1 { + textFormat = src.ParameterFormatCodes[i] == 0 + } + + if textFormat { + formattedParameters[i] = map[string]string{"text": string(p)} + } else { + formattedParameters[i] = map[string]string{"binary": hex.EncodeToString(p)} + } + } + + return json.Marshal(struct { + Type string + DestinationPortal string + PreparedStatement string + ParameterFormatCodes []int16 + Parameters []map[string]string + ResultFormatCodes []int16 + }{ + Type: "Bind", + DestinationPortal: src.DestinationPortal, + PreparedStatement: src.PreparedStatement, + ParameterFormatCodes: src.ParameterFormatCodes, + Parameters: formattedParameters, + ResultFormatCodes: src.ResultFormatCodes, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *Bind) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + DestinationPortal string + PreparedStatement string + ParameterFormatCodes []int16 + Parameters []map[string]string + ResultFormatCodes []int16 + } + err := json.Unmarshal(data, &msg) + if err != nil { + return err + } + dst.DestinationPortal = msg.DestinationPortal + dst.PreparedStatement = msg.PreparedStatement + dst.ParameterFormatCodes = msg.ParameterFormatCodes + dst.Parameters = make([][]byte, len(msg.Parameters)) + dst.ResultFormatCodes = msg.ResultFormatCodes + for n, parameter := range msg.Parameters { + dst.Parameters[n], err = getValueFromJSON(parameter) + if err != nil { + return fmt.Errorf("cannot get param %d: %w", n, err) + } + } + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go new file mode 100644 index 00000000000..3be256c8976 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/bind_complete.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type BindComplete struct{} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*BindComplete) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *BindComplete) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "BindComplete", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *BindComplete) Encode(dst []byte) []byte { + return append(dst, '2', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src BindComplete) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "BindComplete", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go b/vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go new file mode 100644 index 00000000000..8fcf8217ac3 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/cancel_request.go @@ -0,0 +1,58 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const cancelRequestCode = 80877102 + +type CancelRequest struct { + ProcessID uint32 + SecretKey uint32 +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*CancelRequest) Frontend() {} + +func (dst *CancelRequest) Decode(src []byte) error { + if len(src) != 12 { + return errors.New("bad cancel request size") + } + + requestCode := binary.BigEndian.Uint32(src) + + if requestCode != cancelRequestCode { + return errors.New("bad cancel request code") + } + + dst.ProcessID = binary.BigEndian.Uint32(src[4:]) + dst.SecretKey = binary.BigEndian.Uint32(src[8:]) + + return nil +} + +// Encode encodes src into dst. dst will include the 4 byte message length. +func (src *CancelRequest) Encode(dst []byte) []byte { + dst = pgio.AppendInt32(dst, 16) + dst = pgio.AppendInt32(dst, cancelRequestCode) + dst = pgio.AppendUint32(dst, src.ProcessID) + dst = pgio.AppendUint32(dst, src.SecretKey) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CancelRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ProcessID uint32 + SecretKey uint32 + }{ + Type: "CancelRequest", + ProcessID: src.ProcessID, + SecretKey: src.SecretKey, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go b/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go new file mode 100644 index 00000000000..fc0fa61e9ca --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/chunkreader.go @@ -0,0 +1,90 @@ +package pgproto3 + +import ( + "io" + + "github.com/jackc/pgx/v5/internal/iobufpool" +) + +// chunkReader is a io.Reader wrapper that minimizes IO reads and memory allocations. It allocates memory in chunks and +// will read as much as will fit in the current buffer in a single call regardless of how large a read is actually +// requested. The memory returned via Next is only valid until the next call to Next. +// +// This is roughly equivalent to a bufio.Reader that only uses Peek and Discard to never copy bytes. +type chunkReader struct { + r io.Reader + + buf *[]byte + rp, wp int // buf read position and write position + + minBufSize int +} + +// newChunkReader creates and returns a new chunkReader for r with default configuration. If minBufSize is <= 0 it uses +// a default value. +func newChunkReader(r io.Reader, minBufSize int) *chunkReader { + if minBufSize <= 0 { + // By historical reasons Postgres currently has 8KB send buffer inside, + // so here we want to have at least the same size buffer. + // @see https://github.com/postgres/postgres/blob/249d64999615802752940e017ee5166e726bc7cd/src/backend/libpq/pqcomm.c#L134 + // @see https://www.postgresql.org/message-id/0cdc5485-cb3c-5e16-4a46-e3b2f7a41322%40ya.ru + // + // In addition, testing has found no benefit of any larger buffer. + minBufSize = 8192 + } + + return &chunkReader{ + r: r, + minBufSize: minBufSize, + buf: iobufpool.Get(minBufSize), + } +} + +// Next returns buf filled with the next n bytes. buf is only valid until next call of Next. If an error occurs, buf +// will be nil. +func (r *chunkReader) Next(n int) (buf []byte, err error) { + // Reset the buffer if it is empty + if r.rp == r.wp { + if len(*r.buf) != r.minBufSize { + iobufpool.Put(r.buf) + r.buf = iobufpool.Get(r.minBufSize) + } + r.rp = 0 + r.wp = 0 + } + + // n bytes already in buf + if (r.wp - r.rp) >= n { + buf = (*r.buf)[r.rp : r.rp+n : r.rp+n] + r.rp += n + return buf, err + } + + // buf is smaller than requested number of bytes + if len(*r.buf) < n { + bigBuf := iobufpool.Get(n) + r.wp = copy((*bigBuf), (*r.buf)[r.rp:r.wp]) + r.rp = 0 + iobufpool.Put(r.buf) + r.buf = bigBuf + } + + // buf is large enough, but need to shift filled area to start to make enough contiguous space + minReadCount := n - (r.wp - r.rp) + if (len(*r.buf) - r.wp) < minReadCount { + r.wp = copy((*r.buf), (*r.buf)[r.rp:r.wp]) + r.rp = 0 + } + + // Read at least the required number of bytes from the underlying io.Reader + readBytesCount, err := io.ReadAtLeast(r.r, (*r.buf)[r.wp:], minReadCount) + r.wp += readBytesCount + // fmt.Println("read", n) + if err != nil { + return nil, err + } + + buf = (*r.buf)[r.rp : r.rp+n : r.rp+n] + r.rp += n + return buf, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/close.go b/vendor/github.com/jackc/pgx/v5/pgproto3/close.go new file mode 100644 index 00000000000..f99b5943987 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/close.go @@ -0,0 +1,89 @@ +package pgproto3 + +import ( + "bytes" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Close struct { + ObjectType byte // 'S' = prepared statement, 'P' = portal + Name string +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Close) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Close) Decode(src []byte) error { + if len(src) < 2 { + return &invalidMessageFormatErr{messageType: "Close"} + } + + dst.ObjectType = src[0] + rp := 1 + + idx := bytes.IndexByte(src[rp:], 0) + if idx != len(src[rp:])-1 { + return &invalidMessageFormatErr{messageType: "Close"} + } + + dst.Name = string(src[rp : len(src)-1]) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Close) Encode(dst []byte) []byte { + dst = append(dst, 'C') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.ObjectType) + dst = append(dst, src.Name...) + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Close) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ObjectType string + Name string + }{ + Type: "Close", + ObjectType: string(src.ObjectType), + Name: src.Name, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *Close) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + ObjectType string + Name string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + if len(msg.ObjectType) != 1 { + return errors.New("invalid length for Close.ObjectType") + } + + dst.ObjectType = byte(msg.ObjectType[0]) + dst.Name = msg.Name + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go new file mode 100644 index 00000000000..1d7b8f085a3 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/close_complete.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type CloseComplete struct{} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*CloseComplete) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CloseComplete) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "CloseComplete", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CloseComplete) Encode(dst []byte) []byte { + return append(dst, '3', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CloseComplete) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "CloseComplete", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go new file mode 100644 index 00000000000..814027ca1af --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/command_complete.go @@ -0,0 +1,74 @@ +package pgproto3 + +import ( + "bytes" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type CommandComplete struct { + CommandTag []byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*CommandComplete) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CommandComplete) Decode(src []byte) error { + idx := bytes.IndexByte(src, 0) + if idx == -1 { + return &invalidMessageFormatErr{messageType: "CommandComplete", details: "unterminated string"} + } + if idx != len(src)-1 { + return &invalidMessageFormatErr{messageType: "CommandComplete", details: "string terminated too early"} + } + + dst.CommandTag = src[:idx] + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CommandComplete) Encode(dst []byte) []byte { + dst = append(dst, 'C') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.CommandTag...) + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CommandComplete) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + CommandTag string + }{ + Type: "CommandComplete", + CommandTag: string(src.CommandTag), + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *CommandComplete) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + CommandTag string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + dst.CommandTag = []byte(msg.CommandTag) + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go new file mode 100644 index 00000000000..8840a89ec04 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_both_response.go @@ -0,0 +1,95 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type CopyBothResponse struct { + OverallFormat byte + ColumnFormatCodes []uint16 +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*CopyBothResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CopyBothResponse) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + if buf.Len() < 3 { + return &invalidMessageFormatErr{messageType: "CopyBothResponse"} + } + + overallFormat := buf.Next(1)[0] + + columnCount := int(binary.BigEndian.Uint16(buf.Next(2))) + if buf.Len() != columnCount*2 { + return &invalidMessageFormatErr{messageType: "CopyBothResponse"} + } + + columnFormatCodes := make([]uint16, columnCount) + for i := 0; i < columnCount; i++ { + columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2)) + } + + *dst = CopyBothResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes} + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CopyBothResponse) Encode(dst []byte) []byte { + dst = append(dst, 'W') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + dst = append(dst, src.OverallFormat) + dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes))) + for _, fc := range src.ColumnFormatCodes { + dst = pgio.AppendUint16(dst, fc) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CopyBothResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ColumnFormatCodes []uint16 + }{ + Type: "CopyBothResponse", + ColumnFormatCodes: src.ColumnFormatCodes, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *CopyBothResponse) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + OverallFormat string + ColumnFormatCodes []uint16 + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + if len(msg.OverallFormat) != 1 { + return errors.New("invalid length for CopyBothResponse.OverallFormat") + } + + dst.OverallFormat = msg.OverallFormat[0] + dst.ColumnFormatCodes = msg.ColumnFormatCodes + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go new file mode 100644 index 00000000000..59e3dd94290 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_data.go @@ -0,0 +1,62 @@ +package pgproto3 + +import ( + "encoding/hex" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type CopyData struct { + Data []byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*CopyData) Backend() {} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*CopyData) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CopyData) Decode(src []byte) error { + dst.Data = src + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CopyData) Encode(dst []byte) []byte { + dst = append(dst, 'd') + dst = pgio.AppendInt32(dst, int32(4+len(src.Data))) + dst = append(dst, src.Data...) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CopyData) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Data string + }{ + Type: "CopyData", + Data: hex.EncodeToString(src.Data), + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *CopyData) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Data string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + dst.Data = []byte(msg.Data) + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go new file mode 100644 index 00000000000..0e13282bff7 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_done.go @@ -0,0 +1,38 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type CopyDone struct { +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*CopyDone) Backend() {} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*CopyDone) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CopyDone) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "CopyDone", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CopyDone) Encode(dst []byte) []byte { + return append(dst, 'c', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CopyDone) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "CopyDone", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go new file mode 100644 index 00000000000..0041bbb1d32 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_fail.go @@ -0,0 +1,53 @@ +package pgproto3 + +import ( + "bytes" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type CopyFail struct { + Message string +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*CopyFail) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CopyFail) Decode(src []byte) error { + idx := bytes.IndexByte(src, 0) + if idx != len(src)-1 { + return &invalidMessageFormatErr{messageType: "CopyFail"} + } + + dst.Message = string(src[:idx]) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CopyFail) Encode(dst []byte) []byte { + dst = append(dst, 'f') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.Message...) + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CopyFail) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Message string + }{ + Type: "CopyFail", + Message: src.Message, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go new file mode 100644 index 00000000000..4584f7df2d9 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_in_response.go @@ -0,0 +1,96 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type CopyInResponse struct { + OverallFormat byte + ColumnFormatCodes []uint16 +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*CopyInResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CopyInResponse) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + if buf.Len() < 3 { + return &invalidMessageFormatErr{messageType: "CopyInResponse"} + } + + overallFormat := buf.Next(1)[0] + + columnCount := int(binary.BigEndian.Uint16(buf.Next(2))) + if buf.Len() != columnCount*2 { + return &invalidMessageFormatErr{messageType: "CopyInResponse"} + } + + columnFormatCodes := make([]uint16, columnCount) + for i := 0; i < columnCount; i++ { + columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2)) + } + + *dst = CopyInResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes} + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CopyInResponse) Encode(dst []byte) []byte { + dst = append(dst, 'G') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.OverallFormat) + dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes))) + for _, fc := range src.ColumnFormatCodes { + dst = pgio.AppendUint16(dst, fc) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CopyInResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ColumnFormatCodes []uint16 + }{ + Type: "CopyInResponse", + ColumnFormatCodes: src.ColumnFormatCodes, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *CopyInResponse) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + OverallFormat string + ColumnFormatCodes []uint16 + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + if len(msg.OverallFormat) != 1 { + return errors.New("invalid length for CopyInResponse.OverallFormat") + } + + dst.OverallFormat = msg.OverallFormat[0] + dst.ColumnFormatCodes = msg.ColumnFormatCodes + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go new file mode 100644 index 00000000000..3175c6a40c1 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/copy_out_response.go @@ -0,0 +1,96 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type CopyOutResponse struct { + OverallFormat byte + ColumnFormatCodes []uint16 +} + +func (*CopyOutResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *CopyOutResponse) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + if buf.Len() < 3 { + return &invalidMessageFormatErr{messageType: "CopyOutResponse"} + } + + overallFormat := buf.Next(1)[0] + + columnCount := int(binary.BigEndian.Uint16(buf.Next(2))) + if buf.Len() != columnCount*2 { + return &invalidMessageFormatErr{messageType: "CopyOutResponse"} + } + + columnFormatCodes := make([]uint16, columnCount) + for i := 0; i < columnCount; i++ { + columnFormatCodes[i] = binary.BigEndian.Uint16(buf.Next(2)) + } + + *dst = CopyOutResponse{OverallFormat: overallFormat, ColumnFormatCodes: columnFormatCodes} + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *CopyOutResponse) Encode(dst []byte) []byte { + dst = append(dst, 'H') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.OverallFormat) + + dst = pgio.AppendUint16(dst, uint16(len(src.ColumnFormatCodes))) + for _, fc := range src.ColumnFormatCodes { + dst = pgio.AppendUint16(dst, fc) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src CopyOutResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ColumnFormatCodes []uint16 + }{ + Type: "CopyOutResponse", + ColumnFormatCodes: src.ColumnFormatCodes, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *CopyOutResponse) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + OverallFormat string + ColumnFormatCodes []uint16 + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + if len(msg.OverallFormat) != 1 { + return errors.New("invalid length for CopyOutResponse.OverallFormat") + } + + dst.OverallFormat = msg.OverallFormat[0] + dst.ColumnFormatCodes = msg.ColumnFormatCodes + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go b/vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go new file mode 100644 index 00000000000..4de77977217 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/data_row.go @@ -0,0 +1,142 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/hex" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type DataRow struct { + Values [][]byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*DataRow) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *DataRow) Decode(src []byte) error { + if len(src) < 2 { + return &invalidMessageFormatErr{messageType: "DataRow"} + } + rp := 0 + fieldCount := int(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + + // If the capacity of the values slice is too small OR substantially too + // large reallocate. This is too avoid one row with many columns from + // permanently allocating memory. + if cap(dst.Values) < fieldCount || cap(dst.Values)-fieldCount > 32 { + newCap := 32 + if newCap < fieldCount { + newCap = fieldCount + } + dst.Values = make([][]byte, fieldCount, newCap) + } else { + dst.Values = dst.Values[:fieldCount] + } + + for i := 0; i < fieldCount; i++ { + if len(src[rp:]) < 4 { + return &invalidMessageFormatErr{messageType: "DataRow"} + } + + valueLen := int(int32(binary.BigEndian.Uint32(src[rp:]))) + rp += 4 + + // null + if valueLen == -1 { + dst.Values[i] = nil + } else { + if len(src[rp:]) < valueLen || valueLen < 0 { + return &invalidMessageFormatErr{messageType: "DataRow"} + } + + dst.Values[i] = src[rp : rp+valueLen : rp+valueLen] + rp += valueLen + } + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *DataRow) Encode(dst []byte) []byte { + dst = append(dst, 'D') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = pgio.AppendUint16(dst, uint16(len(src.Values))) + for _, v := range src.Values { + if v == nil { + dst = pgio.AppendInt32(dst, -1) + continue + } + + dst = pgio.AppendInt32(dst, int32(len(v))) + dst = append(dst, v...) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src DataRow) MarshalJSON() ([]byte, error) { + formattedValues := make([]map[string]string, len(src.Values)) + for i, v := range src.Values { + if v == nil { + continue + } + + var hasNonPrintable bool + for _, b := range v { + if b < 32 { + hasNonPrintable = true + break + } + } + + if hasNonPrintable { + formattedValues[i] = map[string]string{"binary": hex.EncodeToString(v)} + } else { + formattedValues[i] = map[string]string{"text": string(v)} + } + } + + return json.Marshal(struct { + Type string + Values []map[string]string + }{ + Type: "DataRow", + Values: formattedValues, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *DataRow) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Values []map[string]string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + dst.Values = make([][]byte, len(msg.Values)) + for n, parameter := range msg.Values { + var err error + dst.Values[n], err = getValueFromJSON(parameter) + if err != nil { + return err + } + } + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/describe.go b/vendor/github.com/jackc/pgx/v5/pgproto3/describe.go new file mode 100644 index 00000000000..f131d1f4820 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/describe.go @@ -0,0 +1,88 @@ +package pgproto3 + +import ( + "bytes" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Describe struct { + ObjectType byte // 'S' = prepared statement, 'P' = portal + Name string +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Describe) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Describe) Decode(src []byte) error { + if len(src) < 2 { + return &invalidMessageFormatErr{messageType: "Describe"} + } + + dst.ObjectType = src[0] + rp := 1 + + idx := bytes.IndexByte(src[rp:], 0) + if idx != len(src[rp:])-1 { + return &invalidMessageFormatErr{messageType: "Describe"} + } + + dst.Name = string(src[rp : len(src)-1]) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Describe) Encode(dst []byte) []byte { + dst = append(dst, 'D') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.ObjectType) + dst = append(dst, src.Name...) + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Describe) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ObjectType string + Name string + }{ + Type: "Describe", + ObjectType: string(src.ObjectType), + Name: src.Name, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *Describe) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + ObjectType string + Name string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + if len(msg.ObjectType) != 1 { + return errors.New("invalid length for Describe.ObjectType") + } + + dst.ObjectType = byte(msg.ObjectType[0]) + dst.Name = msg.Name + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/doc.go b/vendor/github.com/jackc/pgx/v5/pgproto3/doc.go new file mode 100644 index 00000000000..e0e1cf87211 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/doc.go @@ -0,0 +1,11 @@ +// Package pgproto3 is a encoder and decoder of the PostgreSQL wire protocol version 3. +// +// The primary interfaces are Frontend and Backend. They correspond to a client and server respectively. Messages are +// sent with Send (or a specialized Send variant). Messages are automatically bufferred to minimize small writes. Call +// Flush to ensure a message has actually been sent. +// +// The Trace method of Frontend and Backend can be used to examine the wire-level message traffic. It outputs in a +// similar format to the PQtrace function in libpq. +// +// See https://www.postgresql.org/docs/current/protocol-message-formats.html for meanings of the different messages. +package pgproto3 diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go new file mode 100644 index 00000000000..2b85e744bc5 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/empty_query_response.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type EmptyQueryResponse struct{} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*EmptyQueryResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *EmptyQueryResponse) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "EmptyQueryResponse", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *EmptyQueryResponse) Encode(dst []byte) []byte { + return append(dst, 'I', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src EmptyQueryResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "EmptyQueryResponse", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go new file mode 100644 index 00000000000..45c9a9810f2 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/error_response.go @@ -0,0 +1,333 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "strconv" +) + +type ErrorResponse struct { + Severity string + SeverityUnlocalized string // only in 9.6 and greater + Code string + Message string + Detail string + Hint string + Position int32 + InternalPosition int32 + InternalQuery string + Where string + SchemaName string + TableName string + ColumnName string + DataTypeName string + ConstraintName string + File string + Line int32 + Routine string + + UnknownFields map[byte]string +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*ErrorResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *ErrorResponse) Decode(src []byte) error { + *dst = ErrorResponse{} + + buf := bytes.NewBuffer(src) + + for { + k, err := buf.ReadByte() + if err != nil { + return err + } + if k == 0 { + break + } + + vb, err := buf.ReadBytes(0) + if err != nil { + return err + } + v := string(vb[:len(vb)-1]) + + switch k { + case 'S': + dst.Severity = v + case 'V': + dst.SeverityUnlocalized = v + case 'C': + dst.Code = v + case 'M': + dst.Message = v + case 'D': + dst.Detail = v + case 'H': + dst.Hint = v + case 'P': + s := v + n, _ := strconv.ParseInt(s, 10, 32) + dst.Position = int32(n) + case 'p': + s := v + n, _ := strconv.ParseInt(s, 10, 32) + dst.InternalPosition = int32(n) + case 'q': + dst.InternalQuery = v + case 'W': + dst.Where = v + case 's': + dst.SchemaName = v + case 't': + dst.TableName = v + case 'c': + dst.ColumnName = v + case 'd': + dst.DataTypeName = v + case 'n': + dst.ConstraintName = v + case 'F': + dst.File = v + case 'L': + s := v + n, _ := strconv.ParseInt(s, 10, 32) + dst.Line = int32(n) + case 'R': + dst.Routine = v + + default: + if dst.UnknownFields == nil { + dst.UnknownFields = make(map[byte]string) + } + dst.UnknownFields[k] = v + } + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *ErrorResponse) Encode(dst []byte) []byte { + return append(dst, src.marshalBinary('E')...) +} + +func (src *ErrorResponse) marshalBinary(typeByte byte) []byte { + var bigEndian BigEndianBuf + buf := &bytes.Buffer{} + + buf.WriteByte(typeByte) + buf.Write(bigEndian.Uint32(0)) + + if src.Severity != "" { + buf.WriteByte('S') + buf.WriteString(src.Severity) + buf.WriteByte(0) + } + if src.SeverityUnlocalized != "" { + buf.WriteByte('V') + buf.WriteString(src.SeverityUnlocalized) + buf.WriteByte(0) + } + if src.Code != "" { + buf.WriteByte('C') + buf.WriteString(src.Code) + buf.WriteByte(0) + } + if src.Message != "" { + buf.WriteByte('M') + buf.WriteString(src.Message) + buf.WriteByte(0) + } + if src.Detail != "" { + buf.WriteByte('D') + buf.WriteString(src.Detail) + buf.WriteByte(0) + } + if src.Hint != "" { + buf.WriteByte('H') + buf.WriteString(src.Hint) + buf.WriteByte(0) + } + if src.Position != 0 { + buf.WriteByte('P') + buf.WriteString(strconv.Itoa(int(src.Position))) + buf.WriteByte(0) + } + if src.InternalPosition != 0 { + buf.WriteByte('p') + buf.WriteString(strconv.Itoa(int(src.InternalPosition))) + buf.WriteByte(0) + } + if src.InternalQuery != "" { + buf.WriteByte('q') + buf.WriteString(src.InternalQuery) + buf.WriteByte(0) + } + if src.Where != "" { + buf.WriteByte('W') + buf.WriteString(src.Where) + buf.WriteByte(0) + } + if src.SchemaName != "" { + buf.WriteByte('s') + buf.WriteString(src.SchemaName) + buf.WriteByte(0) + } + if src.TableName != "" { + buf.WriteByte('t') + buf.WriteString(src.TableName) + buf.WriteByte(0) + } + if src.ColumnName != "" { + buf.WriteByte('c') + buf.WriteString(src.ColumnName) + buf.WriteByte(0) + } + if src.DataTypeName != "" { + buf.WriteByte('d') + buf.WriteString(src.DataTypeName) + buf.WriteByte(0) + } + if src.ConstraintName != "" { + buf.WriteByte('n') + buf.WriteString(src.ConstraintName) + buf.WriteByte(0) + } + if src.File != "" { + buf.WriteByte('F') + buf.WriteString(src.File) + buf.WriteByte(0) + } + if src.Line != 0 { + buf.WriteByte('L') + buf.WriteString(strconv.Itoa(int(src.Line))) + buf.WriteByte(0) + } + if src.Routine != "" { + buf.WriteByte('R') + buf.WriteString(src.Routine) + buf.WriteByte(0) + } + + for k, v := range src.UnknownFields { + buf.WriteByte(k) + buf.WriteString(v) + buf.WriteByte(0) + } + + buf.WriteByte(0) + + binary.BigEndian.PutUint32(buf.Bytes()[1:5], uint32(buf.Len()-1)) + + return buf.Bytes() +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src ErrorResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Severity string + SeverityUnlocalized string // only in 9.6 and greater + Code string + Message string + Detail string + Hint string + Position int32 + InternalPosition int32 + InternalQuery string + Where string + SchemaName string + TableName string + ColumnName string + DataTypeName string + ConstraintName string + File string + Line int32 + Routine string + + UnknownFields map[byte]string + }{ + Type: "ErrorResponse", + Severity: src.Severity, + SeverityUnlocalized: src.SeverityUnlocalized, + Code: src.Code, + Message: src.Message, + Detail: src.Detail, + Hint: src.Hint, + Position: src.Position, + InternalPosition: src.InternalPosition, + InternalQuery: src.InternalQuery, + Where: src.Where, + SchemaName: src.SchemaName, + TableName: src.TableName, + ColumnName: src.ColumnName, + DataTypeName: src.DataTypeName, + ConstraintName: src.ConstraintName, + File: src.File, + Line: src.Line, + Routine: src.Routine, + UnknownFields: src.UnknownFields, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *ErrorResponse) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Type string + Severity string + SeverityUnlocalized string // only in 9.6 and greater + Code string + Message string + Detail string + Hint string + Position int32 + InternalPosition int32 + InternalQuery string + Where string + SchemaName string + TableName string + ColumnName string + DataTypeName string + ConstraintName string + File string + Line int32 + Routine string + + UnknownFields map[byte]string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + + dst.Severity = msg.Severity + dst.SeverityUnlocalized = msg.SeverityUnlocalized + dst.Code = msg.Code + dst.Message = msg.Message + dst.Detail = msg.Detail + dst.Hint = msg.Hint + dst.Position = msg.Position + dst.InternalPosition = msg.InternalPosition + dst.InternalQuery = msg.InternalQuery + dst.Where = msg.Where + dst.SchemaName = msg.SchemaName + dst.TableName = msg.TableName + dst.ColumnName = msg.ColumnName + dst.DataTypeName = msg.DataTypeName + dst.ConstraintName = msg.ConstraintName + dst.File = msg.File + dst.Line = msg.Line + dst.Routine = msg.Routine + + dst.UnknownFields = msg.UnknownFields + + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/execute.go b/vendor/github.com/jackc/pgx/v5/pgproto3/execute.go new file mode 100644 index 00000000000..a5fee7cb910 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/execute.go @@ -0,0 +1,65 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Execute struct { + Portal string + MaxRows uint32 +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Execute) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Execute) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + b, err := buf.ReadBytes(0) + if err != nil { + return err + } + dst.Portal = string(b[:len(b)-1]) + + if buf.Len() < 4 { + return &invalidMessageFormatErr{messageType: "Execute"} + } + dst.MaxRows = binary.BigEndian.Uint32(buf.Next(4)) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Execute) Encode(dst []byte) []byte { + dst = append(dst, 'E') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.Portal...) + dst = append(dst, 0) + + dst = pgio.AppendUint32(dst, src.MaxRows) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Execute) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Portal string + MaxRows uint32 + }{ + Type: "Execute", + Portal: src.Portal, + MaxRows: src.MaxRows, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/flush.go b/vendor/github.com/jackc/pgx/v5/pgproto3/flush.go new file mode 100644 index 00000000000..2725f68942c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/flush.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type Flush struct{} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Flush) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Flush) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "Flush", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Flush) Encode(dst []byte) []byte { + return append(dst, 'H', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Flush) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "Flush", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go b/vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go new file mode 100644 index 00000000000..83dea963839 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/frontend.go @@ -0,0 +1,363 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "io" +) + +// Frontend acts as a client for the PostgreSQL wire protocol version 3. +type Frontend struct { + cr *chunkReader + w io.Writer + + // tracer is used to trace messages when Send or Receive is called. This means an outbound message is traced + // before it is actually transmitted (i.e. before Flush). It is safe to change this variable when the Frontend is + // idle. Setting and unsetting tracer provides equivalent functionality to PQtrace and PQuntrace in libpq. + tracer *tracer + + wbuf []byte + + // Backend message flyweights + authenticationOk AuthenticationOk + authenticationCleartextPassword AuthenticationCleartextPassword + authenticationMD5Password AuthenticationMD5Password + authenticationGSS AuthenticationGSS + authenticationGSSContinue AuthenticationGSSContinue + authenticationSASL AuthenticationSASL + authenticationSASLContinue AuthenticationSASLContinue + authenticationSASLFinal AuthenticationSASLFinal + backendKeyData BackendKeyData + bindComplete BindComplete + closeComplete CloseComplete + commandComplete CommandComplete + copyBothResponse CopyBothResponse + copyData CopyData + copyInResponse CopyInResponse + copyOutResponse CopyOutResponse + copyDone CopyDone + dataRow DataRow + emptyQueryResponse EmptyQueryResponse + errorResponse ErrorResponse + functionCallResponse FunctionCallResponse + noData NoData + noticeResponse NoticeResponse + notificationResponse NotificationResponse + parameterDescription ParameterDescription + parameterStatus ParameterStatus + parseComplete ParseComplete + readyForQuery ReadyForQuery + rowDescription RowDescription + portalSuspended PortalSuspended + + bodyLen int + msgType byte + partialMsg bool + authType uint32 +} + +// NewFrontend creates a new Frontend. +func NewFrontend(r io.Reader, w io.Writer) *Frontend { + cr := newChunkReader(r, 0) + return &Frontend{cr: cr, w: w} +} + +// Send sends a message to the backend (i.e. the server). The message is not guaranteed to be written until Flush is +// called. +// +// Send can work with any FrontendMessage. Some commonly used message types such as Bind have specialized send methods +// such as SendBind. These methods should be preferred when the type of message is known up front (e.g. when building an +// extended query protocol query) as they may be faster due to knowing the type of msg rather than it being hidden +// behind an interface. +func (f *Frontend) Send(msg FrontendMessage) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.traceMessage('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// Flush writes any pending messages to the backend (i.e. the server). +func (f *Frontend) Flush() error { + if len(f.wbuf) == 0 { + return nil + } + + n, err := f.w.Write(f.wbuf) + + const maxLen = 1024 + if len(f.wbuf) > maxLen { + f.wbuf = make([]byte, 0, maxLen) + } else { + f.wbuf = f.wbuf[:0] + } + + if err != nil { + return &writeError{err: err, safeToRetry: n == 0} + } + + return nil +} + +// Trace starts tracing the message traffic to w. It writes in a similar format to that produced by the libpq function +// PQtrace. +func (f *Frontend) Trace(w io.Writer, options TracerOptions) { + f.tracer = &tracer{ + w: w, + buf: &bytes.Buffer{}, + TracerOptions: options, + } +} + +// Untrace stops tracing. +func (f *Frontend) Untrace() { + f.tracer = nil +} + +// SendBind sends a Bind message to the backend (i.e. the server). The message is not guaranteed to be written until +// Flush is called. +func (f *Frontend) SendBind(msg *Bind) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.traceBind('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// SendParse sends a Parse message to the backend (i.e. the server). The message is not guaranteed to be written until +// Flush is called. +func (f *Frontend) SendParse(msg *Parse) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.traceParse('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// SendClose sends a Close message to the backend (i.e. the server). The message is not guaranteed to be written until +// Flush is called. +func (f *Frontend) SendClose(msg *Close) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.traceClose('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// SendDescribe sends a Describe message to the backend (i.e. the server). The message is not guaranteed to be written until +// Flush is called. +func (f *Frontend) SendDescribe(msg *Describe) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.traceDescribe('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// SendExecute sends a Execute message to the backend (i.e. the server). The message is not guaranteed to be written until +// Flush is called. +func (f *Frontend) SendExecute(msg *Execute) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.TraceQueryute('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// SendSync sends a Sync message to the backend (i.e. the server). The message is not guaranteed to be written until +// Flush is called. +func (f *Frontend) SendSync(msg *Sync) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.traceSync('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// SendQuery sends a Query message to the backend (i.e. the server). The message is not guaranteed to be written until +// Flush is called. +func (f *Frontend) SendQuery(msg *Query) { + prevLen := len(f.wbuf) + f.wbuf = msg.Encode(f.wbuf) + if f.tracer != nil { + f.tracer.traceQuery('F', int32(len(f.wbuf)-prevLen), msg) + } +} + +// SendUnbufferedEncodedCopyData immediately sends an encoded CopyData message to the backend (i.e. the server). This method +// is more efficient than sending a CopyData message with Send as the message data is not copied to the internal buffer +// before being written out. The internal buffer is flushed before the message is sent. +func (f *Frontend) SendUnbufferedEncodedCopyData(msg []byte) error { + err := f.Flush() + if err != nil { + return err + } + + n, err := f.w.Write(msg) + if err != nil { + return &writeError{err: err, safeToRetry: n == 0} + } + + if f.tracer != nil { + f.tracer.traceCopyData('F', int32(len(msg)-1), &CopyData{}) + } + + return nil +} + +func translateEOFtoErrUnexpectedEOF(err error) error { + if err == io.EOF { + return io.ErrUnexpectedEOF + } + return err +} + +// Receive receives a message from the backend. The returned message is only valid until the next call to Receive. +func (f *Frontend) Receive() (BackendMessage, error) { + if !f.partialMsg { + header, err := f.cr.Next(5) + if err != nil { + return nil, translateEOFtoErrUnexpectedEOF(err) + } + + f.msgType = header[0] + + msgLength := int(binary.BigEndian.Uint32(header[1:])) + if msgLength < 4 { + return nil, fmt.Errorf("invalid message length: %d", msgLength) + } + + f.bodyLen = msgLength - 4 + f.partialMsg = true + } + + msgBody, err := f.cr.Next(f.bodyLen) + if err != nil { + return nil, translateEOFtoErrUnexpectedEOF(err) + } + + f.partialMsg = false + + var msg BackendMessage + switch f.msgType { + case '1': + msg = &f.parseComplete + case '2': + msg = &f.bindComplete + case '3': + msg = &f.closeComplete + case 'A': + msg = &f.notificationResponse + case 'c': + msg = &f.copyDone + case 'C': + msg = &f.commandComplete + case 'd': + msg = &f.copyData + case 'D': + msg = &f.dataRow + case 'E': + msg = &f.errorResponse + case 'G': + msg = &f.copyInResponse + case 'H': + msg = &f.copyOutResponse + case 'I': + msg = &f.emptyQueryResponse + case 'K': + msg = &f.backendKeyData + case 'n': + msg = &f.noData + case 'N': + msg = &f.noticeResponse + case 'R': + var err error + msg, err = f.findAuthenticationMessageType(msgBody) + if err != nil { + return nil, err + } + case 's': + msg = &f.portalSuspended + case 'S': + msg = &f.parameterStatus + case 't': + msg = &f.parameterDescription + case 'T': + msg = &f.rowDescription + case 'V': + msg = &f.functionCallResponse + case 'W': + msg = &f.copyBothResponse + case 'Z': + msg = &f.readyForQuery + default: + return nil, fmt.Errorf("unknown message type: %c", f.msgType) + } + + err = msg.Decode(msgBody) + if err != nil { + return nil, err + } + + if f.tracer != nil { + f.tracer.traceMessage('B', int32(5+len(msgBody)), msg) + } + + return msg, nil +} + +// Authentication message type constants. +// See src/include/libpq/pqcomm.h for all +// constants. +const ( + AuthTypeOk = 0 + AuthTypeCleartextPassword = 3 + AuthTypeMD5Password = 5 + AuthTypeSCMCreds = 6 + AuthTypeGSS = 7 + AuthTypeGSSCont = 8 + AuthTypeSSPI = 9 + AuthTypeSASL = 10 + AuthTypeSASLContinue = 11 + AuthTypeSASLFinal = 12 +) + +func (f *Frontend) findAuthenticationMessageType(src []byte) (BackendMessage, error) { + if len(src) < 4 { + return nil, errors.New("authentication message too short") + } + f.authType = binary.BigEndian.Uint32(src[:4]) + + switch f.authType { + case AuthTypeOk: + return &f.authenticationOk, nil + case AuthTypeCleartextPassword: + return &f.authenticationCleartextPassword, nil + case AuthTypeMD5Password: + return &f.authenticationMD5Password, nil + case AuthTypeSCMCreds: + return nil, errors.New("AuthTypeSCMCreds is unimplemented") + case AuthTypeGSS: + return &f.authenticationGSS, nil + case AuthTypeGSSCont: + return &f.authenticationGSSContinue, nil + case AuthTypeSSPI: + return nil, errors.New("AuthTypeSSPI is unimplemented") + case AuthTypeSASL: + return &f.authenticationSASL, nil + case AuthTypeSASLContinue: + return &f.authenticationSASLContinue, nil + case AuthTypeSASLFinal: + return &f.authenticationSASLFinal, nil + default: + return nil, fmt.Errorf("unknown authentication type: %d", f.authType) + } +} + +// GetAuthType returns the authType used in the current state of the frontend. +// See SetAuthType for more information. +func (f *Frontend) GetAuthType() uint32 { + return f.authType +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go new file mode 100644 index 00000000000..2c4f38dfd54 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call.go @@ -0,0 +1,95 @@ +package pgproto3 + +import ( + "encoding/binary" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type FunctionCall struct { + Function uint32 + ArgFormatCodes []uint16 + Arguments [][]byte + ResultFormatCode uint16 +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*FunctionCall) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *FunctionCall) Decode(src []byte) error { + *dst = FunctionCall{} + rp := 0 + // Specifies the object ID of the function to call. + dst.Function = binary.BigEndian.Uint32(src[rp:]) + rp += 4 + // The number of argument format codes that follow (denoted C below). + // This can be zero to indicate that there are no arguments or that the arguments all use the default format (text); + // or one, in which case the specified format code is applied to all arguments; + // or it can equal the actual number of arguments. + nArgumentCodes := int(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + argumentCodes := make([]uint16, nArgumentCodes) + for i := 0; i < nArgumentCodes; i++ { + // The argument format codes. Each must presently be zero (text) or one (binary). + ac := binary.BigEndian.Uint16(src[rp:]) + if ac != 0 && ac != 1 { + return &invalidMessageFormatErr{messageType: "FunctionCall"} + } + argumentCodes[i] = ac + rp += 2 + } + dst.ArgFormatCodes = argumentCodes + + // Specifies the number of arguments being supplied to the function. + nArguments := int(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + arguments := make([][]byte, nArguments) + for i := 0; i < nArguments; i++ { + // The length of the argument value, in bytes (this count does not include itself). Can be zero. + // As a special case, -1 indicates a NULL argument value. No value bytes follow in the NULL case. + argumentLength := int(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + if argumentLength == -1 { + arguments[i] = nil + } else { + // The value of the argument, in the format indicated by the associated format code. n is the above length. + argumentValue := src[rp : rp+argumentLength] + rp += argumentLength + arguments[i] = argumentValue + } + } + dst.Arguments = arguments + // The format code for the function result. Must presently be zero (text) or one (binary). + resultFormatCode := binary.BigEndian.Uint16(src[rp:]) + if resultFormatCode != 0 && resultFormatCode != 1 { + return &invalidMessageFormatErr{messageType: "FunctionCall"} + } + dst.ResultFormatCode = resultFormatCode + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *FunctionCall) Encode(dst []byte) []byte { + dst = append(dst, 'F') + sp := len(dst) + dst = pgio.AppendUint32(dst, 0) // Unknown length, set it at the end + dst = pgio.AppendUint32(dst, src.Function) + dst = pgio.AppendUint16(dst, uint16(len(src.ArgFormatCodes))) + for _, argFormatCode := range src.ArgFormatCodes { + dst = pgio.AppendUint16(dst, argFormatCode) + } + dst = pgio.AppendUint16(dst, uint16(len(src.Arguments))) + for _, argument := range src.Arguments { + if argument == nil { + dst = pgio.AppendInt32(dst, -1) + } else { + dst = pgio.AppendInt32(dst, int32(len(argument))) + dst = append(dst, argument...) + } + } + dst = pgio.AppendUint16(dst, src.ResultFormatCode) + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + return dst +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go new file mode 100644 index 00000000000..3d3606ddb31 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/function_call_response.go @@ -0,0 +1,101 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/hex" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type FunctionCallResponse struct { + Result []byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*FunctionCallResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *FunctionCallResponse) Decode(src []byte) error { + if len(src) < 4 { + return &invalidMessageFormatErr{messageType: "FunctionCallResponse"} + } + rp := 0 + resultSize := int(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + + if resultSize == -1 { + dst.Result = nil + return nil + } + + if len(src[rp:]) != resultSize { + return &invalidMessageFormatErr{messageType: "FunctionCallResponse"} + } + + dst.Result = src[rp:] + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *FunctionCallResponse) Encode(dst []byte) []byte { + dst = append(dst, 'V') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + if src.Result == nil { + dst = pgio.AppendInt32(dst, -1) + } else { + dst = pgio.AppendInt32(dst, int32(len(src.Result))) + dst = append(dst, src.Result...) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src FunctionCallResponse) MarshalJSON() ([]byte, error) { + var formattedValue map[string]string + var hasNonPrintable bool + for _, b := range src.Result { + if b < 32 { + hasNonPrintable = true + break + } + } + + if hasNonPrintable { + formattedValue = map[string]string{"binary": hex.EncodeToString(src.Result)} + } else { + formattedValue = map[string]string{"text": string(src.Result)} + } + + return json.Marshal(struct { + Type string + Result map[string]string + }{ + Type: "FunctionCallResponse", + Result: formattedValue, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *FunctionCallResponse) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + Result map[string]string + } + err := json.Unmarshal(data, &msg) + if err != nil { + return err + } + dst.Result, err = getValueFromJSON(msg.Result) + return err +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go new file mode 100644 index 00000000000..30ffc08d275 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_enc_request.go @@ -0,0 +1,49 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const gssEncReqNumber = 80877104 + +type GSSEncRequest struct { +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*GSSEncRequest) Frontend() {} + +func (dst *GSSEncRequest) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("gss encoding request too short") + } + + requestCode := binary.BigEndian.Uint32(src) + + if requestCode != gssEncReqNumber { + return errors.New("bad gss encoding request code") + } + + return nil +} + +// Encode encodes src into dst. dst will include the 4 byte message length. +func (src *GSSEncRequest) Encode(dst []byte) []byte { + dst = pgio.AppendInt32(dst, 8) + dst = pgio.AppendInt32(dst, gssEncReqNumber) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src GSSEncRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ProtocolVersion uint32 + Parameters map[string]string + }{ + Type: "GSSEncRequest", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go new file mode 100644 index 00000000000..64bfbd049a1 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/gss_response.go @@ -0,0 +1,49 @@ +package pgproto3 + +import ( + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type GSSResponse struct { + Data []byte +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (g *GSSResponse) Frontend() {} + +func (g *GSSResponse) Decode(data []byte) error { + g.Data = data + return nil +} + +func (g *GSSResponse) Encode(dst []byte) []byte { + dst = append(dst, 'p') + dst = pgio.AppendInt32(dst, int32(4+len(g.Data))) + dst = append(dst, g.Data...) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (g *GSSResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Data []byte + }{ + Type: "GSSResponse", + Data: g.Data, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (g *GSSResponse) UnmarshalJSON(data []byte) error { + var msg struct { + Data []byte + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + g.Data = msg.Data + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go b/vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go new file mode 100644 index 00000000000..d8f85d38a78 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/no_data.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type NoData struct{} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*NoData) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *NoData) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "NoData", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *NoData) Encode(dst []byte) []byte { + return append(dst, 'n', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src NoData) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "NoData", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go new file mode 100644 index 00000000000..4ac28a7911a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/notice_response.go @@ -0,0 +1,17 @@ +package pgproto3 + +type NoticeResponse ErrorResponse + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*NoticeResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *NoticeResponse) Decode(src []byte) error { + return (*ErrorResponse)(dst).Decode(src) +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *NoticeResponse) Encode(dst []byte) []byte { + return append(dst, (*ErrorResponse)(src).marshalBinary('N')...) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go new file mode 100644 index 00000000000..228e0dac396 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/notification_response.go @@ -0,0 +1,77 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type NotificationResponse struct { + PID uint32 + Channel string + Payload string +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*NotificationResponse) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *NotificationResponse) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + if buf.Len() < 4 { + return &invalidMessageFormatErr{messageType: "NotificationResponse", details: "too short"} + } + + pid := binary.BigEndian.Uint32(buf.Next(4)) + + b, err := buf.ReadBytes(0) + if err != nil { + return err + } + channel := string(b[:len(b)-1]) + + b, err = buf.ReadBytes(0) + if err != nil { + return err + } + payload := string(b[:len(b)-1]) + + *dst = NotificationResponse{PID: pid, Channel: channel, Payload: payload} + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *NotificationResponse) Encode(dst []byte) []byte { + dst = append(dst, 'A') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = pgio.AppendUint32(dst, src.PID) + dst = append(dst, src.Channel...) + dst = append(dst, 0) + dst = append(dst, src.Payload...) + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src NotificationResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + PID uint32 + Channel string + Payload string + }{ + Type: "NotificationResponse", + PID: src.PID, + Channel: src.Channel, + Payload: src.Payload, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go new file mode 100644 index 00000000000..374d38a399a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_description.go @@ -0,0 +1,66 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type ParameterDescription struct { + ParameterOIDs []uint32 +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*ParameterDescription) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *ParameterDescription) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + if buf.Len() < 2 { + return &invalidMessageFormatErr{messageType: "ParameterDescription"} + } + + // Reported parameter count will be incorrect when number of args is greater than uint16 + buf.Next(2) + // Instead infer parameter count by remaining size of message + parameterCount := buf.Len() / 4 + + *dst = ParameterDescription{ParameterOIDs: make([]uint32, parameterCount)} + + for i := 0; i < parameterCount; i++ { + dst.ParameterOIDs[i] = binary.BigEndian.Uint32(buf.Next(4)) + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *ParameterDescription) Encode(dst []byte) []byte { + dst = append(dst, 't') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs))) + for _, oid := range src.ParameterOIDs { + dst = pgio.AppendUint32(dst, oid) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src ParameterDescription) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ParameterOIDs []uint32 + }{ + Type: "ParameterDescription", + ParameterOIDs: src.ParameterOIDs, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go new file mode 100644 index 00000000000..a303e453642 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parameter_status.go @@ -0,0 +1,66 @@ +package pgproto3 + +import ( + "bytes" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type ParameterStatus struct { + Name string + Value string +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*ParameterStatus) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *ParameterStatus) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + b, err := buf.ReadBytes(0) + if err != nil { + return err + } + name := string(b[:len(b)-1]) + + b, err = buf.ReadBytes(0) + if err != nil { + return err + } + value := string(b[:len(b)-1]) + + *dst = ParameterStatus{Name: name, Value: value} + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *ParameterStatus) Encode(dst []byte) []byte { + dst = append(dst, 'S') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.Name...) + dst = append(dst, 0) + dst = append(dst, src.Value...) + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (ps ParameterStatus) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Name string + Value string + }{ + Type: "ParameterStatus", + Name: ps.Name, + Value: ps.Value, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parse.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parse.go new file mode 100644 index 00000000000..b53200dca85 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parse.go @@ -0,0 +1,88 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Parse struct { + Name string + Query string + ParameterOIDs []uint32 +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Parse) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Parse) Decode(src []byte) error { + *dst = Parse{} + + buf := bytes.NewBuffer(src) + + b, err := buf.ReadBytes(0) + if err != nil { + return err + } + dst.Name = string(b[:len(b)-1]) + + b, err = buf.ReadBytes(0) + if err != nil { + return err + } + dst.Query = string(b[:len(b)-1]) + + if buf.Len() < 2 { + return &invalidMessageFormatErr{messageType: "Parse"} + } + parameterOIDCount := int(binary.BigEndian.Uint16(buf.Next(2))) + + for i := 0; i < parameterOIDCount; i++ { + if buf.Len() < 4 { + return &invalidMessageFormatErr{messageType: "Parse"} + } + dst.ParameterOIDs = append(dst.ParameterOIDs, binary.BigEndian.Uint32(buf.Next(4))) + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Parse) Encode(dst []byte) []byte { + dst = append(dst, 'P') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, src.Name...) + dst = append(dst, 0) + dst = append(dst, src.Query...) + dst = append(dst, 0) + + dst = pgio.AppendUint16(dst, uint16(len(src.ParameterOIDs))) + for _, oid := range src.ParameterOIDs { + dst = pgio.AppendUint32(dst, oid) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Parse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Name string + Query string + ParameterOIDs []uint32 + }{ + Type: "Parse", + Name: src.Name, + Query: src.Query, + ParameterOIDs: src.ParameterOIDs, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go b/vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go new file mode 100644 index 00000000000..92c9498b6d4 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/parse_complete.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type ParseComplete struct{} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*ParseComplete) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *ParseComplete) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "ParseComplete", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *ParseComplete) Encode(dst []byte) []byte { + return append(dst, '1', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src ParseComplete) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "ParseComplete", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go b/vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go new file mode 100644 index 00000000000..41f98692be9 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/password_message.go @@ -0,0 +1,54 @@ +package pgproto3 + +import ( + "bytes" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type PasswordMessage struct { + Password string +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*PasswordMessage) Frontend() {} + +// Frontend identifies this message as an authentication response. +func (*PasswordMessage) InitialResponse() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *PasswordMessage) Decode(src []byte) error { + buf := bytes.NewBuffer(src) + + b, err := buf.ReadBytes(0) + if err != nil { + return err + } + dst.Password = string(b[:len(b)-1]) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *PasswordMessage) Encode(dst []byte) []byte { + dst = append(dst, 'p') + dst = pgio.AppendInt32(dst, int32(4+len(src.Password)+1)) + + dst = append(dst, src.Password...) + dst = append(dst, 0) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src PasswordMessage) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Password string + }{ + Type: "PasswordMessage", + Password: src.Password, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go b/vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go new file mode 100644 index 00000000000..ef5a54896be --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/pgproto3.go @@ -0,0 +1,85 @@ +package pgproto3 + +import ( + "encoding/hex" + "errors" + "fmt" +) + +// Message is the interface implemented by an object that can decode and encode +// a particular PostgreSQL message. +type Message interface { + // Decode is allowed and expected to retain a reference to data after + // returning (unlike encoding.BinaryUnmarshaler). + Decode(data []byte) error + + // Encode appends itself to dst and returns the new buffer. + Encode(dst []byte) []byte +} + +// FrontendMessage is a message sent by the frontend (i.e. the client). +type FrontendMessage interface { + Message + Frontend() // no-op method to distinguish frontend from backend methods +} + +// BackendMessage is a message sent by the backend (i.e. the server). +type BackendMessage interface { + Message + Backend() // no-op method to distinguish frontend from backend methods +} + +type AuthenticationResponseMessage interface { + BackendMessage + AuthenticationResponse() // no-op method to distinguish authentication responses +} + +type invalidMessageLenErr struct { + messageType string + expectedLen int + actualLen int +} + +func (e *invalidMessageLenErr) Error() string { + return fmt.Sprintf("%s body must have length of %d, but it is %d", e.messageType, e.expectedLen, e.actualLen) +} + +type invalidMessageFormatErr struct { + messageType string + details string +} + +func (e *invalidMessageFormatErr) Error() string { + return fmt.Sprintf("%s body is invalid %s", e.messageType, e.details) +} + +type writeError struct { + err error + safeToRetry bool +} + +func (e *writeError) Error() string { + return fmt.Sprintf("write failed: %s", e.err.Error()) +} + +func (e *writeError) SafeToRetry() bool { + return e.safeToRetry +} + +func (e *writeError) Unwrap() error { + return e.err +} + +// getValueFromJSON gets the value from a protocol message representation in JSON. +func getValueFromJSON(v map[string]string) ([]byte, error) { + if v == nil { + return nil, nil + } + if text, ok := v["text"]; ok { + return []byte(text), nil + } + if binary, ok := v["binary"]; ok { + return hex.DecodeString(binary) + } + return nil, errors.New("unknown protocol representation") +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go b/vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go new file mode 100644 index 00000000000..1a9e7bfb1a6 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/portal_suspended.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type PortalSuspended struct{} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*PortalSuspended) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *PortalSuspended) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "PortalSuspended", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *PortalSuspended) Encode(dst []byte) []byte { + return append(dst, 's', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src PortalSuspended) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "PortalSuspended", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/query.go b/vendor/github.com/jackc/pgx/v5/pgproto3/query.go new file mode 100644 index 00000000000..e963a0ecea4 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/query.go @@ -0,0 +1,50 @@ +package pgproto3 + +import ( + "bytes" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Query struct { + String string +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Query) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Query) Decode(src []byte) error { + i := bytes.IndexByte(src, 0) + if i != len(src)-1 { + return &invalidMessageFormatErr{messageType: "Query"} + } + + dst.String = string(src[:i]) + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Query) Encode(dst []byte) []byte { + dst = append(dst, 'Q') + dst = pgio.AppendInt32(dst, int32(4+len(src.String)+1)) + + dst = append(dst, src.String...) + dst = append(dst, 0) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Query) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + String string + }{ + Type: "Query", + String: src.String, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go b/vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go new file mode 100644 index 00000000000..67a39be3954 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/ready_for_query.go @@ -0,0 +1,61 @@ +package pgproto3 + +import ( + "encoding/json" + "errors" +) + +type ReadyForQuery struct { + TxStatus byte +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*ReadyForQuery) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *ReadyForQuery) Decode(src []byte) error { + if len(src) != 1 { + return &invalidMessageLenErr{messageType: "ReadyForQuery", expectedLen: 1, actualLen: len(src)} + } + + dst.TxStatus = src[0] + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *ReadyForQuery) Encode(dst []byte) []byte { + return append(dst, 'Z', 0, 0, 0, 5, src.TxStatus) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src ReadyForQuery) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + TxStatus string + }{ + Type: "ReadyForQuery", + TxStatus: string(src.TxStatus), + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *ReadyForQuery) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + TxStatus string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + if len(msg.TxStatus) != 1 { + return errors.New("invalid length for ReadyForQuery.TxStatus") + } + dst.TxStatus = msg.TxStatus[0] + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go b/vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go new file mode 100644 index 00000000000..6f6f06817df --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/row_description.go @@ -0,0 +1,165 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const ( + TextFormat = 0 + BinaryFormat = 1 +) + +type FieldDescription struct { + Name []byte + TableOID uint32 + TableAttributeNumber uint16 + DataTypeOID uint32 + DataTypeSize int16 + TypeModifier int32 + Format int16 +} + +// MarshalJSON implements encoding/json.Marshaler. +func (fd FieldDescription) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Name string + TableOID uint32 + TableAttributeNumber uint16 + DataTypeOID uint32 + DataTypeSize int16 + TypeModifier int32 + Format int16 + }{ + Name: string(fd.Name), + TableOID: fd.TableOID, + TableAttributeNumber: fd.TableAttributeNumber, + DataTypeOID: fd.DataTypeOID, + DataTypeSize: fd.DataTypeSize, + TypeModifier: fd.TypeModifier, + Format: fd.Format, + }) +} + +type RowDescription struct { + Fields []FieldDescription +} + +// Backend identifies this message as sendable by the PostgreSQL backend. +func (*RowDescription) Backend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *RowDescription) Decode(src []byte) error { + + if len(src) < 2 { + return &invalidMessageFormatErr{messageType: "RowDescription"} + } + fieldCount := int(binary.BigEndian.Uint16(src)) + rp := 2 + + dst.Fields = dst.Fields[0:0] + + for i := 0; i < fieldCount; i++ { + var fd FieldDescription + + idx := bytes.IndexByte(src[rp:], 0) + if idx < 0 { + return &invalidMessageFormatErr{messageType: "RowDescription"} + } + fd.Name = src[rp : rp+idx] + rp += idx + 1 + + // Since buf.Next() doesn't return an error if we hit the end of the buffer + // check Len ahead of time + if len(src[rp:]) < 18 { + return &invalidMessageFormatErr{messageType: "RowDescription"} + } + + fd.TableOID = binary.BigEndian.Uint32(src[rp:]) + rp += 4 + fd.TableAttributeNumber = binary.BigEndian.Uint16(src[rp:]) + rp += 2 + fd.DataTypeOID = binary.BigEndian.Uint32(src[rp:]) + rp += 4 + fd.DataTypeSize = int16(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + fd.TypeModifier = int32(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + fd.Format = int16(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + + dst.Fields = append(dst.Fields, fd) + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *RowDescription) Encode(dst []byte) []byte { + dst = append(dst, 'T') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = pgio.AppendUint16(dst, uint16(len(src.Fields))) + for _, fd := range src.Fields { + dst = append(dst, fd.Name...) + dst = append(dst, 0) + + dst = pgio.AppendUint32(dst, fd.TableOID) + dst = pgio.AppendUint16(dst, fd.TableAttributeNumber) + dst = pgio.AppendUint32(dst, fd.DataTypeOID) + dst = pgio.AppendInt16(dst, fd.DataTypeSize) + dst = pgio.AppendInt32(dst, fd.TypeModifier) + dst = pgio.AppendInt16(dst, fd.Format) + } + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src RowDescription) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Fields []FieldDescription + }{ + Type: "RowDescription", + Fields: src.Fields, + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *RowDescription) UnmarshalJSON(data []byte) error { + var msg struct { + Fields []struct { + Name string + TableOID uint32 + TableAttributeNumber uint16 + DataTypeOID uint32 + DataTypeSize int16 + TypeModifier int32 + Format int16 + } + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + dst.Fields = make([]FieldDescription, len(msg.Fields)) + for n, field := range msg.Fields { + dst.Fields[n] = FieldDescription{ + Name: []byte(field.Name), + TableOID: field.TableOID, + TableAttributeNumber: field.TableAttributeNumber, + DataTypeOID: field.DataTypeOID, + DataTypeSize: field.DataTypeSize, + TypeModifier: field.TypeModifier, + Format: field.Format, + } + } + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go new file mode 100644 index 00000000000..eeda4691ab2 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_initial_response.go @@ -0,0 +1,94 @@ +package pgproto3 + +import ( + "bytes" + "encoding/hex" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type SASLInitialResponse struct { + AuthMechanism string + Data []byte +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*SASLInitialResponse) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *SASLInitialResponse) Decode(src []byte) error { + *dst = SASLInitialResponse{} + + rp := 0 + + idx := bytes.IndexByte(src, 0) + if idx < 0 { + return errors.New("invalid SASLInitialResponse") + } + + dst.AuthMechanism = string(src[rp:idx]) + rp = idx + 1 + + rp += 4 // The rest of the message is data so we can just skip the size + dst.Data = src[rp:] + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *SASLInitialResponse) Encode(dst []byte) []byte { + dst = append(dst, 'p') + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = append(dst, []byte(src.AuthMechanism)...) + dst = append(dst, 0) + + dst = pgio.AppendInt32(dst, int32(len(src.Data))) + dst = append(dst, src.Data...) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src SASLInitialResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + AuthMechanism string + Data string + }{ + Type: "SASLInitialResponse", + AuthMechanism: src.AuthMechanism, + Data: string(src.Data), + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *SASLInitialResponse) UnmarshalJSON(data []byte) error { + // Ignore null, like in the main JSON package. + if string(data) == "null" { + return nil + } + + var msg struct { + AuthMechanism string + Data string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + dst.AuthMechanism = msg.AuthMechanism + if msg.Data != "" { + decoded, err := hex.DecodeString(msg.Data) + if err != nil { + return err + } + dst.Data = decoded + } + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go new file mode 100644 index 00000000000..54c3d96f326 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/sasl_response.go @@ -0,0 +1,61 @@ +package pgproto3 + +import ( + "encoding/hex" + "encoding/json" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type SASLResponse struct { + Data []byte +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*SASLResponse) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *SASLResponse) Decode(src []byte) error { + *dst = SASLResponse{Data: src} + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *SASLResponse) Encode(dst []byte) []byte { + dst = append(dst, 'p') + dst = pgio.AppendInt32(dst, int32(4+len(src.Data))) + + dst = append(dst, src.Data...) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src SASLResponse) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + Data string + }{ + Type: "SASLResponse", + Data: string(src.Data), + }) +} + +// UnmarshalJSON implements encoding/json.Unmarshaler. +func (dst *SASLResponse) UnmarshalJSON(data []byte) error { + var msg struct { + Data string + } + if err := json.Unmarshal(data, &msg); err != nil { + return err + } + if msg.Data != "" { + decoded, err := hex.DecodeString(msg.Data) + if err != nil { + return err + } + dst.Data = decoded + } + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go b/vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go new file mode 100644 index 00000000000..1b00c16b393 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/ssl_request.go @@ -0,0 +1,49 @@ +package pgproto3 + +import ( + "encoding/binary" + "encoding/json" + "errors" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const sslRequestNumber = 80877103 + +type SSLRequest struct { +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*SSLRequest) Frontend() {} + +func (dst *SSLRequest) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("ssl request too short") + } + + requestCode := binary.BigEndian.Uint32(src) + + if requestCode != sslRequestNumber { + return errors.New("bad ssl request code") + } + + return nil +} + +// Encode encodes src into dst. dst will include the 4 byte message length. +func (src *SSLRequest) Encode(dst []byte) []byte { + dst = pgio.AppendInt32(dst, 8) + dst = pgio.AppendInt32(dst, sslRequestNumber) + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src SSLRequest) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ProtocolVersion uint32 + Parameters map[string]string + }{ + Type: "SSLRequest", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go b/vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go new file mode 100644 index 00000000000..5c974f02abb --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/startup_message.go @@ -0,0 +1,96 @@ +package pgproto3 + +import ( + "bytes" + "encoding/binary" + "encoding/json" + "errors" + "fmt" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const ProtocolVersionNumber = 196608 // 3.0 + +type StartupMessage struct { + ProtocolVersion uint32 + Parameters map[string]string +} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*StartupMessage) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *StartupMessage) Decode(src []byte) error { + if len(src) < 4 { + return errors.New("startup message too short") + } + + dst.ProtocolVersion = binary.BigEndian.Uint32(src) + rp := 4 + + if dst.ProtocolVersion != ProtocolVersionNumber { + return fmt.Errorf("Bad startup message version number. Expected %d, got %d", ProtocolVersionNumber, dst.ProtocolVersion) + } + + dst.Parameters = make(map[string]string) + for { + idx := bytes.IndexByte(src[rp:], 0) + if idx < 0 { + return &invalidMessageFormatErr{messageType: "StartupMesage"} + } + key := string(src[rp : rp+idx]) + rp += idx + 1 + + idx = bytes.IndexByte(src[rp:], 0) + if idx < 0 { + return &invalidMessageFormatErr{messageType: "StartupMesage"} + } + value := string(src[rp : rp+idx]) + rp += idx + 1 + + dst.Parameters[key] = value + + if len(src[rp:]) == 1 { + if src[rp] != 0 { + return fmt.Errorf("Bad startup message last byte. Expected 0, got %d", src[rp]) + } + break + } + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *StartupMessage) Encode(dst []byte) []byte { + sp := len(dst) + dst = pgio.AppendInt32(dst, -1) + + dst = pgio.AppendUint32(dst, src.ProtocolVersion) + for k, v := range src.Parameters { + dst = append(dst, k...) + dst = append(dst, 0) + dst = append(dst, v...) + dst = append(dst, 0) + } + dst = append(dst, 0) + + pgio.SetInt32(dst[sp:], int32(len(dst[sp:]))) + + return dst +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src StartupMessage) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + ProtocolVersion uint32 + Parameters map[string]string + }{ + Type: "StartupMessage", + ProtocolVersion: src.ProtocolVersion, + Parameters: src.Parameters, + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/sync.go b/vendor/github.com/jackc/pgx/v5/pgproto3/sync.go new file mode 100644 index 00000000000..5db8e07ac18 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/sync.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type Sync struct{} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Sync) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Sync) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "Sync", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Sync) Encode(dst []byte) []byte { + return append(dst, 'S', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Sync) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "Sync", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go b/vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go new file mode 100644 index 00000000000..135191eaee3 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/terminate.go @@ -0,0 +1,34 @@ +package pgproto3 + +import ( + "encoding/json" +) + +type Terminate struct{} + +// Frontend identifies this message as sendable by a PostgreSQL frontend. +func (*Terminate) Frontend() {} + +// Decode decodes src into dst. src must contain the complete message with the exception of the initial 1 byte message +// type identifier and 4 byte message length. +func (dst *Terminate) Decode(src []byte) error { + if len(src) != 0 { + return &invalidMessageLenErr{messageType: "Terminate", expectedLen: 0, actualLen: len(src)} + } + + return nil +} + +// Encode encodes src into dst. dst will include the 1 byte message type identifier and the 4 byte message length. +func (src *Terminate) Encode(dst []byte) []byte { + return append(dst, 'X', 0, 0, 0, 4) +} + +// MarshalJSON implements encoding/json.Marshaler. +func (src Terminate) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + Type string + }{ + Type: "Terminate", + }) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgproto3/trace.go b/vendor/github.com/jackc/pgx/v5/pgproto3/trace.go new file mode 100644 index 00000000000..c09f68d1a67 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgproto3/trace.go @@ -0,0 +1,440 @@ +package pgproto3 + +import ( + "bytes" + "fmt" + "io" + "strconv" + "strings" + "time" +) + +// tracer traces the messages send to and from a Backend or Frontend. The format it produces roughly mimics the +// format produced by the libpq C function PQtrace. +type tracer struct { + w io.Writer + buf *bytes.Buffer + TracerOptions +} + +// TracerOptions controls tracing behavior. It is roughly equivalent to the libpq function PQsetTraceFlags. +type TracerOptions struct { + // SuppressTimestamps prevents printing of timestamps. + SuppressTimestamps bool + + // RegressMode redacts fields that may be vary between executions. + RegressMode bool +} + +func (t *tracer) traceMessage(sender byte, encodedLen int32, msg Message) { + switch msg := msg.(type) { + case *AuthenticationCleartextPassword: + t.traceAuthenticationCleartextPassword(sender, encodedLen, msg) + case *AuthenticationGSS: + t.traceAuthenticationGSS(sender, encodedLen, msg) + case *AuthenticationGSSContinue: + t.traceAuthenticationGSSContinue(sender, encodedLen, msg) + case *AuthenticationMD5Password: + t.traceAuthenticationMD5Password(sender, encodedLen, msg) + case *AuthenticationOk: + t.traceAuthenticationOk(sender, encodedLen, msg) + case *AuthenticationSASL: + t.traceAuthenticationSASL(sender, encodedLen, msg) + case *AuthenticationSASLContinue: + t.traceAuthenticationSASLContinue(sender, encodedLen, msg) + case *AuthenticationSASLFinal: + t.traceAuthenticationSASLFinal(sender, encodedLen, msg) + case *BackendKeyData: + t.traceBackendKeyData(sender, encodedLen, msg) + case *Bind: + t.traceBind(sender, encodedLen, msg) + case *BindComplete: + t.traceBindComplete(sender, encodedLen, msg) + case *CancelRequest: + t.traceCancelRequest(sender, encodedLen, msg) + case *Close: + t.traceClose(sender, encodedLen, msg) + case *CloseComplete: + t.traceCloseComplete(sender, encodedLen, msg) + case *CommandComplete: + t.traceCommandComplete(sender, encodedLen, msg) + case *CopyBothResponse: + t.traceCopyBothResponse(sender, encodedLen, msg) + case *CopyData: + t.traceCopyData(sender, encodedLen, msg) + case *CopyDone: + t.traceCopyDone(sender, encodedLen, msg) + case *CopyFail: + t.traceCopyFail(sender, encodedLen, msg) + case *CopyInResponse: + t.traceCopyInResponse(sender, encodedLen, msg) + case *CopyOutResponse: + t.traceCopyOutResponse(sender, encodedLen, msg) + case *DataRow: + t.traceDataRow(sender, encodedLen, msg) + case *Describe: + t.traceDescribe(sender, encodedLen, msg) + case *EmptyQueryResponse: + t.traceEmptyQueryResponse(sender, encodedLen, msg) + case *ErrorResponse: + t.traceErrorResponse(sender, encodedLen, msg) + case *Execute: + t.TraceQueryute(sender, encodedLen, msg) + case *Flush: + t.traceFlush(sender, encodedLen, msg) + case *FunctionCall: + t.traceFunctionCall(sender, encodedLen, msg) + case *FunctionCallResponse: + t.traceFunctionCallResponse(sender, encodedLen, msg) + case *GSSEncRequest: + t.traceGSSEncRequest(sender, encodedLen, msg) + case *NoData: + t.traceNoData(sender, encodedLen, msg) + case *NoticeResponse: + t.traceNoticeResponse(sender, encodedLen, msg) + case *NotificationResponse: + t.traceNotificationResponse(sender, encodedLen, msg) + case *ParameterDescription: + t.traceParameterDescription(sender, encodedLen, msg) + case *ParameterStatus: + t.traceParameterStatus(sender, encodedLen, msg) + case *Parse: + t.traceParse(sender, encodedLen, msg) + case *ParseComplete: + t.traceParseComplete(sender, encodedLen, msg) + case *PortalSuspended: + t.tracePortalSuspended(sender, encodedLen, msg) + case *Query: + t.traceQuery(sender, encodedLen, msg) + case *ReadyForQuery: + t.traceReadyForQuery(sender, encodedLen, msg) + case *RowDescription: + t.traceRowDescription(sender, encodedLen, msg) + case *SSLRequest: + t.traceSSLRequest(sender, encodedLen, msg) + case *StartupMessage: + t.traceStartupMessage(sender, encodedLen, msg) + case *Sync: + t.traceSync(sender, encodedLen, msg) + case *Terminate: + t.traceTerminate(sender, encodedLen, msg) + default: + t.beginTrace(sender, encodedLen, "Unknown") + t.finishTrace() + } +} + +func (t *tracer) traceAuthenticationCleartextPassword(sender byte, encodedLen int32, msg *AuthenticationCleartextPassword) { + t.beginTrace(sender, encodedLen, "AuthenticationCleartextPassword") + t.finishTrace() +} + +func (t *tracer) traceAuthenticationGSS(sender byte, encodedLen int32, msg *AuthenticationGSS) { + t.beginTrace(sender, encodedLen, "AuthenticationGSS") + t.finishTrace() +} + +func (t *tracer) traceAuthenticationGSSContinue(sender byte, encodedLen int32, msg *AuthenticationGSSContinue) { + t.beginTrace(sender, encodedLen, "AuthenticationGSSContinue") + t.finishTrace() +} + +func (t *tracer) traceAuthenticationMD5Password(sender byte, encodedLen int32, msg *AuthenticationMD5Password) { + t.beginTrace(sender, encodedLen, "AuthenticationMD5Password") + t.finishTrace() +} + +func (t *tracer) traceAuthenticationOk(sender byte, encodedLen int32, msg *AuthenticationOk) { + t.beginTrace(sender, encodedLen, "AuthenticationOk") + t.finishTrace() +} + +func (t *tracer) traceAuthenticationSASL(sender byte, encodedLen int32, msg *AuthenticationSASL) { + t.beginTrace(sender, encodedLen, "AuthenticationSASL") + t.finishTrace() +} + +func (t *tracer) traceAuthenticationSASLContinue(sender byte, encodedLen int32, msg *AuthenticationSASLContinue) { + t.beginTrace(sender, encodedLen, "AuthenticationSASLContinue") + t.finishTrace() +} + +func (t *tracer) traceAuthenticationSASLFinal(sender byte, encodedLen int32, msg *AuthenticationSASLFinal) { + t.beginTrace(sender, encodedLen, "AuthenticationSASLFinal") + t.finishTrace() +} + +func (t *tracer) traceBackendKeyData(sender byte, encodedLen int32, msg *BackendKeyData) { + t.beginTrace(sender, encodedLen, "BackendKeyData") + if t.RegressMode { + t.buf.WriteString("\t NNNN NNNN") + } else { + fmt.Fprintf(t.buf, "\t %d %d", msg.ProcessID, msg.SecretKey) + } + t.finishTrace() +} + +func (t *tracer) traceBind(sender byte, encodedLen int32, msg *Bind) { + t.beginTrace(sender, encodedLen, "Bind") + fmt.Fprintf(t.buf, "\t %s %s %d", traceDoubleQuotedString([]byte(msg.DestinationPortal)), traceDoubleQuotedString([]byte(msg.PreparedStatement)), len(msg.ParameterFormatCodes)) + for _, fc := range msg.ParameterFormatCodes { + fmt.Fprintf(t.buf, " %d", fc) + } + fmt.Fprintf(t.buf, " %d", len(msg.Parameters)) + for _, p := range msg.Parameters { + fmt.Fprintf(t.buf, " %s", traceSingleQuotedString(p)) + } + fmt.Fprintf(t.buf, " %d", len(msg.ResultFormatCodes)) + for _, fc := range msg.ResultFormatCodes { + fmt.Fprintf(t.buf, " %d", fc) + } + t.finishTrace() +} + +func (t *tracer) traceBindComplete(sender byte, encodedLen int32, msg *BindComplete) { + t.beginTrace(sender, encodedLen, "BindComplete") + t.finishTrace() +} + +func (t *tracer) traceCancelRequest(sender byte, encodedLen int32, msg *CancelRequest) { + t.beginTrace(sender, encodedLen, "CancelRequest") + t.finishTrace() +} + +func (t *tracer) traceClose(sender byte, encodedLen int32, msg *Close) { + t.beginTrace(sender, encodedLen, "Close") + t.finishTrace() +} + +func (t *tracer) traceCloseComplete(sender byte, encodedLen int32, msg *CloseComplete) { + t.beginTrace(sender, encodedLen, "CloseComplete") + t.finishTrace() +} + +func (t *tracer) traceCommandComplete(sender byte, encodedLen int32, msg *CommandComplete) { + t.beginTrace(sender, encodedLen, "CommandComplete") + fmt.Fprintf(t.buf, "\t %s", traceDoubleQuotedString(msg.CommandTag)) + t.finishTrace() +} + +func (t *tracer) traceCopyBothResponse(sender byte, encodedLen int32, msg *CopyBothResponse) { + t.beginTrace(sender, encodedLen, "CopyBothResponse") + t.finishTrace() +} + +func (t *tracer) traceCopyData(sender byte, encodedLen int32, msg *CopyData) { + t.beginTrace(sender, encodedLen, "CopyData") + t.finishTrace() +} + +func (t *tracer) traceCopyDone(sender byte, encodedLen int32, msg *CopyDone) { + t.beginTrace(sender, encodedLen, "CopyDone") + t.finishTrace() +} + +func (t *tracer) traceCopyFail(sender byte, encodedLen int32, msg *CopyFail) { + t.beginTrace(sender, encodedLen, "CopyFail") + fmt.Fprintf(t.buf, "\t %s", traceDoubleQuotedString([]byte(msg.Message))) + t.finishTrace() +} + +func (t *tracer) traceCopyInResponse(sender byte, encodedLen int32, msg *CopyInResponse) { + t.beginTrace(sender, encodedLen, "CopyInResponse") + t.finishTrace() +} + +func (t *tracer) traceCopyOutResponse(sender byte, encodedLen int32, msg *CopyOutResponse) { + t.beginTrace(sender, encodedLen, "CopyOutResponse") + t.finishTrace() +} + +func (t *tracer) traceDataRow(sender byte, encodedLen int32, msg *DataRow) { + t.beginTrace(sender, encodedLen, "DataRow") + fmt.Fprintf(t.buf, "\t %d", len(msg.Values)) + for _, v := range msg.Values { + if v == nil { + t.buf.WriteString(" -1") + } else { + fmt.Fprintf(t.buf, " %d %s", len(v), traceSingleQuotedString(v)) + } + } + t.finishTrace() +} + +func (t *tracer) traceDescribe(sender byte, encodedLen int32, msg *Describe) { + t.beginTrace(sender, encodedLen, "Describe") + fmt.Fprintf(t.buf, "\t %c %s", msg.ObjectType, traceDoubleQuotedString([]byte(msg.Name))) + t.finishTrace() +} + +func (t *tracer) traceEmptyQueryResponse(sender byte, encodedLen int32, msg *EmptyQueryResponse) { + t.beginTrace(sender, encodedLen, "EmptyQueryResponse") + t.finishTrace() +} + +func (t *tracer) traceErrorResponse(sender byte, encodedLen int32, msg *ErrorResponse) { + t.beginTrace(sender, encodedLen, "ErrorResponse") + t.finishTrace() +} + +func (t *tracer) TraceQueryute(sender byte, encodedLen int32, msg *Execute) { + t.beginTrace(sender, encodedLen, "Execute") + fmt.Fprintf(t.buf, "\t %s %d", traceDoubleQuotedString([]byte(msg.Portal)), msg.MaxRows) + t.finishTrace() +} + +func (t *tracer) traceFlush(sender byte, encodedLen int32, msg *Flush) { + t.beginTrace(sender, encodedLen, "Flush") + t.finishTrace() +} + +func (t *tracer) traceFunctionCall(sender byte, encodedLen int32, msg *FunctionCall) { + t.beginTrace(sender, encodedLen, "FunctionCall") + t.finishTrace() +} + +func (t *tracer) traceFunctionCallResponse(sender byte, encodedLen int32, msg *FunctionCallResponse) { + t.beginTrace(sender, encodedLen, "FunctionCallResponse") + t.finishTrace() +} + +func (t *tracer) traceGSSEncRequest(sender byte, encodedLen int32, msg *GSSEncRequest) { + t.beginTrace(sender, encodedLen, "GSSEncRequest") + t.finishTrace() +} + +func (t *tracer) traceNoData(sender byte, encodedLen int32, msg *NoData) { + t.beginTrace(sender, encodedLen, "NoData") + t.finishTrace() +} + +func (t *tracer) traceNoticeResponse(sender byte, encodedLen int32, msg *NoticeResponse) { + t.beginTrace(sender, encodedLen, "NoticeResponse") + t.finishTrace() +} + +func (t *tracer) traceNotificationResponse(sender byte, encodedLen int32, msg *NotificationResponse) { + t.beginTrace(sender, encodedLen, "NotificationResponse") + fmt.Fprintf(t.buf, "\t %d %s %s", msg.PID, traceDoubleQuotedString([]byte(msg.Channel)), traceDoubleQuotedString([]byte(msg.Payload))) + t.finishTrace() +} + +func (t *tracer) traceParameterDescription(sender byte, encodedLen int32, msg *ParameterDescription) { + t.beginTrace(sender, encodedLen, "ParameterDescription") + t.finishTrace() +} + +func (t *tracer) traceParameterStatus(sender byte, encodedLen int32, msg *ParameterStatus) { + t.beginTrace(sender, encodedLen, "ParameterStatus") + fmt.Fprintf(t.buf, "\t %s %s", traceDoubleQuotedString([]byte(msg.Name)), traceDoubleQuotedString([]byte(msg.Value))) + t.finishTrace() +} + +func (t *tracer) traceParse(sender byte, encodedLen int32, msg *Parse) { + t.beginTrace(sender, encodedLen, "Parse") + fmt.Fprintf(t.buf, "\t %s %s %d", traceDoubleQuotedString([]byte(msg.Name)), traceDoubleQuotedString([]byte(msg.Query)), len(msg.ParameterOIDs)) + for _, oid := range msg.ParameterOIDs { + fmt.Fprintf(t.buf, " %d", oid) + } + t.finishTrace() +} + +func (t *tracer) traceParseComplete(sender byte, encodedLen int32, msg *ParseComplete) { + t.beginTrace(sender, encodedLen, "ParseComplete") + t.finishTrace() +} + +func (t *tracer) tracePortalSuspended(sender byte, encodedLen int32, msg *PortalSuspended) { + t.beginTrace(sender, encodedLen, "PortalSuspended") + t.finishTrace() +} + +func (t *tracer) traceQuery(sender byte, encodedLen int32, msg *Query) { + t.beginTrace(sender, encodedLen, "Query") + fmt.Fprintf(t.buf, "\t %s", traceDoubleQuotedString([]byte(msg.String))) + t.finishTrace() +} + +func (t *tracer) traceReadyForQuery(sender byte, encodedLen int32, msg *ReadyForQuery) { + t.beginTrace(sender, encodedLen, "ReadyForQuery") + fmt.Fprintf(t.buf, "\t %c", msg.TxStatus) + t.finishTrace() +} + +func (t *tracer) traceRowDescription(sender byte, encodedLen int32, msg *RowDescription) { + t.beginTrace(sender, encodedLen, "RowDescription") + fmt.Fprintf(t.buf, "\t %d", len(msg.Fields)) + for _, fd := range msg.Fields { + fmt.Fprintf(t.buf, ` %s %d %d %d %d %d %d`, traceDoubleQuotedString(fd.Name), fd.TableOID, fd.TableAttributeNumber, fd.DataTypeOID, fd.DataTypeSize, fd.TypeModifier, fd.Format) + } + t.finishTrace() +} + +func (t *tracer) traceSSLRequest(sender byte, encodedLen int32, msg *SSLRequest) { + t.beginTrace(sender, encodedLen, "SSLRequest") + t.finishTrace() +} + +func (t *tracer) traceStartupMessage(sender byte, encodedLen int32, msg *StartupMessage) { + t.beginTrace(sender, encodedLen, "StartupMessage") + t.finishTrace() +} + +func (t *tracer) traceSync(sender byte, encodedLen int32, msg *Sync) { + t.beginTrace(sender, encodedLen, "Sync") + t.finishTrace() +} + +func (t *tracer) traceTerminate(sender byte, encodedLen int32, msg *Terminate) { + t.beginTrace(sender, encodedLen, "Terminate") + t.finishTrace() +} + +func (t *tracer) beginTrace(sender byte, encodedLen int32, msgType string) { + if !t.SuppressTimestamps { + now := time.Now() + t.buf.WriteString(now.Format("2006-01-02 15:04:05.000000")) + t.buf.WriteByte('\t') + } + + t.buf.WriteByte(sender) + t.buf.WriteByte('\t') + t.buf.WriteString(msgType) + t.buf.WriteByte('\t') + t.buf.WriteString(strconv.FormatInt(int64(encodedLen), 10)) +} + +func (t *tracer) finishTrace() { + t.buf.WriteByte('\n') + t.buf.WriteTo(t.w) + + if t.buf.Cap() > 1024 { + t.buf = &bytes.Buffer{} + } else { + t.buf.Reset() + } +} + +// traceDoubleQuotedString returns t.buf as a double-quoted string without any escaping. It is roughly equivalent to +// pqTraceOutputString in libpq. +func traceDoubleQuotedString(buf []byte) string { + return `"` + string(buf) + `"` +} + +// traceSingleQuotedString returns buf as a single-quoted string with non-printable characters hex-escaped. It is +// roughly equivalent to pqTraceOutputNchar in libpq. +func traceSingleQuotedString(buf []byte) string { + sb := &strings.Builder{} + + sb.WriteByte('\'') + for _, b := range buf { + if b < 32 || b > 126 { + fmt.Fprintf(sb, `\x%x`, b) + } else { + sb.WriteByte(b) + } + } + sb.WriteByte('\'') + + return sb.String() +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/array.go b/vendor/github.com/jackc/pgx/v5/pgtype/array.go new file mode 100644 index 00000000000..0fa4c129b39 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/array.go @@ -0,0 +1,481 @@ +package pgtype + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "reflect" + "strconv" + "strings" + "unicode" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// Information on the internals of PostgreSQL arrays can be found in +// src/include/utils/array.h and src/backend/utils/adt/arrayfuncs.c. Of +// particular interest is the array_send function. + +type arrayHeader struct { + ContainsNull bool + ElementOID uint32 + Dimensions []ArrayDimension +} + +type ArrayDimension struct { + Length int32 + LowerBound int32 +} + +// cardinality returns the number of elements in an array of dimensions size. +func cardinality(dimensions []ArrayDimension) int { + if len(dimensions) == 0 { + return 0 + } + + elementCount := int(dimensions[0].Length) + for _, d := range dimensions[1:] { + elementCount *= int(d.Length) + } + + return elementCount +} + +func (dst *arrayHeader) DecodeBinary(m *Map, src []byte) (int, error) { + if len(src) < 12 { + return 0, fmt.Errorf("array header too short: %d", len(src)) + } + + rp := 0 + + numDims := int(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + + dst.ContainsNull = binary.BigEndian.Uint32(src[rp:]) == 1 + rp += 4 + + dst.ElementOID = binary.BigEndian.Uint32(src[rp:]) + rp += 4 + + dst.Dimensions = make([]ArrayDimension, numDims) + if len(src) < 12+numDims*8 { + return 0, fmt.Errorf("array header too short for %d dimensions: %d", numDims, len(src)) + } + for i := range dst.Dimensions { + dst.Dimensions[i].Length = int32(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + + dst.Dimensions[i].LowerBound = int32(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + } + + return rp, nil +} + +func (src arrayHeader) EncodeBinary(buf []byte) []byte { + buf = pgio.AppendInt32(buf, int32(len(src.Dimensions))) + + var containsNull int32 + if src.ContainsNull { + containsNull = 1 + } + buf = pgio.AppendInt32(buf, containsNull) + + buf = pgio.AppendUint32(buf, src.ElementOID) + + for i := range src.Dimensions { + buf = pgio.AppendInt32(buf, src.Dimensions[i].Length) + buf = pgio.AppendInt32(buf, src.Dimensions[i].LowerBound) + } + + return buf +} + +type untypedTextArray struct { + Elements []string + Quoted []bool + Dimensions []ArrayDimension +} + +func parseUntypedTextArray(src string) (*untypedTextArray, error) { + dst := &untypedTextArray{ + Elements: []string{}, + Quoted: []bool{}, + Dimensions: []ArrayDimension{}, + } + + buf := bytes.NewBufferString(src) + + skipWhitespace(buf) + + r, _, err := buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + var explicitDimensions []ArrayDimension + + // Array has explicit dimensions + if r == '[' { + buf.UnreadRune() + + for { + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + if r == '=' { + break + } else if r != '[' { + return nil, fmt.Errorf("invalid array, expected '[' or '=' got %v", r) + } + + lower, err := arrayParseInteger(buf) + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + if r != ':' { + return nil, fmt.Errorf("invalid array, expected ':' got %v", r) + } + + upper, err := arrayParseInteger(buf) + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + if r != ']' { + return nil, fmt.Errorf("invalid array, expected ']' got %v", r) + } + + explicitDimensions = append(explicitDimensions, ArrayDimension{LowerBound: lower, Length: upper - lower + 1}) + } + + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + } + + if r != '{' { + return nil, fmt.Errorf("invalid array, expected '{': %v", err) + } + + implicitDimensions := []ArrayDimension{{LowerBound: 1, Length: 0}} + + // Consume all initial opening brackets. This provides number of dimensions. + for { + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + if r == '{' { + implicitDimensions[len(implicitDimensions)-1].Length = 1 + implicitDimensions = append(implicitDimensions, ArrayDimension{LowerBound: 1}) + } else { + buf.UnreadRune() + break + } + } + currentDim := len(implicitDimensions) - 1 + counterDim := currentDim + + for { + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + switch r { + case '{': + if currentDim == counterDim { + implicitDimensions[currentDim].Length++ + } + currentDim++ + case ',': + case '}': + currentDim-- + if currentDim < counterDim { + counterDim = currentDim + } + default: + buf.UnreadRune() + value, quoted, err := arrayParseValue(buf) + if err != nil { + return nil, fmt.Errorf("invalid array value: %v", err) + } + if currentDim == counterDim { + implicitDimensions[currentDim].Length++ + } + dst.Quoted = append(dst.Quoted, quoted) + dst.Elements = append(dst.Elements, value) + } + + if currentDim < 0 { + break + } + } + + skipWhitespace(buf) + + if buf.Len() > 0 { + return nil, fmt.Errorf("unexpected trailing data: %v", buf.String()) + } + + if len(dst.Elements) == 0 { + } else if len(explicitDimensions) > 0 { + dst.Dimensions = explicitDimensions + } else { + dst.Dimensions = implicitDimensions + } + + return dst, nil +} + +func skipWhitespace(buf *bytes.Buffer) { + var r rune + var err error + for r, _, _ = buf.ReadRune(); unicode.IsSpace(r); r, _, _ = buf.ReadRune() { + } + + if err != io.EOF { + buf.UnreadRune() + } +} + +func arrayParseValue(buf *bytes.Buffer) (string, bool, error) { + r, _, err := buf.ReadRune() + if err != nil { + return "", false, err + } + if r == '"' { + return arrayParseQuotedValue(buf) + } + buf.UnreadRune() + + s := &bytes.Buffer{} + + for { + r, _, err := buf.ReadRune() + if err != nil { + return "", false, err + } + + switch r { + case ',', '}': + buf.UnreadRune() + return s.String(), false, nil + } + + s.WriteRune(r) + } +} + +func arrayParseQuotedValue(buf *bytes.Buffer) (string, bool, error) { + s := &bytes.Buffer{} + + for { + r, _, err := buf.ReadRune() + if err != nil { + return "", false, err + } + + switch r { + case '\\': + r, _, err = buf.ReadRune() + if err != nil { + return "", false, err + } + case '"': + r, _, err = buf.ReadRune() + if err != nil { + return "", false, err + } + buf.UnreadRune() + return s.String(), true, nil + } + s.WriteRune(r) + } +} + +func arrayParseInteger(buf *bytes.Buffer) (int32, error) { + s := &bytes.Buffer{} + + for { + r, _, err := buf.ReadRune() + if err != nil { + return 0, err + } + + if ('0' <= r && r <= '9') || r == '-' { + s.WriteRune(r) + } else { + buf.UnreadRune() + n, err := strconv.ParseInt(s.String(), 10, 32) + if err != nil { + return 0, err + } + return int32(n), nil + } + } +} + +func encodeTextArrayDimensions(buf []byte, dimensions []ArrayDimension) []byte { + var customDimensions bool + for _, dim := range dimensions { + if dim.LowerBound != 1 { + customDimensions = true + } + } + + if !customDimensions { + return buf + } + + for _, dim := range dimensions { + buf = append(buf, '[') + buf = append(buf, strconv.FormatInt(int64(dim.LowerBound), 10)...) + buf = append(buf, ':') + buf = append(buf, strconv.FormatInt(int64(dim.LowerBound+dim.Length-1), 10)...) + buf = append(buf, ']') + } + + return append(buf, '=') +} + +var quoteArrayReplacer = strings.NewReplacer(`\`, `\\`, `"`, `\"`) + +func quoteArrayElement(src string) string { + return `"` + quoteArrayReplacer.Replace(src) + `"` +} + +func isSpace(ch byte) bool { + // see https://github.com/postgres/postgres/blob/REL_12_STABLE/src/backend/parser/scansup.c#L224 + return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r' || ch == '\f' +} + +func quoteArrayElementIfNeeded(src string) string { + if src == "" || (len(src) == 4 && strings.ToLower(src) == "null") || isSpace(src[0]) || isSpace(src[len(src)-1]) || strings.ContainsAny(src, `{},"\`) { + return quoteArrayElement(src) + } + return src +} + +func findDimensionsFromValue(value reflect.Value, dimensions []ArrayDimension, elementsLength int) ([]ArrayDimension, int, bool) { + switch value.Kind() { + case reflect.Array: + fallthrough + case reflect.Slice: + length := value.Len() + if 0 == elementsLength { + elementsLength = length + } else { + elementsLength *= length + } + dimensions = append(dimensions, ArrayDimension{Length: int32(length), LowerBound: 1}) + for i := 0; i < length; i++ { + if d, l, ok := findDimensionsFromValue(value.Index(i), dimensions, elementsLength); ok { + return d, l, true + } + } + } + return dimensions, elementsLength, true +} + +// Array represents a PostgreSQL array for T. It implements the ArrayGetter and ArraySetter interfaces. It preserves +// PostgreSQL dimensions and custom lower bounds. Use FlatArray if these are not needed. +type Array[T any] struct { + Elements []T + Dims []ArrayDimension + Valid bool +} + +func (a Array[T]) Dimensions() []ArrayDimension { + return a.Dims +} + +func (a Array[T]) Index(i int) any { + return a.Elements[i] +} + +func (a Array[T]) IndexType() any { + var el T + return el +} + +func (a *Array[T]) SetDimensions(dimensions []ArrayDimension) error { + if dimensions == nil { + *a = Array[T]{} + return nil + } + + elementCount := cardinality(dimensions) + *a = Array[T]{ + Elements: make([]T, elementCount), + Dims: dimensions, + Valid: true, + } + + return nil +} + +func (a Array[T]) ScanIndex(i int) any { + return &a.Elements[i] +} + +func (a Array[T]) ScanIndexType() any { + return new(T) +} + +// FlatArray implements the ArrayGetter and ArraySetter interfaces for any slice of T. It ignores PostgreSQL dimensions +// and custom lower bounds. Use Array to preserve these. +type FlatArray[T any] []T + +func (a FlatArray[T]) Dimensions() []ArrayDimension { + if a == nil { + return nil + } + + return []ArrayDimension{{Length: int32(len(a)), LowerBound: 1}} +} + +func (a FlatArray[T]) Index(i int) any { + return a[i] +} + +func (a FlatArray[T]) IndexType() any { + var el T + return el +} + +func (a *FlatArray[T]) SetDimensions(dimensions []ArrayDimension) error { + if dimensions == nil { + *a = nil + return nil + } + + elementCount := cardinality(dimensions) + *a = make(FlatArray[T], elementCount) + return nil +} + +func (a FlatArray[T]) ScanIndex(i int) any { + return &a[i] +} + +func (a FlatArray[T]) ScanIndexType() any { + return new(T) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/array_codec.go b/vendor/github.com/jackc/pgx/v5/pgtype/array_codec.go new file mode 100644 index 00000000000..c1863b32abd --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/array_codec.go @@ -0,0 +1,406 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "reflect" + + "github.com/jackc/pgx/v5/internal/anynil" + "github.com/jackc/pgx/v5/internal/pgio" +) + +// ArrayGetter is a type that can be converted into a PostgreSQL array. +type ArrayGetter interface { + // Dimensions returns the array dimensions. If array is nil then nil is returned. + Dimensions() []ArrayDimension + + // Index returns the element at i. + Index(i int) any + + // IndexType returns a non-nil scan target of the type Index will return. This is used by ArrayCodec.PlanEncode. + IndexType() any +} + +// ArraySetter is a type can be set from a PostgreSQL array. +type ArraySetter interface { + // SetDimensions prepares the value such that ScanIndex can be called for each element. This will remove any existing + // elements. dimensions may be nil to indicate a NULL array. If unable to exactly preserve dimensions SetDimensions + // may return an error or silently flatten the array dimensions. + SetDimensions(dimensions []ArrayDimension) error + + // ScanIndex returns a value usable as a scan target for i. SetDimensions must be called before ScanIndex. + ScanIndex(i int) any + + // ScanIndexType returns a non-nil scan target of the type ScanIndex will return. This is used by + // ArrayCodec.PlanScan. + ScanIndexType() any +} + +// ArrayCodec is a codec for any array type. +type ArrayCodec struct { + ElementType *Type +} + +func (c *ArrayCodec) FormatSupported(format int16) bool { + return c.ElementType.Codec.FormatSupported(format) +} + +func (c *ArrayCodec) PreferredFormat() int16 { + // The binary format should always be preferred for arrays if it is supported. Usually, this will happen automatically + // because most types that support binary prefer it. However, text, json, and jsonb support binary but prefer the text + // format. This is because it is simpler for jsonb and PostgreSQL can be significantly faster using the text format + // for text-like data types than binary. However, arrays appear to always be faster in binary. + // + // https://www.postgresql.org/message-id/CAMovtNoHFod2jMAKQjjxv209PCTJx5Kc66anwWvX0mEiaXwgmA%40mail.gmail.com + if c.ElementType.Codec.FormatSupported(BinaryFormatCode) { + return BinaryFormatCode + } + return TextFormatCode +} + +func (c *ArrayCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + arrayValuer, ok := value.(ArrayGetter) + if !ok { + return nil + } + + elementType := arrayValuer.IndexType() + + elementEncodePlan := m.PlanEncode(c.ElementType.OID, format, elementType) + if elementEncodePlan == nil { + if reflect.TypeOf(elementType) != nil { + return nil + } + } + + switch format { + case BinaryFormatCode: + return &encodePlanArrayCodecBinary{ac: c, m: m, oid: oid} + case TextFormatCode: + return &encodePlanArrayCodecText{ac: c, m: m, oid: oid} + } + + return nil +} + +type encodePlanArrayCodecText struct { + ac *ArrayCodec + m *Map + oid uint32 +} + +func (p *encodePlanArrayCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + array := value.(ArrayGetter) + + dimensions := array.Dimensions() + if dimensions == nil { + return nil, nil + } + + elementCount := cardinality(dimensions) + if elementCount == 0 { + return append(buf, '{', '}'), nil + } + + buf = encodeTextArrayDimensions(buf, dimensions) + + // dimElemCounts is the multiples of elements that each array lies on. For + // example, a single dimension array of length 4 would have a dimElemCounts of + // [4]. A multi-dimensional array of lengths [3,5,2] would have a + // dimElemCounts of [30,10,2]. This is used to simplify when to render a '{' + // or '}'. + dimElemCounts := make([]int, len(dimensions)) + dimElemCounts[len(dimensions)-1] = int(dimensions[len(dimensions)-1].Length) + for i := len(dimensions) - 2; i > -1; i-- { + dimElemCounts[i] = int(dimensions[i].Length) * dimElemCounts[i+1] + } + + var encodePlan EncodePlan + var lastElemType reflect.Type + inElemBuf := make([]byte, 0, 32) + for i := 0; i < elementCount; i++ { + if i > 0 { + buf = append(buf, ',') + } + + for _, dec := range dimElemCounts { + if i%dec == 0 { + buf = append(buf, '{') + } + } + + elem := array.Index(i) + var elemBuf []byte + if elem != nil { + elemType := reflect.TypeOf(elem) + if lastElemType != elemType { + lastElemType = elemType + encodePlan = p.m.PlanEncode(p.ac.ElementType.OID, TextFormatCode, elem) + if encodePlan == nil { + return nil, fmt.Errorf("unable to encode %v", array.Index(i)) + } + } + elemBuf, err = encodePlan.Encode(elem, inElemBuf) + if err != nil { + return nil, err + } + } + + if elemBuf == nil { + buf = append(buf, `NULL`...) + } else { + buf = append(buf, quoteArrayElementIfNeeded(string(elemBuf))...) + } + + for _, dec := range dimElemCounts { + if (i+1)%dec == 0 { + buf = append(buf, '}') + } + } + } + + return buf, nil +} + +type encodePlanArrayCodecBinary struct { + ac *ArrayCodec + m *Map + oid uint32 +} + +func (p *encodePlanArrayCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + array := value.(ArrayGetter) + + dimensions := array.Dimensions() + if dimensions == nil { + return nil, nil + } + + arrayHeader := arrayHeader{ + Dimensions: dimensions, + ElementOID: p.ac.ElementType.OID, + } + + containsNullIndex := len(buf) + 4 + + buf = arrayHeader.EncodeBinary(buf) + + elementCount := cardinality(dimensions) + + var encodePlan EncodePlan + var lastElemType reflect.Type + for i := 0; i < elementCount; i++ { + sp := len(buf) + buf = pgio.AppendInt32(buf, -1) + + elem := array.Index(i) + var elemBuf []byte + if elem != nil { + elemType := reflect.TypeOf(elem) + if lastElemType != elemType { + lastElemType = elemType + encodePlan = p.m.PlanEncode(p.ac.ElementType.OID, BinaryFormatCode, elem) + if encodePlan == nil { + return nil, fmt.Errorf("unable to encode %v", array.Index(i)) + } + } + elemBuf, err = encodePlan.Encode(elem, buf) + if err != nil { + return nil, err + } + } + + if elemBuf == nil { + pgio.SetInt32(buf[containsNullIndex:], 1) + } else { + buf = elemBuf + pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4)) + } + } + + return buf, nil +} + +func (c *ArrayCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + arrayScanner, ok := target.(ArraySetter) + if !ok { + return nil + } + + // target / arrayScanner might be a pointer to a nil. If it is create one so we can call ScanIndexType to plan the + // scan of the elements. + if anynil.Is(target) { + arrayScanner = reflect.New(reflect.TypeOf(target).Elem()).Interface().(ArraySetter) + } + + elementType := arrayScanner.ScanIndexType() + + elementScanPlan := m.PlanScan(c.ElementType.OID, format, elementType) + if _, ok := elementScanPlan.(*scanPlanFail); ok { + return nil + } + + return &scanPlanArrayCodec{ + arrayCodec: c, + m: m, + oid: oid, + formatCode: format, + } +} + +func (c *ArrayCodec) decodeBinary(m *Map, arrayOID uint32, src []byte, array ArraySetter) error { + var arrayHeader arrayHeader + rp, err := arrayHeader.DecodeBinary(m, src) + if err != nil { + return err + } + + err = array.SetDimensions(arrayHeader.Dimensions) + if err != nil { + return err + } + + elementCount := cardinality(arrayHeader.Dimensions) + if elementCount == 0 { + return nil + } + + elementScanPlan := c.ElementType.Codec.PlanScan(m, c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0)) + if elementScanPlan == nil { + elementScanPlan = m.PlanScan(c.ElementType.OID, BinaryFormatCode, array.ScanIndex(0)) + } + + for i := 0; i < elementCount; i++ { + elem := array.ScanIndex(i) + elemLen := int(int32(binary.BigEndian.Uint32(src[rp:]))) + rp += 4 + var elemSrc []byte + if elemLen >= 0 { + elemSrc = src[rp : rp+elemLen] + rp += elemLen + } + err = elementScanPlan.Scan(elemSrc, elem) + if err != nil { + return fmt.Errorf("failed to scan array element %d: %w", i, err) + } + } + + return nil +} + +func (c *ArrayCodec) decodeText(m *Map, arrayOID uint32, src []byte, array ArraySetter) error { + uta, err := parseUntypedTextArray(string(src)) + if err != nil { + return err + } + + err = array.SetDimensions(uta.Dimensions) + if err != nil { + return err + } + + if len(uta.Elements) == 0 { + return nil + } + + elementScanPlan := c.ElementType.Codec.PlanScan(m, c.ElementType.OID, TextFormatCode, array.ScanIndex(0)) + if elementScanPlan == nil { + elementScanPlan = m.PlanScan(c.ElementType.OID, TextFormatCode, array.ScanIndex(0)) + } + + for i, s := range uta.Elements { + elem := array.ScanIndex(i) + var elemSrc []byte + if s != "NULL" || uta.Quoted[i] { + elemSrc = []byte(s) + } + + err = elementScanPlan.Scan(elemSrc, elem) + if err != nil { + return err + } + } + + return nil +} + +type scanPlanArrayCodec struct { + arrayCodec *ArrayCodec + m *Map + oid uint32 + formatCode int16 + elementScanPlan ScanPlan +} + +func (spac *scanPlanArrayCodec) Scan(src []byte, dst any) error { + c := spac.arrayCodec + m := spac.m + oid := spac.oid + formatCode := spac.formatCode + + array := dst.(ArraySetter) + + if src == nil { + return array.SetDimensions(nil) + } + + switch formatCode { + case BinaryFormatCode: + return c.decodeBinary(m, oid, src, array) + case TextFormatCode: + return c.decodeText(m, oid, src, array) + default: + return fmt.Errorf("unknown format code %d", formatCode) + } +} + +func (c *ArrayCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + switch format { + case TextFormatCode: + return string(src), nil + case BinaryFormatCode: + buf := make([]byte, len(src)) + copy(buf, src) + return buf, nil + default: + return nil, fmt.Errorf("unknown format code %d", format) + } +} + +func (c *ArrayCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var slice []any + err := m.PlanScan(oid, format, &slice).Scan(src, &slice) + return slice, err +} + +func isRagged(slice reflect.Value) bool { + if slice.Type().Elem().Kind() != reflect.Slice { + return false + } + + sliceLen := slice.Len() + innerLen := 0 + for i := 0; i < sliceLen; i++ { + if i == 0 { + innerLen = slice.Index(i).Len() + } else { + if slice.Index(i).Len() != innerLen { + return true + } + } + if isRagged(slice.Index(i)) { + return true + } + } + + return false +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/bits.go b/vendor/github.com/jackc/pgx/v5/pgtype/bits.go new file mode 100644 index 00000000000..30558118d7c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/bits.go @@ -0,0 +1,208 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type BitsScanner interface { + ScanBits(v Bits) error +} + +type BitsValuer interface { + BitsValue() (Bits, error) +} + +// Bits represents the PostgreSQL bit and varbit types. +type Bits struct { + Bytes []byte + Len int32 // Number of bits + Valid bool +} + +func (b *Bits) ScanBits(v Bits) error { + *b = v + return nil +} + +func (b Bits) BitsValue() (Bits, error) { + return b, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Bits) Scan(src any) error { + if src == nil { + *dst = Bits{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToBitsScanner{}.Scan([]byte(src), dst) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src Bits) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + buf, err := BitsCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type BitsCodec struct{} + +func (BitsCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (BitsCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (BitsCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(BitsValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanBitsCodecBinary{} + case TextFormatCode: + return encodePlanBitsCodecText{} + } + + return nil +} + +type encodePlanBitsCodecBinary struct{} + +func (encodePlanBitsCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + bits, err := value.(BitsValuer).BitsValue() + if err != nil { + return nil, err + } + + if !bits.Valid { + return nil, nil + } + + buf = pgio.AppendInt32(buf, bits.Len) + return append(buf, bits.Bytes...), nil +} + +type encodePlanBitsCodecText struct{} + +func (encodePlanBitsCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + bits, err := value.(BitsValuer).BitsValue() + if err != nil { + return nil, err + } + + if !bits.Valid { + return nil, nil + } + + for i := int32(0); i < bits.Len; i++ { + byteIdx := i / 8 + bitMask := byte(128 >> byte(i%8)) + char := byte('0') + if bits.Bytes[byteIdx]&bitMask > 0 { + char = '1' + } + buf = append(buf, char) + } + + return buf, nil +} + +func (BitsCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case BitsScanner: + return scanPlanBinaryBitsToBitsScanner{} + } + case TextFormatCode: + switch target.(type) { + case BitsScanner: + return scanPlanTextAnyToBitsScanner{} + } + } + + return nil +} + +func (c BitsCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c BitsCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var box Bits + err := codecScan(c, m, oid, format, src, &box) + if err != nil { + return nil, err + } + return box, nil +} + +type scanPlanBinaryBitsToBitsScanner struct{} + +func (scanPlanBinaryBitsToBitsScanner) Scan(src []byte, dst any) error { + scanner := (dst).(BitsScanner) + + if src == nil { + return scanner.ScanBits(Bits{}) + } + + if len(src) < 4 { + return fmt.Errorf("invalid length for bit/varbit: %v", len(src)) + } + + bitLen := int32(binary.BigEndian.Uint32(src)) + rp := 4 + + return scanner.ScanBits(Bits{Bytes: src[rp:], Len: bitLen, Valid: true}) +} + +type scanPlanTextAnyToBitsScanner struct{} + +func (scanPlanTextAnyToBitsScanner) Scan(src []byte, dst any) error { + scanner := (dst).(BitsScanner) + + if src == nil { + return scanner.ScanBits(Bits{}) + } + + bitLen := len(src) + byteLen := bitLen / 8 + if bitLen%8 > 0 { + byteLen++ + } + buf := make([]byte, byteLen) + + for i, b := range src { + if b == '1' { + byteIdx := i / 8 + bitIdx := uint(i % 8) + buf[byteIdx] = buf[byteIdx] | (128 >> bitIdx) + } + } + + return scanner.ScanBits(Bits{Bytes: buf, Len: int32(bitLen), Valid: true}) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/bool.go b/vendor/github.com/jackc/pgx/v5/pgtype/bool.go new file mode 100644 index 00000000000..71caffa74e1 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/bool.go @@ -0,0 +1,343 @@ +package pgtype + +import ( + "bytes" + "database/sql/driver" + "encoding/json" + "fmt" + "strconv" + "strings" +) + +type BoolScanner interface { + ScanBool(v Bool) error +} + +type BoolValuer interface { + BoolValue() (Bool, error) +} + +type Bool struct { + Bool bool + Valid bool +} + +func (b *Bool) ScanBool(v Bool) error { + *b = v + return nil +} + +func (b Bool) BoolValue() (Bool, error) { + return b, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Bool) Scan(src any) error { + if src == nil { + *dst = Bool{} + return nil + } + + switch src := src.(type) { + case bool: + *dst = Bool{Bool: src, Valid: true} + return nil + case string: + b, err := strconv.ParseBool(src) + if err != nil { + return err + } + *dst = Bool{Bool: b, Valid: true} + return nil + case []byte: + b, err := strconv.ParseBool(string(src)) + if err != nil { + return err + } + *dst = Bool{Bool: b, Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src Bool) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + return src.Bool, nil +} + +func (src Bool) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + + if src.Bool { + return []byte("true"), nil + } else { + return []byte("false"), nil + } +} + +func (dst *Bool) UnmarshalJSON(b []byte) error { + var v *bool + err := json.Unmarshal(b, &v) + if err != nil { + return err + } + + if v == nil { + *dst = Bool{} + } else { + *dst = Bool{Bool: *v, Valid: true} + } + + return nil +} + +type BoolCodec struct{} + +func (BoolCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (BoolCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (BoolCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case bool: + return encodePlanBoolCodecBinaryBool{} + case BoolValuer: + return encodePlanBoolCodecBinaryBoolValuer{} + } + case TextFormatCode: + switch value.(type) { + case bool: + return encodePlanBoolCodecTextBool{} + case BoolValuer: + return encodePlanBoolCodecTextBoolValuer{} + } + } + + return nil +} + +type encodePlanBoolCodecBinaryBool struct{} + +func (encodePlanBoolCodecBinaryBool) Encode(value any, buf []byte) (newBuf []byte, err error) { + v := value.(bool) + + if v { + buf = append(buf, 1) + } else { + buf = append(buf, 0) + } + + return buf, nil +} + +type encodePlanBoolCodecTextBoolValuer struct{} + +func (encodePlanBoolCodecTextBoolValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + b, err := value.(BoolValuer).BoolValue() + if err != nil { + return nil, err + } + + if !b.Valid { + return nil, nil + } + + if b.Bool { + buf = append(buf, 't') + } else { + buf = append(buf, 'f') + } + + return buf, nil +} + +type encodePlanBoolCodecBinaryBoolValuer struct{} + +func (encodePlanBoolCodecBinaryBoolValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + b, err := value.(BoolValuer).BoolValue() + if err != nil { + return nil, err + } + + if !b.Valid { + return nil, nil + } + + if b.Bool { + buf = append(buf, 1) + } else { + buf = append(buf, 0) + } + + return buf, nil +} + +type encodePlanBoolCodecTextBool struct{} + +func (encodePlanBoolCodecTextBool) Encode(value any, buf []byte) (newBuf []byte, err error) { + v := value.(bool) + + if v { + buf = append(buf, 't') + } else { + buf = append(buf, 'f') + } + + return buf, nil +} + +func (BoolCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *bool: + return scanPlanBinaryBoolToBool{} + case BoolScanner: + return scanPlanBinaryBoolToBoolScanner{} + } + case TextFormatCode: + switch target.(type) { + case *bool: + return scanPlanTextAnyToBool{} + case BoolScanner: + return scanPlanTextAnyToBoolScanner{} + } + } + + return nil +} + +func (c BoolCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) +} + +func (c BoolCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var b bool + err := codecScan(c, m, oid, format, src, &b) + if err != nil { + return nil, err + } + return b, nil +} + +type scanPlanBinaryBoolToBool struct{} + +func (scanPlanBinaryBoolToBool) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 1 { + return fmt.Errorf("invalid length for bool: %v", len(src)) + } + + p, ok := (dst).(*bool) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = src[0] == 1 + + return nil +} + +type scanPlanTextAnyToBool struct{} + +func (scanPlanTextAnyToBool) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) == 0 { + return fmt.Errorf("cannot scan empty string into %T", dst) + } + + p, ok := (dst).(*bool) + if !ok { + return ErrScanTargetTypeChanged + } + + v, err := planTextToBool(src) + if err != nil { + return err + } + + *p = v + + return nil +} + +type scanPlanBinaryBoolToBoolScanner struct{} + +func (scanPlanBinaryBoolToBoolScanner) Scan(src []byte, dst any) error { + s, ok := (dst).(BoolScanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanBool(Bool{}) + } + + if len(src) != 1 { + return fmt.Errorf("invalid length for bool: %v", len(src)) + } + + return s.ScanBool(Bool{Bool: src[0] == 1, Valid: true}) +} + +type scanPlanTextAnyToBoolScanner struct{} + +func (scanPlanTextAnyToBoolScanner) Scan(src []byte, dst any) error { + s, ok := (dst).(BoolScanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanBool(Bool{}) + } + + if len(src) == 0 { + return fmt.Errorf("cannot scan empty string into %T", dst) + } + + v, err := planTextToBool(src) + if err != nil { + return err + } + + return s.ScanBool(Bool{Bool: v, Valid: true}) +} + +// https://www.postgresql.org/docs/11/datatype-boolean.html +func planTextToBool(src []byte) (bool, error) { + s := string(bytes.ToLower(bytes.TrimSpace(src))) + + switch { + case strings.HasPrefix("true", s), strings.HasPrefix("yes", s), s == "on", s == "1": + return true, nil + case strings.HasPrefix("false", s), strings.HasPrefix("no", s), strings.HasPrefix("off", s), s == "0": + return false, nil + default: + return false, fmt.Errorf("unknown boolean string representation %q", src) + } +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/box.go b/vendor/github.com/jackc/pgx/v5/pgtype/box.go new file mode 100644 index 00000000000..887d268bc70 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/box.go @@ -0,0 +1,238 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type BoxScanner interface { + ScanBox(v Box) error +} + +type BoxValuer interface { + BoxValue() (Box, error) +} + +type Box struct { + P [2]Vec2 + Valid bool +} + +func (b *Box) ScanBox(v Box) error { + *b = v + return nil +} + +func (b Box) BoxValue() (Box, error) { + return b, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Box) Scan(src any) error { + if src == nil { + *dst = Box{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToBoxScanner{}.Scan([]byte(src), dst) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src Box) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + buf, err := BoxCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type BoxCodec struct{} + +func (BoxCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (BoxCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (BoxCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(BoxValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanBoxCodecBinary{} + case TextFormatCode: + return encodePlanBoxCodecText{} + } + + return nil +} + +type encodePlanBoxCodecBinary struct{} + +func (encodePlanBoxCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + box, err := value.(BoxValuer).BoxValue() + if err != nil { + return nil, err + } + + if !box.Valid { + return nil, nil + } + + buf = pgio.AppendUint64(buf, math.Float64bits(box.P[0].X)) + buf = pgio.AppendUint64(buf, math.Float64bits(box.P[0].Y)) + buf = pgio.AppendUint64(buf, math.Float64bits(box.P[1].X)) + buf = pgio.AppendUint64(buf, math.Float64bits(box.P[1].Y)) + return buf, nil +} + +type encodePlanBoxCodecText struct{} + +func (encodePlanBoxCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + box, err := value.(BoxValuer).BoxValue() + if err != nil { + return nil, err + } + + if !box.Valid { + return nil, nil + } + + buf = append(buf, fmt.Sprintf(`(%s,%s),(%s,%s)`, + strconv.FormatFloat(box.P[0].X, 'f', -1, 64), + strconv.FormatFloat(box.P[0].Y, 'f', -1, 64), + strconv.FormatFloat(box.P[1].X, 'f', -1, 64), + strconv.FormatFloat(box.P[1].Y, 'f', -1, 64), + )...) + return buf, nil +} + +func (BoxCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case BoxScanner: + return scanPlanBinaryBoxToBoxScanner{} + } + case TextFormatCode: + switch target.(type) { + case BoxScanner: + return scanPlanTextAnyToBoxScanner{} + } + } + + return nil +} + +type scanPlanBinaryBoxToBoxScanner struct{} + +func (scanPlanBinaryBoxToBoxScanner) Scan(src []byte, dst any) error { + scanner := (dst).(BoxScanner) + + if src == nil { + return scanner.ScanBox(Box{}) + } + + if len(src) != 32 { + return fmt.Errorf("invalid length for Box: %v", len(src)) + } + + x1 := binary.BigEndian.Uint64(src) + y1 := binary.BigEndian.Uint64(src[8:]) + x2 := binary.BigEndian.Uint64(src[16:]) + y2 := binary.BigEndian.Uint64(src[24:]) + + return scanner.ScanBox(Box{ + P: [2]Vec2{ + {math.Float64frombits(x1), math.Float64frombits(y1)}, + {math.Float64frombits(x2), math.Float64frombits(y2)}, + }, + Valid: true, + }) +} + +type scanPlanTextAnyToBoxScanner struct{} + +func (scanPlanTextAnyToBoxScanner) Scan(src []byte, dst any) error { + scanner := (dst).(BoxScanner) + + if src == nil { + return scanner.ScanBox(Box{}) + } + + if len(src) < 11 { + return fmt.Errorf("invalid length for Box: %v", len(src)) + } + + str := string(src[1:]) + + var end int + end = strings.IndexByte(str, ',') + + x1, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+1:] + end = strings.IndexByte(str, ')') + + y1, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+3:] + end = strings.IndexByte(str, ',') + + x2, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+1 : len(str)-1] + + y2, err := strconv.ParseFloat(str, 64) + if err != nil { + return err + } + + return scanner.ScanBox(Box{P: [2]Vec2{{x1, y1}, {x2, y2}}, Valid: true}) +} + +func (c BoxCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c BoxCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var box Box + err := codecScan(c, m, oid, format, src, &box) + if err != nil { + return nil, err + } + return box, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/builtin_wrappers.go b/vendor/github.com/jackc/pgx/v5/pgtype/builtin_wrappers.go new file mode 100644 index 00000000000..8bf367c17cf --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/builtin_wrappers.go @@ -0,0 +1,952 @@ +package pgtype + +import ( + "errors" + "fmt" + "math" + "math/big" + "net" + "net/netip" + "reflect" + "time" +) + +type int8Wrapper int8 + +func (w int8Wrapper) SkipUnderlyingTypePlan() {} + +func (w *int8Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *int8") + } + + if v.Int64 < math.MinInt8 { + return fmt.Errorf("%d is less than minimum value for int8", v.Int64) + } + if v.Int64 > math.MaxInt8 { + return fmt.Errorf("%d is greater than maximum value for int8", v.Int64) + } + *w = int8Wrapper(v.Int64) + + return nil +} + +func (w int8Wrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type int16Wrapper int16 + +func (w int16Wrapper) SkipUnderlyingTypePlan() {} + +func (w *int16Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *int16") + } + + if v.Int64 < math.MinInt16 { + return fmt.Errorf("%d is less than minimum value for int16", v.Int64) + } + if v.Int64 > math.MaxInt16 { + return fmt.Errorf("%d is greater than maximum value for int16", v.Int64) + } + *w = int16Wrapper(v.Int64) + + return nil +} + +func (w int16Wrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type int32Wrapper int32 + +func (w int32Wrapper) SkipUnderlyingTypePlan() {} + +func (w *int32Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *int32") + } + + if v.Int64 < math.MinInt32 { + return fmt.Errorf("%d is less than minimum value for int32", v.Int64) + } + if v.Int64 > math.MaxInt32 { + return fmt.Errorf("%d is greater than maximum value for int32", v.Int64) + } + *w = int32Wrapper(v.Int64) + + return nil +} + +func (w int32Wrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type int64Wrapper int64 + +func (w int64Wrapper) SkipUnderlyingTypePlan() {} + +func (w *int64Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *int64") + } + + *w = int64Wrapper(v.Int64) + + return nil +} + +func (w int64Wrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type intWrapper int + +func (w intWrapper) SkipUnderlyingTypePlan() {} + +func (w *intWrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *int") + } + + if v.Int64 < math.MinInt { + return fmt.Errorf("%d is less than minimum value for int", v.Int64) + } + if v.Int64 > math.MaxInt { + return fmt.Errorf("%d is greater than maximum value for int", v.Int64) + } + + *w = intWrapper(v.Int64) + + return nil +} + +func (w intWrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type uint8Wrapper uint8 + +func (w uint8Wrapper) SkipUnderlyingTypePlan() {} + +func (w *uint8Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *uint8") + } + + if v.Int64 < 0 { + return fmt.Errorf("%d is less than minimum value for uint8", v.Int64) + } + if v.Int64 > math.MaxUint8 { + return fmt.Errorf("%d is greater than maximum value for uint8", v.Int64) + } + *w = uint8Wrapper(v.Int64) + + return nil +} + +func (w uint8Wrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type uint16Wrapper uint16 + +func (w uint16Wrapper) SkipUnderlyingTypePlan() {} + +func (w *uint16Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *uint16") + } + + if v.Int64 < 0 { + return fmt.Errorf("%d is less than minimum value for uint16", v.Int64) + } + if v.Int64 > math.MaxUint16 { + return fmt.Errorf("%d is greater than maximum value for uint16", v.Int64) + } + *w = uint16Wrapper(v.Int64) + + return nil +} + +func (w uint16Wrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type uint32Wrapper uint32 + +func (w uint32Wrapper) SkipUnderlyingTypePlan() {} + +func (w *uint32Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *uint32") + } + + if v.Int64 < 0 { + return fmt.Errorf("%d is less than minimum value for uint32", v.Int64) + } + if v.Int64 > math.MaxUint32 { + return fmt.Errorf("%d is greater than maximum value for uint32", v.Int64) + } + *w = uint32Wrapper(v.Int64) + + return nil +} + +func (w uint32Wrapper) Int64Value() (Int8, error) { + return Int8{Int64: int64(w), Valid: true}, nil +} + +type uint64Wrapper uint64 + +func (w uint64Wrapper) SkipUnderlyingTypePlan() {} + +func (w *uint64Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *uint64") + } + + if v.Int64 < 0 { + return fmt.Errorf("%d is less than minimum value for uint64", v.Int64) + } + + *w = uint64Wrapper(v.Int64) + + return nil +} + +func (w uint64Wrapper) Int64Value() (Int8, error) { + if uint64(w) > uint64(math.MaxInt64) { + return Int8{}, fmt.Errorf("%d is greater than maximum value for int64", w) + } + + return Int8{Int64: int64(w), Valid: true}, nil +} + +func (w *uint64Wrapper) ScanNumeric(v Numeric) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *uint64") + } + + bi, err := v.toBigInt() + if err != nil { + return fmt.Errorf("cannot scan into *uint64: %v", err) + } + + if !bi.IsUint64() { + return fmt.Errorf("cannot scan %v into *uint64", bi.String()) + } + + *w = uint64Wrapper(bi.Uint64()) + + return nil +} + +func (w uint64Wrapper) NumericValue() (Numeric, error) { + return Numeric{Int: new(big.Int).SetUint64(uint64(w)), Valid: true}, nil +} + +type uintWrapper uint + +func (w uintWrapper) SkipUnderlyingTypePlan() {} + +func (w *uintWrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *uint64") + } + + if v.Int64 < 0 { + return fmt.Errorf("%d is less than minimum value for uint64", v.Int64) + } + + if uint64(v.Int64) > math.MaxUint { + return fmt.Errorf("%d is greater than maximum value for uint", v.Int64) + } + + *w = uintWrapper(v.Int64) + + return nil +} + +func (w uintWrapper) Int64Value() (Int8, error) { + if uint64(w) > uint64(math.MaxInt64) { + return Int8{}, fmt.Errorf("%d is greater than maximum value for int64", w) + } + + return Int8{Int64: int64(w), Valid: true}, nil +} + +func (w *uintWrapper) ScanNumeric(v Numeric) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *uint") + } + + bi, err := v.toBigInt() + if err != nil { + return fmt.Errorf("cannot scan into *uint: %v", err) + } + + if !bi.IsUint64() { + return fmt.Errorf("cannot scan %v into *uint", bi.String()) + } + + ui := bi.Uint64() + + if math.MaxUint < ui { + return fmt.Errorf("cannot scan %v into *uint", ui) + } + + *w = uintWrapper(ui) + + return nil +} + +func (w uintWrapper) NumericValue() (Numeric, error) { + return Numeric{Int: new(big.Int).SetUint64(uint64(w)), Valid: true}, nil +} + +type float32Wrapper float32 + +func (w float32Wrapper) SkipUnderlyingTypePlan() {} + +func (w *float32Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *float32") + } + + *w = float32Wrapper(v.Int64) + + return nil +} + +func (w float32Wrapper) Int64Value() (Int8, error) { + if w > math.MaxInt64 { + return Int8{}, fmt.Errorf("%f is greater than maximum value for int64", w) + } + + return Int8{Int64: int64(w), Valid: true}, nil +} + +func (w *float32Wrapper) ScanFloat64(v Float8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *float32") + } + + *w = float32Wrapper(v.Float64) + + return nil +} + +func (w float32Wrapper) Float64Value() (Float8, error) { + return Float8{Float64: float64(w), Valid: true}, nil +} + +type float64Wrapper float64 + +func (w float64Wrapper) SkipUnderlyingTypePlan() {} + +func (w *float64Wrapper) ScanInt64(v Int8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *float64") + } + + *w = float64Wrapper(v.Int64) + + return nil +} + +func (w float64Wrapper) Int64Value() (Int8, error) { + if w > math.MaxInt64 { + return Int8{}, fmt.Errorf("%f is greater than maximum value for int64", w) + } + + return Int8{Int64: int64(w), Valid: true}, nil +} + +func (w *float64Wrapper) ScanFloat64(v Float8) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *float64") + } + + *w = float64Wrapper(v.Float64) + + return nil +} + +func (w float64Wrapper) Float64Value() (Float8, error) { + return Float8{Float64: float64(w), Valid: true}, nil +} + +type stringWrapper string + +func (w stringWrapper) SkipUnderlyingTypePlan() {} + +func (w *stringWrapper) ScanText(v Text) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *string") + } + + *w = stringWrapper(v.String) + return nil +} + +func (w stringWrapper) TextValue() (Text, error) { + return Text{String: string(w), Valid: true}, nil +} + +type timeWrapper time.Time + +func (w *timeWrapper) ScanDate(v Date) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *time.Time") + } + + switch v.InfinityModifier { + case Finite: + *w = timeWrapper(v.Time) + return nil + case Infinity: + return fmt.Errorf("cannot scan Infinity into *time.Time") + case NegativeInfinity: + return fmt.Errorf("cannot scan -Infinity into *time.Time") + default: + return fmt.Errorf("invalid InfinityModifier: %v", v.InfinityModifier) + } +} + +func (w timeWrapper) DateValue() (Date, error) { + return Date{Time: time.Time(w), Valid: true}, nil +} + +func (w *timeWrapper) ScanTimestamp(v Timestamp) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *time.Time") + } + + switch v.InfinityModifier { + case Finite: + *w = timeWrapper(v.Time) + return nil + case Infinity: + return fmt.Errorf("cannot scan Infinity into *time.Time") + case NegativeInfinity: + return fmt.Errorf("cannot scan -Infinity into *time.Time") + default: + return fmt.Errorf("invalid InfinityModifier: %v", v.InfinityModifier) + } +} + +func (w timeWrapper) TimestampValue() (Timestamp, error) { + return Timestamp{Time: time.Time(w), Valid: true}, nil +} + +func (w *timeWrapper) ScanTimestamptz(v Timestamptz) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *time.Time") + } + + switch v.InfinityModifier { + case Finite: + *w = timeWrapper(v.Time) + return nil + case Infinity: + return fmt.Errorf("cannot scan Infinity into *time.Time") + case NegativeInfinity: + return fmt.Errorf("cannot scan -Infinity into *time.Time") + default: + return fmt.Errorf("invalid InfinityModifier: %v", v.InfinityModifier) + } +} + +func (w timeWrapper) TimestamptzValue() (Timestamptz, error) { + return Timestamptz{Time: time.Time(w), Valid: true}, nil +} + +func (w *timeWrapper) ScanTime(v Time) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *time.Time") + } + + // 24:00:00 is max allowed time in PostgreSQL, but time.Time will normalize that to 00:00:00 the next day. + var maxRepresentableByTime int64 = 24*60*60*1000000 - 1 + if v.Microseconds > maxRepresentableByTime { + return fmt.Errorf("%d microseconds cannot be represented as time.Time", v.Microseconds) + } + + usec := v.Microseconds + hours := usec / microsecondsPerHour + usec -= hours * microsecondsPerHour + minutes := usec / microsecondsPerMinute + usec -= minutes * microsecondsPerMinute + seconds := usec / microsecondsPerSecond + usec -= seconds * microsecondsPerSecond + ns := usec * 1000 + *w = timeWrapper(time.Date(2000, 1, 1, int(hours), int(minutes), int(seconds), int(ns), time.UTC)) + return nil +} + +func (w timeWrapper) TimeValue() (Time, error) { + t := time.Time(w) + usec := int64(t.Hour())*microsecondsPerHour + + int64(t.Minute())*microsecondsPerMinute + + int64(t.Second())*microsecondsPerSecond + + int64(t.Nanosecond())/1000 + return Time{Microseconds: usec, Valid: true}, nil +} + +type durationWrapper time.Duration + +func (w durationWrapper) SkipUnderlyingTypePlan() {} + +func (w *durationWrapper) ScanInterval(v Interval) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *time.Interval") + } + + us := int64(v.Months)*microsecondsPerMonth + int64(v.Days)*microsecondsPerDay + v.Microseconds + *w = durationWrapper(time.Duration(us) * time.Microsecond) + return nil +} + +func (w durationWrapper) IntervalValue() (Interval, error) { + return Interval{Microseconds: int64(w) / 1000, Valid: true}, nil +} + +type netIPNetWrapper net.IPNet + +func (w *netIPNetWrapper) ScanNetipPrefix(v netip.Prefix) error { + if !v.IsValid() { + return fmt.Errorf("cannot scan NULL into *net.IPNet") + } + + *w = netIPNetWrapper{ + IP: v.Addr().AsSlice(), + Mask: net.CIDRMask(v.Bits(), v.Addr().BitLen()), + } + + return nil +} +func (w netIPNetWrapper) NetipPrefixValue() (netip.Prefix, error) { + ip, ok := netip.AddrFromSlice(w.IP) + if !ok { + return netip.Prefix{}, errors.New("invalid net.IPNet") + } + + ones, _ := w.Mask.Size() + + return netip.PrefixFrom(ip, ones), nil +} + +type netIPWrapper net.IP + +func (w netIPWrapper) SkipUnderlyingTypePlan() {} + +func (w *netIPWrapper) ScanNetipPrefix(v netip.Prefix) error { + if !v.IsValid() { + *w = nil + return nil + } + + if v.Addr().BitLen() != v.Bits() { + return fmt.Errorf("cannot scan %v to *net.IP", v) + } + + *w = netIPWrapper(v.Addr().AsSlice()) + return nil +} + +func (w netIPWrapper) NetipPrefixValue() (netip.Prefix, error) { + if w == nil { + return netip.Prefix{}, nil + } + + addr, ok := netip.AddrFromSlice([]byte(w)) + if !ok { + return netip.Prefix{}, errors.New("invalid net.IP") + } + + return netip.PrefixFrom(addr, addr.BitLen()), nil +} + +type netipPrefixWrapper netip.Prefix + +func (w *netipPrefixWrapper) ScanNetipPrefix(v netip.Prefix) error { + *w = netipPrefixWrapper(v) + return nil +} + +func (w netipPrefixWrapper) NetipPrefixValue() (netip.Prefix, error) { + return netip.Prefix(w), nil +} + +type netipAddrWrapper netip.Addr + +func (w *netipAddrWrapper) ScanNetipPrefix(v netip.Prefix) error { + if !v.IsValid() { + *w = netipAddrWrapper(netip.Addr{}) + return nil + } + + if v.Addr().BitLen() != v.Bits() { + return fmt.Errorf("cannot scan %v to netip.Addr", v) + } + + *w = netipAddrWrapper(v.Addr()) + + return nil +} + +func (w netipAddrWrapper) NetipPrefixValue() (netip.Prefix, error) { + addr := (netip.Addr)(w) + if !addr.IsValid() { + return netip.Prefix{}, nil + } + + return netip.PrefixFrom(addr, addr.BitLen()), nil +} + +type mapStringToPointerStringWrapper map[string]*string + +func (w *mapStringToPointerStringWrapper) ScanHstore(v Hstore) error { + *w = mapStringToPointerStringWrapper(v) + return nil +} + +func (w mapStringToPointerStringWrapper) HstoreValue() (Hstore, error) { + return Hstore(w), nil +} + +type mapStringToStringWrapper map[string]string + +func (w *mapStringToStringWrapper) ScanHstore(v Hstore) error { + *w = make(mapStringToStringWrapper, len(v)) + for k, v := range v { + if v == nil { + return fmt.Errorf("cannot scan NULL to string") + } + (*w)[k] = *v + } + return nil +} + +func (w mapStringToStringWrapper) HstoreValue() (Hstore, error) { + if w == nil { + return nil, nil + } + + hstore := make(Hstore, len(w)) + for k, v := range w { + s := v + hstore[k] = &s + } + return hstore, nil +} + +type fmtStringerWrapper struct { + s fmt.Stringer +} + +func (w fmtStringerWrapper) TextValue() (Text, error) { + return Text{String: w.s.String(), Valid: true}, nil +} + +type byte16Wrapper [16]byte + +func (w *byte16Wrapper) ScanUUID(v UUID) error { + if !v.Valid { + return fmt.Errorf("cannot scan NULL into *[16]byte") + } + *w = byte16Wrapper(v.Bytes) + return nil +} + +func (w byte16Wrapper) UUIDValue() (UUID, error) { + return UUID{Bytes: [16]byte(w), Valid: true}, nil +} + +type byteSliceWrapper []byte + +func (w byteSliceWrapper) SkipUnderlyingTypePlan() {} + +func (w *byteSliceWrapper) ScanText(v Text) error { + if !v.Valid { + *w = nil + return nil + } + + *w = byteSliceWrapper(v.String) + return nil +} + +func (w byteSliceWrapper) TextValue() (Text, error) { + if w == nil { + return Text{}, nil + } + + return Text{String: string(w), Valid: true}, nil +} + +func (w *byteSliceWrapper) ScanUUID(v UUID) error { + if !v.Valid { + *w = nil + return nil + } + *w = make(byteSliceWrapper, 16) + copy(*w, v.Bytes[:]) + return nil +} + +func (w byteSliceWrapper) UUIDValue() (UUID, error) { + if w == nil { + return UUID{}, nil + } + + uuid := UUID{Valid: true} + copy(uuid.Bytes[:], w) + return uuid, nil +} + +// structWrapper implements CompositeIndexGetter for a struct. +type structWrapper struct { + s any + exportedFields []reflect.Value +} + +func (w structWrapper) IsNull() bool { + return w.s == nil +} + +func (w structWrapper) Index(i int) any { + if i >= len(w.exportedFields) { + return fmt.Errorf("%#v only has %d public fields - %d is out of bounds", w.s, len(w.exportedFields), i) + } + + return w.exportedFields[i].Interface() +} + +// ptrStructWrapper implements CompositeIndexScanner for a pointer to a struct. +type ptrStructWrapper struct { + s any + exportedFields []reflect.Value +} + +func (w *ptrStructWrapper) ScanNull() error { + return fmt.Errorf("cannot scan NULL into %#v", w.s) +} + +func (w *ptrStructWrapper) ScanIndex(i int) any { + if i >= len(w.exportedFields) { + return fmt.Errorf("%#v only has %d public fields - %d is out of bounds", w.s, len(w.exportedFields), i) + } + + return w.exportedFields[i].Addr().Interface() +} + +type anySliceArrayReflect struct { + slice reflect.Value +} + +func (a anySliceArrayReflect) Dimensions() []ArrayDimension { + if a.slice.IsNil() { + return nil + } + + return []ArrayDimension{{Length: int32(a.slice.Len()), LowerBound: 1}} +} + +func (a anySliceArrayReflect) Index(i int) any { + return a.slice.Index(i).Interface() +} + +func (a anySliceArrayReflect) IndexType() any { + return reflect.New(a.slice.Type().Elem()).Elem().Interface() +} + +func (a *anySliceArrayReflect) SetDimensions(dimensions []ArrayDimension) error { + sliceType := a.slice.Type() + + if dimensions == nil { + a.slice.Set(reflect.Zero(sliceType)) + return nil + } + + elementCount := cardinality(dimensions) + slice := reflect.MakeSlice(sliceType, elementCount, elementCount) + a.slice.Set(slice) + return nil +} + +func (a *anySliceArrayReflect) ScanIndex(i int) any { + return a.slice.Index(i).Addr().Interface() +} + +func (a *anySliceArrayReflect) ScanIndexType() any { + return reflect.New(a.slice.Type().Elem()).Interface() +} + +type anyMultiDimSliceArray struct { + slice reflect.Value + dims []ArrayDimension +} + +func (a *anyMultiDimSliceArray) Dimensions() []ArrayDimension { + if a.slice.IsNil() { + return nil + } + + s := a.slice + for { + a.dims = append(a.dims, ArrayDimension{Length: int32(s.Len()), LowerBound: 1}) + if s.Len() > 0 { + s = s.Index(0) + } else { + break + } + if s.Type().Kind() == reflect.Slice { + } else { + break + } + } + + return a.dims +} + +func (a *anyMultiDimSliceArray) Index(i int) any { + if len(a.dims) == 1 { + return a.slice.Index(i).Interface() + } + + indexes := make([]int, len(a.dims)) + for j := len(a.dims) - 1; j >= 0; j-- { + dimLen := int(a.dims[j].Length) + indexes[j] = i % dimLen + i = i / dimLen + } + + v := a.slice + for _, si := range indexes { + v = v.Index(si) + } + + return v.Interface() +} + +func (a *anyMultiDimSliceArray) IndexType() any { + lowestSliceType := a.slice.Type() + for ; lowestSliceType.Elem().Kind() == reflect.Slice; lowestSliceType = lowestSliceType.Elem() { + } + return reflect.New(lowestSliceType.Elem()).Elem().Interface() +} + +func (a *anyMultiDimSliceArray) SetDimensions(dimensions []ArrayDimension) error { + sliceType := a.slice.Type() + + if dimensions == nil { + a.slice.Set(reflect.Zero(sliceType)) + return nil + } + + switch len(dimensions) { + case 0: + // Empty, but non-nil array + slice := reflect.MakeSlice(sliceType, 0, 0) + a.slice.Set(slice) + return nil + case 1: + elementCount := cardinality(dimensions) + slice := reflect.MakeSlice(sliceType, elementCount, elementCount) + a.slice.Set(slice) + return nil + default: + sliceDimensionCount := 1 + lowestSliceType := sliceType + for ; lowestSliceType.Elem().Kind() == reflect.Slice; lowestSliceType = lowestSliceType.Elem() { + sliceDimensionCount++ + } + + if sliceDimensionCount != len(dimensions) { + return fmt.Errorf("PostgreSQL array has %d dimensions but slice has %d dimensions", len(dimensions), sliceDimensionCount) + } + + elementCount := cardinality(dimensions) + flatSlice := reflect.MakeSlice(lowestSliceType, elementCount, elementCount) + + multiDimSlice := a.makeMultidimensionalSlice(sliceType, dimensions, flatSlice, 0) + a.slice.Set(multiDimSlice) + + // Now that a.slice is a multi-dimensional slice with the underlying data pointed at flatSlice change a.slice to + // flatSlice so ScanIndex only has to handle simple one dimensional slices. + a.slice = flatSlice + + return nil + } + +} + +func (a *anyMultiDimSliceArray) makeMultidimensionalSlice(sliceType reflect.Type, dimensions []ArrayDimension, flatSlice reflect.Value, flatSliceIdx int) reflect.Value { + if len(dimensions) == 1 { + endIdx := flatSliceIdx + int(dimensions[0].Length) + return flatSlice.Slice3(flatSliceIdx, endIdx, endIdx) + } + + sliceLen := int(dimensions[0].Length) + slice := reflect.MakeSlice(sliceType, sliceLen, sliceLen) + for i := 0; i < sliceLen; i++ { + subSlice := a.makeMultidimensionalSlice(sliceType.Elem(), dimensions[1:], flatSlice, flatSliceIdx+(i*int(dimensions[1].Length))) + slice.Index(i).Set(subSlice) + } + + return slice +} + +func (a *anyMultiDimSliceArray) ScanIndex(i int) any { + return a.slice.Index(i).Addr().Interface() +} + +func (a *anyMultiDimSliceArray) ScanIndexType() any { + lowestSliceType := a.slice.Type() + for ; lowestSliceType.Elem().Kind() == reflect.Slice; lowestSliceType = lowestSliceType.Elem() { + } + return reflect.New(lowestSliceType.Elem()).Interface() +} + +type anyArrayArrayReflect struct { + array reflect.Value +} + +func (a anyArrayArrayReflect) Dimensions() []ArrayDimension { + return []ArrayDimension{{Length: int32(a.array.Len()), LowerBound: 1}} +} + +func (a anyArrayArrayReflect) Index(i int) any { + return a.array.Index(i).Interface() +} + +func (a anyArrayArrayReflect) IndexType() any { + return reflect.New(a.array.Type().Elem()).Elem().Interface() +} + +func (a *anyArrayArrayReflect) SetDimensions(dimensions []ArrayDimension) error { + if dimensions == nil { + return fmt.Errorf("anyArrayArrayReflect: cannot scan NULL into %v", a.array.Type().String()) + } + + if len(dimensions) != 1 { + return fmt.Errorf("anyArrayArrayReflect: cannot scan multi-dimensional array into %v", a.array.Type().String()) + } + + if int(dimensions[0].Length) != a.array.Len() { + return fmt.Errorf("anyArrayArrayReflect: cannot scan array with length %v into %v", dimensions[0].Length, a.array.Type().String()) + } + + return nil +} + +func (a *anyArrayArrayReflect) ScanIndex(i int) any { + return a.array.Index(i).Addr().Interface() +} + +func (a *anyArrayArrayReflect) ScanIndexType() any { + return reflect.New(a.array.Type().Elem()).Interface() +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/bytea.go b/vendor/github.com/jackc/pgx/v5/pgtype/bytea.go new file mode 100644 index 00000000000..a247705e923 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/bytea.go @@ -0,0 +1,255 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/hex" + "fmt" +) + +type BytesScanner interface { + // ScanBytes receives a byte slice of driver memory that is only valid until the next database method call. + ScanBytes(v []byte) error +} + +type BytesValuer interface { + // BytesValue returns a byte slice of the byte data. The caller must not change the returned slice. + BytesValue() ([]byte, error) +} + +// DriverBytes is a byte slice that holds a reference to memory owned by the driver. It is only valid from the time it +// is scanned until Rows.Next or Rows.Close is called. It is never safe to use DriverBytes with QueryRow as Row.Scan +// internally calls Rows.Close before returning. +type DriverBytes []byte + +func (b *DriverBytes) ScanBytes(v []byte) error { + *b = v + return nil +} + +// PreallocBytes is a byte slice of preallocated memory that scanned bytes will be copied to. If it is too small a new +// slice will be allocated. +type PreallocBytes []byte + +func (b *PreallocBytes) ScanBytes(v []byte) error { + if v == nil { + *b = nil + return nil + } + + if len(v) <= len(*b) { + *b = (*b)[:len(v)] + } else { + *b = make(PreallocBytes, len(v)) + } + copy(*b, v) + return nil +} + +// UndecodedBytes can be used as a scan target to get the raw bytes from PostgreSQL without any decoding. +type UndecodedBytes []byte + +type scanPlanAnyToUndecodedBytes struct{} + +func (scanPlanAnyToUndecodedBytes) Scan(src []byte, dst any) error { + dstBuf := dst.(*UndecodedBytes) + if src == nil { + *dstBuf = nil + return nil + } + + *dstBuf = make([]byte, len(src)) + copy(*dstBuf, src) + return nil +} + +type ByteaCodec struct{} + +func (ByteaCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (ByteaCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (ByteaCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case []byte: + return encodePlanBytesCodecBinaryBytes{} + case BytesValuer: + return encodePlanBytesCodecBinaryBytesValuer{} + } + case TextFormatCode: + switch value.(type) { + case []byte: + return encodePlanBytesCodecTextBytes{} + case BytesValuer: + return encodePlanBytesCodecTextBytesValuer{} + } + } + + return nil +} + +type encodePlanBytesCodecBinaryBytes struct{} + +func (encodePlanBytesCodecBinaryBytes) Encode(value any, buf []byte) (newBuf []byte, err error) { + b := value.([]byte) + if b == nil { + return nil, nil + } + + return append(buf, b...), nil +} + +type encodePlanBytesCodecBinaryBytesValuer struct{} + +func (encodePlanBytesCodecBinaryBytesValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + b, err := value.(BytesValuer).BytesValue() + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + return append(buf, b...), nil +} + +type encodePlanBytesCodecTextBytes struct{} + +func (encodePlanBytesCodecTextBytes) Encode(value any, buf []byte) (newBuf []byte, err error) { + b := value.([]byte) + if b == nil { + return nil, nil + } + + buf = append(buf, `\x`...) + buf = append(buf, hex.EncodeToString(b)...) + return buf, nil +} + +type encodePlanBytesCodecTextBytesValuer struct{} + +func (encodePlanBytesCodecTextBytesValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + b, err := value.(BytesValuer).BytesValue() + if err != nil { + return nil, err + } + if b == nil { + return nil, nil + } + + buf = append(buf, `\x`...) + buf = append(buf, hex.EncodeToString(b)...) + return buf, nil +} + +func (ByteaCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *[]byte: + return scanPlanBinaryBytesToBytes{} + case BytesScanner: + return scanPlanBinaryBytesToBytesScanner{} + } + case TextFormatCode: + switch target.(type) { + case *[]byte: + return scanPlanTextByteaToBytes{} + case BytesScanner: + return scanPlanTextByteaToBytesScanner{} + } + } + + return nil +} + +type scanPlanBinaryBytesToBytes struct{} + +func (scanPlanBinaryBytesToBytes) Scan(src []byte, dst any) error { + dstBuf := dst.(*[]byte) + if src == nil { + *dstBuf = nil + return nil + } + + *dstBuf = make([]byte, len(src)) + copy(*dstBuf, src) + return nil +} + +type scanPlanBinaryBytesToBytesScanner struct{} + +func (scanPlanBinaryBytesToBytesScanner) Scan(src []byte, dst any) error { + scanner := (dst).(BytesScanner) + return scanner.ScanBytes(src) +} + +type scanPlanTextByteaToBytes struct{} + +func (scanPlanTextByteaToBytes) Scan(src []byte, dst any) error { + dstBuf := dst.(*[]byte) + if src == nil { + *dstBuf = nil + return nil + } + + buf, err := decodeHexBytea(src) + if err != nil { + return err + } + *dstBuf = buf + + return nil +} + +type scanPlanTextByteaToBytesScanner struct{} + +func (scanPlanTextByteaToBytesScanner) Scan(src []byte, dst any) error { + scanner := (dst).(BytesScanner) + buf, err := decodeHexBytea(src) + if err != nil { + return err + } + return scanner.ScanBytes(buf) +} + +func decodeHexBytea(src []byte) ([]byte, error) { + if src == nil { + return nil, nil + } + + if len(src) < 2 || src[0] != '\\' || src[1] != 'x' { + return nil, fmt.Errorf("invalid hex format") + } + + buf := make([]byte, (len(src)-2)/2) + _, err := hex.Decode(buf, src[2:]) + if err != nil { + return nil, err + } + + return buf, nil +} + +func (c ByteaCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) +} + +func (c ByteaCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var buf []byte + err := codecScan(c, m, oid, format, src, &buf) + if err != nil { + return nil, err + } + return buf, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/circle.go b/vendor/github.com/jackc/pgx/v5/pgtype/circle.go new file mode 100644 index 00000000000..e8f118cc936 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/circle.go @@ -0,0 +1,222 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type CircleScanner interface { + ScanCircle(v Circle) error +} + +type CircleValuer interface { + CircleValue() (Circle, error) +} + +type Circle struct { + P Vec2 + R float64 + Valid bool +} + +func (c *Circle) ScanCircle(v Circle) error { + *c = v + return nil +} + +func (c Circle) CircleValue() (Circle, error) { + return c, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Circle) Scan(src any) error { + if src == nil { + *dst = Circle{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToCircleScanner{}.Scan([]byte(src), dst) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src Circle) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + buf, err := CircleCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type CircleCodec struct{} + +func (CircleCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (CircleCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (CircleCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(CircleValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanCircleCodecBinary{} + case TextFormatCode: + return encodePlanCircleCodecText{} + } + + return nil +} + +type encodePlanCircleCodecBinary struct{} + +func (encodePlanCircleCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + circle, err := value.(CircleValuer).CircleValue() + if err != nil { + return nil, err + } + + if !circle.Valid { + return nil, nil + } + + buf = pgio.AppendUint64(buf, math.Float64bits(circle.P.X)) + buf = pgio.AppendUint64(buf, math.Float64bits(circle.P.Y)) + buf = pgio.AppendUint64(buf, math.Float64bits(circle.R)) + return buf, nil +} + +type encodePlanCircleCodecText struct{} + +func (encodePlanCircleCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + circle, err := value.(CircleValuer).CircleValue() + if err != nil { + return nil, err + } + + if !circle.Valid { + return nil, nil + } + + buf = append(buf, fmt.Sprintf(`<(%s,%s),%s>`, + strconv.FormatFloat(circle.P.X, 'f', -1, 64), + strconv.FormatFloat(circle.P.Y, 'f', -1, 64), + strconv.FormatFloat(circle.R, 'f', -1, 64), + )...) + return buf, nil +} + +func (CircleCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case BinaryFormatCode: + switch target.(type) { + case CircleScanner: + return scanPlanBinaryCircleToCircleScanner{} + } + case TextFormatCode: + switch target.(type) { + case CircleScanner: + return scanPlanTextAnyToCircleScanner{} + } + } + + return nil +} + +func (c CircleCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c CircleCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var circle Circle + err := codecScan(c, m, oid, format, src, &circle) + if err != nil { + return nil, err + } + return circle, nil +} + +type scanPlanBinaryCircleToCircleScanner struct{} + +func (scanPlanBinaryCircleToCircleScanner) Scan(src []byte, dst any) error { + scanner := (dst).(CircleScanner) + + if src == nil { + return scanner.ScanCircle(Circle{}) + } + + if len(src) != 24 { + return fmt.Errorf("invalid length for Circle: %v", len(src)) + } + + x := binary.BigEndian.Uint64(src) + y := binary.BigEndian.Uint64(src[8:]) + r := binary.BigEndian.Uint64(src[16:]) + + return scanner.ScanCircle(Circle{ + P: Vec2{math.Float64frombits(x), math.Float64frombits(y)}, + R: math.Float64frombits(r), + Valid: true, + }) +} + +type scanPlanTextAnyToCircleScanner struct{} + +func (scanPlanTextAnyToCircleScanner) Scan(src []byte, dst any) error { + scanner := (dst).(CircleScanner) + + if src == nil { + return scanner.ScanCircle(Circle{}) + } + + if len(src) < 9 { + return fmt.Errorf("invalid length for Circle: %v", len(src)) + } + + str := string(src[2:]) + end := strings.IndexByte(str, ',') + x, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+1:] + end = strings.IndexByte(str, ')') + + y, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+2 : len(str)-1] + + r, err := strconv.ParseFloat(str, 64) + if err != nil { + return err + } + + return scanner.ScanCircle(Circle{P: Vec2{x, y}, R: r, Valid: true}) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/composite.go b/vendor/github.com/jackc/pgx/v5/pgtype/composite.go new file mode 100644 index 00000000000..fb372325b63 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/composite.go @@ -0,0 +1,602 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "errors" + "fmt" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// CompositeIndexGetter is a type accessed by index that can be converted into a PostgreSQL composite. +type CompositeIndexGetter interface { + // IsNull returns true if the value is SQL NULL. + IsNull() bool + + // Index returns the element at i. + Index(i int) any +} + +// CompositeIndexScanner is a type accessed by index that can be scanned from a PostgreSQL composite. +type CompositeIndexScanner interface { + // ScanNull sets the value to SQL NULL. + ScanNull() error + + // ScanIndex returns a value usable as a scan target for i. + ScanIndex(i int) any +} + +type CompositeCodecField struct { + Name string + Type *Type +} + +type CompositeCodec struct { + Fields []CompositeCodecField +} + +func (c *CompositeCodec) FormatSupported(format int16) bool { + for _, f := range c.Fields { + if !f.Type.Codec.FormatSupported(format) { + return false + } + } + + return true +} + +func (c *CompositeCodec) PreferredFormat() int16 { + if c.FormatSupported(BinaryFormatCode) { + return BinaryFormatCode + } + return TextFormatCode +} + +func (c *CompositeCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(CompositeIndexGetter); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return &encodePlanCompositeCodecCompositeIndexGetterToBinary{cc: c, m: m} + case TextFormatCode: + return &encodePlanCompositeCodecCompositeIndexGetterToText{cc: c, m: m} + } + + return nil +} + +type encodePlanCompositeCodecCompositeIndexGetterToBinary struct { + cc *CompositeCodec + m *Map +} + +func (plan *encodePlanCompositeCodecCompositeIndexGetterToBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + getter := value.(CompositeIndexGetter) + + if getter.IsNull() { + return nil, nil + } + + builder := NewCompositeBinaryBuilder(plan.m, buf) + for i, field := range plan.cc.Fields { + builder.AppendValue(field.Type.OID, getter.Index(i)) + } + + return builder.Finish() +} + +type encodePlanCompositeCodecCompositeIndexGetterToText struct { + cc *CompositeCodec + m *Map +} + +func (plan *encodePlanCompositeCodecCompositeIndexGetterToText) Encode(value any, buf []byte) (newBuf []byte, err error) { + getter := value.(CompositeIndexGetter) + + if getter.IsNull() { + return nil, nil + } + + b := NewCompositeTextBuilder(plan.m, buf) + for i, field := range plan.cc.Fields { + b.AppendValue(field.Type.OID, getter.Index(i)) + } + + return b.Finish() +} + +func (c *CompositeCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case BinaryFormatCode: + switch target.(type) { + case CompositeIndexScanner: + return &scanPlanBinaryCompositeToCompositeIndexScanner{cc: c, m: m} + } + case TextFormatCode: + switch target.(type) { + case CompositeIndexScanner: + return &scanPlanTextCompositeToCompositeIndexScanner{cc: c, m: m} + } + } + + return nil +} + +type scanPlanBinaryCompositeToCompositeIndexScanner struct { + cc *CompositeCodec + m *Map +} + +func (plan *scanPlanBinaryCompositeToCompositeIndexScanner) Scan(src []byte, target any) error { + targetScanner := (target).(CompositeIndexScanner) + + if src == nil { + return targetScanner.ScanNull() + } + + scanner := NewCompositeBinaryScanner(plan.m, src) + for i, field := range plan.cc.Fields { + if scanner.Next() { + fieldTarget := targetScanner.ScanIndex(i) + if fieldTarget != nil { + fieldPlan := plan.m.PlanScan(field.Type.OID, BinaryFormatCode, fieldTarget) + if fieldPlan == nil { + return fmt.Errorf("unable to encode %v into OID %d in binary format", field, field.Type.OID) + } + + err := fieldPlan.Scan(scanner.Bytes(), fieldTarget) + if err != nil { + return err + } + } + } else { + return errors.New("read past end of composite") + } + } + + if err := scanner.Err(); err != nil { + return err + } + + return nil +} + +type scanPlanTextCompositeToCompositeIndexScanner struct { + cc *CompositeCodec + m *Map +} + +func (plan *scanPlanTextCompositeToCompositeIndexScanner) Scan(src []byte, target any) error { + targetScanner := (target).(CompositeIndexScanner) + + if src == nil { + return targetScanner.ScanNull() + } + + scanner := NewCompositeTextScanner(plan.m, src) + for i, field := range plan.cc.Fields { + if scanner.Next() { + fieldTarget := targetScanner.ScanIndex(i) + if fieldTarget != nil { + fieldPlan := plan.m.PlanScan(field.Type.OID, TextFormatCode, fieldTarget) + if fieldPlan == nil { + return fmt.Errorf("unable to encode %v into OID %d in text format", field, field.Type.OID) + } + + err := fieldPlan.Scan(scanner.Bytes(), fieldTarget) + if err != nil { + return err + } + } + } else { + return errors.New("read past end of composite") + } + } + + if err := scanner.Err(); err != nil { + return err + } + + return nil +} + +func (c *CompositeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + switch format { + case TextFormatCode: + return string(src), nil + case BinaryFormatCode: + buf := make([]byte, len(src)) + copy(buf, src) + return buf, nil + default: + return nil, fmt.Errorf("unknown format code %d", format) + } +} + +func (c *CompositeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + switch format { + case TextFormatCode: + scanner := NewCompositeTextScanner(m, src) + values := make(map[string]any, len(c.Fields)) + for i := 0; scanner.Next() && i < len(c.Fields); i++ { + var v any + fieldPlan := m.PlanScan(c.Fields[i].Type.OID, TextFormatCode, &v) + if fieldPlan == nil { + return nil, fmt.Errorf("unable to scan OID %d in text format into %v", c.Fields[i].Type.OID, v) + } + + err := fieldPlan.Scan(scanner.Bytes(), &v) + if err != nil { + return nil, err + } + + values[c.Fields[i].Name] = v + } + + if err := scanner.Err(); err != nil { + return nil, err + } + + return values, nil + case BinaryFormatCode: + scanner := NewCompositeBinaryScanner(m, src) + values := make(map[string]any, len(c.Fields)) + for i := 0; scanner.Next() && i < len(c.Fields); i++ { + var v any + fieldPlan := m.PlanScan(scanner.OID(), BinaryFormatCode, &v) + if fieldPlan == nil { + return nil, fmt.Errorf("unable to scan OID %d in binary format into %v", scanner.OID(), v) + } + + err := fieldPlan.Scan(scanner.Bytes(), &v) + if err != nil { + return nil, err + } + + values[c.Fields[i].Name] = v + } + + if err := scanner.Err(); err != nil { + return nil, err + } + + return values, nil + default: + return nil, fmt.Errorf("unknown format code %d", format) + } + +} + +type CompositeBinaryScanner struct { + m *Map + rp int + src []byte + + fieldCount int32 + fieldBytes []byte + fieldOID uint32 + err error +} + +// NewCompositeBinaryScanner a scanner over a binary encoded composite balue. +func NewCompositeBinaryScanner(m *Map, src []byte) *CompositeBinaryScanner { + rp := 0 + if len(src[rp:]) < 4 { + return &CompositeBinaryScanner{err: fmt.Errorf("Record incomplete %v", src)} + } + + fieldCount := int32(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + + return &CompositeBinaryScanner{ + m: m, + rp: rp, + src: src, + fieldCount: fieldCount, + } +} + +// Next advances the scanner to the next field. It returns false after the last field is read or an error occurs. After +// Next returns false, the Err method can be called to check if any errors occurred. +func (cfs *CompositeBinaryScanner) Next() bool { + if cfs.err != nil { + return false + } + + if cfs.rp == len(cfs.src) { + return false + } + + if len(cfs.src[cfs.rp:]) < 8 { + cfs.err = fmt.Errorf("Record incomplete %v", cfs.src) + return false + } + cfs.fieldOID = binary.BigEndian.Uint32(cfs.src[cfs.rp:]) + cfs.rp += 4 + + fieldLen := int(int32(binary.BigEndian.Uint32(cfs.src[cfs.rp:]))) + cfs.rp += 4 + + if fieldLen >= 0 { + if len(cfs.src[cfs.rp:]) < fieldLen { + cfs.err = fmt.Errorf("Record incomplete rp=%d src=%v", cfs.rp, cfs.src) + return false + } + cfs.fieldBytes = cfs.src[cfs.rp : cfs.rp+fieldLen] + cfs.rp += fieldLen + } else { + cfs.fieldBytes = nil + } + + return true +} + +func (cfs *CompositeBinaryScanner) FieldCount() int { + return int(cfs.fieldCount) +} + +// Bytes returns the bytes of the field most recently read by Scan(). +func (cfs *CompositeBinaryScanner) Bytes() []byte { + return cfs.fieldBytes +} + +// OID returns the OID of the field most recently read by Scan(). +func (cfs *CompositeBinaryScanner) OID() uint32 { + return cfs.fieldOID +} + +// Err returns any error encountered by the scanner. +func (cfs *CompositeBinaryScanner) Err() error { + return cfs.err +} + +type CompositeTextScanner struct { + m *Map + rp int + src []byte + + fieldBytes []byte + err error +} + +// NewCompositeTextScanner a scanner over a text encoded composite value. +func NewCompositeTextScanner(m *Map, src []byte) *CompositeTextScanner { + if len(src) < 2 { + return &CompositeTextScanner{err: fmt.Errorf("Record incomplete %v", src)} + } + + if src[0] != '(' { + return &CompositeTextScanner{err: fmt.Errorf("composite text format must start with '('")} + } + + if src[len(src)-1] != ')' { + return &CompositeTextScanner{err: fmt.Errorf("composite text format must end with ')'")} + } + + return &CompositeTextScanner{ + m: m, + rp: 1, + src: src, + } +} + +// Next advances the scanner to the next field. It returns false after the last field is read or an error occurs. After +// Next returns false, the Err method can be called to check if any errors occurred. +func (cfs *CompositeTextScanner) Next() bool { + if cfs.err != nil { + return false + } + + if cfs.rp == len(cfs.src) { + return false + } + + switch cfs.src[cfs.rp] { + case ',', ')': // null + cfs.rp++ + cfs.fieldBytes = nil + return true + case '"': // quoted value + cfs.rp++ + cfs.fieldBytes = make([]byte, 0, 16) + for { + ch := cfs.src[cfs.rp] + + if ch == '"' { + cfs.rp++ + if cfs.src[cfs.rp] == '"' { + cfs.fieldBytes = append(cfs.fieldBytes, '"') + cfs.rp++ + } else { + break + } + } else if ch == '\\' { + cfs.rp++ + cfs.fieldBytes = append(cfs.fieldBytes, cfs.src[cfs.rp]) + cfs.rp++ + } else { + cfs.fieldBytes = append(cfs.fieldBytes, ch) + cfs.rp++ + } + } + cfs.rp++ + return true + default: // unquoted value + start := cfs.rp + for { + ch := cfs.src[cfs.rp] + if ch == ',' || ch == ')' { + break + } + cfs.rp++ + } + cfs.fieldBytes = cfs.src[start:cfs.rp] + cfs.rp++ + return true + } +} + +// Bytes returns the bytes of the field most recently read by Scan(). +func (cfs *CompositeTextScanner) Bytes() []byte { + return cfs.fieldBytes +} + +// Err returns any error encountered by the scanner. +func (cfs *CompositeTextScanner) Err() error { + return cfs.err +} + +type CompositeBinaryBuilder struct { + m *Map + buf []byte + startIdx int + fieldCount uint32 + err error +} + +func NewCompositeBinaryBuilder(m *Map, buf []byte) *CompositeBinaryBuilder { + startIdx := len(buf) + buf = append(buf, 0, 0, 0, 0) // allocate room for number of fields + return &CompositeBinaryBuilder{m: m, buf: buf, startIdx: startIdx} +} + +func (b *CompositeBinaryBuilder) AppendValue(oid uint32, field any) { + if b.err != nil { + return + } + + if field == nil { + b.buf = pgio.AppendUint32(b.buf, oid) + b.buf = pgio.AppendInt32(b.buf, -1) + b.fieldCount++ + return + } + + plan := b.m.PlanEncode(oid, BinaryFormatCode, field) + if plan == nil { + b.err = fmt.Errorf("unable to encode %v into OID %d in binary format", field, oid) + return + } + + b.buf = pgio.AppendUint32(b.buf, oid) + lengthPos := len(b.buf) + b.buf = pgio.AppendInt32(b.buf, -1) + fieldBuf, err := plan.Encode(field, b.buf) + if err != nil { + b.err = err + return + } + if fieldBuf != nil { + binary.BigEndian.PutUint32(fieldBuf[lengthPos:], uint32(len(fieldBuf)-len(b.buf))) + b.buf = fieldBuf + } + + b.fieldCount++ +} + +func (b *CompositeBinaryBuilder) Finish() ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + binary.BigEndian.PutUint32(b.buf[b.startIdx:], b.fieldCount) + return b.buf, nil +} + +type CompositeTextBuilder struct { + m *Map + buf []byte + startIdx int + fieldCount uint32 + err error + fieldBuf [32]byte +} + +func NewCompositeTextBuilder(m *Map, buf []byte) *CompositeTextBuilder { + buf = append(buf, '(') // allocate room for number of fields + return &CompositeTextBuilder{m: m, buf: buf} +} + +func (b *CompositeTextBuilder) AppendValue(oid uint32, field any) { + if b.err != nil { + return + } + + if field == nil { + b.buf = append(b.buf, ',') + return + } + + plan := b.m.PlanEncode(oid, TextFormatCode, field) + if plan == nil { + b.err = fmt.Errorf("unable to encode %v into OID %d in text format", field, oid) + return + } + + fieldBuf, err := plan.Encode(field, b.fieldBuf[0:0]) + if err != nil { + b.err = err + return + } + if fieldBuf != nil { + b.buf = append(b.buf, quoteCompositeFieldIfNeeded(string(fieldBuf))...) + } + + b.buf = append(b.buf, ',') +} + +func (b *CompositeTextBuilder) Finish() ([]byte, error) { + if b.err != nil { + return nil, b.err + } + + b.buf[len(b.buf)-1] = ')' + return b.buf, nil +} + +var quoteCompositeReplacer = strings.NewReplacer(`\`, `\\`, `"`, `\"`) + +func quoteCompositeField(src string) string { + return `"` + quoteCompositeReplacer.Replace(src) + `"` +} + +func quoteCompositeFieldIfNeeded(src string) string { + if src == "" || src[0] == ' ' || src[len(src)-1] == ' ' || strings.ContainsAny(src, `(),"\`) { + return quoteCompositeField(src) + } + return src +} + +// CompositeFields represents the values of a composite value. It can be used as an encoding source or as a scan target. +// It cannot scan a NULL, but the composite fields can be NULL. +type CompositeFields []any + +func (cf CompositeFields) SkipUnderlyingTypePlan() {} + +func (cf CompositeFields) IsNull() bool { + return cf == nil +} + +func (cf CompositeFields) Index(i int) any { + return cf[i] +} + +func (cf CompositeFields) ScanNull() error { + return fmt.Errorf("cannot scan NULL into CompositeFields") +} + +func (cf CompositeFields) ScanIndex(i int) any { + return cf[i] +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/convert.go b/vendor/github.com/jackc/pgx/v5/pgtype/convert.go new file mode 100644 index 00000000000..7fddeaa8a9b --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/convert.go @@ -0,0 +1,479 @@ +package pgtype + +import ( + "database/sql" + "fmt" + "math" + "reflect" + "time" +) + +const ( + maxUint = ^uint(0) + maxInt = int(maxUint >> 1) + minInt = -maxInt - 1 +) + +// underlyingNumberType gets the underlying type that can be converted to Int2, Int4, Int8, Float4, or Float8 +func underlyingNumberType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return nil, false + } + convVal := refVal.Elem().Interface() + return convVal, true + case reflect.Int: + convVal := int(refVal.Int()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Int8: + convVal := int8(refVal.Int()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Int16: + convVal := int16(refVal.Int()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Int32: + convVal := int32(refVal.Int()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Int64: + convVal := int64(refVal.Int()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Uint: + convVal := uint(refVal.Uint()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Uint8: + convVal := uint8(refVal.Uint()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Uint16: + convVal := uint16(refVal.Uint()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Uint32: + convVal := uint32(refVal.Uint()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Uint64: + convVal := uint64(refVal.Uint()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Float32: + convVal := float32(refVal.Float()) + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Float64: + convVal := refVal.Float() + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.String: + convVal := refVal.String() + return convVal, reflect.TypeOf(convVal) != refVal.Type() + case reflect.Bool: + convVal := refVal.Bool() + return convVal, reflect.TypeOf(convVal) != refVal.Type() + } + + return nil, false +} + +// underlyingBoolType gets the underlying type that can be converted to Bool +func underlyingBoolType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return nil, false + } + convVal := refVal.Elem().Interface() + return convVal, true + case reflect.Bool: + convVal := refVal.Bool() + return convVal, reflect.TypeOf(convVal) != refVal.Type() + } + + return nil, false +} + +// underlyingBytesType gets the underlying type that can be converted to []byte +func underlyingBytesType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return nil, false + } + convVal := refVal.Elem().Interface() + return convVal, true + case reflect.Slice: + if refVal.Type().Elem().Kind() == reflect.Uint8 { + convVal := refVal.Bytes() + return convVal, reflect.TypeOf(convVal) != refVal.Type() + } + } + + return nil, false +} + +// underlyingStringType gets the underlying type that can be converted to String +func underlyingStringType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return nil, false + } + convVal := refVal.Elem().Interface() + return convVal, true + case reflect.String: + convVal := refVal.String() + return convVal, reflect.TypeOf(convVal) != refVal.Type() + } + + return nil, false +} + +// underlyingPtrType dereferences a pointer +func underlyingPtrType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return nil, false + } + convVal := refVal.Elem().Interface() + return convVal, true + } + + return nil, false +} + +// underlyingTimeType gets the underlying type that can be converted to time.Time +func underlyingTimeType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return nil, false + } + convVal := refVal.Elem().Interface() + return convVal, true + } + + timeType := reflect.TypeOf(time.Time{}) + if refVal.Type().ConvertibleTo(timeType) { + return refVal.Convert(timeType).Interface(), true + } + + return nil, false +} + +// underlyingUUIDType gets the underlying type that can be converted to [16]byte +func underlyingUUIDType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return time.Time{}, false + } + convVal := refVal.Elem().Interface() + return convVal, true + } + + uuidType := reflect.TypeOf([16]byte{}) + if refVal.Type().ConvertibleTo(uuidType) { + return refVal.Convert(uuidType).Interface(), true + } + + return nil, false +} + +// underlyingSliceType gets the underlying slice type +func underlyingSliceType(val any) (any, bool) { + refVal := reflect.ValueOf(val) + + switch refVal.Kind() { + case reflect.Ptr: + if refVal.IsNil() { + return nil, false + } + convVal := refVal.Elem().Interface() + return convVal, true + case reflect.Slice: + baseSliceType := reflect.SliceOf(refVal.Type().Elem()) + if refVal.Type().ConvertibleTo(baseSliceType) { + convVal := refVal.Convert(baseSliceType) + return convVal.Interface(), reflect.TypeOf(convVal.Interface()) != refVal.Type() + } + } + + return nil, false +} + +func int64AssignTo(srcVal int64, srcValid bool, dst any) error { + if srcValid { + switch v := dst.(type) { + case *int: + if srcVal < int64(minInt) { + return fmt.Errorf("%d is less than minimum value for int", srcVal) + } else if srcVal > int64(maxInt) { + return fmt.Errorf("%d is greater than maximum value for int", srcVal) + } + *v = int(srcVal) + case *int8: + if srcVal < math.MinInt8 { + return fmt.Errorf("%d is less than minimum value for int8", srcVal) + } else if srcVal > math.MaxInt8 { + return fmt.Errorf("%d is greater than maximum value for int8", srcVal) + } + *v = int8(srcVal) + case *int16: + if srcVal < math.MinInt16 { + return fmt.Errorf("%d is less than minimum value for int16", srcVal) + } else if srcVal > math.MaxInt16 { + return fmt.Errorf("%d is greater than maximum value for int16", srcVal) + } + *v = int16(srcVal) + case *int32: + if srcVal < math.MinInt32 { + return fmt.Errorf("%d is less than minimum value for int32", srcVal) + } else if srcVal > math.MaxInt32 { + return fmt.Errorf("%d is greater than maximum value for int32", srcVal) + } + *v = int32(srcVal) + case *int64: + if srcVal < math.MinInt64 { + return fmt.Errorf("%d is less than minimum value for int64", srcVal) + } else if srcVal > math.MaxInt64 { + return fmt.Errorf("%d is greater than maximum value for int64", srcVal) + } + *v = int64(srcVal) + case *uint: + if srcVal < 0 { + return fmt.Errorf("%d is less than zero for uint", srcVal) + } else if uint64(srcVal) > uint64(maxUint) { + return fmt.Errorf("%d is greater than maximum value for uint", srcVal) + } + *v = uint(srcVal) + case *uint8: + if srcVal < 0 { + return fmt.Errorf("%d is less than zero for uint8", srcVal) + } else if srcVal > math.MaxUint8 { + return fmt.Errorf("%d is greater than maximum value for uint8", srcVal) + } + *v = uint8(srcVal) + case *uint16: + if srcVal < 0 { + return fmt.Errorf("%d is less than zero for uint16", srcVal) + } else if srcVal > math.MaxUint16 { + return fmt.Errorf("%d is greater than maximum value for uint16", srcVal) + } + *v = uint16(srcVal) + case *uint32: + if srcVal < 0 { + return fmt.Errorf("%d is less than zero for uint32", srcVal) + } else if srcVal > math.MaxUint32 { + return fmt.Errorf("%d is greater than maximum value for uint32", srcVal) + } + *v = uint32(srcVal) + case *uint64: + if srcVal < 0 { + return fmt.Errorf("%d is less than zero for uint64", srcVal) + } + *v = uint64(srcVal) + case sql.Scanner: + return v.Scan(srcVal) + default: + if v := reflect.ValueOf(dst); v.Kind() == reflect.Ptr { + el := v.Elem() + switch el.Kind() { + // if dst is a pointer to pointer, strip the pointer and try again + case reflect.Ptr: + if el.IsNil() { + // allocate destination + el.Set(reflect.New(el.Type().Elem())) + } + return int64AssignTo(srcVal, srcValid, el.Interface()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + if el.OverflowInt(int64(srcVal)) { + return fmt.Errorf("cannot put %d into %T", srcVal, dst) + } + el.SetInt(int64(srcVal)) + return nil + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + if srcVal < 0 { + return fmt.Errorf("%d is less than zero for %T", srcVal, dst) + } + if el.OverflowUint(uint64(srcVal)) { + return fmt.Errorf("cannot put %d into %T", srcVal, dst) + } + el.SetUint(uint64(srcVal)) + return nil + } + } + return fmt.Errorf("cannot assign %v into %T", srcVal, dst) + } + return nil + } + + // if dst is a pointer to pointer and srcStatus is not Valid, nil it out + if v := reflect.ValueOf(dst); v.Kind() == reflect.Ptr { + el := v.Elem() + if el.Kind() == reflect.Ptr { + el.Set(reflect.Zero(el.Type())) + return nil + } + } + + return fmt.Errorf("cannot assign %v %v into %T", srcVal, srcValid, dst) +} + +func float64AssignTo(srcVal float64, srcValid bool, dst any) error { + if srcValid { + switch v := dst.(type) { + case *float32: + *v = float32(srcVal) + case *float64: + *v = srcVal + default: + if v := reflect.ValueOf(dst); v.Kind() == reflect.Ptr { + el := v.Elem() + switch el.Kind() { + // if dst is a type alias of a float32 or 64, set dst val + case reflect.Float32, reflect.Float64: + el.SetFloat(srcVal) + return nil + // if dst is a pointer to pointer, strip the pointer and try again + case reflect.Ptr: + if el.IsNil() { + // allocate destination + el.Set(reflect.New(el.Type().Elem())) + } + return float64AssignTo(srcVal, srcValid, el.Interface()) + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + i64 := int64(srcVal) + if float64(i64) == srcVal { + return int64AssignTo(i64, srcValid, dst) + } + } + } + return fmt.Errorf("cannot assign %v into %T", srcVal, dst) + } + return nil + } + + // if dst is a pointer to pointer and srcStatus is not Valid, nil it out + if v := reflect.ValueOf(dst); v.Kind() == reflect.Ptr { + el := v.Elem() + if el.Kind() == reflect.Ptr { + el.Set(reflect.Zero(el.Type())) + return nil + } + } + + return fmt.Errorf("cannot assign %v %v into %T", srcVal, srcValid, dst) +} + +func NullAssignTo(dst any) error { + dstPtr := reflect.ValueOf(dst) + + // AssignTo dst must always be a pointer + if dstPtr.Kind() != reflect.Ptr { + return &nullAssignmentError{dst: dst} + } + + dstVal := dstPtr.Elem() + + switch dstVal.Kind() { + case reflect.Ptr, reflect.Slice, reflect.Map: + dstVal.Set(reflect.Zero(dstVal.Type())) + return nil + } + + return &nullAssignmentError{dst: dst} +} + +var kindTypes map[reflect.Kind]reflect.Type + +func toInterface(dst reflect.Value, t reflect.Type) (any, bool) { + nextDst := dst.Convert(t) + return nextDst.Interface(), dst.Type() != nextDst.Type() +} + +// GetAssignToDstType attempts to convert dst to something AssignTo can assign +// to. If dst is a pointer to pointer it allocates a value and returns the +// dereferences pointer. If dst is a named type such as *Foo where Foo is type +// Foo int16, it converts dst to *int16. +// +// GetAssignToDstType returns the converted dst and a bool representing if any +// change was made. +func GetAssignToDstType(dst any) (any, bool) { + dstPtr := reflect.ValueOf(dst) + + // AssignTo dst must always be a pointer + if dstPtr.Kind() != reflect.Ptr { + return nil, false + } + + dstVal := dstPtr.Elem() + + // if dst is a pointer to pointer, allocate space try again with the dereferenced pointer + if dstVal.Kind() == reflect.Ptr { + dstVal.Set(reflect.New(dstVal.Type().Elem())) + return dstVal.Interface(), true + } + + // if dst is pointer to a base type that has been renamed + if baseValType, ok := kindTypes[dstVal.Kind()]; ok { + return toInterface(dstPtr, reflect.PtrTo(baseValType)) + } + + if dstVal.Kind() == reflect.Slice { + if baseElemType, ok := kindTypes[dstVal.Type().Elem().Kind()]; ok { + return toInterface(dstPtr, reflect.PtrTo(reflect.SliceOf(baseElemType))) + } + } + + if dstVal.Kind() == reflect.Array { + if baseElemType, ok := kindTypes[dstVal.Type().Elem().Kind()]; ok { + return toInterface(dstPtr, reflect.PtrTo(reflect.ArrayOf(dstVal.Len(), baseElemType))) + } + } + + if dstVal.Kind() == reflect.Struct { + if dstVal.Type().NumField() == 1 && dstVal.Type().Field(0).Anonymous { + dstPtr = dstVal.Field(0).Addr() + nested := dstVal.Type().Field(0).Type + if nested.Kind() == reflect.Array { + if baseElemType, ok := kindTypes[nested.Elem().Kind()]; ok { + return toInterface(dstPtr, reflect.PtrTo(reflect.ArrayOf(nested.Len(), baseElemType))) + } + } + if _, ok := kindTypes[nested.Kind()]; ok && dstPtr.CanInterface() { + return dstPtr.Interface(), true + } + } + } + + return nil, false +} + +func init() { + kindTypes = map[reflect.Kind]reflect.Type{ + reflect.Bool: reflect.TypeOf(false), + reflect.Float32: reflect.TypeOf(float32(0)), + reflect.Float64: reflect.TypeOf(float64(0)), + reflect.Int: reflect.TypeOf(int(0)), + reflect.Int8: reflect.TypeOf(int8(0)), + reflect.Int16: reflect.TypeOf(int16(0)), + reflect.Int32: reflect.TypeOf(int32(0)), + reflect.Int64: reflect.TypeOf(int64(0)), + reflect.Uint: reflect.TypeOf(uint(0)), + reflect.Uint8: reflect.TypeOf(uint8(0)), + reflect.Uint16: reflect.TypeOf(uint16(0)), + reflect.Uint32: reflect.TypeOf(uint32(0)), + reflect.Uint64: reflect.TypeOf(uint64(0)), + reflect.String: reflect.TypeOf(""), + } +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/date.go b/vendor/github.com/jackc/pgx/v5/pgtype/date.go new file mode 100644 index 00000000000..009fc0dbb2e --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/date.go @@ -0,0 +1,351 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "encoding/json" + "fmt" + "regexp" + "strconv" + "time" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type DateScanner interface { + ScanDate(v Date) error +} + +type DateValuer interface { + DateValue() (Date, error) +} + +type Date struct { + Time time.Time + InfinityModifier InfinityModifier + Valid bool +} + +func (d *Date) ScanDate(v Date) error { + *d = v + return nil +} + +func (d Date) DateValue() (Date, error) { + return d, nil +} + +const ( + negativeInfinityDayOffset = -2147483648 + infinityDayOffset = 2147483647 +) + +// Scan implements the database/sql Scanner interface. +func (dst *Date) Scan(src any) error { + if src == nil { + *dst = Date{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToDateScanner{}.Scan([]byte(src), dst) + case time.Time: + *dst = Date{Time: src, Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src Date) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + if src.InfinityModifier != Finite { + return src.InfinityModifier.String(), nil + } + return src.Time, nil +} + +func (src Date) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + + var s string + + switch src.InfinityModifier { + case Finite: + s = src.Time.Format("2006-01-02") + case Infinity: + s = "infinity" + case NegativeInfinity: + s = "-infinity" + } + + return json.Marshal(s) +} + +func (dst *Date) UnmarshalJSON(b []byte) error { + var s *string + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + if s == nil { + *dst = Date{} + return nil + } + + switch *s { + case "infinity": + *dst = Date{Valid: true, InfinityModifier: Infinity} + case "-infinity": + *dst = Date{Valid: true, InfinityModifier: -Infinity} + default: + t, err := time.ParseInLocation("2006-01-02", *s, time.UTC) + if err != nil { + return err + } + + *dst = Date{Time: t, Valid: true} + } + + return nil +} + +type DateCodec struct{} + +func (DateCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (DateCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (DateCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(DateValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanDateCodecBinary{} + case TextFormatCode: + return encodePlanDateCodecText{} + } + + return nil +} + +type encodePlanDateCodecBinary struct{} + +func (encodePlanDateCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + date, err := value.(DateValuer).DateValue() + if err != nil { + return nil, err + } + + if !date.Valid { + return nil, nil + } + + var daysSinceDateEpoch int32 + switch date.InfinityModifier { + case Finite: + tUnix := time.Date(date.Time.Year(), date.Time.Month(), date.Time.Day(), 0, 0, 0, 0, time.UTC).Unix() + dateEpoch := time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC).Unix() + + secSinceDateEpoch := tUnix - dateEpoch + daysSinceDateEpoch = int32(secSinceDateEpoch / 86400) + case Infinity: + daysSinceDateEpoch = infinityDayOffset + case NegativeInfinity: + daysSinceDateEpoch = negativeInfinityDayOffset + } + + return pgio.AppendInt32(buf, daysSinceDateEpoch), nil +} + +type encodePlanDateCodecText struct{} + +func (encodePlanDateCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + date, err := value.(DateValuer).DateValue() + if err != nil { + return nil, err + } + + if !date.Valid { + return nil, nil + } + + switch date.InfinityModifier { + case Finite: + // Year 0000 is 1 BC + bc := false + year := date.Time.Year() + if year <= 0 { + year = -year + 1 + bc = true + } + + yearBytes := strconv.AppendInt(make([]byte, 0, 6), int64(year), 10) + for i := len(yearBytes); i < 4; i++ { + buf = append(buf, '0') + } + buf = append(buf, yearBytes...) + buf = append(buf, '-') + if date.Time.Month() < 10 { + buf = append(buf, '0') + } + buf = strconv.AppendInt(buf, int64(date.Time.Month()), 10) + buf = append(buf, '-') + if date.Time.Day() < 10 { + buf = append(buf, '0') + } + buf = strconv.AppendInt(buf, int64(date.Time.Day()), 10) + + if bc { + buf = append(buf, " BC"...) + } + case Infinity: + buf = append(buf, "infinity"...) + case NegativeInfinity: + buf = append(buf, "-infinity"...) + } + + return buf, nil +} + +func (DateCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case DateScanner: + return scanPlanBinaryDateToDateScanner{} + } + case TextFormatCode: + switch target.(type) { + case DateScanner: + return scanPlanTextAnyToDateScanner{} + } + } + + return nil +} + +type scanPlanBinaryDateToDateScanner struct{} + +func (scanPlanBinaryDateToDateScanner) Scan(src []byte, dst any) error { + scanner := (dst).(DateScanner) + + if src == nil { + return scanner.ScanDate(Date{}) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for date: %v", len(src)) + } + + dayOffset := int32(binary.BigEndian.Uint32(src)) + + switch dayOffset { + case infinityDayOffset: + return scanner.ScanDate(Date{InfinityModifier: Infinity, Valid: true}) + case negativeInfinityDayOffset: + return scanner.ScanDate(Date{InfinityModifier: -Infinity, Valid: true}) + default: + t := time.Date(2000, 1, int(1+dayOffset), 0, 0, 0, 0, time.UTC) + return scanner.ScanDate(Date{Time: t, Valid: true}) + } +} + +type scanPlanTextAnyToDateScanner struct{} + +var dateRegexp = regexp.MustCompile(`^(\d{4,})-(\d\d)-(\d\d)( BC)?$`) + +func (scanPlanTextAnyToDateScanner) Scan(src []byte, dst any) error { + scanner := (dst).(DateScanner) + + if src == nil { + return scanner.ScanDate(Date{}) + } + + sbuf := string(src) + match := dateRegexp.FindStringSubmatch(sbuf) + if match != nil { + year, err := strconv.ParseInt(match[1], 10, 32) + if err != nil { + return fmt.Errorf("BUG: cannot parse date that regexp matched (year): %v", err) + } + + month, err := strconv.ParseInt(match[2], 10, 32) + if err != nil { + return fmt.Errorf("BUG: cannot parse date that regexp matched (month): %v", err) + } + + day, err := strconv.ParseInt(match[3], 10, 32) + if err != nil { + return fmt.Errorf("BUG: cannot parse date that regexp matched (month): %v", err) + } + + // BC matched + if len(match[4]) > 0 { + year = -year + 1 + } + + t := time.Date(int(year), time.Month(month), int(day), 0, 0, 0, 0, time.UTC) + return scanner.ScanDate(Date{Time: t, Valid: true}) + } + + switch sbuf { + case "infinity": + return scanner.ScanDate(Date{InfinityModifier: Infinity, Valid: true}) + case "-infinity": + return scanner.ScanDate(Date{InfinityModifier: -Infinity, Valid: true}) + default: + return fmt.Errorf("invalid date format") + } +} + +func (c DateCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var date Date + err := codecScan(c, m, oid, format, src, &date) + if err != nil { + return nil, err + } + + if date.InfinityModifier != Finite { + return date.InfinityModifier.String(), nil + } + + return date.Time, nil +} + +func (c DateCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var date Date + err := codecScan(c, m, oid, format, src, &date) + if err != nil { + return nil, err + } + + if date.InfinityModifier != Finite { + return date.InfinityModifier, nil + } + + return date.Time, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/doc.go b/vendor/github.com/jackc/pgx/v5/pgtype/doc.go new file mode 100644 index 00000000000..6612c89665b --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/doc.go @@ -0,0 +1,178 @@ +// Package pgtype converts between Go and PostgreSQL values. +/* +The primary type is the Map type. It is a map of PostgreSQL types identified by OID (object ID) to a Codec. A Codec is +responsible for converting between Go and PostgreSQL values. NewMap creates a Map with all supported standard PostgreSQL +types already registered. Additional types can be registered with Map.RegisterType. + +Use Map.Scan and Map.Encode to decode PostgreSQL values to Go and encode Go values to PostgreSQL respectively. + +Base Type Mapping + +pgtype maps between all common base types directly between Go and PostgreSQL. In particular: + + Go PostgreSQL + ----------------------- + string varchar + text + + // Integers are automatically be converted to any other integer type if + // it can be done without overflow or underflow. + int8 + int16 smallint + int32 int + int64 bigint + int + uint8 + uint16 + uint32 + uint64 + uint + + // Floats are strict and do not automatically convert like integers. + float32 float4 + float64 float8 + + time.Time date + timestamp + timestamptz + + netip.Addr inet + netip.Prefix cidr + + []byte bytea + +Null Values + +pgtype can map NULLs in two ways. The first is types that can directly represent NULL such as Int4. They work in a +similar fashion to database/sql. The second is to use a pointer to a pointer. + + var foo pgtype.Text + var bar *string + err := conn.QueryRow("select foo, bar from widgets where id=$1", 42).Scan(&foo, &bar) + if err != nil { + return err + } + +JSON Support + +pgtype automatically marshals and unmarshals data from json and jsonb PostgreSQL types. + +Extending Existing PostgreSQL Type Support + +Generally, all Codecs will support interfaces that can be implemented to enable scanning and encoding. For example, +PointCodec can use any Go type that implements the PointScanner and PointValuer interfaces. So rather than use +pgtype.Point and application can directly use its own point type with pgtype as long as it implements those interfaces. + +See example_custom_type_test.go for an example of a custom type for the PostgreSQL point type. + +Sometimes pgx supports a PostgreSQL type such as numeric but the Go type is in an external package that does not have +pgx support such as github.com/shopspring/decimal. These types can be registered with pgtype with custom conversion +logic. See https://github.com/jackc/pgx-shopspring-decimal and https://github.com/jackc/pgx-gofrs-uuid for a example +integrations. + +New PostgreSQL Type Support + +pgtype uses the PostgreSQL OID to determine how to encode or decode a value. pgtype supports array, composite, domain, +and enum types. However, any type created in PostgreSQL with CREATE TYPE will receive a new OID. This means that the OID +of each new PostgreSQL type must be registered for pgtype to handle values of that type with the correct Codec. + +The pgx.Conn LoadType method can return a *Type for array, composite, domain, and enum types by inspecting the database +metadata. This *Type can then be registered with Map.RegisterType. + +For example, the following function could be called after a connection is established: + + func RegisterDataTypes(ctx context.Context, conn *pgx.Conn) error { + dataTypeNames := []string{ + "foo", + "_foo", + "bar", + "_bar", + } + + for _, typeName := range dataTypeNames { + dataType, err := conn.LoadType(ctx, typeName) + if err != nil { + return err + } + conn.TypeMap().RegisterType(dataType) + } + + return nil + } + +A type cannot be registered unless all types it depends on are already registered. e.g. An array type cannot be +registered until its element type is registered. + +ArrayCodec implements support for arrays. If pgtype supports type T then it can easily support []T by registering an +ArrayCodec for the appropriate PostgreSQL OID. In addition, Array[T] type can support multi-dimensional arrays. + +CompositeCodec implements support for PostgreSQL composite types. Go structs can be scanned into if the public fields of +the struct are in the exact order and type of the PostgreSQL type or by implementing CompositeIndexScanner and +CompositeIndexGetter. + +Domain types are treated as their underlying type if the underlying type and the domain type are registered. + +PostgreSQL enums can usually be treated as text. However, EnumCodec implements support for interning strings which can +reduce memory usage. + +While pgtype will often still work with unregistered types it is highly recommended that all types be registered due to +an improvement in performance and the elimination of certain edge cases. + +If an entirely new PostgreSQL type (e.g. PostGIS types) is used then the application or a library can create a new +Codec. Then the OID / Codec mapping can be registered with Map.RegisterType. There is no difference between a Codec +defined and registered by the application and a Codec built in to pgtype. See any of the Codecs in pgtype for Codec +examples and for examples of type registration. + +Encoding Unknown Types + +pgtype works best when the OID of the PostgreSQL type is known. But in some cases such as using the simple protocol the +OID is unknown. In this case Map.RegisterDefaultPgType can be used to register an assumed OID for a particular Go type. + +Renamed Types + +If pgtype does not recognize a type and that type is a renamed simple type simple (e.g. type MyInt32 int32) pgtype acts +as if it is the underlying type. It currently cannot automatically detect the underlying type of renamed structs (eg.g. +type MyTime time.Time). + +Compatibility with database/sql + +pgtype also includes support for custom types implementing the database/sql.Scanner and database/sql/driver.Valuer +interfaces. + +Child Records + +pgtype's support for arrays and composite records can be used to load records and their children in a single query. See +example_child_records_test.go for an example. + +Overview of Scanning Implementation + +The first step is to use the OID to lookup the correct Codec. If the OID is unavailable, Map will try to find the OID +from previous calls of Map.RegisterDefaultPgType. The Map will call the Codec's PlanScan method to get a plan for +scanning into the Go value. A Codec will support scanning into one or more Go types. Oftentime these Go types are +interfaces rather than explicit types. For example, PointCodec can use any Go type that implments the PointScanner and +PointValuer interfaces. + +If a Go value is not supported directly by a Codec then Map will try wrapping it with additional logic and try again. +For example, Int8Codec does not support scanning into a renamed type (e.g. type myInt64 int64). But Map will detect that +myInt64 is a renamed type and create a plan that converts the value to the underlying int64 type and then passes that to +the Codec (see TryFindUnderlyingTypeScanPlan). + +These plan wrappers are contained in Map.TryWrapScanPlanFuncs. By default these contain shared logic to handle renamed +types, pointers to pointers, slices, composite types, etc. Additional plan wrappers can be added to seamlessly integrate +types that do not support pgx directly. For example, the before mentioned +https://github.com/jackc/pgx-shopspring-decimal package detects decimal.Decimal values, wraps them in something +implementing NumericScanner and passes that to the Codec. + +Map.Scan and Map.Encode are convenience methods that wrap Map.PlanScan and Map.PlanEncode. Determining how to scan or +encode a particular type may be a time consuming operation. Hence the planning and execution steps of a conversion are +internally separated. + +Reducing Compiled Binary Size + +pgx.QueryExecModeExec and pgx.QueryExecModeSimpleProtocol require the default PostgreSQL type to be registered for each +Go type used as a query parameter. By default pgx does this for all supported types and their array variants. If an +application does not use those query execution modes or manually registers the default PostgreSQL type for the types it +uses as query parameters it can use the build tag nopgxregisterdefaulttypes. This omits the default type registration +and reduces the compiled binary size by ~2MB. +*/ +package pgtype diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/enum_codec.go b/vendor/github.com/jackc/pgx/v5/pgtype/enum_codec.go new file mode 100644 index 00000000000..5e787c1e292 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/enum_codec.go @@ -0,0 +1,109 @@ +package pgtype + +import ( + "database/sql/driver" + "fmt" +) + +// EnumCodec is a codec that caches the strings it decodes. If the same string is read multiple times only one copy is +// allocated. These strings are only garbage collected when the EnumCodec is garbage collected. EnumCodec can be used +// for any text type not only enums, but it should only be used when there are a small number of possible values. +type EnumCodec struct { + membersMap map[string]string // map to quickly lookup member and reuse string instead of allocating +} + +func (EnumCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (EnumCodec) PreferredFormat() int16 { + return TextFormatCode +} + +func (EnumCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case TextFormatCode, BinaryFormatCode: + switch value.(type) { + case string: + return encodePlanTextCodecString{} + case []byte: + return encodePlanTextCodecByteSlice{} + case TextValuer: + return encodePlanTextCodecTextValuer{} + } + } + + return nil +} + +func (c *EnumCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case TextFormatCode, BinaryFormatCode: + switch target.(type) { + case *string: + return &scanPlanTextAnyToEnumString{codec: c} + case *[]byte: + return scanPlanAnyToNewByteSlice{} + case TextScanner: + return &scanPlanTextAnyToEnumTextScanner{codec: c} + } + } + + return nil +} + +func (c *EnumCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) +} + +func (c *EnumCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + return c.lookupAndCacheString(src), nil +} + +// lookupAndCacheString looks for src in the members map. If it is not found it is added to the map. +func (c *EnumCodec) lookupAndCacheString(src []byte) string { + if c.membersMap == nil { + c.membersMap = make(map[string]string) + } + + if s, found := c.membersMap[string(src)]; found { + return s + } + + s := string(src) + c.membersMap[s] = s + return s +} + +type scanPlanTextAnyToEnumString struct { + codec *EnumCodec +} + +func (plan *scanPlanTextAnyToEnumString) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p := (dst).(*string) + *p = plan.codec.lookupAndCacheString(src) + + return nil +} + +type scanPlanTextAnyToEnumTextScanner struct { + codec *EnumCodec +} + +func (plan *scanPlanTextAnyToEnumTextScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TextScanner) + + if src == nil { + return scanner.ScanText(Text{}) + } + + return scanner.ScanText(Text{String: plan.codec.lookupAndCacheString(src), Valid: true}) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/float4.go b/vendor/github.com/jackc/pgx/v5/pgtype/float4.go new file mode 100644 index 00000000000..2540f9e510b --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/float4.go @@ -0,0 +1,295 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Float4 struct { + Float32 float32 + Valid bool +} + +// ScanFloat64 implements the Float64Scanner interface. +func (f *Float4) ScanFloat64(n Float8) error { + *f = Float4{Float32: float32(n.Float64), Valid: n.Valid} + return nil +} + +func (f Float4) Float64Value() (Float8, error) { + return Float8{Float64: float64(f.Float32), Valid: f.Valid}, nil +} + +func (f *Float4) ScanInt64(n Int8) error { + *f = Float4{Float32: float32(n.Int64), Valid: n.Valid} + return nil +} + +func (f Float4) Int64Value() (Int8, error) { + return Int8{Int64: int64(f.Float32), Valid: f.Valid}, nil +} + +// Scan implements the database/sql Scanner interface. +func (f *Float4) Scan(src any) error { + if src == nil { + *f = Float4{} + return nil + } + + switch src := src.(type) { + case float64: + *f = Float4{Float32: float32(src), Valid: true} + return nil + case string: + n, err := strconv.ParseFloat(string(src), 32) + if err != nil { + return err + } + *f = Float4{Float32: float32(n), Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (f Float4) Value() (driver.Value, error) { + if !f.Valid { + return nil, nil + } + return float64(f.Float32), nil +} + +type Float4Codec struct{} + +func (Float4Codec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (Float4Codec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (Float4Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case float32: + return encodePlanFloat4CodecBinaryFloat32{} + case Float64Valuer: + return encodePlanFloat4CodecBinaryFloat64Valuer{} + case Int64Valuer: + return encodePlanFloat4CodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case float32: + return encodePlanTextFloat32{} + case Float64Valuer: + return encodePlanTextFloat64Valuer{} + case Int64Valuer: + return encodePlanTextInt64Valuer{} + } + } + + return nil +} + +type encodePlanFloat4CodecBinaryFloat32 struct{} + +func (encodePlanFloat4CodecBinaryFloat32) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(float32) + return pgio.AppendUint32(buf, math.Float32bits(n)), nil +} + +type encodePlanTextFloat32 struct{} + +func (encodePlanTextFloat32) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(float32) + return append(buf, strconv.FormatFloat(float64(n), 'f', -1, 32)...), nil +} + +type encodePlanFloat4CodecBinaryFloat64Valuer struct{} + +func (encodePlanFloat4CodecBinaryFloat64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Float64Valuer).Float64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + return pgio.AppendUint32(buf, math.Float32bits(float32(n.Float64))), nil +} + +type encodePlanFloat4CodecBinaryInt64Valuer struct{} + +func (encodePlanFloat4CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + f := float32(n.Int64) + return pgio.AppendUint32(buf, math.Float32bits(f)), nil +} + +func (Float4Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *float32: + return scanPlanBinaryFloat4ToFloat32{} + case Float64Scanner: + return scanPlanBinaryFloat4ToFloat64Scanner{} + case Int64Scanner: + return scanPlanBinaryFloat4ToInt64Scanner{} + case TextScanner: + return scanPlanBinaryFloat4ToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case *float32: + return scanPlanTextAnyToFloat32{} + case Float64Scanner: + return scanPlanTextAnyToFloat64Scanner{} + case Int64Scanner: + return scanPlanTextAnyToInt64Scanner{} + } + } + + return nil +} + +type scanPlanBinaryFloat4ToFloat32 struct{} + +func (scanPlanBinaryFloat4ToFloat32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for float4: %v", len(src)) + } + + n := int32(binary.BigEndian.Uint32(src)) + f := (dst).(*float32) + *f = math.Float32frombits(uint32(n)) + + return nil +} + +type scanPlanBinaryFloat4ToFloat64Scanner struct{} + +func (scanPlanBinaryFloat4ToFloat64Scanner) Scan(src []byte, dst any) error { + s := (dst).(Float64Scanner) + + if src == nil { + return s.ScanFloat64(Float8{}) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for float4: %v", len(src)) + } + + n := int32(binary.BigEndian.Uint32(src)) + return s.ScanFloat64(Float8{Float64: float64(math.Float32frombits(uint32(n))), Valid: true}) +} + +type scanPlanBinaryFloat4ToInt64Scanner struct{} + +func (scanPlanBinaryFloat4ToInt64Scanner) Scan(src []byte, dst any) error { + s := (dst).(Int64Scanner) + + if src == nil { + return s.ScanInt64(Int8{}) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for float4: %v", len(src)) + } + + ui32 := int32(binary.BigEndian.Uint32(src)) + f32 := math.Float32frombits(uint32(ui32)) + i64 := int64(f32) + if f32 != float32(i64) { + return fmt.Errorf("cannot losslessly convert %v to int64", f32) + } + + return s.ScanInt64(Int8{Int64: i64, Valid: true}) +} + +type scanPlanBinaryFloat4ToTextScanner struct{} + +func (scanPlanBinaryFloat4ToTextScanner) Scan(src []byte, dst any) error { + s := (dst).(TextScanner) + + if src == nil { + return s.ScanText(Text{}) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for float4: %v", len(src)) + } + + ui32 := int32(binary.BigEndian.Uint32(src)) + f32 := math.Float32frombits(uint32(ui32)) + + return s.ScanText(Text{String: strconv.FormatFloat(float64(f32), 'f', -1, 32), Valid: true}) +} + +type scanPlanTextAnyToFloat32 struct{} + +func (scanPlanTextAnyToFloat32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + n, err := strconv.ParseFloat(string(src), 32) + if err != nil { + return err + } + + f := (dst).(*float32) + *f = float32(n) + + return nil +} + +func (c Float4Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var n float64 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +func (c Float4Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n float32 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/float8.go b/vendor/github.com/jackc/pgx/v5/pgtype/float8.go new file mode 100644 index 00000000000..65e5d8b325b --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/float8.go @@ -0,0 +1,349 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "encoding/json" + "fmt" + "math" + "strconv" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Float64Scanner interface { + ScanFloat64(Float8) error +} + +type Float64Valuer interface { + Float64Value() (Float8, error) +} + +type Float8 struct { + Float64 float64 + Valid bool +} + +// ScanFloat64 implements the Float64Scanner interface. +func (f *Float8) ScanFloat64(n Float8) error { + *f = n + return nil +} + +func (f Float8) Float64Value() (Float8, error) { + return f, nil +} + +func (f *Float8) ScanInt64(n Int8) error { + *f = Float8{Float64: float64(n.Int64), Valid: n.Valid} + return nil +} + +func (f Float8) Int64Value() (Int8, error) { + return Int8{Int64: int64(f.Float64), Valid: f.Valid}, nil +} + +// Scan implements the database/sql Scanner interface. +func (f *Float8) Scan(src any) error { + if src == nil { + *f = Float8{} + return nil + } + + switch src := src.(type) { + case float64: + *f = Float8{Float64: src, Valid: true} + return nil + case string: + n, err := strconv.ParseFloat(string(src), 64) + if err != nil { + return err + } + *f = Float8{Float64: n, Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (f Float8) Value() (driver.Value, error) { + if !f.Valid { + return nil, nil + } + return f.Float64, nil +} + +type Float8Codec struct{} + +func (Float8Codec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (Float8Codec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (Float8Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case float64: + return encodePlanFloat8CodecBinaryFloat64{} + case Float64Valuer: + return encodePlanFloat8CodecBinaryFloat64Valuer{} + case Int64Valuer: + return encodePlanFloat8CodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case float64: + return encodePlanTextFloat64{} + case Float64Valuer: + return encodePlanTextFloat64Valuer{} + case Int64Valuer: + return encodePlanTextInt64Valuer{} + } + } + + return nil +} + +func (f *Float8) MarshalJSON() ([]byte, error) { + if !f.Valid { + return []byte("null"), nil + } + return json.Marshal(f.Float64) +} + +type encodePlanFloat8CodecBinaryFloat64 struct{} + +func (encodePlanFloat8CodecBinaryFloat64) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(float64) + return pgio.AppendUint64(buf, math.Float64bits(n)), nil +} + +type encodePlanTextFloat64 struct{} + +func (encodePlanTextFloat64) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(float64) + return append(buf, strconv.FormatFloat(n, 'f', -1, 64)...), nil +} + +type encodePlanFloat8CodecBinaryFloat64Valuer struct{} + +func (encodePlanFloat8CodecBinaryFloat64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Float64Valuer).Float64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + return pgio.AppendUint64(buf, math.Float64bits(n.Float64)), nil +} + +type encodePlanTextFloat64Valuer struct{} + +func (encodePlanTextFloat64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Float64Valuer).Float64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + return append(buf, strconv.FormatFloat(n.Float64, 'f', -1, 64)...), nil +} + +type encodePlanFloat8CodecBinaryInt64Valuer struct{} + +func (encodePlanFloat8CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + f := float64(n.Int64) + return pgio.AppendUint64(buf, math.Float64bits(f)), nil +} + +type encodePlanTextInt64Valuer struct{} + +func (encodePlanTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + return append(buf, strconv.FormatInt(n.Int64, 10)...), nil +} + +func (Float8Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *float64: + return scanPlanBinaryFloat8ToFloat64{} + case Float64Scanner: + return scanPlanBinaryFloat8ToFloat64Scanner{} + case Int64Scanner: + return scanPlanBinaryFloat8ToInt64Scanner{} + case TextScanner: + return scanPlanBinaryFloat8ToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case *float64: + return scanPlanTextAnyToFloat64{} + case Float64Scanner: + return scanPlanTextAnyToFloat64Scanner{} + case Int64Scanner: + return scanPlanTextAnyToInt64Scanner{} + } + } + + return nil +} + +type scanPlanBinaryFloat8ToFloat64 struct{} + +func (scanPlanBinaryFloat8ToFloat64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for float8: %v", len(src)) + } + + n := int64(binary.BigEndian.Uint64(src)) + f := (dst).(*float64) + *f = math.Float64frombits(uint64(n)) + + return nil +} + +type scanPlanBinaryFloat8ToFloat64Scanner struct{} + +func (scanPlanBinaryFloat8ToFloat64Scanner) Scan(src []byte, dst any) error { + s := (dst).(Float64Scanner) + + if src == nil { + return s.ScanFloat64(Float8{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for float8: %v", len(src)) + } + + n := int64(binary.BigEndian.Uint64(src)) + return s.ScanFloat64(Float8{Float64: math.Float64frombits(uint64(n)), Valid: true}) +} + +type scanPlanBinaryFloat8ToInt64Scanner struct{} + +func (scanPlanBinaryFloat8ToInt64Scanner) Scan(src []byte, dst any) error { + s := (dst).(Int64Scanner) + + if src == nil { + return s.ScanInt64(Int8{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for float8: %v", len(src)) + } + + ui64 := int64(binary.BigEndian.Uint64(src)) + f64 := math.Float64frombits(uint64(ui64)) + i64 := int64(f64) + if f64 != float64(i64) { + return fmt.Errorf("cannot losslessly convert %v to int64", f64) + } + + return s.ScanInt64(Int8{Int64: i64, Valid: true}) +} + +type scanPlanBinaryFloat8ToTextScanner struct{} + +func (scanPlanBinaryFloat8ToTextScanner) Scan(src []byte, dst any) error { + s := (dst).(TextScanner) + + if src == nil { + return s.ScanText(Text{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for float8: %v", len(src)) + } + + ui64 := int64(binary.BigEndian.Uint64(src)) + f64 := math.Float64frombits(uint64(ui64)) + + return s.ScanText(Text{String: strconv.FormatFloat(f64, 'f', -1, 64), Valid: true}) +} + +type scanPlanTextAnyToFloat64 struct{} + +func (scanPlanTextAnyToFloat64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + n, err := strconv.ParseFloat(string(src), 64) + if err != nil { + return err + } + + f := (dst).(*float64) + *f = n + + return nil +} + +type scanPlanTextAnyToFloat64Scanner struct{} + +func (scanPlanTextAnyToFloat64Scanner) Scan(src []byte, dst any) error { + s := (dst).(Float64Scanner) + + if src == nil { + return s.ScanFloat64(Float8{}) + } + + n, err := strconv.ParseFloat(string(src), 64) + if err != nil { + return err + } + + return s.ScanFloat64(Float8{Float64: n, Valid: true}) +} + +func (c Float8Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) +} + +func (c Float8Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n float64 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/hstore.go b/vendor/github.com/jackc/pgx/v5/pgtype/hstore.go new file mode 100644 index 00000000000..e4695819a5a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/hstore.go @@ -0,0 +1,467 @@ +package pgtype + +import ( + "bytes" + "database/sql/driver" + "encoding/binary" + "errors" + "fmt" + "unicode" + "unicode/utf8" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type HstoreScanner interface { + ScanHstore(v Hstore) error +} + +type HstoreValuer interface { + HstoreValue() (Hstore, error) +} + +// Hstore represents an hstore column that can be null or have null values +// associated with its keys. +type Hstore map[string]*string + +func (h *Hstore) ScanHstore(v Hstore) error { + *h = v + return nil +} + +func (h Hstore) HstoreValue() (Hstore, error) { + return h, nil +} + +// Scan implements the database/sql Scanner interface. +func (h *Hstore) Scan(src any) error { + if src == nil { + *h = nil + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToHstoreScanner{}.scanString(src, h) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (h Hstore) Value() (driver.Value, error) { + if h == nil { + return nil, nil + } + + buf, err := HstoreCodec{}.PlanEncode(nil, 0, TextFormatCode, h).Encode(h, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type HstoreCodec struct{} + +func (HstoreCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (HstoreCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (HstoreCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(HstoreValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanHstoreCodecBinary{} + case TextFormatCode: + return encodePlanHstoreCodecText{} + } + + return nil +} + +type encodePlanHstoreCodecBinary struct{} + +func (encodePlanHstoreCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + hstore, err := value.(HstoreValuer).HstoreValue() + if err != nil { + return nil, err + } + + if hstore == nil { + return nil, nil + } + + buf = pgio.AppendInt32(buf, int32(len(hstore))) + + for k, v := range hstore { + buf = pgio.AppendInt32(buf, int32(len(k))) + buf = append(buf, k...) + + if v == nil { + buf = pgio.AppendInt32(buf, -1) + } else { + buf = pgio.AppendInt32(buf, int32(len(*v))) + buf = append(buf, (*v)...) + } + } + + return buf, nil +} + +type encodePlanHstoreCodecText struct{} + +func (encodePlanHstoreCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + hstore, err := value.(HstoreValuer).HstoreValue() + if err != nil { + return nil, err + } + + if hstore == nil { + return nil, nil + } + + firstPair := true + + for k, v := range hstore { + if firstPair { + firstPair = false + } else { + buf = append(buf, ',') + } + + // unconditionally quote hstore keys/values like Postgres does + // this avoids a Mac OS X Postgres hstore parsing bug: + // https://www.postgresql.org/message-id/CA%2BHWA9awUW0%2BRV_gO9r1ABZwGoZxPztcJxPy8vMFSTbTfi4jig%40mail.gmail.com + buf = append(buf, '"') + buf = append(buf, quoteArrayReplacer.Replace(k)...) + buf = append(buf, '"') + buf = append(buf, "=>"...) + + if v == nil { + buf = append(buf, "NULL"...) + } else { + buf = append(buf, '"') + buf = append(buf, quoteArrayReplacer.Replace(*v)...) + buf = append(buf, '"') + } + } + + return buf, nil +} + +func (HstoreCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case HstoreScanner: + return scanPlanBinaryHstoreToHstoreScanner{} + } + case TextFormatCode: + switch target.(type) { + case HstoreScanner: + return scanPlanTextAnyToHstoreScanner{} + } + } + + return nil +} + +type scanPlanBinaryHstoreToHstoreScanner struct{} + +func (scanPlanBinaryHstoreToHstoreScanner) Scan(src []byte, dst any) error { + scanner := (dst).(HstoreScanner) + + if src == nil { + return scanner.ScanHstore(Hstore(nil)) + } + + rp := 0 + + if len(src[rp:]) < 4 { + return fmt.Errorf("hstore incomplete %v", src) + } + pairCount := int(int32(binary.BigEndian.Uint32(src[rp:]))) + rp += 4 + + hstore := make(Hstore, pairCount) + + for i := 0; i < pairCount; i++ { + if len(src[rp:]) < 4 { + return fmt.Errorf("hstore incomplete %v", src) + } + keyLen := int(int32(binary.BigEndian.Uint32(src[rp:]))) + rp += 4 + + if len(src[rp:]) < keyLen { + return fmt.Errorf("hstore incomplete %v", src) + } + key := string(src[rp : rp+keyLen]) + rp += keyLen + + if len(src[rp:]) < 4 { + return fmt.Errorf("hstore incomplete %v", src) + } + valueLen := int(int32(binary.BigEndian.Uint32(src[rp:]))) + rp += 4 + + var valueBuf []byte + if valueLen >= 0 { + valueBuf = src[rp : rp+valueLen] + rp += valueLen + } + + var value Text + err := scanPlanTextAnyToTextScanner{}.Scan(valueBuf, &value) + if err != nil { + return err + } + + if value.Valid { + hstore[key] = &value.String + } else { + hstore[key] = nil + } + } + + return scanner.ScanHstore(hstore) +} + +type scanPlanTextAnyToHstoreScanner struct{} + +func (s scanPlanTextAnyToHstoreScanner) Scan(src []byte, dst any) error { + scanner := (dst).(HstoreScanner) + + if src == nil { + return scanner.ScanHstore(Hstore(nil)) + } + return s.scanString(string(src), scanner) +} + +// scanString does not return nil hstore values because string cannot be nil. +func (scanPlanTextAnyToHstoreScanner) scanString(src string, scanner HstoreScanner) error { + keys, values, err := parseHstore(src) + if err != nil { + return err + } + + m := make(Hstore, len(keys)) + for i := range keys { + if values[i].Valid { + m[keys[i]] = &values[i].String + } else { + m[keys[i]] = nil + } + } + + return scanner.ScanHstore(m) +} + +func (c HstoreCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c HstoreCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var hstore Hstore + err := codecScan(c, m, oid, format, src, &hstore) + if err != nil { + return nil, err + } + return hstore, nil +} + +const ( + hsPre = iota + hsKey + hsSep + hsVal + hsNul + hsNext +) + +type hstoreParser struct { + str string + pos int +} + +func newHSP(in string) *hstoreParser { + return &hstoreParser{ + pos: 0, + str: in, + } +} + +func (p *hstoreParser) Consume() (r rune, end bool) { + if p.pos >= len(p.str) { + end = true + return + } + r, w := utf8.DecodeRuneInString(p.str[p.pos:]) + p.pos += w + return +} + +func (p *hstoreParser) Peek() (r rune, end bool) { + if p.pos >= len(p.str) { + end = true + return + } + r, _ = utf8.DecodeRuneInString(p.str[p.pos:]) + return +} + +// parseHstore parses the string representation of an hstore column (the same +// you would get from an ordinary SELECT) into two slices of keys and values. it +// is used internally in the default parsing of hstores. +func parseHstore(s string) (k []string, v []Text, err error) { + if s == "" { + return + } + + buf := bytes.Buffer{} + keys := []string{} + values := []Text{} + p := newHSP(s) + + r, end := p.Consume() + state := hsPre + + for !end { + switch state { + case hsPre: + if r == '"' { + state = hsKey + } else { + err = errors.New("String does not begin with \"") + } + case hsKey: + switch r { + case '"': //End of the key + keys = append(keys, buf.String()) + buf = bytes.Buffer{} + state = hsSep + case '\\': //Potential escaped character + n, end := p.Consume() + switch { + case end: + err = errors.New("Found EOS in key, expecting character or \"") + case n == '"', n == '\\': + buf.WriteRune(n) + default: + buf.WriteRune(r) + buf.WriteRune(n) + } + default: //Any other character + buf.WriteRune(r) + } + case hsSep: + if r == '=' { + r, end = p.Consume() + switch { + case end: + err = errors.New("Found EOS after '=', expecting '>'") + case r == '>': + r, end = p.Consume() + switch { + case end: + err = errors.New("Found EOS after '=>', expecting '\"' or 'NULL'") + case r == '"': + state = hsVal + case r == 'N': + state = hsNul + default: + err = fmt.Errorf("Invalid character '%c' after '=>', expecting '\"' or 'NULL'", r) + } + default: + err = fmt.Errorf("Invalid character after '=', expecting '>'") + } + } else { + err = fmt.Errorf("Invalid character '%c' after value, expecting '='", r) + } + case hsVal: + switch r { + case '"': //End of the value + values = append(values, Text{String: buf.String(), Valid: true}) + buf = bytes.Buffer{} + state = hsNext + case '\\': //Potential escaped character + n, end := p.Consume() + switch { + case end: + err = errors.New("Found EOS in key, expecting character or \"") + case n == '"', n == '\\': + buf.WriteRune(n) + default: + buf.WriteRune(r) + buf.WriteRune(n) + } + default: //Any other character + buf.WriteRune(r) + } + case hsNul: + nulBuf := make([]rune, 3) + nulBuf[0] = r + for i := 1; i < 3; i++ { + r, end = p.Consume() + if end { + err = errors.New("Found EOS in NULL value") + return + } + nulBuf[i] = r + } + if nulBuf[0] == 'U' && nulBuf[1] == 'L' && nulBuf[2] == 'L' { + values = append(values, Text{}) + state = hsNext + } else { + err = fmt.Errorf("Invalid NULL value: 'N%s'", string(nulBuf)) + } + case hsNext: + if r == ',' { + r, end = p.Consume() + switch { + case end: + err = errors.New("Found EOS after ',', expecting space") + case (unicode.IsSpace(r)): + // after space is a doublequote to start the key + r, end = p.Consume() + if end { + err = errors.New("Found EOS after space, expecting \"") + return + } + if r != '"' { + err = fmt.Errorf("Invalid character '%c' after space, expecting \"", r) + return + } + state = hsKey + default: + err = fmt.Errorf("Invalid character '%c' after ',', expecting space", r) + } + } else { + err = fmt.Errorf("Invalid character '%c' after value, expecting ','", r) + } + } + + if err != nil { + return + } + r, end = p.Consume() + } + if state != hsNext { + err = errors.New("Improperly formatted hstore") + return + } + k = keys + v = values + return +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/inet.go b/vendor/github.com/jackc/pgx/v5/pgtype/inet.go new file mode 100644 index 00000000000..a85646d73eb --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/inet.go @@ -0,0 +1,200 @@ +package pgtype + +import ( + "bytes" + "database/sql/driver" + "errors" + "fmt" + "net/netip" +) + +// Network address family is dependent on server socket.h value for AF_INET. +// In practice, all platforms appear to have the same value. See +// src/include/utils/inet.h for more information. +const ( + defaultAFInet = 2 + defaultAFInet6 = 3 +) + +type NetipPrefixScanner interface { + ScanNetipPrefix(v netip.Prefix) error +} + +type NetipPrefixValuer interface { + NetipPrefixValue() (netip.Prefix, error) +} + +// InetCodec handles both inet and cidr PostgreSQL types. The preferred Go types are netip.Prefix and netip.Addr. If +// IsValid() is false then they are treated as SQL NULL. +type InetCodec struct{} + +func (InetCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (InetCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (InetCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(NetipPrefixValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanInetCodecBinary{} + case TextFormatCode: + return encodePlanInetCodecText{} + } + + return nil +} + +type encodePlanInetCodecBinary struct{} + +func (encodePlanInetCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + prefix, err := value.(NetipPrefixValuer).NetipPrefixValue() + if err != nil { + return nil, err + } + + if !prefix.IsValid() { + return nil, nil + } + + var family byte + if prefix.Addr().Is4() { + family = defaultAFInet + } else { + family = defaultAFInet6 + } + + buf = append(buf, family) + + ones := prefix.Bits() + buf = append(buf, byte(ones)) + + // is_cidr is ignored on server + buf = append(buf, 0) + + if family == defaultAFInet { + buf = append(buf, byte(4)) + b := prefix.Addr().As4() + buf = append(buf, b[:]...) + } else { + buf = append(buf, byte(16)) + b := prefix.Addr().As16() + buf = append(buf, b[:]...) + } + + return buf, nil +} + +type encodePlanInetCodecText struct{} + +func (encodePlanInetCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + prefix, err := value.(NetipPrefixValuer).NetipPrefixValue() + if err != nil { + return nil, err + } + + if !prefix.IsValid() { + return nil, nil + } + + return append(buf, prefix.String()...), nil +} + +func (InetCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case NetipPrefixScanner: + return scanPlanBinaryInetToNetipPrefixScanner{} + } + case TextFormatCode: + switch target.(type) { + case NetipPrefixScanner: + return scanPlanTextAnyToNetipPrefixScanner{} + } + } + + return nil +} + +func (c InetCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c InetCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var prefix netip.Prefix + err := codecScan(c, m, oid, format, src, (*netipPrefixWrapper)(&prefix)) + if err != nil { + return nil, err + } + + if !prefix.IsValid() { + return nil, nil + } + + return prefix, nil +} + +type scanPlanBinaryInetToNetipPrefixScanner struct{} + +func (scanPlanBinaryInetToNetipPrefixScanner) Scan(src []byte, dst any) error { + scanner := (dst).(NetipPrefixScanner) + + if src == nil { + return scanner.ScanNetipPrefix(netip.Prefix{}) + } + + if len(src) != 8 && len(src) != 20 { + return fmt.Errorf("Received an invalid size for a inet: %d", len(src)) + } + + // ignore family + bits := src[1] + // ignore is_cidr + // ignore addressLength - implicit in length of message + + addr, ok := netip.AddrFromSlice(src[4:]) + if !ok { + return errors.New("netip.AddrFromSlice failed") + } + + return scanner.ScanNetipPrefix(netip.PrefixFrom(addr, int(bits))) +} + +type scanPlanTextAnyToNetipPrefixScanner struct{} + +func (scanPlanTextAnyToNetipPrefixScanner) Scan(src []byte, dst any) error { + scanner := (dst).(NetipPrefixScanner) + + if src == nil { + return scanner.ScanNetipPrefix(netip.Prefix{}) + } + + var prefix netip.Prefix + if bytes.IndexByte(src, '/') == -1 { + addr, err := netip.ParseAddr(string(src)) + if err != nil { + return err + } + prefix = netip.PrefixFrom(addr, addr.BitLen()) + } else { + var err error + prefix, err = netip.ParsePrefix(string(src)) + if err != nil { + return err + } + } + + return scanner.ScanNetipPrefix(prefix) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/int.go b/vendor/github.com/jackc/pgx/v5/pgtype/int.go new file mode 100644 index 00000000000..90a20a26aa0 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/int.go @@ -0,0 +1,1980 @@ +// Do not edit. Generated from pgtype/int.go.erb +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "encoding/json" + "fmt" + "math" + "strconv" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Int64Scanner interface { + ScanInt64(Int8) error +} + +type Int64Valuer interface { + Int64Value() (Int8, error) +} + +type Int2 struct { + Int16 int16 + Valid bool +} + +// ScanInt64 implements the Int64Scanner interface. +func (dst *Int2) ScanInt64(n Int8) error { + if !n.Valid { + *dst = Int2{} + return nil + } + + if n.Int64 < math.MinInt16 { + return fmt.Errorf("%d is less than minimum value for Int2", n.Int64) + } + if n.Int64 > math.MaxInt16 { + return fmt.Errorf("%d is greater than maximum value for Int2", n.Int64) + } + *dst = Int2{Int16: int16(n.Int64), Valid: true} + + return nil +} + +func (n Int2) Int64Value() (Int8, error) { + return Int8{Int64: int64(n.Int16), Valid: n.Valid}, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Int2) Scan(src any) error { + if src == nil { + *dst = Int2{} + return nil + } + + var n int64 + + switch src := src.(type) { + case int64: + n = src + case string: + var err error + n, err = strconv.ParseInt(src, 10, 16) + if err != nil { + return err + } + case []byte: + var err error + n, err = strconv.ParseInt(string(src), 10, 16) + if err != nil { + return err + } + default: + return fmt.Errorf("cannot scan %T", src) + } + + if n < math.MinInt16 { + return fmt.Errorf("%d is greater than maximum value for Int2", n) + } + if n > math.MaxInt16 { + return fmt.Errorf("%d is greater than maximum value for Int2", n) + } + *dst = Int2{Int16: int16(n), Valid: true} + + return nil +} + +// Value implements the database/sql/driver Valuer interface. +func (src Int2) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + return int64(src.Int16), nil +} + +func (src Int2) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + return []byte(strconv.FormatInt(int64(src.Int16), 10)), nil +} + +func (dst *Int2) UnmarshalJSON(b []byte) error { + var n *int16 + err := json.Unmarshal(b, &n) + if err != nil { + return err + } + + if n == nil { + *dst = Int2{} + } else { + *dst = Int2{Int16: *n, Valid: true} + } + + return nil +} + +type Int2Codec struct{} + +func (Int2Codec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (Int2Codec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (Int2Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case int16: + return encodePlanInt2CodecBinaryInt16{} + case Int64Valuer: + return encodePlanInt2CodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case int16: + return encodePlanInt2CodecTextInt16{} + case Int64Valuer: + return encodePlanInt2CodecTextInt64Valuer{} + } + } + + return nil +} + +type encodePlanInt2CodecBinaryInt16 struct{} + +func (encodePlanInt2CodecBinaryInt16) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int16) + return pgio.AppendInt16(buf, int16(n)), nil +} + +type encodePlanInt2CodecTextInt16 struct{} + +func (encodePlanInt2CodecTextInt16) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int16) + return append(buf, strconv.FormatInt(int64(n), 10)...), nil +} + +type encodePlanInt2CodecBinaryInt64Valuer struct{} + +func (encodePlanInt2CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt16 { + return nil, fmt.Errorf("%d is greater than maximum value for int2", n.Int64) + } + if n.Int64 < math.MinInt16 { + return nil, fmt.Errorf("%d is less than minimum value for int2", n.Int64) + } + + return pgio.AppendInt16(buf, int16(n.Int64)), nil +} + +type encodePlanInt2CodecTextInt64Valuer struct{} + +func (encodePlanInt2CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt16 { + return nil, fmt.Errorf("%d is greater than maximum value for int2", n.Int64) + } + if n.Int64 < math.MinInt16 { + return nil, fmt.Errorf("%d is less than minimum value for int2", n.Int64) + } + + return append(buf, strconv.FormatInt(n.Int64, 10)...), nil +} + +func (Int2Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *int8: + return scanPlanBinaryInt2ToInt8{} + case *int16: + return scanPlanBinaryInt2ToInt16{} + case *int32: + return scanPlanBinaryInt2ToInt32{} + case *int64: + return scanPlanBinaryInt2ToInt64{} + case *int: + return scanPlanBinaryInt2ToInt{} + case *uint8: + return scanPlanBinaryInt2ToUint8{} + case *uint16: + return scanPlanBinaryInt2ToUint16{} + case *uint32: + return scanPlanBinaryInt2ToUint32{} + case *uint64: + return scanPlanBinaryInt2ToUint64{} + case *uint: + return scanPlanBinaryInt2ToUint{} + case Int64Scanner: + return scanPlanBinaryInt2ToInt64Scanner{} + case TextScanner: + return scanPlanBinaryInt2ToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case *int8: + return scanPlanTextAnyToInt8{} + case *int16: + return scanPlanTextAnyToInt16{} + case *int32: + return scanPlanTextAnyToInt32{} + case *int64: + return scanPlanTextAnyToInt64{} + case *int: + return scanPlanTextAnyToInt{} + case *uint8: + return scanPlanTextAnyToUint8{} + case *uint16: + return scanPlanTextAnyToUint16{} + case *uint32: + return scanPlanTextAnyToUint32{} + case *uint64: + return scanPlanTextAnyToUint64{} + case *uint: + return scanPlanTextAnyToUint{} + case Int64Scanner: + return scanPlanTextAnyToInt64Scanner{} + } + } + + return nil +} + +func (c Int2Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var n int64 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +func (c Int2Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n int16 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +type scanPlanBinaryInt2ToInt8 struct{} + +func (scanPlanBinaryInt2ToInt8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for int2: %v", len(src)) + } + + p, ok := (dst).(*int8) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int16(binary.BigEndian.Uint16(src)) + if n < math.MinInt8 { + return fmt.Errorf("%d is less than minimum value for int8", n) + } else if n > math.MaxInt8 { + return fmt.Errorf("%d is greater than maximum value for int8", n) + } + + *p = int8(n) + + return nil +} + +type scanPlanBinaryInt2ToUint8 struct{} + +func (scanPlanBinaryInt2ToUint8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for uint2: %v", len(src)) + } + + p, ok := (dst).(*uint8) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int16(binary.BigEndian.Uint16(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint8", n) + } + + if n > math.MaxUint8 { + return fmt.Errorf("%d is greater than maximum value for uint8", n) + } + + *p = uint8(n) + + return nil +} + +type scanPlanBinaryInt2ToInt16 struct{} + +func (scanPlanBinaryInt2ToInt16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for int2: %v", len(src)) + } + + p, ok := (dst).(*int16) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int16(binary.BigEndian.Uint16(src)) + + return nil +} + +type scanPlanBinaryInt2ToUint16 struct{} + +func (scanPlanBinaryInt2ToUint16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for uint2: %v", len(src)) + } + + p, ok := (dst).(*uint16) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int16(binary.BigEndian.Uint16(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint16", n) + } + + *p = uint16(n) + + return nil +} + +type scanPlanBinaryInt2ToInt32 struct{} + +func (scanPlanBinaryInt2ToInt32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for int2: %v", len(src)) + } + + p, ok := (dst).(*int32) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int32(int16(binary.BigEndian.Uint16(src))) + + return nil +} + +type scanPlanBinaryInt2ToUint32 struct{} + +func (scanPlanBinaryInt2ToUint32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for uint2: %v", len(src)) + } + + p, ok := (dst).(*uint32) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int16(binary.BigEndian.Uint16(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint32", n) + } + + *p = uint32(n) + + return nil +} + +type scanPlanBinaryInt2ToInt64 struct{} + +func (scanPlanBinaryInt2ToInt64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for int2: %v", len(src)) + } + + p, ok := (dst).(*int64) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int64(int16(binary.BigEndian.Uint16(src))) + + return nil +} + +type scanPlanBinaryInt2ToUint64 struct{} + +func (scanPlanBinaryInt2ToUint64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for uint2: %v", len(src)) + } + + p, ok := (dst).(*uint64) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int16(binary.BigEndian.Uint16(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint64", n) + } + + *p = uint64(n) + + return nil +} + +type scanPlanBinaryInt2ToInt struct{} + +func (scanPlanBinaryInt2ToInt) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for int2: %v", len(src)) + } + + p, ok := (dst).(*int) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int(int16(binary.BigEndian.Uint16(src))) + + return nil +} + +type scanPlanBinaryInt2ToUint struct{} + +func (scanPlanBinaryInt2ToUint) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for uint2: %v", len(src)) + } + + p, ok := (dst).(*uint) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(int16(binary.BigEndian.Uint16(src))) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint", n) + } + + *p = uint(n) + + return nil +} + +type scanPlanBinaryInt2ToInt64Scanner struct{} + +func (scanPlanBinaryInt2ToInt64Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Int64Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanInt64(Int8{}) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for int2: %v", len(src)) + } + + n := int64(int16(binary.BigEndian.Uint16(src))) + + return s.ScanInt64(Int8{Int64: n, Valid: true}) +} + +type scanPlanBinaryInt2ToTextScanner struct{} + +func (scanPlanBinaryInt2ToTextScanner) Scan(src []byte, dst any) error { + s, ok := (dst).(TextScanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanText(Text{}) + } + + if len(src) != 2 { + return fmt.Errorf("invalid length for int2: %v", len(src)) + } + + n := int64(int16(binary.BigEndian.Uint16(src))) + + return s.ScanText(Text{String: strconv.FormatInt(n, 10), Valid: true}) +} + +type Int4 struct { + Int32 int32 + Valid bool +} + +// ScanInt64 implements the Int64Scanner interface. +func (dst *Int4) ScanInt64(n Int8) error { + if !n.Valid { + *dst = Int4{} + return nil + } + + if n.Int64 < math.MinInt32 { + return fmt.Errorf("%d is less than minimum value for Int4", n.Int64) + } + if n.Int64 > math.MaxInt32 { + return fmt.Errorf("%d is greater than maximum value for Int4", n.Int64) + } + *dst = Int4{Int32: int32(n.Int64), Valid: true} + + return nil +} + +func (n Int4) Int64Value() (Int8, error) { + return Int8{Int64: int64(n.Int32), Valid: n.Valid}, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Int4) Scan(src any) error { + if src == nil { + *dst = Int4{} + return nil + } + + var n int64 + + switch src := src.(type) { + case int64: + n = src + case string: + var err error + n, err = strconv.ParseInt(src, 10, 32) + if err != nil { + return err + } + case []byte: + var err error + n, err = strconv.ParseInt(string(src), 10, 32) + if err != nil { + return err + } + default: + return fmt.Errorf("cannot scan %T", src) + } + + if n < math.MinInt32 { + return fmt.Errorf("%d is greater than maximum value for Int4", n) + } + if n > math.MaxInt32 { + return fmt.Errorf("%d is greater than maximum value for Int4", n) + } + *dst = Int4{Int32: int32(n), Valid: true} + + return nil +} + +// Value implements the database/sql/driver Valuer interface. +func (src Int4) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + return int64(src.Int32), nil +} + +func (src Int4) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + return []byte(strconv.FormatInt(int64(src.Int32), 10)), nil +} + +func (dst *Int4) UnmarshalJSON(b []byte) error { + var n *int32 + err := json.Unmarshal(b, &n) + if err != nil { + return err + } + + if n == nil { + *dst = Int4{} + } else { + *dst = Int4{Int32: *n, Valid: true} + } + + return nil +} + +type Int4Codec struct{} + +func (Int4Codec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (Int4Codec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (Int4Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case int32: + return encodePlanInt4CodecBinaryInt32{} + case Int64Valuer: + return encodePlanInt4CodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case int32: + return encodePlanInt4CodecTextInt32{} + case Int64Valuer: + return encodePlanInt4CodecTextInt64Valuer{} + } + } + + return nil +} + +type encodePlanInt4CodecBinaryInt32 struct{} + +func (encodePlanInt4CodecBinaryInt32) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int32) + return pgio.AppendInt32(buf, int32(n)), nil +} + +type encodePlanInt4CodecTextInt32 struct{} + +func (encodePlanInt4CodecTextInt32) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int32) + return append(buf, strconv.FormatInt(int64(n), 10)...), nil +} + +type encodePlanInt4CodecBinaryInt64Valuer struct{} + +func (encodePlanInt4CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt32 { + return nil, fmt.Errorf("%d is greater than maximum value for int4", n.Int64) + } + if n.Int64 < math.MinInt32 { + return nil, fmt.Errorf("%d is less than minimum value for int4", n.Int64) + } + + return pgio.AppendInt32(buf, int32(n.Int64)), nil +} + +type encodePlanInt4CodecTextInt64Valuer struct{} + +func (encodePlanInt4CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt32 { + return nil, fmt.Errorf("%d is greater than maximum value for int4", n.Int64) + } + if n.Int64 < math.MinInt32 { + return nil, fmt.Errorf("%d is less than minimum value for int4", n.Int64) + } + + return append(buf, strconv.FormatInt(n.Int64, 10)...), nil +} + +func (Int4Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *int8: + return scanPlanBinaryInt4ToInt8{} + case *int16: + return scanPlanBinaryInt4ToInt16{} + case *int32: + return scanPlanBinaryInt4ToInt32{} + case *int64: + return scanPlanBinaryInt4ToInt64{} + case *int: + return scanPlanBinaryInt4ToInt{} + case *uint8: + return scanPlanBinaryInt4ToUint8{} + case *uint16: + return scanPlanBinaryInt4ToUint16{} + case *uint32: + return scanPlanBinaryInt4ToUint32{} + case *uint64: + return scanPlanBinaryInt4ToUint64{} + case *uint: + return scanPlanBinaryInt4ToUint{} + case Int64Scanner: + return scanPlanBinaryInt4ToInt64Scanner{} + case TextScanner: + return scanPlanBinaryInt4ToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case *int8: + return scanPlanTextAnyToInt8{} + case *int16: + return scanPlanTextAnyToInt16{} + case *int32: + return scanPlanTextAnyToInt32{} + case *int64: + return scanPlanTextAnyToInt64{} + case *int: + return scanPlanTextAnyToInt{} + case *uint8: + return scanPlanTextAnyToUint8{} + case *uint16: + return scanPlanTextAnyToUint16{} + case *uint32: + return scanPlanTextAnyToUint32{} + case *uint64: + return scanPlanTextAnyToUint64{} + case *uint: + return scanPlanTextAnyToUint{} + case Int64Scanner: + return scanPlanTextAnyToInt64Scanner{} + } + } + + return nil +} + +func (c Int4Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var n int64 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +func (c Int4Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n int32 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +type scanPlanBinaryInt4ToInt8 struct{} + +func (scanPlanBinaryInt4ToInt8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for int4: %v", len(src)) + } + + p, ok := (dst).(*int8) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int32(binary.BigEndian.Uint32(src)) + if n < math.MinInt8 { + return fmt.Errorf("%d is less than minimum value for int8", n) + } else if n > math.MaxInt8 { + return fmt.Errorf("%d is greater than maximum value for int8", n) + } + + *p = int8(n) + + return nil +} + +type scanPlanBinaryInt4ToUint8 struct{} + +func (scanPlanBinaryInt4ToUint8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for uint4: %v", len(src)) + } + + p, ok := (dst).(*uint8) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int32(binary.BigEndian.Uint32(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint8", n) + } + + if n > math.MaxUint8 { + return fmt.Errorf("%d is greater than maximum value for uint8", n) + } + + *p = uint8(n) + + return nil +} + +type scanPlanBinaryInt4ToInt16 struct{} + +func (scanPlanBinaryInt4ToInt16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for int4: %v", len(src)) + } + + p, ok := (dst).(*int16) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int32(binary.BigEndian.Uint32(src)) + if n < math.MinInt16 { + return fmt.Errorf("%d is less than minimum value for int16", n) + } else if n > math.MaxInt16 { + return fmt.Errorf("%d is greater than maximum value for int16", n) + } + + *p = int16(n) + + return nil +} + +type scanPlanBinaryInt4ToUint16 struct{} + +func (scanPlanBinaryInt4ToUint16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for uint4: %v", len(src)) + } + + p, ok := (dst).(*uint16) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int32(binary.BigEndian.Uint32(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint16", n) + } + + if n > math.MaxUint16 { + return fmt.Errorf("%d is greater than maximum value for uint16", n) + } + + *p = uint16(n) + + return nil +} + +type scanPlanBinaryInt4ToInt32 struct{} + +func (scanPlanBinaryInt4ToInt32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for int4: %v", len(src)) + } + + p, ok := (dst).(*int32) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int32(binary.BigEndian.Uint32(src)) + + return nil +} + +type scanPlanBinaryInt4ToUint32 struct{} + +func (scanPlanBinaryInt4ToUint32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for uint4: %v", len(src)) + } + + p, ok := (dst).(*uint32) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int32(binary.BigEndian.Uint32(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint32", n) + } + + *p = uint32(n) + + return nil +} + +type scanPlanBinaryInt4ToInt64 struct{} + +func (scanPlanBinaryInt4ToInt64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for int4: %v", len(src)) + } + + p, ok := (dst).(*int64) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int64(int32(binary.BigEndian.Uint32(src))) + + return nil +} + +type scanPlanBinaryInt4ToUint64 struct{} + +func (scanPlanBinaryInt4ToUint64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for uint4: %v", len(src)) + } + + p, ok := (dst).(*uint64) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int32(binary.BigEndian.Uint32(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint64", n) + } + + *p = uint64(n) + + return nil +} + +type scanPlanBinaryInt4ToInt struct{} + +func (scanPlanBinaryInt4ToInt) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for int4: %v", len(src)) + } + + p, ok := (dst).(*int) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int(int32(binary.BigEndian.Uint32(src))) + + return nil +} + +type scanPlanBinaryInt4ToUint struct{} + +func (scanPlanBinaryInt4ToUint) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for uint4: %v", len(src)) + } + + p, ok := (dst).(*uint) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(int32(binary.BigEndian.Uint32(src))) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint", n) + } + + *p = uint(n) + + return nil +} + +type scanPlanBinaryInt4ToInt64Scanner struct{} + +func (scanPlanBinaryInt4ToInt64Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Int64Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanInt64(Int8{}) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for int4: %v", len(src)) + } + + n := int64(int32(binary.BigEndian.Uint32(src))) + + return s.ScanInt64(Int8{Int64: n, Valid: true}) +} + +type scanPlanBinaryInt4ToTextScanner struct{} + +func (scanPlanBinaryInt4ToTextScanner) Scan(src []byte, dst any) error { + s, ok := (dst).(TextScanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanText(Text{}) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for int4: %v", len(src)) + } + + n := int64(int32(binary.BigEndian.Uint32(src))) + + return s.ScanText(Text{String: strconv.FormatInt(n, 10), Valid: true}) +} + +type Int8 struct { + Int64 int64 + Valid bool +} + +// ScanInt64 implements the Int64Scanner interface. +func (dst *Int8) ScanInt64(n Int8) error { + if !n.Valid { + *dst = Int8{} + return nil + } + + if n.Int64 < math.MinInt64 { + return fmt.Errorf("%d is less than minimum value for Int8", n.Int64) + } + if n.Int64 > math.MaxInt64 { + return fmt.Errorf("%d is greater than maximum value for Int8", n.Int64) + } + *dst = Int8{Int64: int64(n.Int64), Valid: true} + + return nil +} + +func (n Int8) Int64Value() (Int8, error) { + return Int8{Int64: int64(n.Int64), Valid: n.Valid}, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Int8) Scan(src any) error { + if src == nil { + *dst = Int8{} + return nil + } + + var n int64 + + switch src := src.(type) { + case int64: + n = src + case string: + var err error + n, err = strconv.ParseInt(src, 10, 64) + if err != nil { + return err + } + case []byte: + var err error + n, err = strconv.ParseInt(string(src), 10, 64) + if err != nil { + return err + } + default: + return fmt.Errorf("cannot scan %T", src) + } + + if n < math.MinInt64 { + return fmt.Errorf("%d is greater than maximum value for Int8", n) + } + if n > math.MaxInt64 { + return fmt.Errorf("%d is greater than maximum value for Int8", n) + } + *dst = Int8{Int64: int64(n), Valid: true} + + return nil +} + +// Value implements the database/sql/driver Valuer interface. +func (src Int8) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + return int64(src.Int64), nil +} + +func (src Int8) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + return []byte(strconv.FormatInt(int64(src.Int64), 10)), nil +} + +func (dst *Int8) UnmarshalJSON(b []byte) error { + var n *int64 + err := json.Unmarshal(b, &n) + if err != nil { + return err + } + + if n == nil { + *dst = Int8{} + } else { + *dst = Int8{Int64: *n, Valid: true} + } + + return nil +} + +type Int8Codec struct{} + +func (Int8Codec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (Int8Codec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (Int8Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case int64: + return encodePlanInt8CodecBinaryInt64{} + case Int64Valuer: + return encodePlanInt8CodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case int64: + return encodePlanInt8CodecTextInt64{} + case Int64Valuer: + return encodePlanInt8CodecTextInt64Valuer{} + } + } + + return nil +} + +type encodePlanInt8CodecBinaryInt64 struct{} + +func (encodePlanInt8CodecBinaryInt64) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int64) + return pgio.AppendInt64(buf, int64(n)), nil +} + +type encodePlanInt8CodecTextInt64 struct{} + +func (encodePlanInt8CodecTextInt64) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int64) + return append(buf, strconv.FormatInt(int64(n), 10)...), nil +} + +type encodePlanInt8CodecBinaryInt64Valuer struct{} + +func (encodePlanInt8CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt64 { + return nil, fmt.Errorf("%d is greater than maximum value for int8", n.Int64) + } + if n.Int64 < math.MinInt64 { + return nil, fmt.Errorf("%d is less than minimum value for int8", n.Int64) + } + + return pgio.AppendInt64(buf, int64(n.Int64)), nil +} + +type encodePlanInt8CodecTextInt64Valuer struct{} + +func (encodePlanInt8CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt64 { + return nil, fmt.Errorf("%d is greater than maximum value for int8", n.Int64) + } + if n.Int64 < math.MinInt64 { + return nil, fmt.Errorf("%d is less than minimum value for int8", n.Int64) + } + + return append(buf, strconv.FormatInt(n.Int64, 10)...), nil +} + +func (Int8Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *int8: + return scanPlanBinaryInt8ToInt8{} + case *int16: + return scanPlanBinaryInt8ToInt16{} + case *int32: + return scanPlanBinaryInt8ToInt32{} + case *int64: + return scanPlanBinaryInt8ToInt64{} + case *int: + return scanPlanBinaryInt8ToInt{} + case *uint8: + return scanPlanBinaryInt8ToUint8{} + case *uint16: + return scanPlanBinaryInt8ToUint16{} + case *uint32: + return scanPlanBinaryInt8ToUint32{} + case *uint64: + return scanPlanBinaryInt8ToUint64{} + case *uint: + return scanPlanBinaryInt8ToUint{} + case Int64Scanner: + return scanPlanBinaryInt8ToInt64Scanner{} + case TextScanner: + return scanPlanBinaryInt8ToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case *int8: + return scanPlanTextAnyToInt8{} + case *int16: + return scanPlanTextAnyToInt16{} + case *int32: + return scanPlanTextAnyToInt32{} + case *int64: + return scanPlanTextAnyToInt64{} + case *int: + return scanPlanTextAnyToInt{} + case *uint8: + return scanPlanTextAnyToUint8{} + case *uint16: + return scanPlanTextAnyToUint16{} + case *uint32: + return scanPlanTextAnyToUint32{} + case *uint64: + return scanPlanTextAnyToUint64{} + case *uint: + return scanPlanTextAnyToUint{} + case Int64Scanner: + return scanPlanTextAnyToInt64Scanner{} + } + } + + return nil +} + +func (c Int8Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var n int64 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +func (c Int8Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n int64 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +type scanPlanBinaryInt8ToInt8 struct{} + +func (scanPlanBinaryInt8ToInt8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for int8: %v", len(src)) + } + + p, ok := (dst).(*int8) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < math.MinInt8 { + return fmt.Errorf("%d is less than minimum value for int8", n) + } else if n > math.MaxInt8 { + return fmt.Errorf("%d is greater than maximum value for int8", n) + } + + *p = int8(n) + + return nil +} + +type scanPlanBinaryInt8ToUint8 struct{} + +func (scanPlanBinaryInt8ToUint8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for uint8: %v", len(src)) + } + + p, ok := (dst).(*uint8) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint8", n) + } + + if n > math.MaxUint8 { + return fmt.Errorf("%d is greater than maximum value for uint8", n) + } + + *p = uint8(n) + + return nil +} + +type scanPlanBinaryInt8ToInt16 struct{} + +func (scanPlanBinaryInt8ToInt16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for int8: %v", len(src)) + } + + p, ok := (dst).(*int16) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < math.MinInt16 { + return fmt.Errorf("%d is less than minimum value for int16", n) + } else if n > math.MaxInt16 { + return fmt.Errorf("%d is greater than maximum value for int16", n) + } + + *p = int16(n) + + return nil +} + +type scanPlanBinaryInt8ToUint16 struct{} + +func (scanPlanBinaryInt8ToUint16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for uint8: %v", len(src)) + } + + p, ok := (dst).(*uint16) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint16", n) + } + + if n > math.MaxUint16 { + return fmt.Errorf("%d is greater than maximum value for uint16", n) + } + + *p = uint16(n) + + return nil +} + +type scanPlanBinaryInt8ToInt32 struct{} + +func (scanPlanBinaryInt8ToInt32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for int8: %v", len(src)) + } + + p, ok := (dst).(*int32) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < math.MinInt32 { + return fmt.Errorf("%d is less than minimum value for int32", n) + } else if n > math.MaxInt32 { + return fmt.Errorf("%d is greater than maximum value for int32", n) + } + + *p = int32(n) + + return nil +} + +type scanPlanBinaryInt8ToUint32 struct{} + +func (scanPlanBinaryInt8ToUint32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for uint8: %v", len(src)) + } + + p, ok := (dst).(*uint32) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint32", n) + } + + if n > math.MaxUint32 { + return fmt.Errorf("%d is greater than maximum value for uint32", n) + } + + *p = uint32(n) + + return nil +} + +type scanPlanBinaryInt8ToInt64 struct{} + +func (scanPlanBinaryInt8ToInt64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for int8: %v", len(src)) + } + + p, ok := (dst).(*int64) + if !ok { + return ErrScanTargetTypeChanged + } + + *p = int64(binary.BigEndian.Uint64(src)) + + return nil +} + +type scanPlanBinaryInt8ToUint64 struct{} + +func (scanPlanBinaryInt8ToUint64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for uint8: %v", len(src)) + } + + p, ok := (dst).(*uint64) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint64", n) + } + + *p = uint64(n) + + return nil +} + +type scanPlanBinaryInt8ToInt struct{} + +func (scanPlanBinaryInt8ToInt) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for int8: %v", len(src)) + } + + p, ok := (dst).(*int) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(binary.BigEndian.Uint64(src)) + if n < math.MinInt { + return fmt.Errorf("%d is less than minimum value for int", n) + } else if n > math.MaxInt { + return fmt.Errorf("%d is greater than maximum value for int", n) + } + + *p = int(n) + + return nil +} + +type scanPlanBinaryInt8ToUint struct{} + +func (scanPlanBinaryInt8ToUint) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for uint8: %v", len(src)) + } + + p, ok := (dst).(*uint) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(int64(binary.BigEndian.Uint64(src))) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint", n) + } + + if uint64(n) > math.MaxUint { + return fmt.Errorf("%d is greater than maximum value for uint", n) + } + + *p = uint(n) + + return nil +} + +type scanPlanBinaryInt8ToInt64Scanner struct{} + +func (scanPlanBinaryInt8ToInt64Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Int64Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanInt64(Int8{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for int8: %v", len(src)) + } + + n := int64(int64(binary.BigEndian.Uint64(src))) + + return s.ScanInt64(Int8{Int64: n, Valid: true}) +} + +type scanPlanBinaryInt8ToTextScanner struct{} + +func (scanPlanBinaryInt8ToTextScanner) Scan(src []byte, dst any) error { + s, ok := (dst).(TextScanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanText(Text{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for int8: %v", len(src)) + } + + n := int64(int64(binary.BigEndian.Uint64(src))) + + return s.ScanText(Text{String: strconv.FormatInt(n, 10), Valid: true}) +} + +type scanPlanTextAnyToInt8 struct{} + +func (scanPlanTextAnyToInt8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*int8) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseInt(string(src), 10, 8) + if err != nil { + return err + } + + *p = int8(n) + return nil +} + +type scanPlanTextAnyToUint8 struct{} + +func (scanPlanTextAnyToUint8) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*uint8) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseUint(string(src), 10, 8) + if err != nil { + return err + } + + *p = uint8(n) + return nil +} + +type scanPlanTextAnyToInt16 struct{} + +func (scanPlanTextAnyToInt16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*int16) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseInt(string(src), 10, 16) + if err != nil { + return err + } + + *p = int16(n) + return nil +} + +type scanPlanTextAnyToUint16 struct{} + +func (scanPlanTextAnyToUint16) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*uint16) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseUint(string(src), 10, 16) + if err != nil { + return err + } + + *p = uint16(n) + return nil +} + +type scanPlanTextAnyToInt32 struct{} + +func (scanPlanTextAnyToInt32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*int32) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseInt(string(src), 10, 32) + if err != nil { + return err + } + + *p = int32(n) + return nil +} + +type scanPlanTextAnyToUint32 struct{} + +func (scanPlanTextAnyToUint32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*uint32) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseUint(string(src), 10, 32) + if err != nil { + return err + } + + *p = uint32(n) + return nil +} + +type scanPlanTextAnyToInt64 struct{} + +func (scanPlanTextAnyToInt64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*int64) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseInt(string(src), 10, 64) + if err != nil { + return err + } + + *p = int64(n) + return nil +} + +type scanPlanTextAnyToUint64 struct{} + +func (scanPlanTextAnyToUint64) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*uint64) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseUint(string(src), 10, 64) + if err != nil { + return err + } + + *p = uint64(n) + return nil +} + +type scanPlanTextAnyToInt struct{} + +func (scanPlanTextAnyToInt) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*int) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseInt(string(src), 10, 0) + if err != nil { + return err + } + + *p = int(n) + return nil +} + +type scanPlanTextAnyToUint struct{} + +func (scanPlanTextAnyToUint) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*uint) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseUint(string(src), 10, 0) + if err != nil { + return err + } + + *p = uint(n) + return nil +} + +type scanPlanTextAnyToInt64Scanner struct{} + +func (scanPlanTextAnyToInt64Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Int64Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanInt64(Int8{}) + } + + n, err := strconv.ParseInt(string(src), 10, 64) + if err != nil { + return err + } + + err = s.ScanInt64(Int8{Int64: n, Valid: true}) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/int.go.erb b/vendor/github.com/jackc/pgx/v5/pgtype/int.go.erb new file mode 100644 index 00000000000..e0c8b7a3ffc --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/int.go.erb @@ -0,0 +1,548 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "encoding/json" + "fmt" + "math" + "strconv" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Int64Scanner interface { + ScanInt64(Int8) error +} + +type Int64Valuer interface { + Int64Value() (Int8, error) +} + + +<% [2, 4, 8].each do |pg_byte_size| %> +<% pg_bit_size = pg_byte_size * 8 %> +type Int<%= pg_byte_size %> struct { + Int<%= pg_bit_size %> int<%= pg_bit_size %> + Valid bool +} + +// ScanInt64 implements the Int64Scanner interface. +func (dst *Int<%= pg_byte_size %>) ScanInt64(n Int8) error { + if !n.Valid { + *dst = Int<%= pg_byte_size %>{} + return nil + } + + if n.Int64 < math.MinInt<%= pg_bit_size %> { + return fmt.Errorf("%d is less than minimum value for Int<%= pg_byte_size %>", n.Int64) + } + if n.Int64 > math.MaxInt<%= pg_bit_size %> { + return fmt.Errorf("%d is greater than maximum value for Int<%= pg_byte_size %>", n.Int64) + } + *dst = Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: int<%= pg_bit_size %>(n.Int64), Valid: true} + + return nil +} + +func (n Int<%= pg_byte_size %>) Int64Value() (Int8, error) { + return Int8{Int64: int64(n.Int<%= pg_bit_size %>), Valid: n.Valid}, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Int<%= pg_byte_size %>) Scan(src any) error { + if src == nil { + *dst = Int<%= pg_byte_size %>{} + return nil + } + + var n int64 + + switch src := src.(type) { + case int64: + n = src + case string: + var err error + n, err = strconv.ParseInt(src, 10, <%= pg_bit_size %>) + if err != nil { + return err + } + case []byte: + var err error + n, err = strconv.ParseInt(string(src), 10, <%= pg_bit_size %>) + if err != nil { + return err + } + default: + return fmt.Errorf("cannot scan %T", src) + } + + if n < math.MinInt<%= pg_bit_size %> { + return fmt.Errorf("%d is greater than maximum value for Int<%= pg_byte_size %>", n) + } + if n > math.MaxInt<%= pg_bit_size %> { + return fmt.Errorf("%d is greater than maximum value for Int<%= pg_byte_size %>", n) + } + *dst = Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: int<%= pg_bit_size %>(n), Valid: true} + + return nil +} + +// Value implements the database/sql/driver Valuer interface. +func (src Int<%= pg_byte_size %>) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + return int64(src.Int<%= pg_bit_size %>), nil +} + +func (src Int<%= pg_byte_size %>) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + return []byte(strconv.FormatInt(int64(src.Int<%= pg_bit_size %>), 10)), nil +} + +func (dst *Int<%= pg_byte_size %>) UnmarshalJSON(b []byte) error { + var n *int<%= pg_bit_size %> + err := json.Unmarshal(b, &n) + if err != nil { + return err + } + + if n == nil { + *dst = Int<%= pg_byte_size %>{} + } else { + *dst = Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: *n, Valid: true} + } + + return nil +} + +type Int<%= pg_byte_size %>Codec struct{} + +func (Int<%= pg_byte_size %>Codec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (Int<%= pg_byte_size %>Codec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (Int<%= pg_byte_size %>Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case int<%= pg_bit_size %>: + return encodePlanInt<%= pg_byte_size %>CodecBinaryInt<%= pg_bit_size %>{} + case Int64Valuer: + return encodePlanInt<%= pg_byte_size %>CodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case int<%= pg_bit_size %>: + return encodePlanInt<%= pg_byte_size %>CodecTextInt<%= pg_bit_size %>{} + case Int64Valuer: + return encodePlanInt<%= pg_byte_size %>CodecTextInt64Valuer{} + } + } + + return nil +} + +type encodePlanInt<%= pg_byte_size %>CodecBinaryInt<%= pg_bit_size %> struct{} + +func (encodePlanInt<%= pg_byte_size %>CodecBinaryInt<%= pg_bit_size %>) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int<%= pg_bit_size %>) + return pgio.AppendInt<%= pg_bit_size %>(buf, int<%= pg_bit_size %>(n)), nil +} + +type encodePlanInt<%= pg_byte_size %>CodecTextInt<%= pg_bit_size %> struct{} + +func (encodePlanInt<%= pg_byte_size %>CodecTextInt<%= pg_bit_size %>) Encode(value any, buf []byte) (newBuf []byte, err error) { + n := value.(int<%= pg_bit_size %>) + return append(buf, strconv.FormatInt(int64(n), 10)...), nil +} + +type encodePlanInt<%= pg_byte_size %>CodecBinaryInt64Valuer struct{} + +func (encodePlanInt<%= pg_byte_size %>CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt<%= pg_bit_size %> { + return nil, fmt.Errorf("%d is greater than maximum value for int<%= pg_byte_size %>", n.Int64) + } + if n.Int64 < math.MinInt<%= pg_bit_size %> { + return nil, fmt.Errorf("%d is less than minimum value for int<%= pg_byte_size %>", n.Int64) + } + + return pgio.AppendInt<%= pg_bit_size %>(buf, int<%= pg_bit_size %>(n.Int64)), nil +} + +type encodePlanInt<%= pg_byte_size %>CodecTextInt64Valuer struct{} + +func (encodePlanInt<%= pg_byte_size %>CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if n.Int64 > math.MaxInt<%= pg_bit_size %> { + return nil, fmt.Errorf("%d is greater than maximum value for int<%= pg_byte_size %>", n.Int64) + } + if n.Int64 < math.MinInt<%= pg_bit_size %> { + return nil, fmt.Errorf("%d is less than minimum value for int<%= pg_byte_size %>", n.Int64) + } + + return append(buf, strconv.FormatInt(n.Int64, 10)...), nil +} + +func (Int<%= pg_byte_size %>Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *int8: + return scanPlanBinaryInt<%= pg_byte_size %>ToInt8{} + case *int16: + return scanPlanBinaryInt<%= pg_byte_size %>ToInt16{} + case *int32: + return scanPlanBinaryInt<%= pg_byte_size %>ToInt32{} + case *int64: + return scanPlanBinaryInt<%= pg_byte_size %>ToInt64{} + case *int: + return scanPlanBinaryInt<%= pg_byte_size %>ToInt{} + case *uint8: + return scanPlanBinaryInt<%= pg_byte_size %>ToUint8{} + case *uint16: + return scanPlanBinaryInt<%= pg_byte_size %>ToUint16{} + case *uint32: + return scanPlanBinaryInt<%= pg_byte_size %>ToUint32{} + case *uint64: + return scanPlanBinaryInt<%= pg_byte_size %>ToUint64{} + case *uint: + return scanPlanBinaryInt<%= pg_byte_size %>ToUint{} + case Int64Scanner: + return scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner{} + case TextScanner: + return scanPlanBinaryInt<%= pg_byte_size %>ToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case *int8: + return scanPlanTextAnyToInt8{} + case *int16: + return scanPlanTextAnyToInt16{} + case *int32: + return scanPlanTextAnyToInt32{} + case *int64: + return scanPlanTextAnyToInt64{} + case *int: + return scanPlanTextAnyToInt{} + case *uint8: + return scanPlanTextAnyToUint8{} + case *uint16: + return scanPlanTextAnyToUint16{} + case *uint32: + return scanPlanTextAnyToUint32{} + case *uint64: + return scanPlanTextAnyToUint64{} + case *uint: + return scanPlanTextAnyToUint{} + case Int64Scanner: + return scanPlanTextAnyToInt64Scanner{} + } + } + + return nil +} + +func (c Int<%= pg_byte_size %>Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var n int64 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +func (c Int<%= pg_byte_size %>Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n int<%= pg_bit_size %> + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +<%# PostgreSQL binary format integer to fixed size Go integers %> +<% [8, 16, 32, 64].each do |dst_bit_size| %> +type scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %> struct{} + +func (scanPlanBinaryInt<%= pg_byte_size %>ToInt<%= dst_bit_size %>) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != <%= pg_byte_size %> { + return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src)) + } + + p, ok := (dst).(*int<%= dst_bit_size %>) + if !ok { + return ErrScanTargetTypeChanged + } + + <% if dst_bit_size < pg_bit_size %> + n := int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)) + if n < math.MinInt<%= dst_bit_size %> { + return fmt.Errorf("%d is less than minimum value for int<%= dst_bit_size %>", n) + } else if n > math.MaxInt<%= dst_bit_size %> { + return fmt.Errorf("%d is greater than maximum value for int<%= dst_bit_size %>", n) + } + + *p = int<%= dst_bit_size %>(n) + <% elsif dst_bit_size == pg_bit_size %> + *p = int<%= dst_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)) + <% else %> + *p = int<%= dst_bit_size %>(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))) + <% end %> + + return nil +} + +type scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %> struct{} + +func (scanPlanBinaryInt<%= pg_byte_size %>ToUint<%= dst_bit_size %>) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != <%= pg_byte_size %> { + return fmt.Errorf("invalid length for uint<%= pg_byte_size %>: %v", len(src)) + } + + p, ok := (dst).(*uint<%= dst_bit_size %>) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src)) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint<%= dst_bit_size %>", n) + } + <% if dst_bit_size < pg_bit_size %> + if n > math.MaxUint<%= dst_bit_size %> { + return fmt.Errorf("%d is greater than maximum value for uint<%= dst_bit_size %>", n) + } + <% end %> + *p = uint<%= dst_bit_size %>(n) + + return nil +} +<% end %> + +<%# PostgreSQL binary format integer to Go machine integers %> +type scanPlanBinaryInt<%= pg_byte_size %>ToInt struct{} + +func (scanPlanBinaryInt<%= pg_byte_size %>ToInt) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != <%= pg_byte_size %> { + return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src)) + } + + p, ok := (dst).(*int) + if !ok { + return ErrScanTargetTypeChanged + } + + <% if 32 < pg_bit_size %> + n := int64(binary.BigEndian.Uint<%= pg_bit_size %>(src)) + if n < math.MinInt { + return fmt.Errorf("%d is less than minimum value for int", n) + } else if n > math.MaxInt { + return fmt.Errorf("%d is greater than maximum value for int", n) + } + + *p = int(n) + <% else %> + *p = int(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))) + <% end %> + + return nil +} + +type scanPlanBinaryInt<%= pg_byte_size %>ToUint struct{} + +func (scanPlanBinaryInt<%= pg_byte_size %>ToUint) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != <%= pg_byte_size %> { + return fmt.Errorf("invalid length for uint<%= pg_byte_size %>: %v", len(src)) + } + + p, ok := (dst).(*uint) + if !ok { + return ErrScanTargetTypeChanged + } + + n := int64(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))) + if n < 0 { + return fmt.Errorf("%d is less than minimum value for uint", n) + } + <% if 32 < pg_bit_size %> + if uint64(n) > math.MaxUint { + return fmt.Errorf("%d is greater than maximum value for uint", n) + } + <% end %> + *p = uint(n) + + return nil +} + +<%# PostgreSQL binary format integer to Go Int64Scanner %> +type scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner struct{} + +func (scanPlanBinaryInt<%= pg_byte_size %>ToInt64Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Int64Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanInt64(Int8{}) + } + + if len(src) != <%= pg_byte_size %> { + return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src)) + } + + + n := int64(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))) + + return s.ScanInt64(Int8{Int64: n, Valid: true}) +} + +<%# PostgreSQL binary format integer to Go TextScanner %> +type scanPlanBinaryInt<%= pg_byte_size %>ToTextScanner struct{} + +func (scanPlanBinaryInt<%= pg_byte_size %>ToTextScanner) Scan(src []byte, dst any) error { + s, ok := (dst).(TextScanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanText(Text{}) + } + + if len(src) != <%= pg_byte_size %> { + return fmt.Errorf("invalid length for int<%= pg_byte_size %>: %v", len(src)) + } + + + n := int64(int<%= pg_bit_size %>(binary.BigEndian.Uint<%= pg_bit_size %>(src))) + + return s.ScanText(Text{String: strconv.FormatInt(n, 10), Valid: true}) +} +<% end %> + +<%# Any text to all integer types %> +<% [ + ["8", 8], + ["16", 16], + ["32", 32], + ["64", 64], + ["", 0] +].each do |type_suffix, bit_size| %> +type scanPlanTextAnyToInt<%= type_suffix %> struct{} + +func (scanPlanTextAnyToInt<%= type_suffix %>) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*int<%= type_suffix %>) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseInt(string(src), 10, <%= bit_size %>) + if err != nil { + return err + } + + *p = int<%= type_suffix %>(n) + return nil +} + +type scanPlanTextAnyToUint<%= type_suffix %> struct{} + +func (scanPlanTextAnyToUint<%= type_suffix %>) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p, ok := (dst).(*uint<%= type_suffix %>) + if !ok { + return ErrScanTargetTypeChanged + } + + n, err := strconv.ParseUint(string(src), 10, <%= bit_size %>) + if err != nil { + return err + } + + *p = uint<%= type_suffix %>(n) + return nil +} +<% end %> + +type scanPlanTextAnyToInt64Scanner struct{} + +func (scanPlanTextAnyToInt64Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Int64Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanInt64(Int8{}) + } + + n, err := strconv.ParseInt(string(src), 10, 64) + if err != nil { + return err + } + + err = s.ScanInt64(Int8{Int64: n, Valid: true}) + if err != nil { + return err + } + + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/int_test.go.erb b/vendor/github.com/jackc/pgx/v5/pgtype/int_test.go.erb new file mode 100644 index 00000000000..ac9a3f1430e --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/int_test.go.erb @@ -0,0 +1,93 @@ +package pgtype_test + +import ( + "math" + "testing" + + "github.com/jackc/pgx/v5/pgtype" +) + +<% [2, 4, 8].each do |pg_byte_size| %> +<% pg_bit_size = pg_byte_size * 8 %> +func TestInt<%= pg_byte_size %>Codec(t *testing.T) { + pgxtest.RunValueRoundTripTests(context.Background(), t, defaultConnTestRunner, nil, "int<%= pg_byte_size %>", []pgxtest.ValueRoundTripTest{ + {int8(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {int16(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {int32(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {int64(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {uint8(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {uint16(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {uint32(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {uint64(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {int(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {uint(1), new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {pgtype.Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: 1, Valid: true}, new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {int32(-1), new(pgtype.Int<%= pg_byte_size %>), isExpectedEq(pgtype.Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: -1, Valid: true})}, + {1, new(int8), isExpectedEq(int8(1))}, + {1, new(int16), isExpectedEq(int16(1))}, + {1, new(int32), isExpectedEq(int32(1))}, + {1, new(int64), isExpectedEq(int64(1))}, + {1, new(uint8), isExpectedEq(uint8(1))}, + {1, new(uint16), isExpectedEq(uint16(1))}, + {1, new(uint32), isExpectedEq(uint32(1))}, + {1, new(uint64), isExpectedEq(uint64(1))}, + {1, new(int), isExpectedEq(int(1))}, + {1, new(uint), isExpectedEq(uint(1))}, + {-1, new(int8), isExpectedEq(int8(-1))}, + {-1, new(int16), isExpectedEq(int16(-1))}, + {-1, new(int32), isExpectedEq(int32(-1))}, + {-1, new(int64), isExpectedEq(int64(-1))}, + {-1, new(int), isExpectedEq(int(-1))}, + {math.MinInt<%= pg_bit_size %>, new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(math.MinInt<%= pg_bit_size %>))}, + {-1, new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(-1))}, + {0, new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(0))}, + {1, new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(1))}, + {math.MaxInt<%= pg_bit_size %>, new(int<%= pg_bit_size %>), isExpectedEq(int<%= pg_bit_size %>(math.MaxInt<%= pg_bit_size %>))}, + {1, new(pgtype.Int<%= pg_byte_size %>), isExpectedEq(pgtype.Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: 1, Valid: true})}, + {"1", new(string), isExpectedEq("1")}, + {pgtype.Int<%= pg_byte_size %>{}, new(pgtype.Int<%= pg_byte_size %>), isExpectedEq(pgtype.Int<%= pg_byte_size %>{})}, + {nil, new(*int<%= pg_bit_size %>), isExpectedEq((*int<%= pg_bit_size %>)(nil))}, + }) +} + +func TestInt<%= pg_byte_size %>MarshalJSON(t *testing.T) { + successfulTests := []struct { + source pgtype.Int<%= pg_byte_size %> + result string + }{ + {source: pgtype.Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: 0}, result: "null"}, + {source: pgtype.Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: 1, Valid: true}, result: "1"}, + } + for i, tt := range successfulTests { + r, err := tt.source.MarshalJSON() + if err != nil { + t.Errorf("%d: %v", i, err) + } + + if string(r) != tt.result { + t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, string(r)) + } + } +} + +func TestInt<%= pg_byte_size %>UnmarshalJSON(t *testing.T) { + successfulTests := []struct { + source string + result pgtype.Int<%= pg_byte_size %> + }{ + {source: "null", result: pgtype.Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: 0}}, + {source: "1", result: pgtype.Int<%= pg_byte_size %>{Int<%= pg_bit_size %>: 1, Valid: true}}, + } + for i, tt := range successfulTests { + var r pgtype.Int<%= pg_byte_size %> + err := r.UnmarshalJSON([]byte(tt.source)) + if err != nil { + t.Errorf("%d: %v", i, err) + } + + if r != tt.result { + t.Errorf("%d: expected %v to convert to %v, but it was %v", i, tt.source, tt.result, r) + } + } +} +<% end %> diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test.go.erb b/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test.go.erb new file mode 100644 index 00000000000..0175700a492 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test.go.erb @@ -0,0 +1,62 @@ +package pgtype_test + +import ( + "context" + "testing" + + "github.com/jackc/pgx/v5/pgtype/testutil" + "github.com/jackc/pgx/v5" +) + +<% + [ + ["int4", ["int16", "int32", "int64", "uint64", "pgtype.Int4"], [[1, 1], [1, 10], [10, 1], [100, 10]]], + ["numeric", ["int64", "float64", "pgtype.Numeric"], [[1, 1], [1, 10], [10, 1], [100, 10]]], + ].each do |pg_type, go_types, rows_columns| +%> +<% go_types.each do |go_type| %> +<% rows_columns.each do |rows, columns| %> +<% [["Text", "pgx.TextFormatCode"], ["Binary", "pgx.BinaryFormatCode"]].each do |format_name, format_code| %> +func BenchmarkQuery<%= format_name %>FormatDecode_PG_<%= pg_type %>_to_Go_<%= go_type.gsub(/\W/, "_") %>_<%= rows %>_rows_<%= columns %>_columns(b *testing.B) { + defaultConnTestRunner.RunTest(context.Background(), b, func(ctx context.Context, _ testing.TB, conn *pgx.Conn) { + b.ResetTimer() + var v [<%= columns %>]<%= go_type %> + for i := 0; i < b.N; i++ { + rows, _ := conn.Query( + ctx, + `select <% columns.times do |col_idx| %><% if col_idx != 0 %>, <% end %>n::<%= pg_type %> + <%= col_idx%><% end %> from generate_series(1, <%= rows %>) n`, + []any{pgx.QueryResultFormats{<%= format_code %>}}, + ) + _, err := pgx.ForEachRow(rows, []any{<% columns.times do |col_idx| %><% if col_idx != 0 %>, <% end %>&v[<%= col_idx%>]<% end %>}, func() error { return nil }) + if err != nil { + b.Fatal(err) + } + } + }) +} +<% end %> +<% end %> +<% end %> +<% end %> + +<% [10, 100, 1000].each do |array_size| %> +<% [["Text", "pgx.TextFormatCode"], ["Binary", "pgx.BinaryFormatCode"]].each do |format_name, format_code| %> +func BenchmarkQuery<%= format_name %>FormatDecode_PG_Int4Array_With_Go_Int4Array_<%= array_size %>(b *testing.B) { + defaultConnTestRunner.RunTest(context.Background(), b, func(ctx context.Context, _ testing.TB, conn *pgx.Conn) { + b.ResetTimer() + var v []int32 + for i := 0; i < b.N; i++ { + rows, _ := conn.Query( + ctx, + `select array_agg(n) from generate_series(1, <%= array_size %>) n`, + []any{pgx.QueryResultFormats{<%= format_code %>}}, + ) + _, err := pgx.ForEachRow(rows, []any{&v}, func() error { return nil }) + if err != nil { + b.Fatal(err) + } + } + }) +} +<% end %> +<% end %> diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test_gen.sh b/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test_gen.sh new file mode 100644 index 00000000000..22ac01aaf49 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/integration_benchmark_test_gen.sh @@ -0,0 +1,2 @@ +erb integration_benchmark_test.go.erb > integration_benchmark_test.go +goimports -w integration_benchmark_test.go diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/interval.go b/vendor/github.com/jackc/pgx/v5/pgtype/interval.go new file mode 100644 index 00000000000..a172ecdb5e7 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/interval.go @@ -0,0 +1,292 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const ( + microsecondsPerSecond = 1000000 + microsecondsPerMinute = 60 * microsecondsPerSecond + microsecondsPerHour = 60 * microsecondsPerMinute + microsecondsPerDay = 24 * microsecondsPerHour + microsecondsPerMonth = 30 * microsecondsPerDay +) + +type IntervalScanner interface { + ScanInterval(v Interval) error +} + +type IntervalValuer interface { + IntervalValue() (Interval, error) +} + +type Interval struct { + Microseconds int64 + Days int32 + Months int32 + Valid bool +} + +func (interval *Interval) ScanInterval(v Interval) error { + *interval = v + return nil +} + +func (interval Interval) IntervalValue() (Interval, error) { + return interval, nil +} + +// Scan implements the database/sql Scanner interface. +func (interval *Interval) Scan(src any) error { + if src == nil { + *interval = Interval{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToIntervalScanner{}.Scan([]byte(src), interval) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (interval Interval) Value() (driver.Value, error) { + if !interval.Valid { + return nil, nil + } + + buf, err := IntervalCodec{}.PlanEncode(nil, 0, TextFormatCode, interval).Encode(interval, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type IntervalCodec struct{} + +func (IntervalCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (IntervalCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (IntervalCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(IntervalValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanIntervalCodecBinary{} + case TextFormatCode: + return encodePlanIntervalCodecText{} + } + + return nil +} + +type encodePlanIntervalCodecBinary struct{} + +func (encodePlanIntervalCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + interval, err := value.(IntervalValuer).IntervalValue() + if err != nil { + return nil, err + } + + if !interval.Valid { + return nil, nil + } + + buf = pgio.AppendInt64(buf, interval.Microseconds) + buf = pgio.AppendInt32(buf, interval.Days) + buf = pgio.AppendInt32(buf, interval.Months) + return buf, nil +} + +type encodePlanIntervalCodecText struct{} + +func (encodePlanIntervalCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + interval, err := value.(IntervalValuer).IntervalValue() + if err != nil { + return nil, err + } + + if !interval.Valid { + return nil, nil + } + + if interval.Months != 0 { + buf = append(buf, strconv.FormatInt(int64(interval.Months), 10)...) + buf = append(buf, " mon "...) + } + + if interval.Days != 0 { + buf = append(buf, strconv.FormatInt(int64(interval.Days), 10)...) + buf = append(buf, " day "...) + } + + absMicroseconds := interval.Microseconds + if absMicroseconds < 0 { + absMicroseconds = -absMicroseconds + buf = append(buf, '-') + } + + hours := absMicroseconds / microsecondsPerHour + minutes := (absMicroseconds % microsecondsPerHour) / microsecondsPerMinute + seconds := (absMicroseconds % microsecondsPerMinute) / microsecondsPerSecond + microseconds := absMicroseconds % microsecondsPerSecond + + timeStr := fmt.Sprintf("%02d:%02d:%02d.%06d", hours, minutes, seconds, microseconds) + buf = append(buf, timeStr...) + return buf, nil +} + +func (IntervalCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case IntervalScanner: + return scanPlanBinaryIntervalToIntervalScanner{} + } + case TextFormatCode: + switch target.(type) { + case IntervalScanner: + return scanPlanTextAnyToIntervalScanner{} + } + } + + return nil +} + +type scanPlanBinaryIntervalToIntervalScanner struct{} + +func (scanPlanBinaryIntervalToIntervalScanner) Scan(src []byte, dst any) error { + scanner := (dst).(IntervalScanner) + + if src == nil { + return scanner.ScanInterval(Interval{}) + } + + if len(src) != 16 { + return fmt.Errorf("Received an invalid size for a interval: %d", len(src)) + } + + microseconds := int64(binary.BigEndian.Uint64(src)) + days := int32(binary.BigEndian.Uint32(src[8:])) + months := int32(binary.BigEndian.Uint32(src[12:])) + + return scanner.ScanInterval(Interval{Microseconds: microseconds, Days: days, Months: months, Valid: true}) +} + +type scanPlanTextAnyToIntervalScanner struct{} + +func (scanPlanTextAnyToIntervalScanner) Scan(src []byte, dst any) error { + scanner := (dst).(IntervalScanner) + + if src == nil { + return scanner.ScanInterval(Interval{}) + } + + var microseconds int64 + var days int32 + var months int32 + + parts := strings.Split(string(src), " ") + + for i := 0; i < len(parts)-1; i += 2 { + scalar, err := strconv.ParseInt(parts[i], 10, 64) + if err != nil { + return fmt.Errorf("bad interval format") + } + + switch parts[i+1] { + case "year", "years": + months += int32(scalar * 12) + case "mon", "mons": + months += int32(scalar) + case "day", "days": + days = int32(scalar) + } + } + + if len(parts)%2 == 1 { + timeParts := strings.SplitN(parts[len(parts)-1], ":", 3) + if len(timeParts) != 3 { + return fmt.Errorf("bad interval format") + } + + var negative bool + if timeParts[0][0] == '-' { + negative = true + timeParts[0] = timeParts[0][1:] + } + + hours, err := strconv.ParseInt(timeParts[0], 10, 64) + if err != nil { + return fmt.Errorf("bad interval hour format: %s", timeParts[0]) + } + + minutes, err := strconv.ParseInt(timeParts[1], 10, 64) + if err != nil { + return fmt.Errorf("bad interval minute format: %s", timeParts[1]) + } + + secondParts := strings.SplitN(timeParts[2], ".", 2) + + seconds, err := strconv.ParseInt(secondParts[0], 10, 64) + if err != nil { + return fmt.Errorf("bad interval second format: %s", secondParts[0]) + } + + var uSeconds int64 + if len(secondParts) == 2 { + uSeconds, err = strconv.ParseInt(secondParts[1], 10, 64) + if err != nil { + return fmt.Errorf("bad interval decimal format: %s", secondParts[1]) + } + + for i := 0; i < 6-len(secondParts[1]); i++ { + uSeconds *= 10 + } + } + + microseconds = hours * microsecondsPerHour + microseconds += minutes * microsecondsPerMinute + microseconds += seconds * microsecondsPerSecond + microseconds += uSeconds + + if negative { + microseconds = -microseconds + } + } + + return scanner.ScanInterval(Interval{Months: months, Days: days, Microseconds: microseconds, Valid: true}) +} + +func (c IntervalCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c IntervalCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var interval Interval + err := codecScan(c, m, oid, format, src, &interval) + if err != nil { + return nil, err + } + return interval, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/json.go b/vendor/github.com/jackc/pgx/v5/pgtype/json.go new file mode 100644 index 00000000000..753f24103ec --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/json.go @@ -0,0 +1,186 @@ +package pgtype + +import ( + "database/sql" + "database/sql/driver" + "encoding/json" + "fmt" + "reflect" +) + +type JSONCodec struct{} + +func (JSONCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (JSONCodec) PreferredFormat() int16 { + return TextFormatCode +} + +func (c JSONCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch value.(type) { + case string: + return encodePlanJSONCodecEitherFormatString{} + case []byte: + return encodePlanJSONCodecEitherFormatByteSlice{} + + // Cannot rely on driver.Valuer being handled later because anything can be marshalled. + // + // https://github.com/jackc/pgx/issues/1430 + case driver.Valuer: + return &encodePlanDriverValuer{m: m, oid: oid, formatCode: format} + } + + // Because anything can be marshalled the normal wrapping in Map.PlanScan doesn't get a chance to run. So try the + // appropriate wrappers here. + for _, f := range []TryWrapEncodePlanFunc{ + TryWrapDerefPointerEncodePlan, + TryWrapFindUnderlyingTypeEncodePlan, + } { + if wrapperPlan, nextValue, ok := f(value); ok { + if nextPlan := c.PlanEncode(m, oid, format, nextValue); nextPlan != nil { + wrapperPlan.SetNext(nextPlan) + return wrapperPlan + } + } + } + + return encodePlanJSONCodecEitherFormatMarshal{} +} + +type encodePlanJSONCodecEitherFormatString struct{} + +func (encodePlanJSONCodecEitherFormatString) Encode(value any, buf []byte) (newBuf []byte, err error) { + jsonString := value.(string) + buf = append(buf, jsonString...) + return buf, nil +} + +type encodePlanJSONCodecEitherFormatByteSlice struct{} + +func (encodePlanJSONCodecEitherFormatByteSlice) Encode(value any, buf []byte) (newBuf []byte, err error) { + jsonBytes := value.([]byte) + if jsonBytes == nil { + return nil, nil + } + + buf = append(buf, jsonBytes...) + return buf, nil +} + +type encodePlanJSONCodecEitherFormatMarshal struct{} + +func (encodePlanJSONCodecEitherFormatMarshal) Encode(value any, buf []byte) (newBuf []byte, err error) { + jsonBytes, err := json.Marshal(value) + if err != nil { + return nil, err + } + + buf = append(buf, jsonBytes...) + return buf, nil +} + +func (JSONCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch target.(type) { + case *string: + return scanPlanAnyToString{} + case *[]byte: + return scanPlanJSONToByteSlice{} + case BytesScanner: + return scanPlanBinaryBytesToBytesScanner{} + + // Cannot rely on sql.Scanner being handled later because scanPlanJSONToJSONUnmarshal will take precedence. + // + // https://github.com/jackc/pgx/issues/1418 + case sql.Scanner: + return &scanPlanSQLScanner{formatCode: format} + } + + // This is to fix **string scanning. It seems wrong to special case sql.Scanner and pointer to pointer, but it's not + // clear what a better solution would be. + // + // https://github.com/jackc/pgx/issues/1470 + if wrapperPlan, nextDst, ok := TryPointerPointerScanPlan(target); ok { + if nextPlan := m.planScan(oid, format, nextDst); nextPlan != nil { + if _, failed := nextPlan.(*scanPlanFail); !failed { + wrapperPlan.SetNext(nextPlan) + return wrapperPlan + } + } + } + + return scanPlanJSONToJSONUnmarshal{} +} + +type scanPlanAnyToString struct{} + +func (scanPlanAnyToString) Scan(src []byte, dst any) error { + p := dst.(*string) + *p = string(src) + return nil +} + +type scanPlanJSONToByteSlice struct{} + +func (scanPlanJSONToByteSlice) Scan(src []byte, dst any) error { + dstBuf := dst.(*[]byte) + if src == nil { + *dstBuf = nil + return nil + } + + *dstBuf = make([]byte, len(src)) + copy(*dstBuf, src) + return nil +} + +type scanPlanJSONToBytesScanner struct{} + +func (scanPlanJSONToBytesScanner) Scan(src []byte, dst any) error { + scanner := (dst).(BytesScanner) + return scanner.ScanBytes(src) +} + +type scanPlanJSONToJSONUnmarshal struct{} + +func (scanPlanJSONToJSONUnmarshal) Scan(src []byte, dst any) error { + if src == nil { + dstValue := reflect.ValueOf(dst) + if dstValue.Kind() == reflect.Ptr { + el := dstValue.Elem() + switch el.Kind() { + case reflect.Ptr, reflect.Slice, reflect.Map, reflect.Interface: + el.Set(reflect.Zero(el.Type())) + return nil + } + } + + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + elem := reflect.ValueOf(dst).Elem() + elem.Set(reflect.Zero(elem.Type())) + + return json.Unmarshal(src, dst) +} + +func (c JSONCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + dstBuf := make([]byte, len(src)) + copy(dstBuf, src) + return dstBuf, nil +} + +func (c JSONCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var dst any + err := json.Unmarshal(src, &dst) + return dst, err +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/jsonb.go b/vendor/github.com/jackc/pgx/v5/pgtype/jsonb.go new file mode 100644 index 00000000000..25555e7ffe4 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/jsonb.go @@ -0,0 +1,127 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/json" + "fmt" +) + +type JSONBCodec struct{} + +func (JSONBCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (JSONBCodec) PreferredFormat() int16 { + return TextFormatCode +} + +func (JSONBCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + plan := JSONCodec{}.PlanEncode(m, oid, TextFormatCode, value) + if plan != nil { + return &encodePlanJSONBCodecBinaryWrapper{textPlan: plan} + } + case TextFormatCode: + return JSONCodec{}.PlanEncode(m, oid, format, value) + } + + return nil +} + +type encodePlanJSONBCodecBinaryWrapper struct { + textPlan EncodePlan +} + +func (plan *encodePlanJSONBCodecBinaryWrapper) Encode(value any, buf []byte) (newBuf []byte, err error) { + buf = append(buf, 1) + return plan.textPlan.Encode(value, buf) +} + +func (JSONBCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case BinaryFormatCode: + plan := JSONCodec{}.PlanScan(m, oid, TextFormatCode, target) + if plan != nil { + return &scanPlanJSONBCodecBinaryUnwrapper{textPlan: plan} + } + case TextFormatCode: + return JSONCodec{}.PlanScan(m, oid, format, target) + } + + return nil +} + +type scanPlanJSONBCodecBinaryUnwrapper struct { + textPlan ScanPlan +} + +func (plan *scanPlanJSONBCodecBinaryUnwrapper) Scan(src []byte, dst any) error { + if src == nil { + return plan.textPlan.Scan(src, dst) + } + + if len(src) == 0 { + return fmt.Errorf("jsonb too short") + } + + if src[0] != 1 { + return fmt.Errorf("unknown jsonb version number %d", src[0]) + } + + return plan.textPlan.Scan(src[1:], dst) +} + +func (c JSONBCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + switch format { + case BinaryFormatCode: + if len(src) == 0 { + return nil, fmt.Errorf("jsonb too short") + } + + if src[0] != 1 { + return nil, fmt.Errorf("unknown jsonb version number %d", src[0]) + } + + dstBuf := make([]byte, len(src)-1) + copy(dstBuf, src[1:]) + return dstBuf, nil + case TextFormatCode: + dstBuf := make([]byte, len(src)) + copy(dstBuf, src) + return dstBuf, nil + default: + return nil, fmt.Errorf("unknown format code: %v", format) + } +} + +func (c JSONBCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + switch format { + case BinaryFormatCode: + if len(src) == 0 { + return nil, fmt.Errorf("jsonb too short") + } + + if src[0] != 1 { + return nil, fmt.Errorf("unknown jsonb version number %d", src[0]) + } + + src = src[1:] + case TextFormatCode: + default: + return nil, fmt.Errorf("unknown format code: %v", format) + } + + var dst any + err := json.Unmarshal(src, &dst) + return dst, err +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/line.go b/vendor/github.com/jackc/pgx/v5/pgtype/line.go new file mode 100644 index 00000000000..4ae8003e800 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/line.go @@ -0,0 +1,225 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type LineScanner interface { + ScanLine(v Line) error +} + +type LineValuer interface { + LineValue() (Line, error) +} + +type Line struct { + A, B, C float64 + Valid bool +} + +func (line *Line) ScanLine(v Line) error { + *line = v + return nil +} + +func (line Line) LineValue() (Line, error) { + return line, nil +} + +func (line *Line) Set(src any) error { + return fmt.Errorf("cannot convert %v to Line", src) +} + +// Scan implements the database/sql Scanner interface. +func (line *Line) Scan(src any) error { + if src == nil { + *line = Line{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToLineScanner{}.Scan([]byte(src), line) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (line Line) Value() (driver.Value, error) { + if !line.Valid { + return nil, nil + } + + buf, err := LineCodec{}.PlanEncode(nil, 0, TextFormatCode, line).Encode(line, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type LineCodec struct{} + +func (LineCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (LineCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (LineCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(LineValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanLineCodecBinary{} + case TextFormatCode: + return encodePlanLineCodecText{} + } + + return nil +} + +type encodePlanLineCodecBinary struct{} + +func (encodePlanLineCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + line, err := value.(LineValuer).LineValue() + if err != nil { + return nil, err + } + + if !line.Valid { + return nil, nil + } + + buf = pgio.AppendUint64(buf, math.Float64bits(line.A)) + buf = pgio.AppendUint64(buf, math.Float64bits(line.B)) + buf = pgio.AppendUint64(buf, math.Float64bits(line.C)) + return buf, nil +} + +type encodePlanLineCodecText struct{} + +func (encodePlanLineCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + line, err := value.(LineValuer).LineValue() + if err != nil { + return nil, err + } + + if !line.Valid { + return nil, nil + } + + buf = append(buf, fmt.Sprintf(`{%s,%s,%s}`, + strconv.FormatFloat(line.A, 'f', -1, 64), + strconv.FormatFloat(line.B, 'f', -1, 64), + strconv.FormatFloat(line.C, 'f', -1, 64), + )...) + return buf, nil +} + +func (LineCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case LineScanner: + return scanPlanBinaryLineToLineScanner{} + } + case TextFormatCode: + switch target.(type) { + case LineScanner: + return scanPlanTextAnyToLineScanner{} + } + } + + return nil +} + +type scanPlanBinaryLineToLineScanner struct{} + +func (scanPlanBinaryLineToLineScanner) Scan(src []byte, dst any) error { + scanner := (dst).(LineScanner) + + if src == nil { + return scanner.ScanLine(Line{}) + } + + if len(src) != 24 { + return fmt.Errorf("invalid length for line: %v", len(src)) + } + + a := binary.BigEndian.Uint64(src) + b := binary.BigEndian.Uint64(src[8:]) + c := binary.BigEndian.Uint64(src[16:]) + + return scanner.ScanLine(Line{ + A: math.Float64frombits(a), + B: math.Float64frombits(b), + C: math.Float64frombits(c), + Valid: true, + }) +} + +type scanPlanTextAnyToLineScanner struct{} + +func (scanPlanTextAnyToLineScanner) Scan(src []byte, dst any) error { + scanner := (dst).(LineScanner) + + if src == nil { + return scanner.ScanLine(Line{}) + } + + if len(src) < 7 { + return fmt.Errorf("invalid length for line: %v", len(src)) + } + + parts := strings.SplitN(string(src[1:len(src)-1]), ",", 3) + if len(parts) < 3 { + return fmt.Errorf("invalid format for line") + } + + a, err := strconv.ParseFloat(parts[0], 64) + if err != nil { + return err + } + + b, err := strconv.ParseFloat(parts[1], 64) + if err != nil { + return err + } + + c, err := strconv.ParseFloat(parts[2], 64) + if err != nil { + return err + } + + return scanner.ScanLine(Line{A: a, B: b, C: c, Valid: true}) +} + +func (c LineCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c LineCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var line Line + err := codecScan(c, m, oid, format, src, &line) + if err != nil { + return nil, err + } + return line, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/lseg.go b/vendor/github.com/jackc/pgx/v5/pgtype/lseg.go new file mode 100644 index 00000000000..05a86e1c89c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/lseg.go @@ -0,0 +1,238 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type LsegScanner interface { + ScanLseg(v Lseg) error +} + +type LsegValuer interface { + LsegValue() (Lseg, error) +} + +type Lseg struct { + P [2]Vec2 + Valid bool +} + +func (lseg *Lseg) ScanLseg(v Lseg) error { + *lseg = v + return nil +} + +func (lseg Lseg) LsegValue() (Lseg, error) { + return lseg, nil +} + +// Scan implements the database/sql Scanner interface. +func (lseg *Lseg) Scan(src any) error { + if src == nil { + *lseg = Lseg{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToLsegScanner{}.Scan([]byte(src), lseg) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (lseg Lseg) Value() (driver.Value, error) { + if !lseg.Valid { + return nil, nil + } + + buf, err := LsegCodec{}.PlanEncode(nil, 0, TextFormatCode, lseg).Encode(lseg, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type LsegCodec struct{} + +func (LsegCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (LsegCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (LsegCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(LsegValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanLsegCodecBinary{} + case TextFormatCode: + return encodePlanLsegCodecText{} + } + + return nil +} + +type encodePlanLsegCodecBinary struct{} + +func (encodePlanLsegCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + lseg, err := value.(LsegValuer).LsegValue() + if err != nil { + return nil, err + } + + if !lseg.Valid { + return nil, nil + } + + buf = pgio.AppendUint64(buf, math.Float64bits(lseg.P[0].X)) + buf = pgio.AppendUint64(buf, math.Float64bits(lseg.P[0].Y)) + buf = pgio.AppendUint64(buf, math.Float64bits(lseg.P[1].X)) + buf = pgio.AppendUint64(buf, math.Float64bits(lseg.P[1].Y)) + return buf, nil +} + +type encodePlanLsegCodecText struct{} + +func (encodePlanLsegCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + lseg, err := value.(LsegValuer).LsegValue() + if err != nil { + return nil, err + } + + if !lseg.Valid { + return nil, nil + } + + buf = append(buf, fmt.Sprintf(`[(%s,%s),(%s,%s)]`, + strconv.FormatFloat(lseg.P[0].X, 'f', -1, 64), + strconv.FormatFloat(lseg.P[0].Y, 'f', -1, 64), + strconv.FormatFloat(lseg.P[1].X, 'f', -1, 64), + strconv.FormatFloat(lseg.P[1].Y, 'f', -1, 64), + )...) + return buf, nil +} + +func (LsegCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case LsegScanner: + return scanPlanBinaryLsegToLsegScanner{} + } + case TextFormatCode: + switch target.(type) { + case LsegScanner: + return scanPlanTextAnyToLsegScanner{} + } + } + + return nil +} + +type scanPlanBinaryLsegToLsegScanner struct{} + +func (scanPlanBinaryLsegToLsegScanner) Scan(src []byte, dst any) error { + scanner := (dst).(LsegScanner) + + if src == nil { + return scanner.ScanLseg(Lseg{}) + } + + if len(src) != 32 { + return fmt.Errorf("invalid length for lseg: %v", len(src)) + } + + x1 := binary.BigEndian.Uint64(src) + y1 := binary.BigEndian.Uint64(src[8:]) + x2 := binary.BigEndian.Uint64(src[16:]) + y2 := binary.BigEndian.Uint64(src[24:]) + + return scanner.ScanLseg(Lseg{ + P: [2]Vec2{ + {math.Float64frombits(x1), math.Float64frombits(y1)}, + {math.Float64frombits(x2), math.Float64frombits(y2)}, + }, + Valid: true, + }) +} + +type scanPlanTextAnyToLsegScanner struct{} + +func (scanPlanTextAnyToLsegScanner) Scan(src []byte, dst any) error { + scanner := (dst).(LsegScanner) + + if src == nil { + return scanner.ScanLseg(Lseg{}) + } + + if len(src) < 11 { + return fmt.Errorf("invalid length for lseg: %v", len(src)) + } + + str := string(src[2:]) + + var end int + end = strings.IndexByte(str, ',') + + x1, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+1:] + end = strings.IndexByte(str, ')') + + y1, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+3:] + end = strings.IndexByte(str, ',') + + x2, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+1 : len(str)-2] + + y2, err := strconv.ParseFloat(str, 64) + if err != nil { + return err + } + + return scanner.ScanLseg(Lseg{P: [2]Vec2{{x1, y1}, {x2, y2}}, Valid: true}) +} + +func (c LsegCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c LsegCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var lseg Lseg + err := codecScan(c, m, oid, format, src, &lseg) + if err != nil { + return nil, err + } + return lseg, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/macaddr.go b/vendor/github.com/jackc/pgx/v5/pgtype/macaddr.go new file mode 100644 index 00000000000..e913ec9034c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/macaddr.go @@ -0,0 +1,162 @@ +package pgtype + +import ( + "database/sql/driver" + "net" +) + +type MacaddrCodec struct{} + +func (MacaddrCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (MacaddrCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (MacaddrCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case net.HardwareAddr: + return encodePlanMacaddrCodecBinaryHardwareAddr{} + case TextValuer: + return encodePlanMacAddrCodecTextValuer{} + + } + case TextFormatCode: + switch value.(type) { + case net.HardwareAddr: + return encodePlanMacaddrCodecTextHardwareAddr{} + case TextValuer: + return encodePlanTextCodecTextValuer{} + } + } + + return nil +} + +type encodePlanMacaddrCodecBinaryHardwareAddr struct{} + +func (encodePlanMacaddrCodecBinaryHardwareAddr) Encode(value any, buf []byte) (newBuf []byte, err error) { + addr := value.(net.HardwareAddr) + if addr == nil { + return nil, nil + } + + return append(buf, addr...), nil +} + +type encodePlanMacAddrCodecTextValuer struct{} + +func (encodePlanMacAddrCodecTextValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + t, err := value.(TextValuer).TextValue() + if err != nil { + return nil, err + } + if !t.Valid { + return nil, nil + } + + addr, err := net.ParseMAC(t.String) + if err != nil { + return nil, err + } + + return append(buf, addr...), nil +} + +type encodePlanMacaddrCodecTextHardwareAddr struct{} + +func (encodePlanMacaddrCodecTextHardwareAddr) Encode(value any, buf []byte) (newBuf []byte, err error) { + addr := value.(net.HardwareAddr) + if addr == nil { + return nil, nil + } + + return append(buf, addr.String()...), nil +} + +func (MacaddrCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case BinaryFormatCode: + switch target.(type) { + case *net.HardwareAddr: + return scanPlanBinaryMacaddrToHardwareAddr{} + case TextScanner: + return scanPlanBinaryMacaddrToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case *net.HardwareAddr: + return scanPlanTextMacaddrToHardwareAddr{} + case TextScanner: + return scanPlanTextAnyToTextScanner{} + } + } + + return nil +} + +type scanPlanBinaryMacaddrToHardwareAddr struct{} + +func (scanPlanBinaryMacaddrToHardwareAddr) Scan(src []byte, dst any) error { + dstBuf := dst.(*net.HardwareAddr) + if src == nil { + *dstBuf = nil + return nil + } + + *dstBuf = make([]byte, len(src)) + copy(*dstBuf, src) + return nil +} + +type scanPlanBinaryMacaddrToTextScanner struct{} + +func (scanPlanBinaryMacaddrToTextScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TextScanner) + if src == nil { + return scanner.ScanText(Text{}) + } + + return scanner.ScanText(Text{String: net.HardwareAddr(src).String(), Valid: true}) +} + +type scanPlanTextMacaddrToHardwareAddr struct{} + +func (scanPlanTextMacaddrToHardwareAddr) Scan(src []byte, dst any) error { + p := dst.(*net.HardwareAddr) + + if src == nil { + *p = nil + return nil + } + + addr, err := net.ParseMAC(string(src)) + if err != nil { + return err + } + + *p = addr + + return nil +} + +func (c MacaddrCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c MacaddrCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var addr net.HardwareAddr + err := codecScan(c, m, oid, format, src, &addr) + if err != nil { + return nil, err + } + return addr, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/multirange.go b/vendor/github.com/jackc/pgx/v5/pgtype/multirange.go new file mode 100644 index 00000000000..34950b3450c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/multirange.go @@ -0,0 +1,443 @@ +package pgtype + +import ( + "bytes" + "database/sql/driver" + "encoding/binary" + "fmt" + "reflect" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// MultirangeGetter is a type that can be converted into a PostgreSQL multirange. +type MultirangeGetter interface { + // IsNull returns true if the value is SQL NULL. + IsNull() bool + + // Len returns the number of elements in the multirange. + Len() int + + // Index returns the element at i. + Index(i int) any + + // IndexType returns a non-nil scan target of the type Index will return. This is used by MultirangeCodec.PlanEncode. + IndexType() any +} + +// MultirangeSetter is a type can be set from a PostgreSQL multirange. +type MultirangeSetter interface { + // ScanNull sets the value to SQL NULL. + ScanNull() error + + // SetLen prepares the value such that ScanIndex can be called for each element. This will remove any existing + // elements. + SetLen(n int) error + + // ScanIndex returns a value usable as a scan target for i. SetLen must be called before ScanIndex. + ScanIndex(i int) any + + // ScanIndexType returns a non-nil scan target of the type ScanIndex will return. This is used by + // MultirangeCodec.PlanScan. + ScanIndexType() any +} + +// MultirangeCodec is a codec for any multirange type. +type MultirangeCodec struct { + ElementType *Type +} + +func (c *MultirangeCodec) FormatSupported(format int16) bool { + return c.ElementType.Codec.FormatSupported(format) +} + +func (c *MultirangeCodec) PreferredFormat() int16 { + return c.ElementType.Codec.PreferredFormat() +} + +func (c *MultirangeCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + multirangeValuer, ok := value.(MultirangeGetter) + if !ok { + return nil + } + + elementType := multirangeValuer.IndexType() + + elementEncodePlan := m.PlanEncode(c.ElementType.OID, format, elementType) + if elementEncodePlan == nil { + return nil + } + + switch format { + case BinaryFormatCode: + return &encodePlanMultirangeCodecBinary{ac: c, m: m, oid: oid} + case TextFormatCode: + return &encodePlanMultirangeCodecText{ac: c, m: m, oid: oid} + } + + return nil +} + +type encodePlanMultirangeCodecText struct { + ac *MultirangeCodec + m *Map + oid uint32 +} + +func (p *encodePlanMultirangeCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + multirange := value.(MultirangeGetter) + + if multirange.IsNull() { + return nil, nil + } + + elementCount := multirange.Len() + + buf = append(buf, '{') + + var encodePlan EncodePlan + var lastElemType reflect.Type + inElemBuf := make([]byte, 0, 32) + for i := 0; i < elementCount; i++ { + if i > 0 { + buf = append(buf, ',') + } + + elem := multirange.Index(i) + var elemBuf []byte + if elem != nil { + elemType := reflect.TypeOf(elem) + if lastElemType != elemType { + lastElemType = elemType + encodePlan = p.m.PlanEncode(p.ac.ElementType.OID, TextFormatCode, elem) + if encodePlan == nil { + return nil, fmt.Errorf("unable to encode %v", multirange.Index(i)) + } + } + elemBuf, err = encodePlan.Encode(elem, inElemBuf) + if err != nil { + return nil, err + } + } + + if elemBuf == nil { + return nil, fmt.Errorf("multirange cannot contain NULL element") + } else { + buf = append(buf, elemBuf...) + } + } + + buf = append(buf, '}') + + return buf, nil +} + +type encodePlanMultirangeCodecBinary struct { + ac *MultirangeCodec + m *Map + oid uint32 +} + +func (p *encodePlanMultirangeCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + multirange := value.(MultirangeGetter) + + if multirange.IsNull() { + return nil, nil + } + + elementCount := multirange.Len() + + buf = pgio.AppendInt32(buf, int32(elementCount)) + + var encodePlan EncodePlan + var lastElemType reflect.Type + for i := 0; i < elementCount; i++ { + sp := len(buf) + buf = pgio.AppendInt32(buf, -1) + + elem := multirange.Index(i) + var elemBuf []byte + if elem != nil { + elemType := reflect.TypeOf(elem) + if lastElemType != elemType { + lastElemType = elemType + encodePlan = p.m.PlanEncode(p.ac.ElementType.OID, BinaryFormatCode, elem) + if encodePlan == nil { + return nil, fmt.Errorf("unable to encode %v", multirange.Index(i)) + } + } + elemBuf, err = encodePlan.Encode(elem, buf) + if err != nil { + return nil, err + } + } + + if elemBuf == nil { + return nil, fmt.Errorf("multirange cannot contain NULL element") + } else { + buf = elemBuf + pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4)) + } + } + + return buf, nil +} + +func (c *MultirangeCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + multirangeScanner, ok := target.(MultirangeSetter) + if !ok { + return nil + } + + elementType := multirangeScanner.ScanIndexType() + + elementScanPlan := m.PlanScan(c.ElementType.OID, format, elementType) + if _, ok := elementScanPlan.(*scanPlanFail); ok { + return nil + } + + return &scanPlanMultirangeCodec{ + multirangeCodec: c, + m: m, + oid: oid, + formatCode: format, + } +} + +func (c *MultirangeCodec) decodeBinary(m *Map, multirangeOID uint32, src []byte, multirange MultirangeSetter) error { + rp := 0 + + elementCount := int(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + + err := multirange.SetLen(elementCount) + if err != nil { + return err + } + + if elementCount == 0 { + return nil + } + + elementScanPlan := c.ElementType.Codec.PlanScan(m, c.ElementType.OID, BinaryFormatCode, multirange.ScanIndex(0)) + if elementScanPlan == nil { + elementScanPlan = m.PlanScan(c.ElementType.OID, BinaryFormatCode, multirange.ScanIndex(0)) + } + + for i := 0; i < elementCount; i++ { + elem := multirange.ScanIndex(i) + elemLen := int(int32(binary.BigEndian.Uint32(src[rp:]))) + rp += 4 + var elemSrc []byte + if elemLen >= 0 { + elemSrc = src[rp : rp+elemLen] + rp += elemLen + } + err = elementScanPlan.Scan(elemSrc, elem) + if err != nil { + return fmt.Errorf("failed to scan multirange element %d: %w", i, err) + } + } + + return nil +} + +func (c *MultirangeCodec) decodeText(m *Map, multirangeOID uint32, src []byte, multirange MultirangeSetter) error { + elements, err := parseUntypedTextMultirange(src) + if err != nil { + return err + } + + err = multirange.SetLen(len(elements)) + if err != nil { + return err + } + + if len(elements) == 0 { + return nil + } + + elementScanPlan := c.ElementType.Codec.PlanScan(m, c.ElementType.OID, TextFormatCode, multirange.ScanIndex(0)) + if elementScanPlan == nil { + elementScanPlan = m.PlanScan(c.ElementType.OID, TextFormatCode, multirange.ScanIndex(0)) + } + + for i, s := range elements { + elem := multirange.ScanIndex(i) + err = elementScanPlan.Scan([]byte(s), elem) + if err != nil { + return err + } + } + + return nil +} + +type scanPlanMultirangeCodec struct { + multirangeCodec *MultirangeCodec + m *Map + oid uint32 + formatCode int16 + elementScanPlan ScanPlan +} + +func (spac *scanPlanMultirangeCodec) Scan(src []byte, dst any) error { + c := spac.multirangeCodec + m := spac.m + oid := spac.oid + formatCode := spac.formatCode + + multirange := dst.(MultirangeSetter) + + if src == nil { + return multirange.ScanNull() + } + + switch formatCode { + case BinaryFormatCode: + return c.decodeBinary(m, oid, src, multirange) + case TextFormatCode: + return c.decodeText(m, oid, src, multirange) + default: + return fmt.Errorf("unknown format code %d", formatCode) + } +} + +func (c *MultirangeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + switch format { + case TextFormatCode: + return string(src), nil + case BinaryFormatCode: + buf := make([]byte, len(src)) + copy(buf, src) + return buf, nil + default: + return nil, fmt.Errorf("unknown format code %d", format) + } +} + +func (c *MultirangeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var multirange Multirange[Range[any]] + err := m.PlanScan(oid, format, &multirange).Scan(src, &multirange) + return multirange, err +} + +func parseUntypedTextMultirange(src []byte) ([]string, error) { + elements := make([]string, 0) + + buf := bytes.NewBuffer(src) + + skipWhitespace(buf) + + r, _, err := buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid array: %v", err) + } + + if r != '{' { + return nil, fmt.Errorf("invalid multirange, expected '{': %v", err) + } + +parseValueLoop: + for { + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid multirange: %v", err) + } + + switch r { + case ',': // skip range separator + case '}': + break parseValueLoop + default: + buf.UnreadRune() + value, err := parseRange(buf) + if err != nil { + return nil, fmt.Errorf("invalid multirange value: %v", err) + } + elements = append(elements, value) + } + } + + skipWhitespace(buf) + + if buf.Len() > 0 { + return nil, fmt.Errorf("unexpected trailing data: %v", buf.String()) + } + + return elements, nil + +} + +func parseRange(buf *bytes.Buffer) (string, error) { + s := &bytes.Buffer{} + + boundSepRead := false + for { + r, _, err := buf.ReadRune() + if err != nil { + return "", err + } + + switch r { + case ',', '}': + if r == ',' && !boundSepRead { + boundSepRead = true + break + } + buf.UnreadRune() + return s.String(), nil + } + + s.WriteRune(r) + } +} + +// Multirange is a generic multirange type. +// +// T should implement RangeValuer and *T should implement RangeScanner. However, there does not appear to be a way to +// enforce the RangeScanner constraint. +type Multirange[T RangeValuer] []T + +func (r Multirange[T]) IsNull() bool { + return r == nil +} + +func (r Multirange[T]) Len() int { + return len(r) +} + +func (r Multirange[T]) Index(i int) any { + return r[i] +} + +func (r Multirange[T]) IndexType() any { + var zero T + return zero +} + +func (r *Multirange[T]) ScanNull() error { + *r = nil + return nil +} + +func (r *Multirange[T]) SetLen(n int) error { + *r = make([]T, n) + return nil +} + +func (r Multirange[T]) ScanIndex(i int) any { + return &r[i] +} + +func (r Multirange[T]) ScanIndexType() any { + return new(T) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/numeric.go b/vendor/github.com/jackc/pgx/v5/pgtype/numeric.go new file mode 100644 index 00000000000..376c03fe851 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/numeric.go @@ -0,0 +1,820 @@ +package pgtype + +import ( + "bytes" + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "math/big" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// PostgreSQL internal numeric storage uses 16-bit "digits" with base of 10,000 +const nbase = 10000 + +const ( + pgNumericNaN = 0x00000000c0000000 + pgNumericNaNSign = 0xc000 + + pgNumericPosInf = 0x00000000d0000000 + pgNumericPosInfSign = 0xd000 + + pgNumericNegInf = 0x00000000f0000000 + pgNumericNegInfSign = 0xf000 +) + +var big0 *big.Int = big.NewInt(0) +var big1 *big.Int = big.NewInt(1) +var big10 *big.Int = big.NewInt(10) +var big100 *big.Int = big.NewInt(100) +var big1000 *big.Int = big.NewInt(1000) + +var bigMaxInt8 *big.Int = big.NewInt(math.MaxInt8) +var bigMinInt8 *big.Int = big.NewInt(math.MinInt8) +var bigMaxInt16 *big.Int = big.NewInt(math.MaxInt16) +var bigMinInt16 *big.Int = big.NewInt(math.MinInt16) +var bigMaxInt32 *big.Int = big.NewInt(math.MaxInt32) +var bigMinInt32 *big.Int = big.NewInt(math.MinInt32) +var bigMaxInt64 *big.Int = big.NewInt(math.MaxInt64) +var bigMinInt64 *big.Int = big.NewInt(math.MinInt64) +var bigMaxInt *big.Int = big.NewInt(int64(maxInt)) +var bigMinInt *big.Int = big.NewInt(int64(minInt)) + +var bigMaxUint8 *big.Int = big.NewInt(math.MaxUint8) +var bigMaxUint16 *big.Int = big.NewInt(math.MaxUint16) +var bigMaxUint32 *big.Int = big.NewInt(math.MaxUint32) +var bigMaxUint64 *big.Int = (&big.Int{}).SetUint64(uint64(math.MaxUint64)) +var bigMaxUint *big.Int = (&big.Int{}).SetUint64(uint64(maxUint)) + +var bigNBase *big.Int = big.NewInt(nbase) +var bigNBaseX2 *big.Int = big.NewInt(nbase * nbase) +var bigNBaseX3 *big.Int = big.NewInt(nbase * nbase * nbase) +var bigNBaseX4 *big.Int = big.NewInt(nbase * nbase * nbase * nbase) + +type NumericScanner interface { + ScanNumeric(v Numeric) error +} + +type NumericValuer interface { + NumericValue() (Numeric, error) +} + +type Numeric struct { + Int *big.Int + Exp int32 + NaN bool + InfinityModifier InfinityModifier + Valid bool +} + +func (n *Numeric) ScanNumeric(v Numeric) error { + *n = v + return nil +} + +func (n Numeric) NumericValue() (Numeric, error) { + return n, nil +} + +func (n Numeric) Float64Value() (Float8, error) { + if !n.Valid { + return Float8{}, nil + } else if n.NaN { + return Float8{Float64: math.NaN(), Valid: true}, nil + } else if n.InfinityModifier == Infinity { + return Float8{Float64: math.Inf(1), Valid: true}, nil + } else if n.InfinityModifier == NegativeInfinity { + return Float8{Float64: math.Inf(-1), Valid: true}, nil + } + + buf := make([]byte, 0, 32) + + if n.Int == nil { + buf = append(buf, '0') + } else { + buf = append(buf, n.Int.String()...) + } + buf = append(buf, 'e') + buf = append(buf, strconv.FormatInt(int64(n.Exp), 10)...) + + f, err := strconv.ParseFloat(string(buf), 64) + if err != nil { + return Float8{}, err + } + + return Float8{Float64: f, Valid: true}, nil +} + +func (n *Numeric) ScanInt64(v Int8) error { + if !v.Valid { + *n = Numeric{} + return nil + } + + *n = Numeric{Int: big.NewInt(v.Int64), Valid: true} + return nil +} + +func (n Numeric) Int64Value() (Int8, error) { + if !n.Valid { + return Int8{}, nil + } + + bi, err := n.toBigInt() + if err != nil { + return Int8{}, err + } + + if !bi.IsInt64() { + return Int8{}, fmt.Errorf("cannot convert %v to int64", n) + } + + return Int8{Int64: bi.Int64(), Valid: true}, nil +} + +func (n *Numeric) toBigInt() (*big.Int, error) { + if n.Exp == 0 { + return n.Int, nil + } + + num := &big.Int{} + num.Set(n.Int) + if n.Exp > 0 { + mul := &big.Int{} + mul.Exp(big10, big.NewInt(int64(n.Exp)), nil) + num.Mul(num, mul) + return num, nil + } + + div := &big.Int{} + div.Exp(big10, big.NewInt(int64(-n.Exp)), nil) + remainder := &big.Int{} + num.DivMod(num, div, remainder) + if remainder.Cmp(big0) != 0 { + return nil, fmt.Errorf("cannot convert %v to integer", n) + } + return num, nil +} + +func parseNumericString(str string) (n *big.Int, exp int32, err error) { + parts := strings.SplitN(str, ".", 2) + digits := strings.Join(parts, "") + + if len(parts) > 1 { + exp = int32(-len(parts[1])) + } else { + for len(digits) > 1 && digits[len(digits)-1] == '0' && digits[len(digits)-2] != '-' { + digits = digits[:len(digits)-1] + exp++ + } + } + + accum := &big.Int{} + if _, ok := accum.SetString(digits, 10); !ok { + return nil, 0, fmt.Errorf("%s is not a number", str) + } + + return accum, exp, nil +} + +func nbaseDigitsToInt64(src []byte) (accum int64, bytesRead, digitsRead int) { + digits := len(src) / 2 + if digits > 4 { + digits = 4 + } + + rp := 0 + + for i := 0; i < digits; i++ { + if i > 0 { + accum *= nbase + } + accum += int64(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + } + + return accum, rp, digits +} + +// Scan implements the database/sql Scanner interface. +func (n *Numeric) Scan(src any) error { + if src == nil { + *n = Numeric{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToNumericScanner{}.Scan([]byte(src), n) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (n Numeric) Value() (driver.Value, error) { + if !n.Valid { + return nil, nil + } + + buf, err := NumericCodec{}.PlanEncode(nil, 0, TextFormatCode, n).Encode(n, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +func (n Numeric) MarshalJSON() ([]byte, error) { + if !n.Valid { + return []byte("null"), nil + } + + if n.NaN { + return []byte(`"NaN"`), nil + } + + return n.numberTextBytes(), nil +} + +func (n *Numeric) UnmarshalJSON(src []byte) error { + if bytes.Compare(src, []byte(`null`)) == 0 { + *n = Numeric{} + return nil + } + if bytes.Compare(src, []byte(`"NaN"`)) == 0 { + *n = Numeric{NaN: true, Valid: true} + return nil + } + return scanPlanTextAnyToNumericScanner{}.Scan(src, n) +} + +// numberString returns a string of the number. undefined if NaN, infinite, or NULL +func (n Numeric) numberTextBytes() []byte { + intStr := n.Int.String() + + buf := &bytes.Buffer{} + + if len(intStr) > 0 && intStr[:1] == "-" { + intStr = intStr[1:] + buf.WriteByte('-') + } + + exp := int(n.Exp) + if exp > 0 { + buf.WriteString(intStr) + for i := 0; i < exp; i++ { + buf.WriteByte('0') + } + } else if exp < 0 { + if len(intStr) <= -exp { + buf.WriteString("0.") + leadingZeros := -exp - len(intStr) + for i := 0; i < leadingZeros; i++ { + buf.WriteByte('0') + } + buf.WriteString(intStr) + } else if len(intStr) > -exp { + dpPos := len(intStr) + exp + buf.WriteString(intStr[:dpPos]) + buf.WriteByte('.') + buf.WriteString(intStr[dpPos:]) + } + } else { + buf.WriteString(intStr) + } + + return buf.Bytes() +} + +type NumericCodec struct{} + +func (NumericCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (NumericCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (NumericCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case NumericValuer: + return encodePlanNumericCodecBinaryNumericValuer{} + case Float64Valuer: + return encodePlanNumericCodecBinaryFloat64Valuer{} + case Int64Valuer: + return encodePlanNumericCodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case NumericValuer: + return encodePlanNumericCodecTextNumericValuer{} + case Float64Valuer: + return encodePlanNumericCodecTextFloat64Valuer{} + case Int64Valuer: + return encodePlanNumericCodecTextInt64Valuer{} + } + } + + return nil +} + +type encodePlanNumericCodecBinaryNumericValuer struct{} + +func (encodePlanNumericCodecBinaryNumericValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(NumericValuer).NumericValue() + if err != nil { + return nil, err + } + + return encodeNumericBinary(n, buf) +} + +type encodePlanNumericCodecBinaryFloat64Valuer struct{} + +func (encodePlanNumericCodecBinaryFloat64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Float64Valuer).Float64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if math.IsNaN(n.Float64) { + return encodeNumericBinary(Numeric{NaN: true, Valid: true}, buf) + } else if math.IsInf(n.Float64, 1) { + return encodeNumericBinary(Numeric{InfinityModifier: Infinity, Valid: true}, buf) + } else if math.IsInf(n.Float64, -1) { + return encodeNumericBinary(Numeric{InfinityModifier: NegativeInfinity, Valid: true}, buf) + } + num, exp, err := parseNumericString(strconv.FormatFloat(n.Float64, 'f', -1, 64)) + if err != nil { + return nil, err + } + + return encodeNumericBinary(Numeric{Int: num, Exp: exp, Valid: true}, buf) +} + +type encodePlanNumericCodecBinaryInt64Valuer struct{} + +func (encodePlanNumericCodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + return encodeNumericBinary(Numeric{Int: big.NewInt(n.Int64), Valid: true}, buf) +} + +func encodeNumericBinary(n Numeric, buf []byte) (newBuf []byte, err error) { + if !n.Valid { + return nil, nil + } + + if n.NaN { + buf = pgio.AppendUint64(buf, pgNumericNaN) + return buf, nil + } else if n.InfinityModifier == Infinity { + buf = pgio.AppendUint64(buf, pgNumericPosInf) + return buf, nil + } else if n.InfinityModifier == NegativeInfinity { + buf = pgio.AppendUint64(buf, pgNumericNegInf) + return buf, nil + } + + var sign int16 + if n.Int.Cmp(big0) < 0 { + sign = 16384 + } + + absInt := &big.Int{} + wholePart := &big.Int{} + fracPart := &big.Int{} + remainder := &big.Int{} + absInt.Abs(n.Int) + + // Normalize absInt and exp to where exp is always a multiple of 4. This makes + // converting to 16-bit base 10,000 digits easier. + var exp int32 + switch n.Exp % 4 { + case 1, -3: + exp = n.Exp - 1 + absInt.Mul(absInt, big10) + case 2, -2: + exp = n.Exp - 2 + absInt.Mul(absInt, big100) + case 3, -1: + exp = n.Exp - 3 + absInt.Mul(absInt, big1000) + default: + exp = n.Exp + } + + if exp < 0 { + divisor := &big.Int{} + divisor.Exp(big10, big.NewInt(int64(-exp)), nil) + wholePart.DivMod(absInt, divisor, fracPart) + fracPart.Add(fracPart, divisor) + } else { + wholePart = absInt + } + + var wholeDigits, fracDigits []int16 + + for wholePart.Cmp(big0) != 0 { + wholePart.DivMod(wholePart, bigNBase, remainder) + wholeDigits = append(wholeDigits, int16(remainder.Int64())) + } + + if fracPart.Cmp(big0) != 0 { + for fracPart.Cmp(big1) != 0 { + fracPart.DivMod(fracPart, bigNBase, remainder) + fracDigits = append(fracDigits, int16(remainder.Int64())) + } + } + + buf = pgio.AppendInt16(buf, int16(len(wholeDigits)+len(fracDigits))) + + var weight int16 + if len(wholeDigits) > 0 { + weight = int16(len(wholeDigits) - 1) + if exp > 0 { + weight += int16(exp / 4) + } + } else { + weight = int16(exp/4) - 1 + int16(len(fracDigits)) + } + buf = pgio.AppendInt16(buf, weight) + + buf = pgio.AppendInt16(buf, sign) + + var dscale int16 + if n.Exp < 0 { + dscale = int16(-n.Exp) + } + buf = pgio.AppendInt16(buf, dscale) + + for i := len(wholeDigits) - 1; i >= 0; i-- { + buf = pgio.AppendInt16(buf, wholeDigits[i]) + } + + for i := len(fracDigits) - 1; i >= 0; i-- { + buf = pgio.AppendInt16(buf, fracDigits[i]) + } + + return buf, nil +} + +type encodePlanNumericCodecTextNumericValuer struct{} + +func (encodePlanNumericCodecTextNumericValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(NumericValuer).NumericValue() + if err != nil { + return nil, err + } + + return encodeNumericText(n, buf) +} + +type encodePlanNumericCodecTextFloat64Valuer struct{} + +func (encodePlanNumericCodecTextFloat64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Float64Valuer).Float64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + if math.IsNaN(n.Float64) { + buf = append(buf, "NaN"...) + } else if math.IsInf(n.Float64, 1) { + buf = append(buf, "Infinity"...) + } else if math.IsInf(n.Float64, -1) { + buf = append(buf, "-Infinity"...) + } else { + buf = append(buf, strconv.FormatFloat(n.Float64, 'f', -1, 64)...) + } + return buf, nil +} + +type encodePlanNumericCodecTextInt64Valuer struct{} + +func (encodePlanNumericCodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + n, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !n.Valid { + return nil, nil + } + + buf = append(buf, strconv.FormatInt(n.Int64, 10)...) + return buf, nil +} + +func encodeNumericText(n Numeric, buf []byte) (newBuf []byte, err error) { + if !n.Valid { + return nil, nil + } + + if n.NaN { + buf = append(buf, "NaN"...) + return buf, nil + } else if n.InfinityModifier == Infinity { + buf = append(buf, "Infinity"...) + return buf, nil + } else if n.InfinityModifier == NegativeInfinity { + buf = append(buf, "-Infinity"...) + return buf, nil + } + + buf = append(buf, n.numberTextBytes()...) + + return buf, nil +} + +func (NumericCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case NumericScanner: + return scanPlanBinaryNumericToNumericScanner{} + case Float64Scanner: + return scanPlanBinaryNumericToFloat64Scanner{} + case Int64Scanner: + return scanPlanBinaryNumericToInt64Scanner{} + case TextScanner: + return scanPlanBinaryNumericToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case NumericScanner: + return scanPlanTextAnyToNumericScanner{} + case Float64Scanner: + return scanPlanTextAnyToFloat64Scanner{} + case Int64Scanner: + return scanPlanTextAnyToInt64Scanner{} + } + } + + return nil +} + +type scanPlanBinaryNumericToNumericScanner struct{} + +func (scanPlanBinaryNumericToNumericScanner) Scan(src []byte, dst any) error { + scanner := (dst).(NumericScanner) + + if src == nil { + return scanner.ScanNumeric(Numeric{}) + } + + if len(src) < 8 { + return fmt.Errorf("numeric incomplete %v", src) + } + + rp := 0 + ndigits := binary.BigEndian.Uint16(src[rp:]) + rp += 2 + weight := int16(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + sign := binary.BigEndian.Uint16(src[rp:]) + rp += 2 + dscale := int16(binary.BigEndian.Uint16(src[rp:])) + rp += 2 + + if sign == pgNumericNaNSign { + return scanner.ScanNumeric(Numeric{NaN: true, Valid: true}) + } else if sign == pgNumericPosInfSign { + return scanner.ScanNumeric(Numeric{InfinityModifier: Infinity, Valid: true}) + } else if sign == pgNumericNegInfSign { + return scanner.ScanNumeric(Numeric{InfinityModifier: NegativeInfinity, Valid: true}) + } + + if ndigits == 0 { + return scanner.ScanNumeric(Numeric{Int: big.NewInt(0), Valid: true}) + } + + if len(src[rp:]) < int(ndigits)*2 { + return fmt.Errorf("numeric incomplete %v", src) + } + + accum := &big.Int{} + + for i := 0; i < int(ndigits+3)/4; i++ { + int64accum, bytesRead, digitsRead := nbaseDigitsToInt64(src[rp:]) + rp += bytesRead + + if i > 0 { + var mul *big.Int + switch digitsRead { + case 1: + mul = bigNBase + case 2: + mul = bigNBaseX2 + case 3: + mul = bigNBaseX3 + case 4: + mul = bigNBaseX4 + default: + return fmt.Errorf("invalid digitsRead: %d (this can't happen)", digitsRead) + } + accum.Mul(accum, mul) + } + + accum.Add(accum, big.NewInt(int64accum)) + } + + exp := (int32(weight) - int32(ndigits) + 1) * 4 + + if dscale > 0 { + fracNBaseDigits := int16(int32(ndigits) - int32(weight) - 1) + fracDecimalDigits := fracNBaseDigits * 4 + + if dscale > fracDecimalDigits { + multCount := int(dscale - fracDecimalDigits) + for i := 0; i < multCount; i++ { + accum.Mul(accum, big10) + exp-- + } + } else if dscale < fracDecimalDigits { + divCount := int(fracDecimalDigits - dscale) + for i := 0; i < divCount; i++ { + accum.Div(accum, big10) + exp++ + } + } + } + + reduced := &big.Int{} + remainder := &big.Int{} + if exp >= 0 { + for { + reduced.DivMod(accum, big10, remainder) + if remainder.Cmp(big0) != 0 { + break + } + accum.Set(reduced) + exp++ + } + } + + if sign != 0 { + accum.Neg(accum) + } + + return scanner.ScanNumeric(Numeric{Int: accum, Exp: exp, Valid: true}) +} + +type scanPlanBinaryNumericToFloat64Scanner struct{} + +func (scanPlanBinaryNumericToFloat64Scanner) Scan(src []byte, dst any) error { + scanner := (dst).(Float64Scanner) + + if src == nil { + return scanner.ScanFloat64(Float8{}) + } + + var n Numeric + + err := scanPlanBinaryNumericToNumericScanner{}.Scan(src, &n) + if err != nil { + return err + } + + f8, err := n.Float64Value() + if err != nil { + return err + } + + return scanner.ScanFloat64(f8) +} + +type scanPlanBinaryNumericToInt64Scanner struct{} + +func (scanPlanBinaryNumericToInt64Scanner) Scan(src []byte, dst any) error { + scanner := (dst).(Int64Scanner) + + if src == nil { + return scanner.ScanInt64(Int8{}) + } + + var n Numeric + + err := scanPlanBinaryNumericToNumericScanner{}.Scan(src, &n) + if err != nil { + return err + } + + bigInt, err := n.toBigInt() + if err != nil { + return err + } + + if !bigInt.IsInt64() { + return fmt.Errorf("%v is out of range for int64", bigInt) + } + + return scanner.ScanInt64(Int8{Int64: bigInt.Int64(), Valid: true}) +} + +type scanPlanBinaryNumericToTextScanner struct{} + +func (scanPlanBinaryNumericToTextScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TextScanner) + + if src == nil { + return scanner.ScanText(Text{}) + } + + var n Numeric + + err := scanPlanBinaryNumericToNumericScanner{}.Scan(src, &n) + if err != nil { + return err + } + + sbuf, err := encodeNumericText(n, nil) + if err != nil { + return err + } + + return scanner.ScanText(Text{String: string(sbuf), Valid: true}) +} + +type scanPlanTextAnyToNumericScanner struct{} + +func (scanPlanTextAnyToNumericScanner) Scan(src []byte, dst any) error { + scanner := (dst).(NumericScanner) + + if src == nil { + return scanner.ScanNumeric(Numeric{}) + } + + if string(src) == "NaN" { + return scanner.ScanNumeric(Numeric{NaN: true, Valid: true}) + } else if string(src) == "Infinity" { + return scanner.ScanNumeric(Numeric{InfinityModifier: Infinity, Valid: true}) + } else if string(src) == "-Infinity" { + return scanner.ScanNumeric(Numeric{InfinityModifier: NegativeInfinity, Valid: true}) + } + + num, exp, err := parseNumericString(string(src)) + if err != nil { + return err + } + + return scanner.ScanNumeric(Numeric{Int: num, Exp: exp, Valid: true}) +} + +func (c NumericCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + if format == TextFormatCode { + return string(src), nil + } + + var n Numeric + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + + buf, err := m.Encode(oid, TextFormatCode, n, nil) + if err != nil { + return nil, err + } + return string(buf), nil +} + +func (c NumericCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n Numeric + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/path.go b/vendor/github.com/jackc/pgx/v5/pgtype/path.go new file mode 100644 index 00000000000..73e0ec52f3c --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/path.go @@ -0,0 +1,272 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type PathScanner interface { + ScanPath(v Path) error +} + +type PathValuer interface { + PathValue() (Path, error) +} + +type Path struct { + P []Vec2 + Closed bool + Valid bool +} + +func (path *Path) ScanPath(v Path) error { + *path = v + return nil +} + +func (path Path) PathValue() (Path, error) { + return path, nil +} + +// Scan implements the database/sql Scanner interface. +func (path *Path) Scan(src any) error { + if src == nil { + *path = Path{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToPathScanner{}.Scan([]byte(src), path) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (path Path) Value() (driver.Value, error) { + if !path.Valid { + return nil, nil + } + + buf, err := PathCodec{}.PlanEncode(nil, 0, TextFormatCode, path).Encode(path, nil) + if err != nil { + return nil, err + } + + return string(buf), err +} + +type PathCodec struct{} + +func (PathCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (PathCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (PathCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(PathValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanPathCodecBinary{} + case TextFormatCode: + return encodePlanPathCodecText{} + } + + return nil +} + +type encodePlanPathCodecBinary struct{} + +func (encodePlanPathCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + path, err := value.(PathValuer).PathValue() + if err != nil { + return nil, err + } + + if !path.Valid { + return nil, nil + } + + var closeByte byte + if path.Closed { + closeByte = 1 + } + buf = append(buf, closeByte) + + buf = pgio.AppendInt32(buf, int32(len(path.P))) + + for _, p := range path.P { + buf = pgio.AppendUint64(buf, math.Float64bits(p.X)) + buf = pgio.AppendUint64(buf, math.Float64bits(p.Y)) + } + + return buf, nil +} + +type encodePlanPathCodecText struct{} + +func (encodePlanPathCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + path, err := value.(PathValuer).PathValue() + if err != nil { + return nil, err + } + + if !path.Valid { + return nil, nil + } + + var startByte, endByte byte + if path.Closed { + startByte = '(' + endByte = ')' + } else { + startByte = '[' + endByte = ']' + } + buf = append(buf, startByte) + + for i, p := range path.P { + if i > 0 { + buf = append(buf, ',') + } + buf = append(buf, fmt.Sprintf(`(%s,%s)`, + strconv.FormatFloat(p.X, 'f', -1, 64), + strconv.FormatFloat(p.Y, 'f', -1, 64), + )...) + } + + buf = append(buf, endByte) + + return buf, nil +} + +func (PathCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case PathScanner: + return scanPlanBinaryPathToPathScanner{} + } + case TextFormatCode: + switch target.(type) { + case PathScanner: + return scanPlanTextAnyToPathScanner{} + } + } + + return nil +} + +type scanPlanBinaryPathToPathScanner struct{} + +func (scanPlanBinaryPathToPathScanner) Scan(src []byte, dst any) error { + scanner := (dst).(PathScanner) + + if src == nil { + return scanner.ScanPath(Path{}) + } + + if len(src) < 5 { + return fmt.Errorf("invalid length for Path: %v", len(src)) + } + + closed := src[0] == 1 + pointCount := int(binary.BigEndian.Uint32(src[1:])) + + rp := 5 + + if 5+pointCount*16 != len(src) { + return fmt.Errorf("invalid length for Path with %d points: %v", pointCount, len(src)) + } + + points := make([]Vec2, pointCount) + for i := 0; i < len(points); i++ { + x := binary.BigEndian.Uint64(src[rp:]) + rp += 8 + y := binary.BigEndian.Uint64(src[rp:]) + rp += 8 + points[i] = Vec2{math.Float64frombits(x), math.Float64frombits(y)} + } + + return scanner.ScanPath(Path{ + P: points, + Closed: closed, + Valid: true, + }) +} + +type scanPlanTextAnyToPathScanner struct{} + +func (scanPlanTextAnyToPathScanner) Scan(src []byte, dst any) error { + scanner := (dst).(PathScanner) + + if src == nil { + return scanner.ScanPath(Path{}) + } + + if len(src) < 7 { + return fmt.Errorf("invalid length for Path: %v", len(src)) + } + + closed := src[0] == '(' + points := make([]Vec2, 0) + + str := string(src[2:]) + + for { + end := strings.IndexByte(str, ',') + x, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+1:] + end = strings.IndexByte(str, ')') + + y, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + points = append(points, Vec2{x, y}) + + if end+3 < len(str) { + str = str[end+3:] + } else { + break + } + } + + return scanner.ScanPath(Path{P: points, Closed: closed, Valid: true}) +} + +func (c PathCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c PathCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var path Path + err := codecScan(c, m, oid, format, src, &path) + if err != nil { + return nil, err + } + return path, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go new file mode 100644 index 00000000000..2672ba005c3 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype.go @@ -0,0 +1,1975 @@ +package pgtype + +import ( + "database/sql" + "database/sql/driver" + "errors" + "fmt" + "net" + "net/netip" + "reflect" + "time" +) + +// PostgreSQL oids for common types +const ( + BoolOID = 16 + ByteaOID = 17 + QCharOID = 18 + NameOID = 19 + Int8OID = 20 + Int2OID = 21 + Int4OID = 23 + TextOID = 25 + OIDOID = 26 + TIDOID = 27 + XIDOID = 28 + CIDOID = 29 + JSONOID = 114 + JSONArrayOID = 199 + PointOID = 600 + LsegOID = 601 + PathOID = 602 + BoxOID = 603 + PolygonOID = 604 + LineOID = 628 + LineArrayOID = 629 + CIDROID = 650 + CIDRArrayOID = 651 + Float4OID = 700 + Float8OID = 701 + CircleOID = 718 + CircleArrayOID = 719 + UnknownOID = 705 + MacaddrOID = 829 + InetOID = 869 + BoolArrayOID = 1000 + QCharArrayOID = 1003 + NameArrayOID = 1003 + Int2ArrayOID = 1005 + Int4ArrayOID = 1007 + TextArrayOID = 1009 + TIDArrayOID = 1010 + ByteaArrayOID = 1001 + XIDArrayOID = 1011 + CIDArrayOID = 1012 + BPCharArrayOID = 1014 + VarcharArrayOID = 1015 + Int8ArrayOID = 1016 + PointArrayOID = 1017 + LsegArrayOID = 1018 + PathArrayOID = 1019 + BoxArrayOID = 1020 + Float4ArrayOID = 1021 + Float8ArrayOID = 1022 + PolygonArrayOID = 1027 + OIDArrayOID = 1028 + ACLItemOID = 1033 + ACLItemArrayOID = 1034 + MacaddrArrayOID = 1040 + InetArrayOID = 1041 + BPCharOID = 1042 + VarcharOID = 1043 + DateOID = 1082 + TimeOID = 1083 + TimestampOID = 1114 + TimestampArrayOID = 1115 + DateArrayOID = 1182 + TimeArrayOID = 1183 + TimestamptzOID = 1184 + TimestamptzArrayOID = 1185 + IntervalOID = 1186 + IntervalArrayOID = 1187 + NumericArrayOID = 1231 + BitOID = 1560 + BitArrayOID = 1561 + VarbitOID = 1562 + VarbitArrayOID = 1563 + NumericOID = 1700 + RecordOID = 2249 + RecordArrayOID = 2287 + UUIDOID = 2950 + UUIDArrayOID = 2951 + JSONBOID = 3802 + JSONBArrayOID = 3807 + DaterangeOID = 3912 + DaterangeArrayOID = 3913 + Int4rangeOID = 3904 + Int4rangeArrayOID = 3905 + NumrangeOID = 3906 + NumrangeArrayOID = 3907 + TsrangeOID = 3908 + TsrangeArrayOID = 3909 + TstzrangeOID = 3910 + TstzrangeArrayOID = 3911 + Int8rangeOID = 3926 + Int8rangeArrayOID = 3927 + JSONPathOID = 4072 + JSONPathArrayOID = 4073 + Int4multirangeOID = 4451 + NummultirangeOID = 4532 + TsmultirangeOID = 4533 + TstzmultirangeOID = 4534 + DatemultirangeOID = 4535 + Int8multirangeOID = 4536 + Int4multirangeArrayOID = 6150 + NummultirangeArrayOID = 6151 + TsmultirangeArrayOID = 6152 + TstzmultirangeArrayOID = 6153 + DatemultirangeArrayOID = 6155 + Int8multirangeArrayOID = 6157 +) + +type InfinityModifier int8 + +const ( + Infinity InfinityModifier = 1 + Finite InfinityModifier = 0 + NegativeInfinity InfinityModifier = -Infinity +) + +func (im InfinityModifier) String() string { + switch im { + case Finite: + return "finite" + case Infinity: + return "infinity" + case NegativeInfinity: + return "-infinity" + default: + return "invalid" + } +} + +// PostgreSQL format codes +const ( + TextFormatCode = 0 + BinaryFormatCode = 1 +) + +// A Codec converts between Go and PostgreSQL values. A Codec must not be mutated after it is registered with a Map. +type Codec interface { + // FormatSupported returns true if the format is supported. + FormatSupported(int16) bool + + // PreferredFormat returns the preferred format. + PreferredFormat() int16 + + // PlanEncode returns an EncodePlan for encoding value into PostgreSQL format for oid and format. If no plan can be + // found then nil is returned. + PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan + + // PlanScan returns a ScanPlan for scanning a PostgreSQL value into a destination with the same type as target. If + // no plan can be found then nil is returned. + PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan + + // DecodeDatabaseSQLValue returns src decoded into a value compatible with the sql.Scanner interface. + DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) + + // DecodeValue returns src decoded into its default format. + DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) +} + +type nullAssignmentError struct { + dst any +} + +func (e *nullAssignmentError) Error() string { + return fmt.Sprintf("cannot assign NULL to %T", e.dst) +} + +// Type represents a PostgreSQL data type. It must not be mutated after it is registered with a Map. +type Type struct { + Codec Codec + Name string + OID uint32 +} + +// Map is the mapping between PostgreSQL server types and Go type handling logic. It can encode values for +// transmission to a PostgreSQL server and scan received values. +type Map struct { + oidToType map[uint32]*Type + nameToType map[string]*Type + reflectTypeToName map[reflect.Type]string + oidToFormatCode map[uint32]int16 + + reflectTypeToType map[reflect.Type]*Type + + memoizedScanPlans map[uint32]map[reflect.Type][2]ScanPlan + memoizedEncodePlans map[uint32]map[reflect.Type][2]EncodePlan + + // TryWrapEncodePlanFuncs is a slice of functions that will wrap a value that cannot be encoded by the Codec. Every + // time a wrapper is found the PlanEncode method will be recursively called with the new value. This allows several layers of wrappers + // to be built up. There are default functions placed in this slice by NewMap(). In most cases these functions + // should run last. i.e. Additional functions should typically be prepended not appended. + TryWrapEncodePlanFuncs []TryWrapEncodePlanFunc + + // TryWrapScanPlanFuncs is a slice of functions that will wrap a target that cannot be scanned into by the Codec. Every + // time a wrapper is found the PlanScan method will be recursively called with the new target. This allows several layers of wrappers + // to be built up. There are default functions placed in this slice by NewMap(). In most cases these functions + // should run last. i.e. Additional functions should typically be prepended not appended. + TryWrapScanPlanFuncs []TryWrapScanPlanFunc +} + +func NewMap() *Map { + defaultMapInitOnce.Do(initDefaultMap) + + return &Map{ + oidToType: make(map[uint32]*Type), + nameToType: make(map[string]*Type), + reflectTypeToName: make(map[reflect.Type]string), + oidToFormatCode: make(map[uint32]int16), + + memoizedScanPlans: make(map[uint32]map[reflect.Type][2]ScanPlan), + memoizedEncodePlans: make(map[uint32]map[reflect.Type][2]EncodePlan), + + TryWrapEncodePlanFuncs: []TryWrapEncodePlanFunc{ + TryWrapDerefPointerEncodePlan, + TryWrapBuiltinTypeEncodePlan, + TryWrapFindUnderlyingTypeEncodePlan, + TryWrapStructEncodePlan, + TryWrapSliceEncodePlan, + TryWrapMultiDimSliceEncodePlan, + TryWrapArrayEncodePlan, + }, + + TryWrapScanPlanFuncs: []TryWrapScanPlanFunc{ + TryPointerPointerScanPlan, + TryWrapBuiltinTypeScanPlan, + TryFindUnderlyingTypeScanPlan, + TryWrapStructScanPlan, + TryWrapPtrSliceScanPlan, + TryWrapPtrMultiDimSliceScanPlan, + TryWrapPtrArrayScanPlan, + }, + } +} + +// RegisterType registers a data type with the Map. t must not be mutated after it is registered. +func (m *Map) RegisterType(t *Type) { + m.oidToType[t.OID] = t + m.nameToType[t.Name] = t + m.oidToFormatCode[t.OID] = t.Codec.PreferredFormat() + + // Invalidated by type registration + m.reflectTypeToType = nil + for k := range m.memoizedScanPlans { + delete(m.memoizedScanPlans, k) + } + for k := range m.memoizedEncodePlans { + delete(m.memoizedEncodePlans, k) + } +} + +// RegisterDefaultPgType registers a mapping of a Go type to a PostgreSQL type name. Typically the data type to be +// encoded or decoded is determined by the PostgreSQL OID. But if the OID of a value to be encoded or decoded is +// unknown, this additional mapping will be used by TypeForValue to determine a suitable data type. +func (m *Map) RegisterDefaultPgType(value any, name string) { + m.reflectTypeToName[reflect.TypeOf(value)] = name + + // Invalidated by type registration + m.reflectTypeToType = nil + for k := range m.memoizedScanPlans { + delete(m.memoizedScanPlans, k) + } + for k := range m.memoizedEncodePlans { + delete(m.memoizedEncodePlans, k) + } +} + +// TypeForOID returns the Type registered for the given OID. The returned Type must not be mutated. +func (m *Map) TypeForOID(oid uint32) (*Type, bool) { + if dt, ok := m.oidToType[oid]; ok { + return dt, true + } + + dt, ok := defaultMap.oidToType[oid] + return dt, ok +} + +// TypeForName returns the Type registered for the given name. The returned Type must not be mutated. +func (m *Map) TypeForName(name string) (*Type, bool) { + if dt, ok := m.nameToType[name]; ok { + return dt, true + } + dt, ok := defaultMap.nameToType[name] + return dt, ok +} + +func (m *Map) buildReflectTypeToType() { + m.reflectTypeToType = make(map[reflect.Type]*Type) + + for reflectType, name := range m.reflectTypeToName { + if dt, ok := m.TypeForName(name); ok { + m.reflectTypeToType[reflectType] = dt + } + } +} + +// TypeForValue finds a data type suitable for v. Use RegisterType to register types that can encode and decode +// themselves. Use RegisterDefaultPgType to register that can be handled by a registered data type. The returned Type +// must not be mutated. +func (m *Map) TypeForValue(v any) (*Type, bool) { + if m.reflectTypeToType == nil { + m.buildReflectTypeToType() + } + + if dt, ok := m.reflectTypeToType[reflect.TypeOf(v)]; ok { + return dt, true + } + + if defaultMap.reflectTypeToType == nil { + defaultMap.buildReflectTypeToType() + } + + dt, ok := defaultMap.reflectTypeToType[reflect.TypeOf(v)] + return dt, ok +} + +// FormatCodeForOID returns the preferred format code for type oid. If the type is not registered it returns the text +// format code. +func (m *Map) FormatCodeForOID(oid uint32) int16 { + if fc, ok := m.oidToFormatCode[oid]; ok { + return fc + } + + if fc, ok := defaultMap.oidToFormatCode[oid]; ok { + return fc + } + + return TextFormatCode +} + +// EncodePlan is a precompiled plan to encode a particular type into a particular OID and format. +type EncodePlan interface { + // Encode appends the encoded bytes of value to buf. If value is the SQL value NULL then append nothing and return + // (nil, nil). The caller of Encode is responsible for writing the correct NULL value or the length of the data + // written. + Encode(value any, buf []byte) (newBuf []byte, err error) +} + +// ScanPlan is a precompiled plan to scan into a type of destination. +type ScanPlan interface { + // Scan scans src into target. src is only valid during the call to Scan. The ScanPlan must not retain a reference to + // src. + Scan(src []byte, target any) error +} + +type scanPlanCodecSQLScanner struct { + c Codec + m *Map + oid uint32 + formatCode int16 +} + +func (plan *scanPlanCodecSQLScanner) Scan(src []byte, dst any) error { + value, err := plan.c.DecodeDatabaseSQLValue(plan.m, plan.oid, plan.formatCode, src) + if err != nil { + return err + } + + scanner := dst.(sql.Scanner) + return scanner.Scan(value) +} + +type scanPlanSQLScanner struct { + formatCode int16 +} + +func (plan *scanPlanSQLScanner) Scan(src []byte, dst any) error { + scanner := dst.(sql.Scanner) + if src == nil { + // This is necessary because interface value []byte:nil does not equal nil:nil for the binary format path and the + // text format path would be converted to empty string. + return scanner.Scan(nil) + } else if plan.formatCode == BinaryFormatCode { + return scanner.Scan(src) + } else { + return scanner.Scan(string(src)) + } +} + +type scanPlanString struct{} + +func (scanPlanString) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p := (dst).(*string) + *p = string(src) + return nil +} + +type scanPlanAnyTextToBytes struct{} + +func (scanPlanAnyTextToBytes) Scan(src []byte, dst any) error { + dstBuf := dst.(*[]byte) + if src == nil { + *dstBuf = nil + return nil + } + + *dstBuf = make([]byte, len(src)) + copy(*dstBuf, src) + return nil +} + +type scanPlanFail struct { + m *Map + oid uint32 + formatCode int16 +} + +func (plan *scanPlanFail) Scan(src []byte, dst any) error { + // If src is NULL it might be possible to scan into dst even though it is the types are not compatible. While this + // may seem to be a contrived case it can occur when selecting NULL directly. PostgreSQL assigns it the type of text. + // It would be surprising to the caller to have to cast the NULL (e.g. `select null::int`). So try to figure out a + // compatible data type for dst and scan with that. + // + // See https://github.com/jackc/pgx/issues/1326 + if src == nil { + // As a horrible hack try all types to find anything that can scan into dst. + for oid := range plan.m.oidToType { + // using planScan instead of Scan or PlanScan to avoid polluting the planned scan cache. + plan := plan.m.planScan(oid, plan.formatCode, dst) + if _, ok := plan.(*scanPlanFail); !ok { + return plan.Scan(src, dst) + } + } + for oid := range defaultMap.oidToType { + if _, ok := plan.m.oidToType[oid]; !ok { + plan := plan.m.planScan(oid, plan.formatCode, dst) + if _, ok := plan.(*scanPlanFail); !ok { + return plan.Scan(src, dst) + } + } + } + } + + var format string + switch plan.formatCode { + case TextFormatCode: + format = "text" + case BinaryFormatCode: + format = "binary" + default: + format = fmt.Sprintf("unknown %d", plan.formatCode) + } + + var dataTypeName string + if t, ok := plan.m.TypeForOID(plan.oid); ok { + dataTypeName = t.Name + } else { + dataTypeName = "unknown type" + } + + return fmt.Errorf("cannot scan %s (OID %d) in %v format into %T", dataTypeName, plan.oid, format, dst) +} + +// TryWrapScanPlanFunc is a function that tries to create a wrapper plan for target. If successful it returns a plan +// that will convert the target passed to Scan and then call the next plan. nextTarget is target as it will be converted +// by plan. It must be used to find another suitable ScanPlan. When it is found SetNext must be called on plan for it +// to be usabled. ok indicates if a suitable wrapper was found. +type TryWrapScanPlanFunc func(target any) (plan WrappedScanPlanNextSetter, nextTarget any, ok bool) + +type pointerPointerScanPlan struct { + dstType reflect.Type + next ScanPlan +} + +func (plan *pointerPointerScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *pointerPointerScanPlan) Scan(src []byte, dst any) error { + el := reflect.ValueOf(dst).Elem() + if src == nil { + el.Set(reflect.Zero(el.Type())) + return nil + } + + el.Set(reflect.New(el.Type().Elem())) + return plan.next.Scan(src, el.Interface()) +} + +// TryPointerPointerScanPlan handles a pointer to a pointer by setting the target to nil for SQL NULL and allocating and +// scanning for non-NULL. +func TryPointerPointerScanPlan(target any) (plan WrappedScanPlanNextSetter, nextTarget any, ok bool) { + if dstValue := reflect.ValueOf(target); dstValue.Kind() == reflect.Ptr { + elemValue := dstValue.Elem() + if elemValue.Kind() == reflect.Ptr { + plan = &pointerPointerScanPlan{dstType: dstValue.Type()} + return plan, reflect.Zero(elemValue.Type()).Interface(), true + } + } + + return nil, nil, false +} + +// SkipUnderlyingTypePlanner prevents PlanScan and PlanDecode from trying to use the underlying type. +type SkipUnderlyingTypePlanner interface { + SkipUnderlyingTypePlan() +} + +var elemKindToPointerTypes map[reflect.Kind]reflect.Type = map[reflect.Kind]reflect.Type{ + reflect.Int: reflect.TypeOf(new(int)), + reflect.Int8: reflect.TypeOf(new(int8)), + reflect.Int16: reflect.TypeOf(new(int16)), + reflect.Int32: reflect.TypeOf(new(int32)), + reflect.Int64: reflect.TypeOf(new(int64)), + reflect.Uint: reflect.TypeOf(new(uint)), + reflect.Uint8: reflect.TypeOf(new(uint8)), + reflect.Uint16: reflect.TypeOf(new(uint16)), + reflect.Uint32: reflect.TypeOf(new(uint32)), + reflect.Uint64: reflect.TypeOf(new(uint64)), + reflect.Float32: reflect.TypeOf(new(float32)), + reflect.Float64: reflect.TypeOf(new(float64)), + reflect.String: reflect.TypeOf(new(string)), + reflect.Bool: reflect.TypeOf(new(bool)), +} + +type underlyingTypeScanPlan struct { + dstType reflect.Type + nextDstType reflect.Type + next ScanPlan +} + +func (plan *underlyingTypeScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *underlyingTypeScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, reflect.ValueOf(dst).Convert(plan.nextDstType).Interface()) +} + +// TryFindUnderlyingTypeScanPlan tries to convert to a Go builtin type. e.g. If value was of type MyString and +// MyString was defined as a string then a wrapper plan would be returned that converts MyString to string. +func TryFindUnderlyingTypeScanPlan(dst any) (plan WrappedScanPlanNextSetter, nextDst any, ok bool) { + if _, ok := dst.(SkipUnderlyingTypePlanner); ok { + return nil, nil, false + } + + dstValue := reflect.ValueOf(dst) + + if dstValue.Kind() == reflect.Ptr { + var elemValue reflect.Value + if dstValue.IsNil() { + elemValue = reflect.New(dstValue.Type().Elem()).Elem() + } else { + elemValue = dstValue.Elem() + } + nextDstType := elemKindToPointerTypes[elemValue.Kind()] + if nextDstType == nil && elemValue.Kind() == reflect.Slice { + if elemValue.Type().Elem().Kind() == reflect.Uint8 { + var v *[]byte + nextDstType = reflect.TypeOf(v) + } + } + + if nextDstType != nil && dstValue.Type() != nextDstType { + return &underlyingTypeScanPlan{dstType: dstValue.Type(), nextDstType: nextDstType}, dstValue.Convert(nextDstType).Interface(), true + } + + } + + return nil, nil, false +} + +type WrappedScanPlanNextSetter interface { + SetNext(ScanPlan) + ScanPlan +} + +// TryWrapBuiltinTypeScanPlan tries to wrap a builtin type with a wrapper that provides additional methods. e.g. If +// value was of type int32 then a wrapper plan would be returned that converts target to a value that implements +// Int64Scanner. +func TryWrapBuiltinTypeScanPlan(target any) (plan WrappedScanPlanNextSetter, nextDst any, ok bool) { + switch target := target.(type) { + case *int8: + return &wrapInt8ScanPlan{}, (*int8Wrapper)(target), true + case *int16: + return &wrapInt16ScanPlan{}, (*int16Wrapper)(target), true + case *int32: + return &wrapInt32ScanPlan{}, (*int32Wrapper)(target), true + case *int64: + return &wrapInt64ScanPlan{}, (*int64Wrapper)(target), true + case *int: + return &wrapIntScanPlan{}, (*intWrapper)(target), true + case *uint8: + return &wrapUint8ScanPlan{}, (*uint8Wrapper)(target), true + case *uint16: + return &wrapUint16ScanPlan{}, (*uint16Wrapper)(target), true + case *uint32: + return &wrapUint32ScanPlan{}, (*uint32Wrapper)(target), true + case *uint64: + return &wrapUint64ScanPlan{}, (*uint64Wrapper)(target), true + case *uint: + return &wrapUintScanPlan{}, (*uintWrapper)(target), true + case *float32: + return &wrapFloat32ScanPlan{}, (*float32Wrapper)(target), true + case *float64: + return &wrapFloat64ScanPlan{}, (*float64Wrapper)(target), true + case *string: + return &wrapStringScanPlan{}, (*stringWrapper)(target), true + case *time.Time: + return &wrapTimeScanPlan{}, (*timeWrapper)(target), true + case *time.Duration: + return &wrapDurationScanPlan{}, (*durationWrapper)(target), true + case *net.IPNet: + return &wrapNetIPNetScanPlan{}, (*netIPNetWrapper)(target), true + case *net.IP: + return &wrapNetIPScanPlan{}, (*netIPWrapper)(target), true + case *netip.Prefix: + return &wrapNetipPrefixScanPlan{}, (*netipPrefixWrapper)(target), true + case *netip.Addr: + return &wrapNetipAddrScanPlan{}, (*netipAddrWrapper)(target), true + case *map[string]*string: + return &wrapMapStringToPointerStringScanPlan{}, (*mapStringToPointerStringWrapper)(target), true + case *map[string]string: + return &wrapMapStringToStringScanPlan{}, (*mapStringToStringWrapper)(target), true + case *[16]byte: + return &wrapByte16ScanPlan{}, (*byte16Wrapper)(target), true + case *[]byte: + return &wrapByteSliceScanPlan{}, (*byteSliceWrapper)(target), true + } + + return nil, nil, false +} + +type wrapInt8ScanPlan struct { + next ScanPlan +} + +func (plan *wrapInt8ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapInt8ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*int8Wrapper)(dst.(*int8))) +} + +type wrapInt16ScanPlan struct { + next ScanPlan +} + +func (plan *wrapInt16ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapInt16ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*int16Wrapper)(dst.(*int16))) +} + +type wrapInt32ScanPlan struct { + next ScanPlan +} + +func (plan *wrapInt32ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapInt32ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*int32Wrapper)(dst.(*int32))) +} + +type wrapInt64ScanPlan struct { + next ScanPlan +} + +func (plan *wrapInt64ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapInt64ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*int64Wrapper)(dst.(*int64))) +} + +type wrapIntScanPlan struct { + next ScanPlan +} + +func (plan *wrapIntScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapIntScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*intWrapper)(dst.(*int))) +} + +type wrapUint8ScanPlan struct { + next ScanPlan +} + +func (plan *wrapUint8ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapUint8ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*uint8Wrapper)(dst.(*uint8))) +} + +type wrapUint16ScanPlan struct { + next ScanPlan +} + +func (plan *wrapUint16ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapUint16ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*uint16Wrapper)(dst.(*uint16))) +} + +type wrapUint32ScanPlan struct { + next ScanPlan +} + +func (plan *wrapUint32ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapUint32ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*uint32Wrapper)(dst.(*uint32))) +} + +type wrapUint64ScanPlan struct { + next ScanPlan +} + +func (plan *wrapUint64ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapUint64ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*uint64Wrapper)(dst.(*uint64))) +} + +type wrapUintScanPlan struct { + next ScanPlan +} + +func (plan *wrapUintScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapUintScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*uintWrapper)(dst.(*uint))) +} + +type wrapFloat32ScanPlan struct { + next ScanPlan +} + +func (plan *wrapFloat32ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapFloat32ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*float32Wrapper)(dst.(*float32))) +} + +type wrapFloat64ScanPlan struct { + next ScanPlan +} + +func (plan *wrapFloat64ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapFloat64ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*float64Wrapper)(dst.(*float64))) +} + +type wrapStringScanPlan struct { + next ScanPlan +} + +func (plan *wrapStringScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapStringScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*stringWrapper)(dst.(*string))) +} + +type wrapTimeScanPlan struct { + next ScanPlan +} + +func (plan *wrapTimeScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapTimeScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*timeWrapper)(dst.(*time.Time))) +} + +type wrapDurationScanPlan struct { + next ScanPlan +} + +func (plan *wrapDurationScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapDurationScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*durationWrapper)(dst.(*time.Duration))) +} + +type wrapNetIPNetScanPlan struct { + next ScanPlan +} + +func (plan *wrapNetIPNetScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapNetIPNetScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*netIPNetWrapper)(dst.(*net.IPNet))) +} + +type wrapNetIPScanPlan struct { + next ScanPlan +} + +func (plan *wrapNetIPScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapNetIPScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*netIPWrapper)(dst.(*net.IP))) +} + +type wrapNetipPrefixScanPlan struct { + next ScanPlan +} + +func (plan *wrapNetipPrefixScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapNetipPrefixScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*netipPrefixWrapper)(dst.(*netip.Prefix))) +} + +type wrapNetipAddrScanPlan struct { + next ScanPlan +} + +func (plan *wrapNetipAddrScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapNetipAddrScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*netipAddrWrapper)(dst.(*netip.Addr))) +} + +type wrapMapStringToPointerStringScanPlan struct { + next ScanPlan +} + +func (plan *wrapMapStringToPointerStringScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapMapStringToPointerStringScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*mapStringToPointerStringWrapper)(dst.(*map[string]*string))) +} + +type wrapMapStringToStringScanPlan struct { + next ScanPlan +} + +func (plan *wrapMapStringToStringScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapMapStringToStringScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*mapStringToStringWrapper)(dst.(*map[string]string))) +} + +type wrapByte16ScanPlan struct { + next ScanPlan +} + +func (plan *wrapByte16ScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapByte16ScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*byte16Wrapper)(dst.(*[16]byte))) +} + +type wrapByteSliceScanPlan struct { + next ScanPlan +} + +func (plan *wrapByteSliceScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapByteSliceScanPlan) Scan(src []byte, dst any) error { + return plan.next.Scan(src, (*byteSliceWrapper)(dst.(*[]byte))) +} + +type pointerEmptyInterfaceScanPlan struct { + codec Codec + m *Map + oid uint32 + formatCode int16 +} + +func (plan *pointerEmptyInterfaceScanPlan) Scan(src []byte, dst any) error { + value, err := plan.codec.DecodeValue(plan.m, plan.oid, plan.formatCode, src) + if err != nil { + return err + } + + ptrAny := dst.(*any) + *ptrAny = value + + return nil +} + +// TryWrapStructPlan tries to wrap a struct with a wrapper that implements CompositeIndexGetter. +func TryWrapStructScanPlan(target any) (plan WrappedScanPlanNextSetter, nextValue any, ok bool) { + targetValue := reflect.ValueOf(target) + if targetValue.Kind() != reflect.Ptr { + return nil, nil, false + } + + var targetElemValue reflect.Value + if targetValue.IsNil() { + targetElemValue = reflect.Zero(targetValue.Type().Elem()) + } else { + targetElemValue = targetValue.Elem() + } + targetElemType := targetElemValue.Type() + + if targetElemType.Kind() == reflect.Struct { + exportedFields := getExportedFieldValues(targetElemValue) + if len(exportedFields) == 0 { + return nil, nil, false + } + + w := ptrStructWrapper{ + s: target, + exportedFields: exportedFields, + } + return &wrapAnyPtrStructScanPlan{}, &w, true + } + + return nil, nil, false +} + +type wrapAnyPtrStructScanPlan struct { + next ScanPlan +} + +func (plan *wrapAnyPtrStructScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapAnyPtrStructScanPlan) Scan(src []byte, target any) error { + w := ptrStructWrapper{ + s: target, + exportedFields: getExportedFieldValues(reflect.ValueOf(target).Elem()), + } + + return plan.next.Scan(src, &w) +} + +// TryWrapPtrSliceScanPlan tries to wrap a pointer to a single dimension slice. +func TryWrapPtrSliceScanPlan(target any) (plan WrappedScanPlanNextSetter, nextValue any, ok bool) { + // Avoid using reflect path for common types. + switch target := target.(type) { + case *[]int16: + return &wrapPtrSliceScanPlan[int16]{}, (*FlatArray[int16])(target), true + case *[]int32: + return &wrapPtrSliceScanPlan[int32]{}, (*FlatArray[int32])(target), true + case *[]int64: + return &wrapPtrSliceScanPlan[int64]{}, (*FlatArray[int64])(target), true + case *[]float32: + return &wrapPtrSliceScanPlan[float32]{}, (*FlatArray[float32])(target), true + case *[]float64: + return &wrapPtrSliceScanPlan[float64]{}, (*FlatArray[float64])(target), true + case *[]string: + return &wrapPtrSliceScanPlan[string]{}, (*FlatArray[string])(target), true + case *[]time.Time: + return &wrapPtrSliceScanPlan[time.Time]{}, (*FlatArray[time.Time])(target), true + } + + targetType := reflect.TypeOf(target) + if targetType.Kind() != reflect.Ptr { + return nil, nil, false + } + + targetElemType := targetType.Elem() + + if targetElemType.Kind() == reflect.Slice { + slice := reflect.New(targetElemType).Elem() + return &wrapPtrSliceReflectScanPlan{}, &anySliceArrayReflect{slice: slice}, true + } + return nil, nil, false +} + +type wrapPtrSliceScanPlan[T any] struct { + next ScanPlan +} + +func (plan *wrapPtrSliceScanPlan[T]) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapPtrSliceScanPlan[T]) Scan(src []byte, target any) error { + return plan.next.Scan(src, (*FlatArray[T])(target.(*[]T))) +} + +type wrapPtrSliceReflectScanPlan struct { + next ScanPlan +} + +func (plan *wrapPtrSliceReflectScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapPtrSliceReflectScanPlan) Scan(src []byte, target any) error { + return plan.next.Scan(src, &anySliceArrayReflect{slice: reflect.ValueOf(target).Elem()}) +} + +// TryWrapPtrMultiDimSliceScanPlan tries to wrap a pointer to a multi-dimension slice. +func TryWrapPtrMultiDimSliceScanPlan(target any) (plan WrappedScanPlanNextSetter, nextValue any, ok bool) { + targetValue := reflect.ValueOf(target) + if targetValue.Kind() != reflect.Ptr { + return nil, nil, false + } + + targetElemValue := targetValue.Elem() + + if targetElemValue.Kind() == reflect.Slice { + elemElemKind := targetElemValue.Type().Elem().Kind() + if elemElemKind == reflect.Slice { + if !isRagged(targetElemValue) { + return &wrapPtrMultiDimSliceScanPlan{}, &anyMultiDimSliceArray{slice: targetValue.Elem()}, true + } + } + } + + return nil, nil, false +} + +type wrapPtrMultiDimSliceScanPlan struct { + next ScanPlan +} + +func (plan *wrapPtrMultiDimSliceScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapPtrMultiDimSliceScanPlan) Scan(src []byte, target any) error { + return plan.next.Scan(src, &anyMultiDimSliceArray{slice: reflect.ValueOf(target).Elem()}) +} + +// TryWrapPtrArrayScanPlan tries to wrap a pointer to a single dimension array. +func TryWrapPtrArrayScanPlan(target any) (plan WrappedScanPlanNextSetter, nextValue any, ok bool) { + targetValue := reflect.ValueOf(target) + if targetValue.Kind() != reflect.Ptr { + return nil, nil, false + } + + targetElemValue := targetValue.Elem() + + if targetElemValue.Kind() == reflect.Array { + return &wrapPtrArrayReflectScanPlan{}, &anyArrayArrayReflect{array: targetElemValue}, true + } + return nil, nil, false +} + +type wrapPtrArrayReflectScanPlan struct { + next ScanPlan +} + +func (plan *wrapPtrArrayReflectScanPlan) SetNext(next ScanPlan) { plan.next = next } + +func (plan *wrapPtrArrayReflectScanPlan) Scan(src []byte, target any) error { + return plan.next.Scan(src, &anyArrayArrayReflect{array: reflect.ValueOf(target).Elem()}) +} + +// PlanScan prepares a plan to scan a value into target. +func (m *Map) PlanScan(oid uint32, formatCode int16, target any) ScanPlan { + oidMemo := m.memoizedScanPlans[oid] + if oidMemo == nil { + oidMemo = make(map[reflect.Type][2]ScanPlan) + m.memoizedScanPlans[oid] = oidMemo + } + targetReflectType := reflect.TypeOf(target) + typeMemo := oidMemo[targetReflectType] + plan := typeMemo[formatCode] + if plan == nil { + plan = m.planScan(oid, formatCode, target) + typeMemo[formatCode] = plan + oidMemo[targetReflectType] = typeMemo + } + + return plan +} + +func (m *Map) planScan(oid uint32, formatCode int16, target any) ScanPlan { + if target == nil { + return &scanPlanFail{m: m, oid: oid, formatCode: formatCode} + } + + if _, ok := target.(*UndecodedBytes); ok { + return scanPlanAnyToUndecodedBytes{} + } + + switch formatCode { + case BinaryFormatCode: + switch target.(type) { + case *string: + switch oid { + case TextOID, VarcharOID: + return scanPlanString{} + } + } + case TextFormatCode: + switch target.(type) { + case *string: + return scanPlanString{} + case *[]byte: + if oid != ByteaOID { + return scanPlanAnyTextToBytes{} + } + case TextScanner: + return scanPlanTextAnyToTextScanner{} + } + } + + var dt *Type + + if dataType, ok := m.TypeForOID(oid); ok { + dt = dataType + } else if dataType, ok := m.TypeForValue(target); ok { + dt = dataType + oid = dt.OID // Preserve assumed OID in case we are recursively called below. + } + + if dt != nil { + if plan := dt.Codec.PlanScan(m, oid, formatCode, target); plan != nil { + return plan + } + } + + // This needs to happen before trying m.TryWrapScanPlanFuncs. Otherwise, a sql.Scanner would not get called if it was + // defined on a type that could be unwrapped such as `type myString string`. + // + // https://github.com/jackc/pgtype/issues/197 + if _, ok := target.(sql.Scanner); ok { + if dt == nil { + return &scanPlanSQLScanner{formatCode: formatCode} + } else { + return &scanPlanCodecSQLScanner{c: dt.Codec, m: m, oid: oid, formatCode: formatCode} + } + } + + for _, f := range m.TryWrapScanPlanFuncs { + if wrapperPlan, nextDst, ok := f(target); ok { + if nextPlan := m.planScan(oid, formatCode, nextDst); nextPlan != nil { + if _, failed := nextPlan.(*scanPlanFail); !failed { + wrapperPlan.SetNext(nextPlan) + return wrapperPlan + } + } + } + } + + if dt != nil { + if _, ok := target.(*any); ok { + return &pointerEmptyInterfaceScanPlan{codec: dt.Codec, m: m, oid: oid, formatCode: formatCode} + } + } + + return &scanPlanFail{m: m, oid: oid, formatCode: formatCode} +} + +func (m *Map) Scan(oid uint32, formatCode int16, src []byte, dst any) error { + if dst == nil { + return nil + } + + plan := m.PlanScan(oid, formatCode, dst) + return plan.Scan(src, dst) +} + +func scanUnknownType(oid uint32, formatCode int16, buf []byte, dest any) error { + switch dest := dest.(type) { + case *string: + if formatCode == BinaryFormatCode { + return fmt.Errorf("unknown oid %d in binary format cannot be scanned into %T", oid, dest) + } + *dest = string(buf) + return nil + case *[]byte: + *dest = buf + return nil + default: + if nextDst, retry := GetAssignToDstType(dest); retry { + return scanUnknownType(oid, formatCode, buf, nextDst) + } + return fmt.Errorf("unknown oid %d cannot be scanned into %T", oid, dest) + } +} + +var ErrScanTargetTypeChanged = errors.New("scan target type changed") + +func codecScan(codec Codec, m *Map, oid uint32, format int16, src []byte, dst any) error { + scanPlan := codec.PlanScan(m, oid, format, dst) + if scanPlan == nil { + return fmt.Errorf("PlanScan did not find a plan") + } + return scanPlan.Scan(src, dst) +} + +func codecDecodeToTextFormat(codec Codec, m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + if format == TextFormatCode { + return string(src), nil + } else { + value, err := codec.DecodeValue(m, oid, format, src) + if err != nil { + return nil, err + } + buf, err := m.Encode(oid, TextFormatCode, value, nil) + if err != nil { + return nil, err + } + return string(buf), nil + } +} + +// PlanEncode returns an Encode plan for encoding value into PostgreSQL format for oid and format. If no plan can be +// found then nil is returned. +func (m *Map) PlanEncode(oid uint32, format int16, value any) EncodePlan { + oidMemo := m.memoizedEncodePlans[oid] + if oidMemo == nil { + oidMemo = make(map[reflect.Type][2]EncodePlan) + m.memoizedEncodePlans[oid] = oidMemo + } + targetReflectType := reflect.TypeOf(value) + typeMemo := oidMemo[targetReflectType] + plan := typeMemo[format] + if plan == nil { + plan = m.planEncode(oid, format, value) + typeMemo[format] = plan + oidMemo[targetReflectType] = typeMemo + } + + return plan +} + +func (m *Map) planEncode(oid uint32, format int16, value any) EncodePlan { + if format == TextFormatCode { + switch value.(type) { + case string: + return encodePlanStringToAnyTextFormat{} + case TextValuer: + return encodePlanTextValuerToAnyTextFormat{} + } + } + + var dt *Type + if dataType, ok := m.TypeForOID(oid); ok { + dt = dataType + } else { + // If no type for the OID was found, then either it is unknowable (e.g. the simple protocol) or it is an + // unregistered type. In either case try to find the type and OID that matches the value (e.g. a []byte would be + // registered to PostgreSQL bytea). + if dataType, ok := m.TypeForValue(value); ok { + dt = dataType + oid = dt.OID // Preserve assumed OID in case we are recursively called below. + } + } + + if dt != nil { + if plan := dt.Codec.PlanEncode(m, oid, format, value); plan != nil { + return plan + } + } + + for _, f := range m.TryWrapEncodePlanFuncs { + if wrapperPlan, nextValue, ok := f(value); ok { + if nextPlan := m.PlanEncode(oid, format, nextValue); nextPlan != nil { + wrapperPlan.SetNext(nextPlan) + return wrapperPlan + } + } + } + + if _, ok := value.(driver.Valuer); ok { + return &encodePlanDriverValuer{m: m, oid: oid, formatCode: format} + } + + return nil +} + +type encodePlanStringToAnyTextFormat struct{} + +func (encodePlanStringToAnyTextFormat) Encode(value any, buf []byte) (newBuf []byte, err error) { + s := value.(string) + return append(buf, s...), nil +} + +type encodePlanTextValuerToAnyTextFormat struct{} + +func (encodePlanTextValuerToAnyTextFormat) Encode(value any, buf []byte) (newBuf []byte, err error) { + t, err := value.(TextValuer).TextValue() + if err != nil { + return nil, err + } + if !t.Valid { + return nil, nil + } + + return append(buf, t.String...), nil +} + +type encodePlanDriverValuer struct { + m *Map + oid uint32 + formatCode int16 +} + +func (plan *encodePlanDriverValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + dv := value.(driver.Valuer) + if dv == nil { + return nil, nil + } + v, err := dv.Value() + if err != nil { + return nil, err + } + if v == nil { + return nil, nil + } + + newBuf, err = plan.m.Encode(plan.oid, plan.formatCode, v, buf) + if err == nil { + return newBuf, nil + } + + s, ok := v.(string) + if !ok { + return nil, err + } + + var scannedValue any + scanErr := plan.m.Scan(plan.oid, TextFormatCode, []byte(s), &scannedValue) + if scanErr != nil { + return nil, err + } + + // Prevent infinite loop. We can't encode this. See https://github.com/jackc/pgx/issues/1331. + if reflect.TypeOf(value) == reflect.TypeOf(scannedValue) { + return nil, fmt.Errorf("tried to encode %v via encoding to text and scanning but failed due to receiving same type back", value) + } + + var err2 error + newBuf, err2 = plan.m.Encode(plan.oid, BinaryFormatCode, scannedValue, buf) + if err2 != nil { + return nil, err + } + + return newBuf, nil +} + +// TryWrapEncodePlanFunc is a function that tries to create a wrapper plan for value. If successful it returns a plan +// that will convert the value passed to Encode and then call the next plan. nextValue is value as it will be converted +// by plan. It must be used to find another suitable EncodePlan. When it is found SetNext must be called on plan for it +// to be usabled. ok indicates if a suitable wrapper was found. +type TryWrapEncodePlanFunc func(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) + +type derefPointerEncodePlan struct { + next EncodePlan +} + +func (plan *derefPointerEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *derefPointerEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + ptr := reflect.ValueOf(value) + + if ptr.IsNil() { + return nil, nil + } + + return plan.next.Encode(ptr.Elem().Interface(), buf) +} + +// TryWrapDerefPointerEncodePlan tries to dereference a pointer. e.g. If value was of type *string then a wrapper plan +// would be returned that derefences the value. +func TryWrapDerefPointerEncodePlan(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) { + if _, ok := value.(driver.Valuer); ok { + return nil, nil, false + } + + if valueType := reflect.TypeOf(value); valueType != nil && valueType.Kind() == reflect.Ptr { + return &derefPointerEncodePlan{}, reflect.New(valueType.Elem()).Elem().Interface(), true + } + + return nil, nil, false +} + +var kindToTypes map[reflect.Kind]reflect.Type = map[reflect.Kind]reflect.Type{ + reflect.Int: reflect.TypeOf(int(0)), + reflect.Int8: reflect.TypeOf(int8(0)), + reflect.Int16: reflect.TypeOf(int16(0)), + reflect.Int32: reflect.TypeOf(int32(0)), + reflect.Int64: reflect.TypeOf(int64(0)), + reflect.Uint: reflect.TypeOf(uint(0)), + reflect.Uint8: reflect.TypeOf(uint8(0)), + reflect.Uint16: reflect.TypeOf(uint16(0)), + reflect.Uint32: reflect.TypeOf(uint32(0)), + reflect.Uint64: reflect.TypeOf(uint64(0)), + reflect.Float32: reflect.TypeOf(float32(0)), + reflect.Float64: reflect.TypeOf(float64(0)), + reflect.String: reflect.TypeOf(""), + reflect.Bool: reflect.TypeOf(false), +} + +type underlyingTypeEncodePlan struct { + nextValueType reflect.Type + next EncodePlan +} + +func (plan *underlyingTypeEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *underlyingTypeEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(reflect.ValueOf(value).Convert(plan.nextValueType).Interface(), buf) +} + +// TryWrapFindUnderlyingTypeEncodePlan tries to convert to a Go builtin type. e.g. If value was of type MyString and +// MyString was defined as a string then a wrapper plan would be returned that converts MyString to string. +func TryWrapFindUnderlyingTypeEncodePlan(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) { + if _, ok := value.(driver.Valuer); ok { + return nil, nil, false + } + + if _, ok := value.(SkipUnderlyingTypePlanner); ok { + return nil, nil, false + } + + refValue := reflect.ValueOf(value) + + nextValueType := kindToTypes[refValue.Kind()] + if nextValueType != nil && refValue.Type() != nextValueType { + return &underlyingTypeEncodePlan{nextValueType: nextValueType}, refValue.Convert(nextValueType).Interface(), true + } + + return nil, nil, false +} + +type WrappedEncodePlanNextSetter interface { + SetNext(EncodePlan) + EncodePlan +} + +// TryWrapBuiltinTypeEncodePlan tries to wrap a builtin type with a wrapper that provides additional methods. e.g. If +// value was of type int32 then a wrapper plan would be returned that converts value to a type that implements +// Int64Valuer. +func TryWrapBuiltinTypeEncodePlan(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) { + if _, ok := value.(driver.Valuer); ok { + return nil, nil, false + } + + switch value := value.(type) { + case int8: + return &wrapInt8EncodePlan{}, int8Wrapper(value), true + case int16: + return &wrapInt16EncodePlan{}, int16Wrapper(value), true + case int32: + return &wrapInt32EncodePlan{}, int32Wrapper(value), true + case int64: + return &wrapInt64EncodePlan{}, int64Wrapper(value), true + case int: + return &wrapIntEncodePlan{}, intWrapper(value), true + case uint8: + return &wrapUint8EncodePlan{}, uint8Wrapper(value), true + case uint16: + return &wrapUint16EncodePlan{}, uint16Wrapper(value), true + case uint32: + return &wrapUint32EncodePlan{}, uint32Wrapper(value), true + case uint64: + return &wrapUint64EncodePlan{}, uint64Wrapper(value), true + case uint: + return &wrapUintEncodePlan{}, uintWrapper(value), true + case float32: + return &wrapFloat32EncodePlan{}, float32Wrapper(value), true + case float64: + return &wrapFloat64EncodePlan{}, float64Wrapper(value), true + case string: + return &wrapStringEncodePlan{}, stringWrapper(value), true + case time.Time: + return &wrapTimeEncodePlan{}, timeWrapper(value), true + case time.Duration: + return &wrapDurationEncodePlan{}, durationWrapper(value), true + case net.IPNet: + return &wrapNetIPNetEncodePlan{}, netIPNetWrapper(value), true + case net.IP: + return &wrapNetIPEncodePlan{}, netIPWrapper(value), true + case netip.Prefix: + return &wrapNetipPrefixEncodePlan{}, netipPrefixWrapper(value), true + case netip.Addr: + return &wrapNetipAddrEncodePlan{}, netipAddrWrapper(value), true + case map[string]*string: + return &wrapMapStringToPointerStringEncodePlan{}, mapStringToPointerStringWrapper(value), true + case map[string]string: + return &wrapMapStringToStringEncodePlan{}, mapStringToStringWrapper(value), true + case [16]byte: + return &wrapByte16EncodePlan{}, byte16Wrapper(value), true + case []byte: + return &wrapByteSliceEncodePlan{}, byteSliceWrapper(value), true + case fmt.Stringer: + return &wrapFmtStringerEncodePlan{}, fmtStringerWrapper{value}, true + } + + return nil, nil, false +} + +type wrapInt8EncodePlan struct { + next EncodePlan +} + +func (plan *wrapInt8EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapInt8EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(int8Wrapper(value.(int8)), buf) +} + +type wrapInt16EncodePlan struct { + next EncodePlan +} + +func (plan *wrapInt16EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapInt16EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(int16Wrapper(value.(int16)), buf) +} + +type wrapInt32EncodePlan struct { + next EncodePlan +} + +func (plan *wrapInt32EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapInt32EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(int32Wrapper(value.(int32)), buf) +} + +type wrapInt64EncodePlan struct { + next EncodePlan +} + +func (plan *wrapInt64EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapInt64EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(int64Wrapper(value.(int64)), buf) +} + +type wrapIntEncodePlan struct { + next EncodePlan +} + +func (plan *wrapIntEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapIntEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(intWrapper(value.(int)), buf) +} + +type wrapUint8EncodePlan struct { + next EncodePlan +} + +func (plan *wrapUint8EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapUint8EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(uint8Wrapper(value.(uint8)), buf) +} + +type wrapUint16EncodePlan struct { + next EncodePlan +} + +func (plan *wrapUint16EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapUint16EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(uint16Wrapper(value.(uint16)), buf) +} + +type wrapUint32EncodePlan struct { + next EncodePlan +} + +func (plan *wrapUint32EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapUint32EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(uint32Wrapper(value.(uint32)), buf) +} + +type wrapUint64EncodePlan struct { + next EncodePlan +} + +func (plan *wrapUint64EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapUint64EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(uint64Wrapper(value.(uint64)), buf) +} + +type wrapUintEncodePlan struct { + next EncodePlan +} + +func (plan *wrapUintEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapUintEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(uintWrapper(value.(uint)), buf) +} + +type wrapFloat32EncodePlan struct { + next EncodePlan +} + +func (plan *wrapFloat32EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapFloat32EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(float32Wrapper(value.(float32)), buf) +} + +type wrapFloat64EncodePlan struct { + next EncodePlan +} + +func (plan *wrapFloat64EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapFloat64EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(float64Wrapper(value.(float64)), buf) +} + +type wrapStringEncodePlan struct { + next EncodePlan +} + +func (plan *wrapStringEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapStringEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(stringWrapper(value.(string)), buf) +} + +type wrapTimeEncodePlan struct { + next EncodePlan +} + +func (plan *wrapTimeEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapTimeEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(timeWrapper(value.(time.Time)), buf) +} + +type wrapDurationEncodePlan struct { + next EncodePlan +} + +func (plan *wrapDurationEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapDurationEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(durationWrapper(value.(time.Duration)), buf) +} + +type wrapNetIPNetEncodePlan struct { + next EncodePlan +} + +func (plan *wrapNetIPNetEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapNetIPNetEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(netIPNetWrapper(value.(net.IPNet)), buf) +} + +type wrapNetIPEncodePlan struct { + next EncodePlan +} + +func (plan *wrapNetIPEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapNetIPEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(netIPWrapper(value.(net.IP)), buf) +} + +type wrapNetipPrefixEncodePlan struct { + next EncodePlan +} + +func (plan *wrapNetipPrefixEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapNetipPrefixEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(netipPrefixWrapper(value.(netip.Prefix)), buf) +} + +type wrapNetipAddrEncodePlan struct { + next EncodePlan +} + +func (plan *wrapNetipAddrEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapNetipAddrEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(netipAddrWrapper(value.(netip.Addr)), buf) +} + +type wrapMapStringToPointerStringEncodePlan struct { + next EncodePlan +} + +func (plan *wrapMapStringToPointerStringEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapMapStringToPointerStringEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(mapStringToPointerStringWrapper(value.(map[string]*string)), buf) +} + +type wrapMapStringToStringEncodePlan struct { + next EncodePlan +} + +func (plan *wrapMapStringToStringEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapMapStringToStringEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(mapStringToStringWrapper(value.(map[string]string)), buf) +} + +type wrapByte16EncodePlan struct { + next EncodePlan +} + +func (plan *wrapByte16EncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapByte16EncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(byte16Wrapper(value.([16]byte)), buf) +} + +type wrapByteSliceEncodePlan struct { + next EncodePlan +} + +func (plan *wrapByteSliceEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapByteSliceEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(byteSliceWrapper(value.([]byte)), buf) +} + +type wrapFmtStringerEncodePlan struct { + next EncodePlan +} + +func (plan *wrapFmtStringerEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapFmtStringerEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode(fmtStringerWrapper{value.(fmt.Stringer)}, buf) +} + +// TryWrapStructPlan tries to wrap a struct with a wrapper that implements CompositeIndexGetter. +func TryWrapStructEncodePlan(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) { + if _, ok := value.(driver.Valuer); ok { + return nil, nil, false + } + + if valueType := reflect.TypeOf(value); valueType != nil && valueType.Kind() == reflect.Struct { + exportedFields := getExportedFieldValues(reflect.ValueOf(value)) + if len(exportedFields) == 0 { + return nil, nil, false + } + + w := structWrapper{ + s: value, + exportedFields: exportedFields, + } + return &wrapAnyStructEncodePlan{}, w, true + } + + return nil, nil, false +} + +type wrapAnyStructEncodePlan struct { + next EncodePlan +} + +func (plan *wrapAnyStructEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapAnyStructEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + w := structWrapper{ + s: value, + exportedFields: getExportedFieldValues(reflect.ValueOf(value)), + } + + return plan.next.Encode(w, buf) +} + +func getExportedFieldValues(structValue reflect.Value) []reflect.Value { + structType := structValue.Type() + exportedFields := make([]reflect.Value, 0, structValue.NumField()) + for i := 0; i < structType.NumField(); i++ { + sf := structType.Field(i) + if sf.IsExported() { + exportedFields = append(exportedFields, structValue.Field(i)) + } + } + + return exportedFields +} + +func TryWrapSliceEncodePlan(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) { + if _, ok := value.(driver.Valuer); ok { + return nil, nil, false + } + + // Avoid using reflect path for common types. + switch value := value.(type) { + case []int16: + return &wrapSliceEncodePlan[int16]{}, (FlatArray[int16])(value), true + case []int32: + return &wrapSliceEncodePlan[int32]{}, (FlatArray[int32])(value), true + case []int64: + return &wrapSliceEncodePlan[int64]{}, (FlatArray[int64])(value), true + case []float32: + return &wrapSliceEncodePlan[float32]{}, (FlatArray[float32])(value), true + case []float64: + return &wrapSliceEncodePlan[float64]{}, (FlatArray[float64])(value), true + case []string: + return &wrapSliceEncodePlan[string]{}, (FlatArray[string])(value), true + case []time.Time: + return &wrapSliceEncodePlan[time.Time]{}, (FlatArray[time.Time])(value), true + } + + if valueType := reflect.TypeOf(value); valueType != nil && valueType.Kind() == reflect.Slice { + w := anySliceArrayReflect{ + slice: reflect.ValueOf(value), + } + return &wrapSliceEncodeReflectPlan{}, w, true + } + + return nil, nil, false +} + +type wrapSliceEncodePlan[T any] struct { + next EncodePlan +} + +func (plan *wrapSliceEncodePlan[T]) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapSliceEncodePlan[T]) Encode(value any, buf []byte) (newBuf []byte, err error) { + return plan.next.Encode((FlatArray[T])(value.([]T)), buf) +} + +type wrapSliceEncodeReflectPlan struct { + next EncodePlan +} + +func (plan *wrapSliceEncodeReflectPlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapSliceEncodeReflectPlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + w := anySliceArrayReflect{ + slice: reflect.ValueOf(value), + } + + return plan.next.Encode(w, buf) +} + +func TryWrapMultiDimSliceEncodePlan(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) { + if _, ok := value.(driver.Valuer); ok { + return nil, nil, false + } + + sliceValue := reflect.ValueOf(value) + if sliceValue.Kind() == reflect.Slice { + valueElemType := sliceValue.Type().Elem() + + if valueElemType.Kind() == reflect.Slice { + if !isRagged(sliceValue) { + w := anyMultiDimSliceArray{ + slice: reflect.ValueOf(value), + } + return &wrapMultiDimSliceEncodePlan{}, &w, true + } + } + } + + return nil, nil, false +} + +type wrapMultiDimSliceEncodePlan struct { + next EncodePlan +} + +func (plan *wrapMultiDimSliceEncodePlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapMultiDimSliceEncodePlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + w := anyMultiDimSliceArray{ + slice: reflect.ValueOf(value), + } + + return plan.next.Encode(&w, buf) +} + +func TryWrapArrayEncodePlan(value any) (plan WrappedEncodePlanNextSetter, nextValue any, ok bool) { + if _, ok := value.(driver.Valuer); ok { + return nil, nil, false + } + + if valueType := reflect.TypeOf(value); valueType != nil && valueType.Kind() == reflect.Array { + w := anyArrayArrayReflect{ + array: reflect.ValueOf(value), + } + return &wrapArrayEncodeReflectPlan{}, w, true + } + + return nil, nil, false +} + +type wrapArrayEncodeReflectPlan struct { + next EncodePlan +} + +func (plan *wrapArrayEncodeReflectPlan) SetNext(next EncodePlan) { plan.next = next } + +func (plan *wrapArrayEncodeReflectPlan) Encode(value any, buf []byte) (newBuf []byte, err error) { + w := anyArrayArrayReflect{ + array: reflect.ValueOf(value), + } + + return plan.next.Encode(w, buf) +} + +func newEncodeError(value any, m *Map, oid uint32, formatCode int16, err error) error { + var format string + switch formatCode { + case TextFormatCode: + format = "text" + case BinaryFormatCode: + format = "binary" + default: + format = fmt.Sprintf("unknown (%d)", formatCode) + } + + var dataTypeName string + if t, ok := m.TypeForOID(oid); ok { + dataTypeName = t.Name + } else { + dataTypeName = "unknown type" + } + + return fmt.Errorf("unable to encode %#v into %s format for %s (OID %d): %w", value, format, dataTypeName, oid, err) +} + +// Encode appends the encoded bytes of value to buf. If value is the SQL value NULL then append nothing and return +// (nil, nil). The caller of Encode is responsible for writing the correct NULL value or the length of the data +// written. +func (m *Map) Encode(oid uint32, formatCode int16, value any, buf []byte) (newBuf []byte, err error) { + if value == nil { + return nil, nil + } + + plan := m.PlanEncode(oid, formatCode, value) + if plan == nil { + return nil, newEncodeError(value, m, oid, formatCode, errors.New("cannot find encode plan")) + } + + newBuf, err = plan.Encode(value, buf) + if err != nil { + return nil, newEncodeError(value, m, oid, formatCode, err) + } + + return newBuf, nil +} + +// SQLScanner returns a database/sql.Scanner for v. This is necessary for types like Array[T] and Range[T] where the +// type needs assistance from Map to implement the sql.Scanner interface. It is not necessary for types like Box that +// implement sql.Scanner directly. +// +// This uses the type of v to look up the PostgreSQL OID that v presumably came from. This means v must be registered +// with m by calling RegisterDefaultPgType. +func (m *Map) SQLScanner(v any) sql.Scanner { + if s, ok := v.(sql.Scanner); ok { + return s + } + + return &sqlScannerWrapper{m: m, v: v} +} + +type sqlScannerWrapper struct { + m *Map + v any +} + +func (w *sqlScannerWrapper) Scan(src any) error { + t, ok := w.m.TypeForValue(w.v) + if !ok { + return fmt.Errorf("cannot convert to sql.Scanner: cannot find registered type for %T", w.v) + } + + var bufSrc []byte + if src != nil { + switch src := src.(type) { + case string: + bufSrc = []byte(src) + case []byte: + bufSrc = src + default: + bufSrc = []byte(fmt.Sprint(bufSrc)) + } + } + + return w.m.Scan(t.OID, TextFormatCode, bufSrc, w.v) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go new file mode 100644 index 00000000000..7526efc6041 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/pgtype_default.go @@ -0,0 +1,221 @@ +package pgtype + +import ( + "net" + "net/netip" + "reflect" + "sync" + "time" +) + +var ( + // defaultMap contains default mappings between PostgreSQL server types and Go type handling logic. + defaultMap *Map + defaultMapInitOnce = sync.Once{} +) + +func initDefaultMap() { + defaultMap = &Map{ + oidToType: make(map[uint32]*Type), + nameToType: make(map[string]*Type), + reflectTypeToName: make(map[reflect.Type]string), + oidToFormatCode: make(map[uint32]int16), + + memoizedScanPlans: make(map[uint32]map[reflect.Type][2]ScanPlan), + memoizedEncodePlans: make(map[uint32]map[reflect.Type][2]EncodePlan), + + TryWrapEncodePlanFuncs: []TryWrapEncodePlanFunc{ + TryWrapDerefPointerEncodePlan, + TryWrapBuiltinTypeEncodePlan, + TryWrapFindUnderlyingTypeEncodePlan, + TryWrapStructEncodePlan, + TryWrapSliceEncodePlan, + TryWrapMultiDimSliceEncodePlan, + TryWrapArrayEncodePlan, + }, + + TryWrapScanPlanFuncs: []TryWrapScanPlanFunc{ + TryPointerPointerScanPlan, + TryWrapBuiltinTypeScanPlan, + TryFindUnderlyingTypeScanPlan, + TryWrapStructScanPlan, + TryWrapPtrSliceScanPlan, + TryWrapPtrMultiDimSliceScanPlan, + TryWrapPtrArrayScanPlan, + }, + } + + // Base types + defaultMap.RegisterType(&Type{Name: "aclitem", OID: ACLItemOID, Codec: &TextFormatOnlyCodec{TextCodec{}}}) + defaultMap.RegisterType(&Type{Name: "bit", OID: BitOID, Codec: BitsCodec{}}) + defaultMap.RegisterType(&Type{Name: "bool", OID: BoolOID, Codec: BoolCodec{}}) + defaultMap.RegisterType(&Type{Name: "box", OID: BoxOID, Codec: BoxCodec{}}) + defaultMap.RegisterType(&Type{Name: "bpchar", OID: BPCharOID, Codec: TextCodec{}}) + defaultMap.RegisterType(&Type{Name: "bytea", OID: ByteaOID, Codec: ByteaCodec{}}) + defaultMap.RegisterType(&Type{Name: "char", OID: QCharOID, Codec: QCharCodec{}}) + defaultMap.RegisterType(&Type{Name: "cid", OID: CIDOID, Codec: Uint32Codec{}}) + defaultMap.RegisterType(&Type{Name: "cidr", OID: CIDROID, Codec: InetCodec{}}) + defaultMap.RegisterType(&Type{Name: "circle", OID: CircleOID, Codec: CircleCodec{}}) + defaultMap.RegisterType(&Type{Name: "date", OID: DateOID, Codec: DateCodec{}}) + defaultMap.RegisterType(&Type{Name: "float4", OID: Float4OID, Codec: Float4Codec{}}) + defaultMap.RegisterType(&Type{Name: "float8", OID: Float8OID, Codec: Float8Codec{}}) + defaultMap.RegisterType(&Type{Name: "inet", OID: InetOID, Codec: InetCodec{}}) + defaultMap.RegisterType(&Type{Name: "int2", OID: Int2OID, Codec: Int2Codec{}}) + defaultMap.RegisterType(&Type{Name: "int4", OID: Int4OID, Codec: Int4Codec{}}) + defaultMap.RegisterType(&Type{Name: "int8", OID: Int8OID, Codec: Int8Codec{}}) + defaultMap.RegisterType(&Type{Name: "interval", OID: IntervalOID, Codec: IntervalCodec{}}) + defaultMap.RegisterType(&Type{Name: "json", OID: JSONOID, Codec: JSONCodec{}}) + defaultMap.RegisterType(&Type{Name: "jsonb", OID: JSONBOID, Codec: JSONBCodec{}}) + defaultMap.RegisterType(&Type{Name: "jsonpath", OID: JSONPathOID, Codec: &TextFormatOnlyCodec{TextCodec{}}}) + defaultMap.RegisterType(&Type{Name: "line", OID: LineOID, Codec: LineCodec{}}) + defaultMap.RegisterType(&Type{Name: "lseg", OID: LsegOID, Codec: LsegCodec{}}) + defaultMap.RegisterType(&Type{Name: "macaddr", OID: MacaddrOID, Codec: MacaddrCodec{}}) + defaultMap.RegisterType(&Type{Name: "name", OID: NameOID, Codec: TextCodec{}}) + defaultMap.RegisterType(&Type{Name: "numeric", OID: NumericOID, Codec: NumericCodec{}}) + defaultMap.RegisterType(&Type{Name: "oid", OID: OIDOID, Codec: Uint32Codec{}}) + defaultMap.RegisterType(&Type{Name: "path", OID: PathOID, Codec: PathCodec{}}) + defaultMap.RegisterType(&Type{Name: "point", OID: PointOID, Codec: PointCodec{}}) + defaultMap.RegisterType(&Type{Name: "polygon", OID: PolygonOID, Codec: PolygonCodec{}}) + defaultMap.RegisterType(&Type{Name: "record", OID: RecordOID, Codec: RecordCodec{}}) + defaultMap.RegisterType(&Type{Name: "text", OID: TextOID, Codec: TextCodec{}}) + defaultMap.RegisterType(&Type{Name: "tid", OID: TIDOID, Codec: TIDCodec{}}) + defaultMap.RegisterType(&Type{Name: "time", OID: TimeOID, Codec: TimeCodec{}}) + defaultMap.RegisterType(&Type{Name: "timestamp", OID: TimestampOID, Codec: TimestampCodec{}}) + defaultMap.RegisterType(&Type{Name: "timestamptz", OID: TimestamptzOID, Codec: TimestamptzCodec{}}) + defaultMap.RegisterType(&Type{Name: "unknown", OID: UnknownOID, Codec: TextCodec{}}) + defaultMap.RegisterType(&Type{Name: "uuid", OID: UUIDOID, Codec: UUIDCodec{}}) + defaultMap.RegisterType(&Type{Name: "varbit", OID: VarbitOID, Codec: BitsCodec{}}) + defaultMap.RegisterType(&Type{Name: "varchar", OID: VarcharOID, Codec: TextCodec{}}) + defaultMap.RegisterType(&Type{Name: "xid", OID: XIDOID, Codec: Uint32Codec{}}) + + // Range types + defaultMap.RegisterType(&Type{Name: "daterange", OID: DaterangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[DateOID]}}) + defaultMap.RegisterType(&Type{Name: "int4range", OID: Int4rangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[Int4OID]}}) + defaultMap.RegisterType(&Type{Name: "int8range", OID: Int8rangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[Int8OID]}}) + defaultMap.RegisterType(&Type{Name: "numrange", OID: NumrangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[NumericOID]}}) + defaultMap.RegisterType(&Type{Name: "tsrange", OID: TsrangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[TimestampOID]}}) + defaultMap.RegisterType(&Type{Name: "tstzrange", OID: TstzrangeOID, Codec: &RangeCodec{ElementType: defaultMap.oidToType[TimestamptzOID]}}) + + // Multirange types + defaultMap.RegisterType(&Type{Name: "datemultirange", OID: DatemultirangeOID, Codec: &MultirangeCodec{ElementType: defaultMap.oidToType[DaterangeOID]}}) + defaultMap.RegisterType(&Type{Name: "int4multirange", OID: Int4multirangeOID, Codec: &MultirangeCodec{ElementType: defaultMap.oidToType[Int4rangeOID]}}) + defaultMap.RegisterType(&Type{Name: "int8multirange", OID: Int8multirangeOID, Codec: &MultirangeCodec{ElementType: defaultMap.oidToType[Int8rangeOID]}}) + defaultMap.RegisterType(&Type{Name: "nummultirange", OID: NummultirangeOID, Codec: &MultirangeCodec{ElementType: defaultMap.oidToType[NumrangeOID]}}) + defaultMap.RegisterType(&Type{Name: "tsmultirange", OID: TsmultirangeOID, Codec: &MultirangeCodec{ElementType: defaultMap.oidToType[TsrangeOID]}}) + defaultMap.RegisterType(&Type{Name: "tstzmultirange", OID: TstzmultirangeOID, Codec: &MultirangeCodec{ElementType: defaultMap.oidToType[TstzrangeOID]}}) + + // Array types + defaultMap.RegisterType(&Type{Name: "_aclitem", OID: ACLItemArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[ACLItemOID]}}) + defaultMap.RegisterType(&Type{Name: "_bit", OID: BitArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[BitOID]}}) + defaultMap.RegisterType(&Type{Name: "_bool", OID: BoolArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[BoolOID]}}) + defaultMap.RegisterType(&Type{Name: "_box", OID: BoxArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[BoxOID]}}) + defaultMap.RegisterType(&Type{Name: "_bpchar", OID: BPCharArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[BPCharOID]}}) + defaultMap.RegisterType(&Type{Name: "_bytea", OID: ByteaArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[ByteaOID]}}) + defaultMap.RegisterType(&Type{Name: "_char", OID: QCharArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[QCharOID]}}) + defaultMap.RegisterType(&Type{Name: "_cid", OID: CIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[CIDOID]}}) + defaultMap.RegisterType(&Type{Name: "_cidr", OID: CIDRArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[CIDROID]}}) + defaultMap.RegisterType(&Type{Name: "_circle", OID: CircleArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[CircleOID]}}) + defaultMap.RegisterType(&Type{Name: "_date", OID: DateArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[DateOID]}}) + defaultMap.RegisterType(&Type{Name: "_daterange", OID: DaterangeArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[DaterangeOID]}}) + defaultMap.RegisterType(&Type{Name: "_float4", OID: Float4ArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[Float4OID]}}) + defaultMap.RegisterType(&Type{Name: "_float8", OID: Float8ArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[Float8OID]}}) + defaultMap.RegisterType(&Type{Name: "_inet", OID: InetArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[InetOID]}}) + defaultMap.RegisterType(&Type{Name: "_int2", OID: Int2ArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[Int2OID]}}) + defaultMap.RegisterType(&Type{Name: "_int4", OID: Int4ArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[Int4OID]}}) + defaultMap.RegisterType(&Type{Name: "_int4range", OID: Int4rangeArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[Int4rangeOID]}}) + defaultMap.RegisterType(&Type{Name: "_int8", OID: Int8ArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[Int8OID]}}) + defaultMap.RegisterType(&Type{Name: "_int8range", OID: Int8rangeArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[Int8rangeOID]}}) + defaultMap.RegisterType(&Type{Name: "_interval", OID: IntervalArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[IntervalOID]}}) + defaultMap.RegisterType(&Type{Name: "_json", OID: JSONArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[JSONOID]}}) + defaultMap.RegisterType(&Type{Name: "_jsonb", OID: JSONBArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[JSONBOID]}}) + defaultMap.RegisterType(&Type{Name: "_jsonpath", OID: JSONPathArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[JSONPathOID]}}) + defaultMap.RegisterType(&Type{Name: "_line", OID: LineArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[LineOID]}}) + defaultMap.RegisterType(&Type{Name: "_lseg", OID: LsegArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[LsegOID]}}) + defaultMap.RegisterType(&Type{Name: "_macaddr", OID: MacaddrArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[MacaddrOID]}}) + defaultMap.RegisterType(&Type{Name: "_name", OID: NameArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[NameOID]}}) + defaultMap.RegisterType(&Type{Name: "_numeric", OID: NumericArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[NumericOID]}}) + defaultMap.RegisterType(&Type{Name: "_numrange", OID: NumrangeArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[NumrangeOID]}}) + defaultMap.RegisterType(&Type{Name: "_oid", OID: OIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[OIDOID]}}) + defaultMap.RegisterType(&Type{Name: "_path", OID: PathArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[PathOID]}}) + defaultMap.RegisterType(&Type{Name: "_point", OID: PointArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[PointOID]}}) + defaultMap.RegisterType(&Type{Name: "_polygon", OID: PolygonArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[PolygonOID]}}) + defaultMap.RegisterType(&Type{Name: "_record", OID: RecordArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[RecordOID]}}) + defaultMap.RegisterType(&Type{Name: "_text", OID: TextArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[TextOID]}}) + defaultMap.RegisterType(&Type{Name: "_tid", OID: TIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[TIDOID]}}) + defaultMap.RegisterType(&Type{Name: "_time", OID: TimeArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[TimeOID]}}) + defaultMap.RegisterType(&Type{Name: "_timestamp", OID: TimestampArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[TimestampOID]}}) + defaultMap.RegisterType(&Type{Name: "_timestamptz", OID: TimestamptzArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[TimestamptzOID]}}) + defaultMap.RegisterType(&Type{Name: "_tsrange", OID: TsrangeArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[TsrangeOID]}}) + defaultMap.RegisterType(&Type{Name: "_tstzrange", OID: TstzrangeArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[TstzrangeOID]}}) + defaultMap.RegisterType(&Type{Name: "_uuid", OID: UUIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[UUIDOID]}}) + defaultMap.RegisterType(&Type{Name: "_varbit", OID: VarbitArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarbitOID]}}) + defaultMap.RegisterType(&Type{Name: "_varchar", OID: VarcharArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[VarcharOID]}}) + defaultMap.RegisterType(&Type{Name: "_xid", OID: XIDArrayOID, Codec: &ArrayCodec{ElementType: defaultMap.oidToType[XIDOID]}}) + + // Integer types that directly map to a PostgreSQL type + registerDefaultPgTypeVariants[int16](defaultMap, "int2") + registerDefaultPgTypeVariants[int32](defaultMap, "int4") + registerDefaultPgTypeVariants[int64](defaultMap, "int8") + + // Integer types that do not have a direct match to a PostgreSQL type + registerDefaultPgTypeVariants[int8](defaultMap, "int8") + registerDefaultPgTypeVariants[int](defaultMap, "int8") + registerDefaultPgTypeVariants[uint8](defaultMap, "int8") + registerDefaultPgTypeVariants[uint16](defaultMap, "int8") + registerDefaultPgTypeVariants[uint32](defaultMap, "int8") + registerDefaultPgTypeVariants[uint64](defaultMap, "numeric") + registerDefaultPgTypeVariants[uint](defaultMap, "numeric") + + registerDefaultPgTypeVariants[float32](defaultMap, "float4") + registerDefaultPgTypeVariants[float64](defaultMap, "float8") + + registerDefaultPgTypeVariants[bool](defaultMap, "bool") + registerDefaultPgTypeVariants[time.Time](defaultMap, "timestamptz") + registerDefaultPgTypeVariants[time.Duration](defaultMap, "interval") + registerDefaultPgTypeVariants[string](defaultMap, "text") + registerDefaultPgTypeVariants[[]byte](defaultMap, "bytea") + + registerDefaultPgTypeVariants[net.IP](defaultMap, "inet") + registerDefaultPgTypeVariants[net.IPNet](defaultMap, "cidr") + registerDefaultPgTypeVariants[netip.Addr](defaultMap, "inet") + registerDefaultPgTypeVariants[netip.Prefix](defaultMap, "cidr") + + // pgtype provided structs + registerDefaultPgTypeVariants[Bits](defaultMap, "varbit") + registerDefaultPgTypeVariants[Bool](defaultMap, "bool") + registerDefaultPgTypeVariants[Box](defaultMap, "box") + registerDefaultPgTypeVariants[Circle](defaultMap, "circle") + registerDefaultPgTypeVariants[Date](defaultMap, "date") + registerDefaultPgTypeVariants[Range[Date]](defaultMap, "daterange") + registerDefaultPgTypeVariants[Multirange[Range[Date]]](defaultMap, "datemultirange") + registerDefaultPgTypeVariants[Float4](defaultMap, "float4") + registerDefaultPgTypeVariants[Float8](defaultMap, "float8") + registerDefaultPgTypeVariants[Range[Float8]](defaultMap, "numrange") // There is no PostgreSQL builtin float8range so map it to numrange. + registerDefaultPgTypeVariants[Multirange[Range[Float8]]](defaultMap, "nummultirange") // There is no PostgreSQL builtin float8multirange so map it to nummultirange. + registerDefaultPgTypeVariants[Int2](defaultMap, "int2") + registerDefaultPgTypeVariants[Int4](defaultMap, "int4") + registerDefaultPgTypeVariants[Range[Int4]](defaultMap, "int4range") + registerDefaultPgTypeVariants[Multirange[Range[Int4]]](defaultMap, "int4multirange") + registerDefaultPgTypeVariants[Int8](defaultMap, "int8") + registerDefaultPgTypeVariants[Range[Int8]](defaultMap, "int8range") + registerDefaultPgTypeVariants[Multirange[Range[Int8]]](defaultMap, "int8multirange") + registerDefaultPgTypeVariants[Interval](defaultMap, "interval") + registerDefaultPgTypeVariants[Line](defaultMap, "line") + registerDefaultPgTypeVariants[Lseg](defaultMap, "lseg") + registerDefaultPgTypeVariants[Numeric](defaultMap, "numeric") + registerDefaultPgTypeVariants[Range[Numeric]](defaultMap, "numrange") + registerDefaultPgTypeVariants[Multirange[Range[Numeric]]](defaultMap, "nummultirange") + registerDefaultPgTypeVariants[Path](defaultMap, "path") + registerDefaultPgTypeVariants[Point](defaultMap, "point") + registerDefaultPgTypeVariants[Polygon](defaultMap, "polygon") + registerDefaultPgTypeVariants[TID](defaultMap, "tid") + registerDefaultPgTypeVariants[Text](defaultMap, "text") + registerDefaultPgTypeVariants[Time](defaultMap, "time") + registerDefaultPgTypeVariants[Timestamp](defaultMap, "timestamp") + registerDefaultPgTypeVariants[Timestamptz](defaultMap, "timestamptz") + registerDefaultPgTypeVariants[Range[Timestamp]](defaultMap, "tsrange") + registerDefaultPgTypeVariants[Multirange[Range[Timestamp]]](defaultMap, "tsmultirange") + registerDefaultPgTypeVariants[Range[Timestamptz]](defaultMap, "tstzrange") + registerDefaultPgTypeVariants[Multirange[Range[Timestamptz]]](defaultMap, "tstzmultirange") + registerDefaultPgTypeVariants[UUID](defaultMap, "uuid") +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/point.go b/vendor/github.com/jackc/pgx/v5/pgtype/point.go new file mode 100644 index 00000000000..cfa5a9f1a26 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/point.go @@ -0,0 +1,266 @@ +package pgtype + +import ( + "bytes" + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Vec2 struct { + X float64 + Y float64 +} + +type PointScanner interface { + ScanPoint(v Point) error +} + +type PointValuer interface { + PointValue() (Point, error) +} + +type Point struct { + P Vec2 + Valid bool +} + +func (p *Point) ScanPoint(v Point) error { + *p = v + return nil +} + +func (p Point) PointValue() (Point, error) { + return p, nil +} + +func parsePoint(src []byte) (*Point, error) { + if src == nil || bytes.Compare(src, []byte("null")) == 0 { + return &Point{}, nil + } + + if len(src) < 5 { + return nil, fmt.Errorf("invalid length for point: %v", len(src)) + } + if src[0] == '"' && src[len(src)-1] == '"' { + src = src[1 : len(src)-1] + } + parts := strings.SplitN(string(src[1:len(src)-1]), ",", 2) + if len(parts) < 2 { + return nil, fmt.Errorf("invalid format for point") + } + + x, err := strconv.ParseFloat(parts[0], 64) + if err != nil { + return nil, err + } + + y, err := strconv.ParseFloat(parts[1], 64) + if err != nil { + return nil, err + } + + return &Point{P: Vec2{x, y}, Valid: true}, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Point) Scan(src any) error { + if src == nil { + *dst = Point{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToPointScanner{}.Scan([]byte(src), dst) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src Point) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + buf, err := PointCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +func (src Point) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + + var buff bytes.Buffer + buff.WriteByte('"') + buff.WriteString(fmt.Sprintf("(%g,%g)", src.P.X, src.P.Y)) + buff.WriteByte('"') + return buff.Bytes(), nil +} + +func (dst *Point) UnmarshalJSON(point []byte) error { + p, err := parsePoint(point) + if err != nil { + return err + } + *dst = *p + return nil +} + +type PointCodec struct{} + +func (PointCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (PointCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (PointCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(PointValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanPointCodecBinary{} + case TextFormatCode: + return encodePlanPointCodecText{} + } + + return nil +} + +type encodePlanPointCodecBinary struct{} + +func (encodePlanPointCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + point, err := value.(PointValuer).PointValue() + if err != nil { + return nil, err + } + + if !point.Valid { + return nil, nil + } + + buf = pgio.AppendUint64(buf, math.Float64bits(point.P.X)) + buf = pgio.AppendUint64(buf, math.Float64bits(point.P.Y)) + return buf, nil +} + +type encodePlanPointCodecText struct{} + +func (encodePlanPointCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + point, err := value.(PointValuer).PointValue() + if err != nil { + return nil, err + } + + if !point.Valid { + return nil, nil + } + + return append(buf, fmt.Sprintf(`(%s,%s)`, + strconv.FormatFloat(point.P.X, 'f', -1, 64), + strconv.FormatFloat(point.P.Y, 'f', -1, 64), + )...), nil +} + +func (PointCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case PointScanner: + return scanPlanBinaryPointToPointScanner{} + } + case TextFormatCode: + switch target.(type) { + case PointScanner: + return scanPlanTextAnyToPointScanner{} + } + } + + return nil +} + +func (c PointCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c PointCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var point Point + err := codecScan(c, m, oid, format, src, &point) + if err != nil { + return nil, err + } + return point, nil +} + +type scanPlanBinaryPointToPointScanner struct{} + +func (scanPlanBinaryPointToPointScanner) Scan(src []byte, dst any) error { + scanner := (dst).(PointScanner) + + if src == nil { + return scanner.ScanPoint(Point{}) + } + + if len(src) != 16 { + return fmt.Errorf("invalid length for point: %v", len(src)) + } + + x := binary.BigEndian.Uint64(src) + y := binary.BigEndian.Uint64(src[8:]) + + return scanner.ScanPoint(Point{ + P: Vec2{math.Float64frombits(x), math.Float64frombits(y)}, + Valid: true, + }) +} + +type scanPlanTextAnyToPointScanner struct{} + +func (scanPlanTextAnyToPointScanner) Scan(src []byte, dst any) error { + scanner := (dst).(PointScanner) + + if src == nil { + return scanner.ScanPoint(Point{}) + } + + if len(src) < 5 { + return fmt.Errorf("invalid length for point: %v", len(src)) + } + + parts := strings.SplitN(string(src[1:len(src)-1]), ",", 2) + if len(parts) < 2 { + return fmt.Errorf("invalid format for point") + } + + x, err := strconv.ParseFloat(parts[0], 64) + if err != nil { + return err + } + + y, err := strconv.ParseFloat(parts[1], 64) + if err != nil { + return err + } + + return scanner.ScanPoint(Point{P: Vec2{x, y}, Valid: true}) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/polygon.go b/vendor/github.com/jackc/pgx/v5/pgtype/polygon.go new file mode 100644 index 00000000000..04b0ba6b073 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/polygon.go @@ -0,0 +1,253 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type PolygonScanner interface { + ScanPolygon(v Polygon) error +} + +type PolygonValuer interface { + PolygonValue() (Polygon, error) +} + +type Polygon struct { + P []Vec2 + Valid bool +} + +func (p *Polygon) ScanPolygon(v Polygon) error { + *p = v + return nil +} + +func (p Polygon) PolygonValue() (Polygon, error) { + return p, nil +} + +// Scan implements the database/sql Scanner interface. +func (p *Polygon) Scan(src any) error { + if src == nil { + *p = Polygon{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToPolygonScanner{}.Scan([]byte(src), p) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (p Polygon) Value() (driver.Value, error) { + if !p.Valid { + return nil, nil + } + + buf, err := PolygonCodec{}.PlanEncode(nil, 0, TextFormatCode, p).Encode(p, nil) + if err != nil { + return nil, err + } + + return string(buf), err +} + +type PolygonCodec struct{} + +func (PolygonCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (PolygonCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (PolygonCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(PolygonValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanPolygonCodecBinary{} + case TextFormatCode: + return encodePlanPolygonCodecText{} + } + + return nil +} + +type encodePlanPolygonCodecBinary struct{} + +func (encodePlanPolygonCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + polygon, err := value.(PolygonValuer).PolygonValue() + if err != nil { + return nil, err + } + + if !polygon.Valid { + return nil, nil + } + + buf = pgio.AppendInt32(buf, int32(len(polygon.P))) + + for _, p := range polygon.P { + buf = pgio.AppendUint64(buf, math.Float64bits(p.X)) + buf = pgio.AppendUint64(buf, math.Float64bits(p.Y)) + } + + return buf, nil +} + +type encodePlanPolygonCodecText struct{} + +func (encodePlanPolygonCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + polygon, err := value.(PolygonValuer).PolygonValue() + if err != nil { + return nil, err + } + + if !polygon.Valid { + return nil, nil + } + + buf = append(buf, '(') + + for i, p := range polygon.P { + if i > 0 { + buf = append(buf, ',') + } + buf = append(buf, fmt.Sprintf(`(%s,%s)`, + strconv.FormatFloat(p.X, 'f', -1, 64), + strconv.FormatFloat(p.Y, 'f', -1, 64), + )...) + } + + buf = append(buf, ')') + + return buf, nil +} + +func (PolygonCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case PolygonScanner: + return scanPlanBinaryPolygonToPolygonScanner{} + } + case TextFormatCode: + switch target.(type) { + case PolygonScanner: + return scanPlanTextAnyToPolygonScanner{} + } + } + + return nil +} + +type scanPlanBinaryPolygonToPolygonScanner struct{} + +func (scanPlanBinaryPolygonToPolygonScanner) Scan(src []byte, dst any) error { + scanner := (dst).(PolygonScanner) + + if src == nil { + return scanner.ScanPolygon(Polygon{}) + } + + if len(src) < 5 { + return fmt.Errorf("invalid length for polygon: %v", len(src)) + } + + pointCount := int(binary.BigEndian.Uint32(src)) + rp := 4 + + if 4+pointCount*16 != len(src) { + return fmt.Errorf("invalid length for Polygon with %d points: %v", pointCount, len(src)) + } + + points := make([]Vec2, pointCount) + for i := 0; i < len(points); i++ { + x := binary.BigEndian.Uint64(src[rp:]) + rp += 8 + y := binary.BigEndian.Uint64(src[rp:]) + rp += 8 + points[i] = Vec2{math.Float64frombits(x), math.Float64frombits(y)} + } + + return scanner.ScanPolygon(Polygon{ + P: points, + Valid: true, + }) +} + +type scanPlanTextAnyToPolygonScanner struct{} + +func (scanPlanTextAnyToPolygonScanner) Scan(src []byte, dst any) error { + scanner := (dst).(PolygonScanner) + + if src == nil { + return scanner.ScanPolygon(Polygon{}) + } + + if len(src) < 7 { + return fmt.Errorf("invalid length for Polygon: %v", len(src)) + } + + points := make([]Vec2, 0) + + str := string(src[2:]) + + for { + end := strings.IndexByte(str, ',') + x, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + str = str[end+1:] + end = strings.IndexByte(str, ')') + + y, err := strconv.ParseFloat(str[:end], 64) + if err != nil { + return err + } + + points = append(points, Vec2{x, y}) + + if end+3 < len(str) { + str = str[end+3:] + } else { + break + } + } + + return scanner.ScanPolygon(Polygon{P: points, Valid: true}) +} + +func (c PolygonCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c PolygonCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var polygon Polygon + err := codecScan(c, m, oid, format, src, &polygon) + if err != nil { + return nil, err + } + return polygon, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/qchar.go b/vendor/github.com/jackc/pgx/v5/pgtype/qchar.go new file mode 100644 index 00000000000..fc40a5b2cfe --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/qchar.go @@ -0,0 +1,141 @@ +package pgtype + +import ( + "database/sql/driver" + "fmt" + "math" +) + +// QCharCodec is for PostgreSQL's special 8-bit-only "char" type more akin to the C +// language's char type, or Go's byte type. (Note that the name in PostgreSQL +// itself is "char", in double-quotes, and not char.) It gets used a lot in +// PostgreSQL's system tables to hold a single ASCII character value (eg +// pg_class.relkind). It is named Qchar for quoted char to disambiguate from SQL +// standard type char. +type QCharCodec struct{} + +func (QCharCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (QCharCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (QCharCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case TextFormatCode, BinaryFormatCode: + switch value.(type) { + case byte: + return encodePlanQcharCodecByte{} + case rune: + return encodePlanQcharCodecRune{} + } + } + + return nil +} + +type encodePlanQcharCodecByte struct{} + +func (encodePlanQcharCodecByte) Encode(value any, buf []byte) (newBuf []byte, err error) { + b := value.(byte) + buf = append(buf, b) + return buf, nil +} + +type encodePlanQcharCodecRune struct{} + +func (encodePlanQcharCodecRune) Encode(value any, buf []byte) (newBuf []byte, err error) { + r := value.(rune) + if r > math.MaxUint8 { + return nil, fmt.Errorf(`%v cannot be encoded to "char"`, r) + } + b := byte(r) + buf = append(buf, b) + return buf, nil +} + +func (QCharCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case TextFormatCode, BinaryFormatCode: + switch target.(type) { + case *byte: + return scanPlanQcharCodecByte{} + case *rune: + return scanPlanQcharCodecRune{} + } + } + + return nil +} + +type scanPlanQcharCodecByte struct{} + +func (scanPlanQcharCodecByte) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) > 1 { + return fmt.Errorf(`invalid length for "char": %v`, len(src)) + } + + b := dst.(*byte) + // In the text format the zero value is returned as a zero byte value instead of 0 + if len(src) == 0 { + *b = 0 + } else { + *b = src[0] + } + + return nil +} + +type scanPlanQcharCodecRune struct{} + +func (scanPlanQcharCodecRune) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) > 1 { + return fmt.Errorf(`invalid length for "char": %v`, len(src)) + } + + r := dst.(*rune) + // In the text format the zero value is returned as a zero byte value instead of 0 + if len(src) == 0 { + *r = 0 + } else { + *r = rune(src[0]) + } + + return nil +} + +func (c QCharCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var r rune + err := codecScan(c, m, oid, format, src, &r) + if err != nil { + return nil, err + } + return string(r), nil +} + +func (c QCharCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var r rune + err := codecScan(c, m, oid, format, src, &r) + if err != nil { + return nil, err + } + return r, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/range.go b/vendor/github.com/jackc/pgx/v5/pgtype/range.go new file mode 100644 index 00000000000..8f408f9f39d --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/range.go @@ -0,0 +1,322 @@ +package pgtype + +import ( + "bytes" + "encoding/binary" + "fmt" +) + +type BoundType byte + +const ( + Inclusive = BoundType('i') + Exclusive = BoundType('e') + Unbounded = BoundType('U') + Empty = BoundType('E') +) + +func (bt BoundType) String() string { + return string(bt) +} + +type untypedTextRange struct { + Lower string + Upper string + LowerType BoundType + UpperType BoundType +} + +func parseUntypedTextRange(src string) (*untypedTextRange, error) { + utr := &untypedTextRange{} + if src == "empty" { + utr.LowerType = Empty + utr.UpperType = Empty + return utr, nil + } + + buf := bytes.NewBufferString(src) + + skipWhitespace(buf) + + r, _, err := buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid lower bound: %v", err) + } + switch r { + case '(': + utr.LowerType = Exclusive + case '[': + utr.LowerType = Inclusive + default: + return nil, fmt.Errorf("missing lower bound, instead got: %v", string(r)) + } + + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid lower value: %v", err) + } + buf.UnreadRune() + + if r == ',' { + utr.LowerType = Unbounded + } else { + utr.Lower, err = rangeParseValue(buf) + if err != nil { + return nil, fmt.Errorf("invalid lower value: %v", err) + } + } + + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("missing range separator: %v", err) + } + if r != ',' { + return nil, fmt.Errorf("missing range separator: %v", r) + } + + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("invalid upper value: %v", err) + } + + if r == ')' || r == ']' { + utr.UpperType = Unbounded + } else { + buf.UnreadRune() + utr.Upper, err = rangeParseValue(buf) + if err != nil { + return nil, fmt.Errorf("invalid upper value: %v", err) + } + + r, _, err = buf.ReadRune() + if err != nil { + return nil, fmt.Errorf("missing upper bound: %v", err) + } + switch r { + case ')': + utr.UpperType = Exclusive + case ']': + utr.UpperType = Inclusive + default: + return nil, fmt.Errorf("missing upper bound, instead got: %v", string(r)) + } + } + + skipWhitespace(buf) + + if buf.Len() > 0 { + return nil, fmt.Errorf("unexpected trailing data: %v", buf.String()) + } + + return utr, nil +} + +func rangeParseValue(buf *bytes.Buffer) (string, error) { + r, _, err := buf.ReadRune() + if err != nil { + return "", err + } + if r == '"' { + return rangeParseQuotedValue(buf) + } + buf.UnreadRune() + + s := &bytes.Buffer{} + + for { + r, _, err := buf.ReadRune() + if err != nil { + return "", err + } + + switch r { + case '\\': + r, _, err = buf.ReadRune() + if err != nil { + return "", err + } + case ',', '[', ']', '(', ')': + buf.UnreadRune() + return s.String(), nil + } + + s.WriteRune(r) + } +} + +func rangeParseQuotedValue(buf *bytes.Buffer) (string, error) { + s := &bytes.Buffer{} + + for { + r, _, err := buf.ReadRune() + if err != nil { + return "", err + } + + switch r { + case '\\': + r, _, err = buf.ReadRune() + if err != nil { + return "", err + } + case '"': + r, _, err = buf.ReadRune() + if err != nil { + return "", err + } + if r != '"' { + buf.UnreadRune() + return s.String(), nil + } + } + s.WriteRune(r) + } +} + +type untypedBinaryRange struct { + Lower []byte + Upper []byte + LowerType BoundType + UpperType BoundType +} + +// 0 = () = 00000 +// 1 = empty = 00001 +// 2 = [) = 00010 +// 4 = (] = 00100 +// 6 = [] = 00110 +// 8 = ) = 01000 +// 12 = ] = 01100 +// 16 = ( = 10000 +// 18 = [ = 10010 +// 24 = = 11000 + +const emptyMask = 1 +const lowerInclusiveMask = 2 +const upperInclusiveMask = 4 +const lowerUnboundedMask = 8 +const upperUnboundedMask = 16 + +func parseUntypedBinaryRange(src []byte) (*untypedBinaryRange, error) { + ubr := &untypedBinaryRange{} + + if len(src) == 0 { + return nil, fmt.Errorf("range too short: %v", len(src)) + } + + rangeType := src[0] + rp := 1 + + if rangeType&emptyMask > 0 { + if len(src[rp:]) > 0 { + return nil, fmt.Errorf("unexpected trailing bytes parsing empty range: %v", len(src[rp:])) + } + ubr.LowerType = Empty + ubr.UpperType = Empty + return ubr, nil + } + + if rangeType&lowerInclusiveMask > 0 { + ubr.LowerType = Inclusive + } else if rangeType&lowerUnboundedMask > 0 { + ubr.LowerType = Unbounded + } else { + ubr.LowerType = Exclusive + } + + if rangeType&upperInclusiveMask > 0 { + ubr.UpperType = Inclusive + } else if rangeType&upperUnboundedMask > 0 { + ubr.UpperType = Unbounded + } else { + ubr.UpperType = Exclusive + } + + if ubr.LowerType == Unbounded && ubr.UpperType == Unbounded { + if len(src[rp:]) > 0 { + return nil, fmt.Errorf("unexpected trailing bytes parsing unbounded range: %v", len(src[rp:])) + } + return ubr, nil + } + + if len(src[rp:]) < 4 { + return nil, fmt.Errorf("too few bytes for size: %v", src[rp:]) + } + valueLen := int(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + + val := src[rp : rp+valueLen] + rp += valueLen + + if ubr.LowerType != Unbounded { + ubr.Lower = val + } else { + ubr.Upper = val + if len(src[rp:]) > 0 { + return nil, fmt.Errorf("unexpected trailing bytes parsing range: %v", len(src[rp:])) + } + return ubr, nil + } + + if ubr.UpperType != Unbounded { + if len(src[rp:]) < 4 { + return nil, fmt.Errorf("too few bytes for size: %v", src[rp:]) + } + valueLen := int(binary.BigEndian.Uint32(src[rp:])) + rp += 4 + ubr.Upper = src[rp : rp+valueLen] + rp += valueLen + } + + if len(src[rp:]) > 0 { + return nil, fmt.Errorf("unexpected trailing bytes parsing range: %v", len(src[rp:])) + } + + return ubr, nil + +} + +// Range is a generic range type. +type Range[T any] struct { + Lower T + Upper T + LowerType BoundType + UpperType BoundType + Valid bool +} + +func (r Range[T]) IsNull() bool { + return !r.Valid +} + +func (r Range[T]) BoundTypes() (lower, upper BoundType) { + return r.LowerType, r.UpperType +} + +func (r Range[T]) Bounds() (lower, upper any) { + return &r.Lower, &r.Upper +} + +func (r *Range[T]) ScanNull() error { + *r = Range[T]{} + return nil +} + +func (r *Range[T]) ScanBounds() (lowerTarget, upperTarget any) { + return &r.Lower, &r.Upper +} + +func (r *Range[T]) SetBoundTypes(lower, upper BoundType) error { + if lower == Unbounded || lower == Empty { + var zero T + r.Lower = zero + } + if upper == Unbounded || upper == Empty { + var zero T + r.Upper = zero + } + r.LowerType = lower + r.UpperType = upper + r.Valid = true + return nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/range_codec.go b/vendor/github.com/jackc/pgx/v5/pgtype/range_codec.go new file mode 100644 index 00000000000..8cfb3a630f3 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/range_codec.go @@ -0,0 +1,379 @@ +package pgtype + +import ( + "database/sql/driver" + "fmt" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +// RangeValuer is a type that can be converted into a PostgreSQL range. +type RangeValuer interface { + // IsNull returns true if the value is SQL NULL. + IsNull() bool + + // BoundTypes returns the lower and upper bound types. + BoundTypes() (lower, upper BoundType) + + // Bounds returns the lower and upper range values. + Bounds() (lower, upper any) +} + +// RangeScanner is a type can be scanned from a PostgreSQL range. +type RangeScanner interface { + // ScanNull sets the value to SQL NULL. + ScanNull() error + + // ScanBounds returns values usable as a scan target. The returned values may not be scanned if the range is empty or + // the bound type is unbounded. + ScanBounds() (lowerTarget, upperTarget any) + + // SetBoundTypes sets the lower and upper bound types. ScanBounds will be called and the returned values scanned + // (if appropriate) before SetBoundTypes is called. If the bound types are unbounded or empty this method must + // also set the bound values. + SetBoundTypes(lower, upper BoundType) error +} + +// RangeCodec is a codec for any range type. +type RangeCodec struct { + ElementType *Type +} + +func (c *RangeCodec) FormatSupported(format int16) bool { + return c.ElementType.Codec.FormatSupported(format) +} + +func (c *RangeCodec) PreferredFormat() int16 { + if c.FormatSupported(BinaryFormatCode) { + return BinaryFormatCode + } + return TextFormatCode +} + +func (c *RangeCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(RangeValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return &encodePlanRangeCodecRangeValuerToBinary{rc: c, m: m} + case TextFormatCode: + return &encodePlanRangeCodecRangeValuerToText{rc: c, m: m} + } + + return nil +} + +type encodePlanRangeCodecRangeValuerToBinary struct { + rc *RangeCodec + m *Map +} + +func (plan *encodePlanRangeCodecRangeValuerToBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + getter := value.(RangeValuer) + + if getter.IsNull() { + return nil, nil + } + + lowerType, upperType := getter.BoundTypes() + lower, upper := getter.Bounds() + + var rangeType byte + switch lowerType { + case Inclusive: + rangeType |= lowerInclusiveMask + case Unbounded: + rangeType |= lowerUnboundedMask + case Exclusive: + case Empty: + return append(buf, emptyMask), nil + default: + return nil, fmt.Errorf("unknown LowerType: %v", lowerType) + } + + switch upperType { + case Inclusive: + rangeType |= upperInclusiveMask + case Unbounded: + rangeType |= upperUnboundedMask + case Exclusive: + default: + return nil, fmt.Errorf("unknown UpperType: %v", upperType) + } + + buf = append(buf, rangeType) + + if lowerType != Unbounded { + if lower == nil { + return nil, fmt.Errorf("Lower cannot be NULL unless LowerType is Unbounded") + } + + sp := len(buf) + buf = pgio.AppendInt32(buf, -1) + + lowerPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, BinaryFormatCode, lower) + if lowerPlan == nil { + return nil, fmt.Errorf("cannot encode %v as element of range", lower) + } + + buf, err = lowerPlan.Encode(lower, buf) + if err != nil { + return nil, fmt.Errorf("failed to encode %v as element of range: %v", lower, err) + } + if buf == nil { + return nil, fmt.Errorf("Lower cannot be NULL unless LowerType is Unbounded") + } + + pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4)) + } + + if upperType != Unbounded { + if upper == nil { + return nil, fmt.Errorf("Upper cannot be NULL unless UpperType is Unbounded") + } + + sp := len(buf) + buf = pgio.AppendInt32(buf, -1) + + upperPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, BinaryFormatCode, upper) + if upperPlan == nil { + return nil, fmt.Errorf("cannot encode %v as element of range", upper) + } + + buf, err = upperPlan.Encode(upper, buf) + if err != nil { + return nil, fmt.Errorf("failed to encode %v as element of range: %v", upper, err) + } + if buf == nil { + return nil, fmt.Errorf("Upper cannot be NULL unless UpperType is Unbounded") + } + + pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4)) + } + + return buf, nil +} + +type encodePlanRangeCodecRangeValuerToText struct { + rc *RangeCodec + m *Map +} + +func (plan *encodePlanRangeCodecRangeValuerToText) Encode(value any, buf []byte) (newBuf []byte, err error) { + getter := value.(RangeValuer) + + if getter.IsNull() { + return nil, nil + } + + lowerType, upperType := getter.BoundTypes() + lower, upper := getter.Bounds() + + switch lowerType { + case Exclusive, Unbounded: + buf = append(buf, '(') + case Inclusive: + buf = append(buf, '[') + case Empty: + return append(buf, "empty"...), nil + default: + return nil, fmt.Errorf("unknown lower bound type %v", lowerType) + } + + if lowerType != Unbounded { + if lower == nil { + return nil, fmt.Errorf("Lower cannot be NULL unless LowerType is Unbounded") + } + + lowerPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, TextFormatCode, lower) + if lowerPlan == nil { + return nil, fmt.Errorf("cannot encode %v as element of range", lower) + } + + buf, err = lowerPlan.Encode(lower, buf) + if err != nil { + return nil, fmt.Errorf("failed to encode %v as element of range: %v", lower, err) + } + if buf == nil { + return nil, fmt.Errorf("Lower cannot be NULL unless LowerType is Unbounded") + } + } + + buf = append(buf, ',') + + if upperType != Unbounded { + if upper == nil { + return nil, fmt.Errorf("Upper cannot be NULL unless UpperType is Unbounded") + } + + upperPlan := plan.m.PlanEncode(plan.rc.ElementType.OID, TextFormatCode, upper) + if upperPlan == nil { + return nil, fmt.Errorf("cannot encode %v as element of range", upper) + } + + buf, err = upperPlan.Encode(upper, buf) + if err != nil { + return nil, fmt.Errorf("failed to encode %v as element of range: %v", upper, err) + } + if buf == nil { + return nil, fmt.Errorf("Upper cannot be NULL unless UpperType is Unbounded") + } + } + + switch upperType { + case Exclusive, Unbounded: + buf = append(buf, ')') + case Inclusive: + buf = append(buf, ']') + default: + return nil, fmt.Errorf("unknown upper bound type %v", upperType) + } + + return buf, nil +} + +func (c *RangeCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case BinaryFormatCode: + switch target.(type) { + case RangeScanner: + return &scanPlanBinaryRangeToRangeScanner{rc: c, m: m} + } + case TextFormatCode: + switch target.(type) { + case RangeScanner: + return &scanPlanTextRangeToRangeScanner{rc: c, m: m} + } + } + + return nil +} + +type scanPlanBinaryRangeToRangeScanner struct { + rc *RangeCodec + m *Map +} + +func (plan *scanPlanBinaryRangeToRangeScanner) Scan(src []byte, target any) error { + rangeScanner := (target).(RangeScanner) + + if src == nil { + return rangeScanner.ScanNull() + } + + ubr, err := parseUntypedBinaryRange(src) + if err != nil { + return err + } + + if ubr.LowerType == Empty { + return rangeScanner.SetBoundTypes(ubr.LowerType, ubr.UpperType) + } + + lowerTarget, upperTarget := rangeScanner.ScanBounds() + + if ubr.LowerType == Inclusive || ubr.LowerType == Exclusive { + lowerPlan := plan.m.PlanScan(plan.rc.ElementType.OID, BinaryFormatCode, lowerTarget) + if lowerPlan == nil { + return fmt.Errorf("cannot scan into %v from range element", lowerTarget) + } + + err = lowerPlan.Scan(ubr.Lower, lowerTarget) + if err != nil { + return fmt.Errorf("cannot scan into %v from range element: %v", lowerTarget, err) + } + } + + if ubr.UpperType == Inclusive || ubr.UpperType == Exclusive { + upperPlan := plan.m.PlanScan(plan.rc.ElementType.OID, BinaryFormatCode, upperTarget) + if upperPlan == nil { + return fmt.Errorf("cannot scan into %v from range element", upperTarget) + } + + err = upperPlan.Scan(ubr.Upper, upperTarget) + if err != nil { + return fmt.Errorf("cannot scan into %v from range element: %v", upperTarget, err) + } + } + + return rangeScanner.SetBoundTypes(ubr.LowerType, ubr.UpperType) +} + +type scanPlanTextRangeToRangeScanner struct { + rc *RangeCodec + m *Map +} + +func (plan *scanPlanTextRangeToRangeScanner) Scan(src []byte, target any) error { + rangeScanner := (target).(RangeScanner) + + if src == nil { + return rangeScanner.ScanNull() + } + + utr, err := parseUntypedTextRange(string(src)) + if err != nil { + return err + } + + if utr.LowerType == Empty { + return rangeScanner.SetBoundTypes(utr.LowerType, utr.UpperType) + } + + lowerTarget, upperTarget := rangeScanner.ScanBounds() + + if utr.LowerType == Inclusive || utr.LowerType == Exclusive { + lowerPlan := plan.m.PlanScan(plan.rc.ElementType.OID, TextFormatCode, lowerTarget) + if lowerPlan == nil { + return fmt.Errorf("cannot scan into %v from range element", lowerTarget) + } + + err = lowerPlan.Scan([]byte(utr.Lower), lowerTarget) + if err != nil { + return fmt.Errorf("cannot scan into %v from range element: %v", lowerTarget, err) + } + } + + if utr.UpperType == Inclusive || utr.UpperType == Exclusive { + upperPlan := plan.m.PlanScan(plan.rc.ElementType.OID, TextFormatCode, upperTarget) + if upperPlan == nil { + return fmt.Errorf("cannot scan into %v from range element", upperTarget) + } + + err = upperPlan.Scan([]byte(utr.Upper), upperTarget) + if err != nil { + return fmt.Errorf("cannot scan into %v from range element: %v", upperTarget, err) + } + } + + return rangeScanner.SetBoundTypes(utr.LowerType, utr.UpperType) +} + +func (c *RangeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + switch format { + case TextFormatCode: + return string(src), nil + case BinaryFormatCode: + buf := make([]byte, len(src)) + copy(buf, src) + return buf, nil + default: + return nil, fmt.Errorf("unknown format code %d", format) + } +} + +func (c *RangeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var r Range[any] + err := c.PlanScan(m, oid, format, &r).Scan(src, &r) + return r, err +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/record_codec.go b/vendor/github.com/jackc/pgx/v5/pgtype/record_codec.go new file mode 100644 index 00000000000..b3b16604521 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/record_codec.go @@ -0,0 +1,125 @@ +package pgtype + +import ( + "database/sql/driver" + "fmt" +) + +// ArrayGetter is a type that can be converted into a PostgreSQL array. + +// RecordCodec is a codec for the generic PostgreSQL record type such as is created with the "row" function. Record can +// only decode the binary format. The text format output format from PostgreSQL does not include type information and +// is therefore impossible to decode. Encoding is impossible because PostgreSQL does not support input of generic +// records. +type RecordCodec struct{} + +func (RecordCodec) FormatSupported(format int16) bool { + return format == BinaryFormatCode +} + +func (RecordCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (RecordCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + return nil +} + +func (RecordCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + if format == BinaryFormatCode { + switch target.(type) { + case CompositeIndexScanner: + return &scanPlanBinaryRecordToCompositeIndexScanner{m: m} + } + } + + return nil +} + +type scanPlanBinaryRecordToCompositeIndexScanner struct { + m *Map +} + +func (plan *scanPlanBinaryRecordToCompositeIndexScanner) Scan(src []byte, target any) error { + targetScanner := (target).(CompositeIndexScanner) + + if src == nil { + return targetScanner.ScanNull() + } + + scanner := NewCompositeBinaryScanner(plan.m, src) + for i := 0; scanner.Next(); i++ { + fieldTarget := targetScanner.ScanIndex(i) + if fieldTarget != nil { + fieldPlan := plan.m.PlanScan(scanner.OID(), BinaryFormatCode, fieldTarget) + if fieldPlan == nil { + return fmt.Errorf("unable to scan OID %d in binary format into %v", scanner.OID(), fieldTarget) + } + + err := fieldPlan.Scan(scanner.Bytes(), fieldTarget) + if err != nil { + return err + } + } + } + + if err := scanner.Err(); err != nil { + return err + } + + return nil +} + +func (RecordCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + switch format { + case TextFormatCode: + return string(src), nil + case BinaryFormatCode: + buf := make([]byte, len(src)) + copy(buf, src) + return buf, nil + default: + return nil, fmt.Errorf("unknown format code %d", format) + } +} + +func (RecordCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + switch format { + case TextFormatCode: + return string(src), nil + case BinaryFormatCode: + scanner := NewCompositeBinaryScanner(m, src) + values := make([]any, scanner.FieldCount()) + for i := 0; scanner.Next(); i++ { + var v any + fieldPlan := m.PlanScan(scanner.OID(), BinaryFormatCode, &v) + if fieldPlan == nil { + return nil, fmt.Errorf("unable to scan OID %d in binary format into %v", scanner.OID(), v) + } + + err := fieldPlan.Scan(scanner.Bytes(), &v) + if err != nil { + return nil, err + } + + values[i] = v + } + + if err := scanner.Err(); err != nil { + return nil, err + } + + return values, nil + default: + return nil, fmt.Errorf("unknown format code %d", format) + } + +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types.go b/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types.go new file mode 100644 index 00000000000..be1ca4a189a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types.go @@ -0,0 +1,35 @@ +//go:build !nopgxregisterdefaulttypes + +package pgtype + +func registerDefaultPgTypeVariants[T any](m *Map, name string) { + arrayName := "_" + name + + var value T + m.RegisterDefaultPgType(value, name) // T + m.RegisterDefaultPgType(&value, name) // *T + + var sliceT []T + m.RegisterDefaultPgType(sliceT, arrayName) // []T + m.RegisterDefaultPgType(&sliceT, arrayName) // *[]T + + var slicePtrT []*T + m.RegisterDefaultPgType(slicePtrT, arrayName) // []*T + m.RegisterDefaultPgType(&slicePtrT, arrayName) // *[]*T + + var arrayOfT Array[T] + m.RegisterDefaultPgType(arrayOfT, arrayName) // Array[T] + m.RegisterDefaultPgType(&arrayOfT, arrayName) // *Array[T] + + var arrayOfPtrT Array[*T] + m.RegisterDefaultPgType(arrayOfPtrT, arrayName) // Array[*T] + m.RegisterDefaultPgType(&arrayOfPtrT, arrayName) // *Array[*T] + + var flatArrayOfT FlatArray[T] + m.RegisterDefaultPgType(flatArrayOfT, arrayName) // FlatArray[T] + m.RegisterDefaultPgType(&flatArrayOfT, arrayName) // *FlatArray[T] + + var flatArrayOfPtrT FlatArray[*T] + m.RegisterDefaultPgType(flatArrayOfPtrT, arrayName) // FlatArray[*T] + m.RegisterDefaultPgType(&flatArrayOfPtrT, arrayName) // *FlatArray[*T] +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types_disabled.go b/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types_disabled.go new file mode 100644 index 00000000000..56fe7c226aa --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/register_default_pg_types_disabled.go @@ -0,0 +1,6 @@ +//go:build nopgxregisterdefaulttypes + +package pgtype + +func registerDefaultPgTypeVariants[T any](m *Map, name string) { +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/text.go b/vendor/github.com/jackc/pgx/v5/pgtype/text.go new file mode 100644 index 00000000000..021ee331bf0 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/text.go @@ -0,0 +1,223 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/json" + "fmt" +) + +type TextScanner interface { + ScanText(v Text) error +} + +type TextValuer interface { + TextValue() (Text, error) +} + +type Text struct { + String string + Valid bool +} + +func (t *Text) ScanText(v Text) error { + *t = v + return nil +} + +func (t Text) TextValue() (Text, error) { + return t, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Text) Scan(src any) error { + if src == nil { + *dst = Text{} + return nil + } + + switch src := src.(type) { + case string: + *dst = Text{String: src, Valid: true} + return nil + case []byte: + *dst = Text{String: string(src), Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src Text) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + return src.String, nil +} + +func (src Text) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + + return json.Marshal(src.String) +} + +func (dst *Text) UnmarshalJSON(b []byte) error { + var s *string + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + if s == nil { + *dst = Text{} + } else { + *dst = Text{String: *s, Valid: true} + } + + return nil +} + +type TextCodec struct{} + +func (TextCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (TextCodec) PreferredFormat() int16 { + return TextFormatCode +} + +func (TextCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case TextFormatCode, BinaryFormatCode: + switch value.(type) { + case string: + return encodePlanTextCodecString{} + case []byte: + return encodePlanTextCodecByteSlice{} + case TextValuer: + return encodePlanTextCodecTextValuer{} + } + } + + return nil +} + +type encodePlanTextCodecString struct{} + +func (encodePlanTextCodecString) Encode(value any, buf []byte) (newBuf []byte, err error) { + s := value.(string) + buf = append(buf, s...) + return buf, nil +} + +type encodePlanTextCodecByteSlice struct{} + +func (encodePlanTextCodecByteSlice) Encode(value any, buf []byte) (newBuf []byte, err error) { + s := value.([]byte) + buf = append(buf, s...) + return buf, nil +} + +type encodePlanTextCodecStringer struct{} + +func (encodePlanTextCodecStringer) Encode(value any, buf []byte) (newBuf []byte, err error) { + s := value.(fmt.Stringer) + buf = append(buf, s.String()...) + return buf, nil +} + +type encodePlanTextCodecTextValuer struct{} + +func (encodePlanTextCodecTextValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + text, err := value.(TextValuer).TextValue() + if err != nil { + return nil, err + } + + if !text.Valid { + return nil, nil + } + + buf = append(buf, text.String...) + return buf, nil +} + +func (TextCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case TextFormatCode, BinaryFormatCode: + switch target.(type) { + case *string: + return scanPlanTextAnyToString{} + case *[]byte: + return scanPlanAnyToNewByteSlice{} + case BytesScanner: + return scanPlanAnyToByteScanner{} + case TextScanner: + return scanPlanTextAnyToTextScanner{} + } + } + + return nil +} + +func (c TextCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return c.DecodeValue(m, oid, format, src) +} + +func (c TextCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + return string(src), nil +} + +type scanPlanTextAnyToString struct{} + +func (scanPlanTextAnyToString) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + p := (dst).(*string) + *p = string(src) + + return nil +} + +type scanPlanAnyToNewByteSlice struct{} + +func (scanPlanAnyToNewByteSlice) Scan(src []byte, dst any) error { + p := (dst).(*[]byte) + if src == nil { + *p = nil + } else { + *p = make([]byte, len(src)) + copy(*p, src) + } + + return nil +} + +type scanPlanAnyToByteScanner struct{} + +func (scanPlanAnyToByteScanner) Scan(src []byte, dst any) error { + p := (dst).(BytesScanner) + return p.ScanBytes(src) +} + +type scanPlanTextAnyToTextScanner struct{} + +func (scanPlanTextAnyToTextScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TextScanner) + + if src == nil { + return scanner.ScanText(Text{}) + } + + return scanner.ScanText(Text{String: string(src), Valid: true}) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/text_format_only_codec.go b/vendor/github.com/jackc/pgx/v5/pgtype/text_format_only_codec.go new file mode 100644 index 00000000000..d5e4cdb3815 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/text_format_only_codec.go @@ -0,0 +1,13 @@ +package pgtype + +type TextFormatOnlyCodec struct { + Codec +} + +func (c *TextFormatOnlyCodec) FormatSupported(format int16) bool { + return format == TextFormatCode && c.Codec.FormatSupported(format) +} + +func (TextFormatOnlyCodec) PreferredFormat() int16 { + return TextFormatCode +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/tid.go b/vendor/github.com/jackc/pgx/v5/pgtype/tid.go new file mode 100644 index 00000000000..5839e87403b --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/tid.go @@ -0,0 +1,241 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type TIDScanner interface { + ScanTID(v TID) error +} + +type TIDValuer interface { + TIDValue() (TID, error) +} + +// TID is PostgreSQL's Tuple Identifier type. +// +// When one does +// +// select ctid, * from some_table; +// +// it is the data type of the ctid hidden system column. +// +// It is currently implemented as a pair unsigned two byte integers. +// Its conversion functions can be found in src/backend/utils/adt/tid.c +// in the PostgreSQL sources. +type TID struct { + BlockNumber uint32 + OffsetNumber uint16 + Valid bool +} + +func (b *TID) ScanTID(v TID) error { + *b = v + return nil +} + +func (b TID) TIDValue() (TID, error) { + return b, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *TID) Scan(src any) error { + if src == nil { + *dst = TID{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToTIDScanner{}.Scan([]byte(src), dst) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src TID) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + buf, err := TIDCodec{}.PlanEncode(nil, 0, TextFormatCode, src).Encode(src, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type TIDCodec struct{} + +func (TIDCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (TIDCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (TIDCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(TIDValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanTIDCodecBinary{} + case TextFormatCode: + return encodePlanTIDCodecText{} + } + + return nil +} + +type encodePlanTIDCodecBinary struct{} + +func (encodePlanTIDCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + tid, err := value.(TIDValuer).TIDValue() + if err != nil { + return nil, err + } + + if !tid.Valid { + return nil, nil + } + + buf = pgio.AppendUint32(buf, tid.BlockNumber) + buf = pgio.AppendUint16(buf, tid.OffsetNumber) + return buf, nil +} + +type encodePlanTIDCodecText struct{} + +func (encodePlanTIDCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + tid, err := value.(TIDValuer).TIDValue() + if err != nil { + return nil, err + } + + if !tid.Valid { + return nil, nil + } + + buf = append(buf, fmt.Sprintf(`(%d,%d)`, tid.BlockNumber, tid.OffsetNumber)...) + return buf, nil +} + +func (TIDCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case TIDScanner: + return scanPlanBinaryTIDToTIDScanner{} + case TextScanner: + return scanPlanBinaryTIDToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case TIDScanner: + return scanPlanTextAnyToTIDScanner{} + } + } + + return nil +} + +type scanPlanBinaryTIDToTIDScanner struct{} + +func (scanPlanBinaryTIDToTIDScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TIDScanner) + + if src == nil { + return scanner.ScanTID(TID{}) + } + + if len(src) != 6 { + return fmt.Errorf("invalid length for tid: %v", len(src)) + } + + return scanner.ScanTID(TID{ + BlockNumber: binary.BigEndian.Uint32(src), + OffsetNumber: binary.BigEndian.Uint16(src[4:]), + Valid: true, + }) +} + +type scanPlanBinaryTIDToTextScanner struct{} + +func (scanPlanBinaryTIDToTextScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TextScanner) + + if src == nil { + return scanner.ScanText(Text{}) + } + + if len(src) != 6 { + return fmt.Errorf("invalid length for tid: %v", len(src)) + } + + blockNumber := binary.BigEndian.Uint32(src) + offsetNumber := binary.BigEndian.Uint16(src[4:]) + + return scanner.ScanText(Text{ + String: fmt.Sprintf(`(%d,%d)`, blockNumber, offsetNumber), + Valid: true, + }) +} + +type scanPlanTextAnyToTIDScanner struct{} + +func (scanPlanTextAnyToTIDScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TIDScanner) + + if src == nil { + return scanner.ScanTID(TID{}) + } + + if len(src) < 5 { + return fmt.Errorf("invalid length for tid: %v", len(src)) + } + + parts := strings.SplitN(string(src[1:len(src)-1]), ",", 2) + if len(parts) < 2 { + return fmt.Errorf("invalid format for tid") + } + + blockNumber, err := strconv.ParseUint(parts[0], 10, 32) + if err != nil { + return err + } + + offsetNumber, err := strconv.ParseUint(parts[1], 10, 16) + if err != nil { + return err + } + + return scanner.ScanTID(TID{BlockNumber: uint32(blockNumber), OffsetNumber: uint16(offsetNumber), Valid: true}) +} + +func (c TIDCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c TIDCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var tid TID + err := codecScan(c, m, oid, format, src, &tid) + if err != nil { + return nil, err + } + return tid, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/time.go b/vendor/github.com/jackc/pgx/v5/pgtype/time.go new file mode 100644 index 00000000000..2eb6ace28b5 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/time.go @@ -0,0 +1,233 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "strconv" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type TimeScanner interface { + ScanTime(v Time) error +} + +type TimeValuer interface { + TimeValue() (Time, error) +} + +// Time represents the PostgreSQL time type. The PostgreSQL time is a time of day without time zone. +// +// Time is represented as the number of microseconds since midnight in the same way that PostgreSQL does. Other time +// and date types in pgtype can use time.Time as the underlying representation. However, pgtype.Time type cannot due +// to needing to handle 24:00:00. time.Time converts that to 00:00:00 on the following day. +type Time struct { + Microseconds int64 // Number of microseconds since midnight + Valid bool +} + +func (t *Time) ScanTime(v Time) error { + *t = v + return nil +} + +func (t Time) TimeValue() (Time, error) { + return t, nil +} + +// Scan implements the database/sql Scanner interface. +func (t *Time) Scan(src any) error { + if src == nil { + *t = Time{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextAnyToTimeScanner{}.Scan([]byte(src), t) + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (t Time) Value() (driver.Value, error) { + if !t.Valid { + return nil, nil + } + + buf, err := TimeCodec{}.PlanEncode(nil, 0, TextFormatCode, t).Encode(t, nil) + if err != nil { + return nil, err + } + return string(buf), err +} + +type TimeCodec struct{} + +func (TimeCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (TimeCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (TimeCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(TimeValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanTimeCodecBinary{} + case TextFormatCode: + return encodePlanTimeCodecText{} + } + + return nil +} + +type encodePlanTimeCodecBinary struct{} + +func (encodePlanTimeCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + t, err := value.(TimeValuer).TimeValue() + if err != nil { + return nil, err + } + + if !t.Valid { + return nil, nil + } + + return pgio.AppendInt64(buf, t.Microseconds), nil +} + +type encodePlanTimeCodecText struct{} + +func (encodePlanTimeCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + t, err := value.(TimeValuer).TimeValue() + if err != nil { + return nil, err + } + + if !t.Valid { + return nil, nil + } + + usec := t.Microseconds + hours := usec / microsecondsPerHour + usec -= hours * microsecondsPerHour + minutes := usec / microsecondsPerMinute + usec -= minutes * microsecondsPerMinute + seconds := usec / microsecondsPerSecond + usec -= seconds * microsecondsPerSecond + + s := fmt.Sprintf("%02d:%02d:%02d.%06d", hours, minutes, seconds, usec) + + return append(buf, s...), nil +} + +func (TimeCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case TimeScanner: + return scanPlanBinaryTimeToTimeScanner{} + } + case TextFormatCode: + switch target.(type) { + case TimeScanner: + return scanPlanTextAnyToTimeScanner{} + } + } + + return nil +} + +type scanPlanBinaryTimeToTimeScanner struct{} + +func (scanPlanBinaryTimeToTimeScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TimeScanner) + + if src == nil { + return scanner.ScanTime(Time{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for time: %v", len(src)) + } + + usec := int64(binary.BigEndian.Uint64(src)) + + return scanner.ScanTime(Time{Microseconds: usec, Valid: true}) +} + +type scanPlanTextAnyToTimeScanner struct{} + +func (scanPlanTextAnyToTimeScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TimeScanner) + + if src == nil { + return scanner.ScanTime(Time{}) + } + + s := string(src) + + if len(s) < 8 { + return fmt.Errorf("cannot decode %v into Time", s) + } + + hours, err := strconv.ParseInt(s[0:2], 10, 64) + if err != nil { + return fmt.Errorf("cannot decode %v into Time", s) + } + usec := hours * microsecondsPerHour + + minutes, err := strconv.ParseInt(s[3:5], 10, 64) + if err != nil { + return fmt.Errorf("cannot decode %v into Time", s) + } + usec += minutes * microsecondsPerMinute + + seconds, err := strconv.ParseInt(s[6:8], 10, 64) + if err != nil { + return fmt.Errorf("cannot decode %v into Time", s) + } + usec += seconds * microsecondsPerSecond + + if len(s) > 9 { + fraction := s[9:] + n, err := strconv.ParseInt(fraction, 10, 64) + if err != nil { + return fmt.Errorf("cannot decode %v into Time", s) + } + + for i := len(fraction); i < 6; i++ { + n *= 10 + } + + usec += n + } + + return scanner.ScanTime(Time{Microseconds: usec, Valid: true}) +} + +func (c TimeCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + return codecDecodeToTextFormat(c, m, oid, format, src) +} + +func (c TimeCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var t Time + err := codecScan(c, m, oid, format, src, &t) + if err != nil { + return nil, err + } + return t, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/timestamp.go b/vendor/github.com/jackc/pgx/v5/pgtype/timestamp.go new file mode 100644 index 00000000000..35d7395660e --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/timestamp.go @@ -0,0 +1,345 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "encoding/json" + "fmt" + "strings" + "time" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const pgTimestampFormat = "2006-01-02 15:04:05.999999999" + +type TimestampScanner interface { + ScanTimestamp(v Timestamp) error +} + +type TimestampValuer interface { + TimestampValue() (Timestamp, error) +} + +// Timestamp represents the PostgreSQL timestamp type. +type Timestamp struct { + Time time.Time // Time zone will be ignored when encoding to PostgreSQL. + InfinityModifier InfinityModifier + Valid bool +} + +func (ts *Timestamp) ScanTimestamp(v Timestamp) error { + *ts = v + return nil +} + +func (ts Timestamp) TimestampValue() (Timestamp, error) { + return ts, nil +} + +// Scan implements the database/sql Scanner interface. +func (ts *Timestamp) Scan(src any) error { + if src == nil { + *ts = Timestamp{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextTimestampToTimestampScanner{}.Scan([]byte(src), ts) + case time.Time: + *ts = Timestamp{Time: src, Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (ts Timestamp) Value() (driver.Value, error) { + if !ts.Valid { + return nil, nil + } + + if ts.InfinityModifier != Finite { + return ts.InfinityModifier.String(), nil + } + return ts.Time, nil +} + +func (ts Timestamp) MarshalJSON() ([]byte, error) { + if !ts.Valid { + return []byte("null"), nil + } + + var s string + + switch ts.InfinityModifier { + case Finite: + s = ts.Time.Format(time.RFC3339Nano) + case Infinity: + s = "infinity" + case NegativeInfinity: + s = "-infinity" + } + + return json.Marshal(s) +} + +func (ts *Timestamp) UnmarshalJSON(b []byte) error { + var s *string + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + if s == nil { + *ts = Timestamp{} + return nil + } + + switch *s { + case "infinity": + *ts = Timestamp{Valid: true, InfinityModifier: Infinity} + case "-infinity": + *ts = Timestamp{Valid: true, InfinityModifier: -Infinity} + default: + // PostgreSQL uses ISO 8601 for to_json function and casting from a string to timestamptz + tim, err := time.Parse(time.RFC3339Nano, *s) + if err != nil { + return err + } + + *ts = Timestamp{Time: tim, Valid: true} + } + + return nil +} + +type TimestampCodec struct{} + +func (TimestampCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (TimestampCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (TimestampCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(TimestampValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanTimestampCodecBinary{} + case TextFormatCode: + return encodePlanTimestampCodecText{} + } + + return nil +} + +type encodePlanTimestampCodecBinary struct{} + +func (encodePlanTimestampCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + ts, err := value.(TimestampValuer).TimestampValue() + if err != nil { + return nil, err + } + + if !ts.Valid { + return nil, nil + } + + var microsecSinceY2K int64 + switch ts.InfinityModifier { + case Finite: + t := discardTimeZone(ts.Time) + microsecSinceUnixEpoch := t.Unix()*1000000 + int64(t.Nanosecond())/1000 + microsecSinceY2K = microsecSinceUnixEpoch - microsecFromUnixEpochToY2K + case Infinity: + microsecSinceY2K = infinityMicrosecondOffset + case NegativeInfinity: + microsecSinceY2K = negativeInfinityMicrosecondOffset + } + + buf = pgio.AppendInt64(buf, microsecSinceY2K) + + return buf, nil +} + +type encodePlanTimestampCodecText struct{} + +func (encodePlanTimestampCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + ts, err := value.(TimestampValuer).TimestampValue() + if err != nil { + return nil, err + } + + if !ts.Valid { + return nil, nil + } + + var s string + + switch ts.InfinityModifier { + case Finite: + t := discardTimeZone(ts.Time) + + // Year 0000 is 1 BC + bc := false + if year := t.Year(); year <= 0 { + year = -year + 1 + t = time.Date(year, t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC) + bc = true + } + + s = t.Truncate(time.Microsecond).Format(pgTimestampFormat) + + if bc { + s = s + " BC" + } + case Infinity: + s = "infinity" + case NegativeInfinity: + s = "-infinity" + } + + buf = append(buf, s...) + + return buf, nil +} + +func discardTimeZone(t time.Time) time.Time { + if t.Location() != time.UTC { + return time.Date(t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC) + } + + return t +} + +func (TimestampCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case TimestampScanner: + return scanPlanBinaryTimestampToTimestampScanner{} + } + case TextFormatCode: + switch target.(type) { + case TimestampScanner: + return scanPlanTextTimestampToTimestampScanner{} + } + } + + return nil +} + +type scanPlanBinaryTimestampToTimestampScanner struct{} + +func (scanPlanBinaryTimestampToTimestampScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TimestampScanner) + + if src == nil { + return scanner.ScanTimestamp(Timestamp{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for timestamp: %v", len(src)) + } + + var ts Timestamp + microsecSinceY2K := int64(binary.BigEndian.Uint64(src)) + + switch microsecSinceY2K { + case infinityMicrosecondOffset: + ts = Timestamp{Valid: true, InfinityModifier: Infinity} + case negativeInfinityMicrosecondOffset: + ts = Timestamp{Valid: true, InfinityModifier: -Infinity} + default: + tim := time.Unix( + microsecFromUnixEpochToY2K/1000000+microsecSinceY2K/1000000, + (microsecFromUnixEpochToY2K%1000000*1000)+(microsecSinceY2K%1000000*1000), + ).UTC() + ts = Timestamp{Time: tim, Valid: true} + } + + return scanner.ScanTimestamp(ts) +} + +type scanPlanTextTimestampToTimestampScanner struct{} + +func (scanPlanTextTimestampToTimestampScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TimestampScanner) + + if src == nil { + return scanner.ScanTimestamp(Timestamp{}) + } + + var ts Timestamp + sbuf := string(src) + switch sbuf { + case "infinity": + ts = Timestamp{Valid: true, InfinityModifier: Infinity} + case "-infinity": + ts = Timestamp{Valid: true, InfinityModifier: -Infinity} + default: + bc := false + if strings.HasSuffix(sbuf, " BC") { + sbuf = sbuf[:len(sbuf)-3] + bc = true + } + tim, err := time.Parse(pgTimestampFormat, sbuf) + if err != nil { + return err + } + + if bc { + year := -tim.Year() + 1 + tim = time.Date(year, tim.Month(), tim.Day(), tim.Hour(), tim.Minute(), tim.Second(), tim.Nanosecond(), tim.Location()) + } + + ts = Timestamp{Time: tim, Valid: true} + } + + return scanner.ScanTimestamp(ts) +} + +func (c TimestampCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var ts Timestamp + err := codecScan(c, m, oid, format, src, &ts) + if err != nil { + return nil, err + } + + if ts.InfinityModifier != Finite { + return ts.InfinityModifier.String(), nil + } + + return ts.Time, nil +} + +func (c TimestampCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var ts Timestamp + err := codecScan(c, m, oid, format, src, &ts) + if err != nil { + return nil, err + } + + if ts.InfinityModifier != Finite { + return ts.InfinityModifier, nil + } + + return ts.Time, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/timestamptz.go b/vendor/github.com/jackc/pgx/v5/pgtype/timestamptz.go new file mode 100644 index 00000000000..f568fe3020a --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/timestamptz.go @@ -0,0 +1,355 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "encoding/json" + "fmt" + "strings" + "time" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +const pgTimestamptzHourFormat = "2006-01-02 15:04:05.999999999Z07" +const pgTimestamptzMinuteFormat = "2006-01-02 15:04:05.999999999Z07:00" +const pgTimestamptzSecondFormat = "2006-01-02 15:04:05.999999999Z07:00:00" +const microsecFromUnixEpochToY2K = 946684800 * 1000000 + +const ( + negativeInfinityMicrosecondOffset = -9223372036854775808 + infinityMicrosecondOffset = 9223372036854775807 +) + +type TimestamptzScanner interface { + ScanTimestamptz(v Timestamptz) error +} + +type TimestamptzValuer interface { + TimestamptzValue() (Timestamptz, error) +} + +// Timestamptz represents the PostgreSQL timestamptz type. +type Timestamptz struct { + Time time.Time + InfinityModifier InfinityModifier + Valid bool +} + +func (tstz *Timestamptz) ScanTimestamptz(v Timestamptz) error { + *tstz = v + return nil +} + +func (tstz Timestamptz) TimestamptzValue() (Timestamptz, error) { + return tstz, nil +} + +// Scan implements the database/sql Scanner interface. +func (tstz *Timestamptz) Scan(src any) error { + if src == nil { + *tstz = Timestamptz{} + return nil + } + + switch src := src.(type) { + case string: + return scanPlanTextTimestamptzToTimestamptzScanner{}.Scan([]byte(src), tstz) + case time.Time: + *tstz = Timestamptz{Time: src, Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (tstz Timestamptz) Value() (driver.Value, error) { + if !tstz.Valid { + return nil, nil + } + + if tstz.InfinityModifier != Finite { + return tstz.InfinityModifier.String(), nil + } + return tstz.Time, nil +} + +func (tstz Timestamptz) MarshalJSON() ([]byte, error) { + if !tstz.Valid { + return []byte("null"), nil + } + + var s string + + switch tstz.InfinityModifier { + case Finite: + s = tstz.Time.Format(time.RFC3339Nano) + case Infinity: + s = "infinity" + case NegativeInfinity: + s = "-infinity" + } + + return json.Marshal(s) +} + +func (tstz *Timestamptz) UnmarshalJSON(b []byte) error { + var s *string + err := json.Unmarshal(b, &s) + if err != nil { + return err + } + + if s == nil { + *tstz = Timestamptz{} + return nil + } + + switch *s { + case "infinity": + *tstz = Timestamptz{Valid: true, InfinityModifier: Infinity} + case "-infinity": + *tstz = Timestamptz{Valid: true, InfinityModifier: -Infinity} + default: + // PostgreSQL uses ISO 8601 for to_json function and casting from a string to timestamptz + tim, err := time.Parse(time.RFC3339Nano, *s) + if err != nil { + return err + } + + *tstz = Timestamptz{Time: tim, Valid: true} + } + + return nil +} + +type TimestamptzCodec struct{} + +func (TimestamptzCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (TimestamptzCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (TimestamptzCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(TimestamptzValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanTimestamptzCodecBinary{} + case TextFormatCode: + return encodePlanTimestamptzCodecText{} + } + + return nil +} + +type encodePlanTimestamptzCodecBinary struct{} + +func (encodePlanTimestamptzCodecBinary) Encode(value any, buf []byte) (newBuf []byte, err error) { + ts, err := value.(TimestamptzValuer).TimestamptzValue() + if err != nil { + return nil, err + } + + if !ts.Valid { + return nil, nil + } + + var microsecSinceY2K int64 + switch ts.InfinityModifier { + case Finite: + microsecSinceUnixEpoch := ts.Time.Unix()*1000000 + int64(ts.Time.Nanosecond())/1000 + microsecSinceY2K = microsecSinceUnixEpoch - microsecFromUnixEpochToY2K + case Infinity: + microsecSinceY2K = infinityMicrosecondOffset + case NegativeInfinity: + microsecSinceY2K = negativeInfinityMicrosecondOffset + } + + buf = pgio.AppendInt64(buf, microsecSinceY2K) + + return buf, nil +} + +type encodePlanTimestamptzCodecText struct{} + +func (encodePlanTimestamptzCodecText) Encode(value any, buf []byte) (newBuf []byte, err error) { + ts, err := value.(TimestamptzValuer).TimestamptzValue() + if err != nil { + return nil, err + } + + if !ts.Valid { + return nil, nil + } + + var s string + + switch ts.InfinityModifier { + case Finite: + + t := ts.Time.UTC().Truncate(time.Microsecond) + + // Year 0000 is 1 BC + bc := false + if year := t.Year(); year <= 0 { + year = -year + 1 + t = time.Date(year, t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), time.UTC) + bc = true + } + + s = t.Format(pgTimestamptzSecondFormat) + + if bc { + s = s + " BC" + } + case Infinity: + s = "infinity" + case NegativeInfinity: + s = "-infinity" + } + + buf = append(buf, s...) + + return buf, nil +} + +func (TimestamptzCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case TimestamptzScanner: + return scanPlanBinaryTimestamptzToTimestamptzScanner{} + } + case TextFormatCode: + switch target.(type) { + case TimestamptzScanner: + return scanPlanTextTimestamptzToTimestamptzScanner{} + } + } + + return nil +} + +type scanPlanBinaryTimestamptzToTimestamptzScanner struct{} + +func (scanPlanBinaryTimestamptzToTimestamptzScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TimestamptzScanner) + + if src == nil { + return scanner.ScanTimestamptz(Timestamptz{}) + } + + if len(src) != 8 { + return fmt.Errorf("invalid length for timestamptz: %v", len(src)) + } + + var tstz Timestamptz + microsecSinceY2K := int64(binary.BigEndian.Uint64(src)) + + switch microsecSinceY2K { + case infinityMicrosecondOffset: + tstz = Timestamptz{Valid: true, InfinityModifier: Infinity} + case negativeInfinityMicrosecondOffset: + tstz = Timestamptz{Valid: true, InfinityModifier: -Infinity} + default: + tim := time.Unix( + microsecFromUnixEpochToY2K/1000000+microsecSinceY2K/1000000, + (microsecFromUnixEpochToY2K%1000000*1000)+(microsecSinceY2K%1000000*1000), + ) + tstz = Timestamptz{Time: tim, Valid: true} + } + + return scanner.ScanTimestamptz(tstz) +} + +type scanPlanTextTimestamptzToTimestamptzScanner struct{} + +func (scanPlanTextTimestamptzToTimestamptzScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TimestamptzScanner) + + if src == nil { + return scanner.ScanTimestamptz(Timestamptz{}) + } + + var tstz Timestamptz + sbuf := string(src) + switch sbuf { + case "infinity": + tstz = Timestamptz{Valid: true, InfinityModifier: Infinity} + case "-infinity": + tstz = Timestamptz{Valid: true, InfinityModifier: -Infinity} + default: + bc := false + if strings.HasSuffix(sbuf, " BC") { + sbuf = sbuf[:len(sbuf)-3] + bc = true + } + + var format string + if len(sbuf) >= 9 && (sbuf[len(sbuf)-9] == '-' || sbuf[len(sbuf)-9] == '+') { + format = pgTimestamptzSecondFormat + } else if len(sbuf) >= 6 && (sbuf[len(sbuf)-6] == '-' || sbuf[len(sbuf)-6] == '+') { + format = pgTimestamptzMinuteFormat + } else { + format = pgTimestamptzHourFormat + } + + tim, err := time.Parse(format, sbuf) + if err != nil { + return err + } + + if bc { + year := -tim.Year() + 1 + tim = time.Date(year, tim.Month(), tim.Day(), tim.Hour(), tim.Minute(), tim.Second(), tim.Nanosecond(), tim.Location()) + } + + tstz = Timestamptz{Time: tim, Valid: true} + } + + return scanner.ScanTimestamptz(tstz) +} + +func (c TimestamptzCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var tstz Timestamptz + err := codecScan(c, m, oid, format, src, &tstz) + if err != nil { + return nil, err + } + + if tstz.InfinityModifier != Finite { + return tstz.InfinityModifier.String(), nil + } + + return tstz.Time, nil +} + +func (c TimestamptzCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var tstz Timestamptz + err := codecScan(c, m, oid, format, src, &tstz) + if err != nil { + return nil, err + } + + if tstz.InfinityModifier != Finite { + return tstz.InfinityModifier, nil + } + + return tstz.Time, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go b/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go new file mode 100644 index 00000000000..098c516c127 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/uint32.go @@ -0,0 +1,303 @@ +package pgtype + +import ( + "database/sql/driver" + "encoding/binary" + "fmt" + "math" + "strconv" + + "github.com/jackc/pgx/v5/internal/pgio" +) + +type Uint32Scanner interface { + ScanUint32(v Uint32) error +} + +type Uint32Valuer interface { + Uint32Value() (Uint32, error) +} + +// Uint32 is the core type that is used to represent PostgreSQL types such as OID, CID, and XID. +type Uint32 struct { + Uint32 uint32 + Valid bool +} + +func (n *Uint32) ScanUint32(v Uint32) error { + *n = v + return nil +} + +func (n Uint32) Uint32Value() (Uint32, error) { + return n, nil +} + +// Scan implements the database/sql Scanner interface. +func (dst *Uint32) Scan(src any) error { + if src == nil { + *dst = Uint32{} + return nil + } + + var n int64 + + switch src := src.(type) { + case int64: + n = src + case string: + un, err := strconv.ParseUint(src, 10, 32) + if err != nil { + return err + } + n = int64(un) + default: + return fmt.Errorf("cannot scan %T", src) + } + + if n < 0 { + return fmt.Errorf("%d is less than the minimum value for Uint32", n) + } + if n > math.MaxUint32 { + return fmt.Errorf("%d is greater than maximum value for Uint32", n) + } + + *dst = Uint32{Uint32: uint32(n), Valid: true} + + return nil +} + +// Value implements the database/sql/driver Valuer interface. +func (src Uint32) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + return int64(src.Uint32), nil +} + +type Uint32Codec struct{} + +func (Uint32Codec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (Uint32Codec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (Uint32Codec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + switch format { + case BinaryFormatCode: + switch value.(type) { + case uint32: + return encodePlanUint32CodecBinaryUint32{} + case Uint32Valuer: + return encodePlanUint32CodecBinaryUint32Valuer{} + case Int64Valuer: + return encodePlanUint32CodecBinaryInt64Valuer{} + } + case TextFormatCode: + switch value.(type) { + case uint32: + return encodePlanUint32CodecTextUint32{} + case Int64Valuer: + return encodePlanUint32CodecTextInt64Valuer{} + } + } + + return nil +} + +type encodePlanUint32CodecBinaryUint32 struct{} + +func (encodePlanUint32CodecBinaryUint32) Encode(value any, buf []byte) (newBuf []byte, err error) { + v := value.(uint32) + return pgio.AppendUint32(buf, v), nil +} + +type encodePlanUint32CodecBinaryUint32Valuer struct{} + +func (encodePlanUint32CodecBinaryUint32Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + v, err := value.(Uint32Valuer).Uint32Value() + if err != nil { + return nil, err + } + + if !v.Valid { + return nil, nil + } + + return pgio.AppendUint32(buf, v.Uint32), nil +} + +type encodePlanUint32CodecBinaryInt64Valuer struct{} + +func (encodePlanUint32CodecBinaryInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + v, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !v.Valid { + return nil, nil + } + + if v.Int64 < 0 { + return nil, fmt.Errorf("%d is less than minimum value for uint32", v.Int64) + } + if v.Int64 > math.MaxUint32 { + return nil, fmt.Errorf("%d is greater than maximum value for uint32", v.Int64) + } + + return pgio.AppendUint32(buf, uint32(v.Int64)), nil +} + +type encodePlanUint32CodecTextUint32 struct{} + +func (encodePlanUint32CodecTextUint32) Encode(value any, buf []byte) (newBuf []byte, err error) { + v := value.(uint32) + return append(buf, strconv.FormatUint(uint64(v), 10)...), nil +} + +type encodePlanUint32CodecTextUint32Valuer struct{} + +func (encodePlanUint32CodecTextUint32Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + v, err := value.(Uint32Valuer).Uint32Value() + if err != nil { + return nil, err + } + + if !v.Valid { + return nil, nil + } + + return append(buf, strconv.FormatUint(uint64(v.Uint32), 10)...), nil +} + +type encodePlanUint32CodecTextInt64Valuer struct{} + +func (encodePlanUint32CodecTextInt64Valuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + v, err := value.(Int64Valuer).Int64Value() + if err != nil { + return nil, err + } + + if !v.Valid { + return nil, nil + } + + if v.Int64 < 0 { + return nil, fmt.Errorf("%d is less than minimum value for uint32", v.Int64) + } + if v.Int64 > math.MaxUint32 { + return nil, fmt.Errorf("%d is greater than maximum value for uint32", v.Int64) + } + + return append(buf, strconv.FormatInt(v.Int64, 10)...), nil +} + +func (Uint32Codec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + + switch format { + case BinaryFormatCode: + switch target.(type) { + case *uint32: + return scanPlanBinaryUint32ToUint32{} + case Uint32Scanner: + return scanPlanBinaryUint32ToUint32Scanner{} + } + case TextFormatCode: + switch target.(type) { + case *uint32: + return scanPlanTextAnyToUint32{} + case Uint32Scanner: + return scanPlanTextAnyToUint32Scanner{} + } + } + + return nil +} + +func (c Uint32Codec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var n uint32 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return int64(n), nil +} + +func (c Uint32Codec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var n uint32 + err := codecScan(c, m, oid, format, src, &n) + if err != nil { + return nil, err + } + return n, nil +} + +type scanPlanBinaryUint32ToUint32 struct{} + +func (scanPlanBinaryUint32ToUint32) Scan(src []byte, dst any) error { + if src == nil { + return fmt.Errorf("cannot scan NULL into %T", dst) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for uint32: %v", len(src)) + } + + p := (dst).(*uint32) + *p = binary.BigEndian.Uint32(src) + + return nil +} + +type scanPlanBinaryUint32ToUint32Scanner struct{} + +func (scanPlanBinaryUint32ToUint32Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Uint32Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanUint32(Uint32{}) + } + + if len(src) != 4 { + return fmt.Errorf("invalid length for uint32: %v", len(src)) + } + + n := binary.BigEndian.Uint32(src) + + return s.ScanUint32(Uint32{Uint32: n, Valid: true}) +} + +type scanPlanTextAnyToUint32Scanner struct{} + +func (scanPlanTextAnyToUint32Scanner) Scan(src []byte, dst any) error { + s, ok := (dst).(Uint32Scanner) + if !ok { + return ErrScanTargetTypeChanged + } + + if src == nil { + return s.ScanUint32(Uint32{}) + } + + n, err := strconv.ParseUint(string(src), 10, 32) + if err != nil { + return err + } + + return s.ScanUint32(Uint32{Uint32: uint32(n), Valid: true}) +} diff --git a/vendor/github.com/jackc/pgx/v5/pgtype/uuid.go b/vendor/github.com/jackc/pgx/v5/pgtype/uuid.go new file mode 100644 index 00000000000..96a4c32fd12 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/pgtype/uuid.go @@ -0,0 +1,269 @@ +package pgtype + +import ( + "bytes" + "database/sql/driver" + "encoding/hex" + "fmt" +) + +type UUIDScanner interface { + ScanUUID(v UUID) error +} + +type UUIDValuer interface { + UUIDValue() (UUID, error) +} + +type UUID struct { + Bytes [16]byte + Valid bool +} + +func (b *UUID) ScanUUID(v UUID) error { + *b = v + return nil +} + +func (b UUID) UUIDValue() (UUID, error) { + return b, nil +} + +// parseUUID converts a string UUID in standard form to a byte array. +func parseUUID(src string) (dst [16]byte, err error) { + switch len(src) { + case 36: + src = src[0:8] + src[9:13] + src[14:18] + src[19:23] + src[24:] + case 32: + // dashes already stripped, assume valid + default: + // assume invalid. + return dst, fmt.Errorf("cannot parse UUID %v", src) + } + + buf, err := hex.DecodeString(src) + if err != nil { + return dst, err + } + + copy(dst[:], buf) + return dst, err +} + +// encodeUUID converts a uuid byte array to UUID standard string form. +func encodeUUID(src [16]byte) string { + return fmt.Sprintf("%x-%x-%x-%x-%x", src[0:4], src[4:6], src[6:8], src[8:10], src[10:16]) +} + +// Scan implements the database/sql Scanner interface. +func (dst *UUID) Scan(src any) error { + if src == nil { + *dst = UUID{} + return nil + } + + switch src := src.(type) { + case string: + buf, err := parseUUID(src) + if err != nil { + return err + } + *dst = UUID{Bytes: buf, Valid: true} + return nil + } + + return fmt.Errorf("cannot scan %T", src) +} + +// Value implements the database/sql/driver Valuer interface. +func (src UUID) Value() (driver.Value, error) { + if !src.Valid { + return nil, nil + } + + return encodeUUID(src.Bytes), nil +} + +func (src UUID) MarshalJSON() ([]byte, error) { + if !src.Valid { + return []byte("null"), nil + } + + var buff bytes.Buffer + buff.WriteByte('"') + buff.WriteString(encodeUUID(src.Bytes)) + buff.WriteByte('"') + return buff.Bytes(), nil +} + +func (dst *UUID) UnmarshalJSON(src []byte) error { + if bytes.Compare(src, []byte("null")) == 0 { + *dst = UUID{} + return nil + } + if len(src) != 38 { + return fmt.Errorf("invalid length for UUID: %v", len(src)) + } + buf, err := parseUUID(string(src[1 : len(src)-1])) + if err != nil { + return err + } + *dst = UUID{Bytes: buf, Valid: true} + return nil +} + +type UUIDCodec struct{} + +func (UUIDCodec) FormatSupported(format int16) bool { + return format == TextFormatCode || format == BinaryFormatCode +} + +func (UUIDCodec) PreferredFormat() int16 { + return BinaryFormatCode +} + +func (UUIDCodec) PlanEncode(m *Map, oid uint32, format int16, value any) EncodePlan { + if _, ok := value.(UUIDValuer); !ok { + return nil + } + + switch format { + case BinaryFormatCode: + return encodePlanUUIDCodecBinaryUUIDValuer{} + case TextFormatCode: + return encodePlanUUIDCodecTextUUIDValuer{} + } + + return nil +} + +type encodePlanUUIDCodecBinaryUUIDValuer struct{} + +func (encodePlanUUIDCodecBinaryUUIDValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + uuid, err := value.(UUIDValuer).UUIDValue() + if err != nil { + return nil, err + } + + if !uuid.Valid { + return nil, nil + } + + return append(buf, uuid.Bytes[:]...), nil +} + +type encodePlanUUIDCodecTextUUIDValuer struct{} + +func (encodePlanUUIDCodecTextUUIDValuer) Encode(value any, buf []byte) (newBuf []byte, err error) { + uuid, err := value.(UUIDValuer).UUIDValue() + if err != nil { + return nil, err + } + + if !uuid.Valid { + return nil, nil + } + + return append(buf, encodeUUID(uuid.Bytes)...), nil +} + +func (UUIDCodec) PlanScan(m *Map, oid uint32, format int16, target any) ScanPlan { + switch format { + case BinaryFormatCode: + switch target.(type) { + case UUIDScanner: + return scanPlanBinaryUUIDToUUIDScanner{} + case TextScanner: + return scanPlanBinaryUUIDToTextScanner{} + } + case TextFormatCode: + switch target.(type) { + case UUIDScanner: + return scanPlanTextAnyToUUIDScanner{} + } + } + + return nil +} + +type scanPlanBinaryUUIDToUUIDScanner struct{} + +func (scanPlanBinaryUUIDToUUIDScanner) Scan(src []byte, dst any) error { + scanner := (dst).(UUIDScanner) + + if src == nil { + return scanner.ScanUUID(UUID{}) + } + + if len(src) != 16 { + return fmt.Errorf("invalid length for UUID: %v", len(src)) + } + + uuid := UUID{Valid: true} + copy(uuid.Bytes[:], src) + + return scanner.ScanUUID(uuid) +} + +type scanPlanBinaryUUIDToTextScanner struct{} + +func (scanPlanBinaryUUIDToTextScanner) Scan(src []byte, dst any) error { + scanner := (dst).(TextScanner) + + if src == nil { + return scanner.ScanText(Text{}) + } + + if len(src) != 16 { + return fmt.Errorf("invalid length for UUID: %v", len(src)) + } + + var buf [16]byte + copy(buf[:], src) + + return scanner.ScanText(Text{String: encodeUUID(buf), Valid: true}) +} + +type scanPlanTextAnyToUUIDScanner struct{} + +func (scanPlanTextAnyToUUIDScanner) Scan(src []byte, dst any) error { + scanner := (dst).(UUIDScanner) + + if src == nil { + return scanner.ScanUUID(UUID{}) + } + + buf, err := parseUUID(string(src)) + if err != nil { + return err + } + + return scanner.ScanUUID(UUID{Bytes: buf, Valid: true}) +} + +func (c UUIDCodec) DecodeDatabaseSQLValue(m *Map, oid uint32, format int16, src []byte) (driver.Value, error) { + if src == nil { + return nil, nil + } + + var uuid UUID + err := codecScan(c, m, oid, format, src, &uuid) + if err != nil { + return nil, err + } + + return encodeUUID(uuid.Bytes), nil +} + +func (c UUIDCodec) DecodeValue(m *Map, oid uint32, format int16, src []byte) (any, error) { + if src == nil { + return nil, nil + } + + var uuid UUID + err := codecScan(c, m, oid, format, src, &uuid) + if err != nil { + return nil, err + } + return uuid.Bytes, nil +} diff --git a/vendor/github.com/jackc/pgx/v5/rows.go b/vendor/github.com/jackc/pgx/v5/rows.go new file mode 100644 index 00000000000..cdd72a25f3f --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/rows.go @@ -0,0 +1,676 @@ +package pgx + +import ( + "context" + "errors" + "fmt" + "reflect" + "strings" + "time" + + "github.com/jackc/pgx/v5/internal/stmtcache" + "github.com/jackc/pgx/v5/pgconn" + "github.com/jackc/pgx/v5/pgtype" +) + +// Rows is the result set returned from *Conn.Query. Rows must be closed before +// the *Conn can be used again. Rows are closed by explicitly calling Close(), +// calling Next() until it returns false, or when a fatal error occurs. +// +// Once a Rows is closed the only methods that may be called are Close(), Err(), and CommandTag(). +// +// Rows is an interface instead of a struct to allow tests to mock Query. However, +// adding a method to an interface is technically a breaking change. Because of this +// the Rows interface is partially excluded from semantic version requirements. +// Methods will not be removed or changed, but new methods may be added. +type Rows interface { + // Close closes the rows, making the connection ready for use again. It is safe + // to call Close after rows is already closed. + Close() + + // Err returns any error that occurred while reading. Err must only be called after the Rows is closed (either by + // calling Close or by Next returning false). If it is called early it may return nil even if there was an error + // executing the query. + Err() error + + // CommandTag returns the command tag from this query. It is only available after Rows is closed. + CommandTag() pgconn.CommandTag + + // FieldDescriptions returns the field descriptions of the columns. It may return nil. In particular this can occur + // when there was an error executing the query. + FieldDescriptions() []pgconn.FieldDescription + + // Next prepares the next row for reading. It returns true if there is another + // row and false if no more rows are available. It automatically closes rows + // when all rows are read. + Next() bool + + // Scan reads the values from the current row into dest values positionally. + // dest can include pointers to core types, values implementing the Scanner + // interface, and nil. nil will skip the value entirely. It is an error to + // call Scan without first calling Next() and checking that it returned true. + Scan(dest ...any) error + + // Values returns the decoded row values. As with Scan(), it is an error to + // call Values without first calling Next() and checking that it returned + // true. + Values() ([]any, error) + + // RawValues returns the unparsed bytes of the row values. The returned data is only valid until the next Next + // call or the Rows is closed. + RawValues() [][]byte + + // Conn returns the underlying *Conn on which the query was executed. This may return nil if Rows did not come from a + // *Conn (e.g. if it was created by RowsFromResultReader) + Conn() *Conn +} + +// Row is a convenience wrapper over Rows that is returned by QueryRow. +// +// Row is an interface instead of a struct to allow tests to mock QueryRow. However, +// adding a method to an interface is technically a breaking change. Because of this +// the Row interface is partially excluded from semantic version requirements. +// Methods will not be removed or changed, but new methods may be added. +type Row interface { + // Scan works the same as Rows. with the following exceptions. If no + // rows were found it returns ErrNoRows. If multiple rows are returned it + // ignores all but the first. + Scan(dest ...any) error +} + +// RowScanner scans an entire row at a time into the RowScanner. +type RowScanner interface { + // ScanRows scans the row. + ScanRow(rows Rows) error +} + +// connRow implements the Row interface for Conn.QueryRow. +type connRow baseRows + +func (r *connRow) Scan(dest ...any) (err error) { + rows := (*baseRows)(r) + + if rows.Err() != nil { + return rows.Err() + } + + for _, d := range dest { + if _, ok := d.(*pgtype.DriverBytes); ok { + rows.Close() + return fmt.Errorf("cannot scan into *pgtype.DriverBytes from QueryRow") + } + } + + if !rows.Next() { + if rows.Err() == nil { + return ErrNoRows + } + return rows.Err() + } + + rows.Scan(dest...) + rows.Close() + return rows.Err() +} + +// baseRows implements the Rows interface for Conn.Query. +type baseRows struct { + typeMap *pgtype.Map + resultReader *pgconn.ResultReader + + values [][]byte + + commandTag pgconn.CommandTag + err error + closed bool + + scanPlans []pgtype.ScanPlan + scanTypes []reflect.Type + + conn *Conn + multiResultReader *pgconn.MultiResultReader + + queryTracer QueryTracer + batchTracer BatchTracer + ctx context.Context + startTime time.Time + sql string + args []any + rowCount int +} + +func (rows *baseRows) FieldDescriptions() []pgconn.FieldDescription { + return rows.resultReader.FieldDescriptions() +} + +func (rows *baseRows) Close() { + if rows.closed { + return + } + + rows.closed = true + + if rows.resultReader != nil { + var closeErr error + rows.commandTag, closeErr = rows.resultReader.Close() + if rows.err == nil { + rows.err = closeErr + } + } + + if rows.multiResultReader != nil { + closeErr := rows.multiResultReader.Close() + if rows.err == nil { + rows.err = closeErr + } + } + + if rows.err != nil && rows.conn != nil && rows.sql != "" { + if stmtcache.IsStatementInvalid(rows.err) { + if sc := rows.conn.statementCache; sc != nil { + sc.Invalidate(rows.sql) + } + + if sc := rows.conn.descriptionCache; sc != nil { + sc.Invalidate(rows.sql) + } + } + } + + if rows.batchTracer != nil { + rows.batchTracer.TraceBatchQuery(rows.ctx, rows.conn, TraceBatchQueryData{SQL: rows.sql, Args: rows.args, CommandTag: rows.commandTag, Err: rows.err}) + } else if rows.queryTracer != nil { + rows.queryTracer.TraceQueryEnd(rows.ctx, rows.conn, TraceQueryEndData{rows.commandTag, rows.err}) + } +} + +func (rows *baseRows) CommandTag() pgconn.CommandTag { + return rows.commandTag +} + +func (rows *baseRows) Err() error { + return rows.err +} + +// fatal signals an error occurred after the query was sent to the server. It +// closes the rows automatically. +func (rows *baseRows) fatal(err error) { + if rows.err != nil { + return + } + + rows.err = err + rows.Close() +} + +func (rows *baseRows) Next() bool { + if rows.closed { + return false + } + + if rows.resultReader.NextRow() { + rows.rowCount++ + rows.values = rows.resultReader.Values() + return true + } else { + rows.Close() + return false + } +} + +func (rows *baseRows) Scan(dest ...any) error { + m := rows.typeMap + fieldDescriptions := rows.FieldDescriptions() + values := rows.values + + if len(fieldDescriptions) != len(values) { + err := fmt.Errorf("number of field descriptions must equal number of values, got %d and %d", len(fieldDescriptions), len(values)) + rows.fatal(err) + return err + } + + if len(dest) == 1 { + if rc, ok := dest[0].(RowScanner); ok { + return rc.ScanRow(rows) + } + } + + if len(fieldDescriptions) != len(dest) { + err := fmt.Errorf("number of field descriptions must equal number of destinations, got %d and %d", len(fieldDescriptions), len(dest)) + rows.fatal(err) + return err + } + + if rows.scanPlans == nil { + rows.scanPlans = make([]pgtype.ScanPlan, len(values)) + rows.scanTypes = make([]reflect.Type, len(values)) + for i := range dest { + rows.scanPlans[i] = m.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i]) + rows.scanTypes[i] = reflect.TypeOf(dest[i]) + } + } + + for i, dst := range dest { + if dst == nil { + continue + } + + if rows.scanTypes[i] != reflect.TypeOf(dst) { + rows.scanPlans[i] = m.PlanScan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, dest[i]) + rows.scanTypes[i] = reflect.TypeOf(dest[i]) + } + + err := rows.scanPlans[i].Scan(values[i], dst) + if err != nil { + err = ScanArgError{ColumnIndex: i, Err: err} + rows.fatal(err) + return err + } + } + + return nil +} + +func (rows *baseRows) Values() ([]any, error) { + if rows.closed { + return nil, errors.New("rows is closed") + } + + values := make([]any, 0, len(rows.FieldDescriptions())) + + for i := range rows.FieldDescriptions() { + buf := rows.values[i] + fd := &rows.FieldDescriptions()[i] + + if buf == nil { + values = append(values, nil) + continue + } + + if dt, ok := rows.typeMap.TypeForOID(fd.DataTypeOID); ok { + value, err := dt.Codec.DecodeValue(rows.typeMap, fd.DataTypeOID, fd.Format, buf) + if err != nil { + rows.fatal(err) + } + values = append(values, value) + } else { + switch fd.Format { + case TextFormatCode: + values = append(values, string(buf)) + case BinaryFormatCode: + newBuf := make([]byte, len(buf)) + copy(newBuf, buf) + values = append(values, newBuf) + default: + rows.fatal(errors.New("Unknown format code")) + } + } + + if rows.Err() != nil { + return nil, rows.Err() + } + } + + return values, rows.Err() +} + +func (rows *baseRows) RawValues() [][]byte { + return rows.values +} + +func (rows *baseRows) Conn() *Conn { + return rows.conn +} + +type ScanArgError struct { + ColumnIndex int + Err error +} + +func (e ScanArgError) Error() string { + return fmt.Sprintf("can't scan into dest[%d]: %v", e.ColumnIndex, e.Err) +} + +func (e ScanArgError) Unwrap() error { + return e.Err +} + +// ScanRow decodes raw row data into dest. It can be used to scan rows read from the lower level pgconn interface. +// +// typeMap - OID to Go type mapping. +// fieldDescriptions - OID and format of values +// values - the raw data as returned from the PostgreSQL server +// dest - the destination that values will be decoded into +func ScanRow(typeMap *pgtype.Map, fieldDescriptions []pgconn.FieldDescription, values [][]byte, dest ...any) error { + if len(fieldDescriptions) != len(values) { + return fmt.Errorf("number of field descriptions must equal number of values, got %d and %d", len(fieldDescriptions), len(values)) + } + if len(fieldDescriptions) != len(dest) { + return fmt.Errorf("number of field descriptions must equal number of destinations, got %d and %d", len(fieldDescriptions), len(dest)) + } + + for i, d := range dest { + if d == nil { + continue + } + + err := typeMap.Scan(fieldDescriptions[i].DataTypeOID, fieldDescriptions[i].Format, values[i], d) + if err != nil { + return ScanArgError{ColumnIndex: i, Err: err} + } + } + + return nil +} + +// RowsFromResultReader returns a Rows that will read from values resultReader and decode with typeMap. It can be used +// to read from the lower level pgconn interface. +func RowsFromResultReader(typeMap *pgtype.Map, resultReader *pgconn.ResultReader) Rows { + return &baseRows{ + typeMap: typeMap, + resultReader: resultReader, + } +} + +// ForEachRow iterates through rows. For each row it scans into the elements of scans and calls fn. If any row +// fails to scan or fn returns an error the query will be aborted and the error will be returned. Rows will be closed +// when ForEachRow returns. +func ForEachRow(rows Rows, scans []any, fn func() error) (pgconn.CommandTag, error) { + defer rows.Close() + + for rows.Next() { + err := rows.Scan(scans...) + if err != nil { + return pgconn.CommandTag{}, err + } + + err = fn() + if err != nil { + return pgconn.CommandTag{}, err + } + } + + if err := rows.Err(); err != nil { + return pgconn.CommandTag{}, err + } + + return rows.CommandTag(), nil +} + +// CollectableRow is the subset of Rows methods that a RowToFunc is allowed to call. +type CollectableRow interface { + FieldDescriptions() []pgconn.FieldDescription + Scan(dest ...any) error + Values() ([]any, error) + RawValues() [][]byte +} + +// RowToFunc is a function that scans or otherwise converts row to a T. +type RowToFunc[T any] func(row CollectableRow) (T, error) + +// CollectRows iterates through rows, calling fn for each row, and collecting the results into a slice of T. +func CollectRows[T any](rows Rows, fn RowToFunc[T]) ([]T, error) { + defer rows.Close() + + slice := []T{} + + for rows.Next() { + value, err := fn(rows) + if err != nil { + return nil, err + } + slice = append(slice, value) + } + + if err := rows.Err(); err != nil { + return nil, err + } + + return slice, nil +} + +// CollectOneRow calls fn for the first row in rows and returns the result. If no rows are found returns an error where errors.Is(ErrNoRows) is true. +// CollectOneRow is to CollectRows as QueryRow is to Query. +func CollectOneRow[T any](rows Rows, fn RowToFunc[T]) (T, error) { + defer rows.Close() + + var value T + var err error + + if !rows.Next() { + if err = rows.Err(); err != nil { + return value, err + } + return value, ErrNoRows + } + + value, err = fn(rows) + if err != nil { + return value, err + } + + rows.Close() + return value, rows.Err() +} + +// RowTo returns a T scanned from row. +func RowTo[T any](row CollectableRow) (T, error) { + var value T + err := row.Scan(&value) + return value, err +} + +// RowTo returns a the address of a T scanned from row. +func RowToAddrOf[T any](row CollectableRow) (*T, error) { + var value T + err := row.Scan(&value) + return &value, err +} + +// RowToMap returns a map scanned from row. +func RowToMap(row CollectableRow) (map[string]any, error) { + var value map[string]any + err := row.Scan((*mapRowScanner)(&value)) + return value, err +} + +type mapRowScanner map[string]any + +func (rs *mapRowScanner) ScanRow(rows Rows) error { + values, err := rows.Values() + if err != nil { + return err + } + + *rs = make(mapRowScanner, len(values)) + + for i := range values { + (*rs)[string(rows.FieldDescriptions()[i].Name)] = values[i] + } + + return nil +} + +// RowToStructByPos returns a T scanned from row. T must be a struct. T must have the same number a public fields as row +// has fields. The row and T fields will by matched by position. +func RowToStructByPos[T any](row CollectableRow) (T, error) { + var value T + err := row.Scan(&positionalStructRowScanner{ptrToStruct: &value}) + return value, err +} + +// RowToAddrOfStructByPos returns the address of a T scanned from row. T must be a struct. T must have the same number a +// public fields as row has fields. The row and T fields will by matched by position. +func RowToAddrOfStructByPos[T any](row CollectableRow) (*T, error) { + var value T + err := row.Scan(&positionalStructRowScanner{ptrToStruct: &value}) + return &value, err +} + +type positionalStructRowScanner struct { + ptrToStruct any +} + +func (rs *positionalStructRowScanner) ScanRow(rows Rows) error { + dst := rs.ptrToStruct + dstValue := reflect.ValueOf(dst) + if dstValue.Kind() != reflect.Ptr { + return fmt.Errorf("dst not a pointer") + } + + dstElemValue := dstValue.Elem() + scanTargets := rs.appendScanTargets(dstElemValue, nil) + + if len(rows.RawValues()) > len(scanTargets) { + return fmt.Errorf("got %d values, but dst struct has only %d fields", len(rows.RawValues()), len(scanTargets)) + } + + return rows.Scan(scanTargets...) +} + +func (rs *positionalStructRowScanner) appendScanTargets(dstElemValue reflect.Value, scanTargets []any) []any { + dstElemType := dstElemValue.Type() + + if scanTargets == nil { + scanTargets = make([]any, 0, dstElemType.NumField()) + } + + for i := 0; i < dstElemType.NumField(); i++ { + sf := dstElemType.Field(i) + // Handle anonymous struct embedding, but do not try to handle embedded pointers. + if sf.Anonymous && sf.Type.Kind() == reflect.Struct { + scanTargets = rs.appendScanTargets(dstElemValue.Field(i), scanTargets) + } else if sf.PkgPath == "" { + scanTargets = append(scanTargets, dstElemValue.Field(i).Addr().Interface()) + } + } + + return scanTargets +} + +// RowToStructByName returns a T scanned from row. T must be a struct. T must have the same number of named public +// fields as row has fields. The row and T fields will by matched by name. The match is case-insensitive. The database +// column name can be overridden with a "db" struct tag. If the "db" struct tag is "-" then the field will be ignored. +func RowToStructByName[T any](row CollectableRow) (T, error) { + var value T + err := row.Scan(&namedStructRowScanner{ptrToStruct: &value}) + return value, err +} + +// RowToAddrOfStructByName returns the address of a T scanned from row. T must be a struct. T must have the same number +// of named public fields as row has fields. The row and T fields will by matched by name. The match is +// case-insensitive. The database column name can be overridden with a "db" struct tag. If the "db" struct tag is "-" +// then the field will be ignored. +func RowToAddrOfStructByName[T any](row CollectableRow) (*T, error) { + var value T + err := row.Scan(&namedStructRowScanner{ptrToStruct: &value}) + return &value, err +} + +// RowToStructByNameLax returns a T scanned from row. T must be a struct. T must have greater than or equal number of named public +// fields as row has fields. The row and T fields will by matched by name. The match is case-insensitive. The database +// column name can be overridden with a "db" struct tag. If the "db" struct tag is "-" then the field will be ignored. +func RowToStructByNameLax[T any](row CollectableRow) (T, error) { + var value T + err := row.Scan(&namedStructRowScanner{ptrToStruct: &value, lax: true}) + return value, err +} + +// RowToAddrOfStructByNameLax returns the address of a T scanned from row. T must be a struct. T must have greater than or +// equal number of named public fields as row has fields. The row and T fields will by matched by name. The match is +// case-insensitive. The database column name can be overridden with a "db" struct tag. If the "db" struct tag is "-" +// then the field will be ignored. +func RowToAddrOfStructByNameLax[T any](row CollectableRow) (*T, error) { + var value T + err := row.Scan(&namedStructRowScanner{ptrToStruct: &value, lax: true}) + return &value, err +} + +type namedStructRowScanner struct { + ptrToStruct any + lax bool +} + +func (rs *namedStructRowScanner) ScanRow(rows Rows) error { + dst := rs.ptrToStruct + dstValue := reflect.ValueOf(dst) + if dstValue.Kind() != reflect.Ptr { + return fmt.Errorf("dst not a pointer") + } + + dstElemValue := dstValue.Elem() + scanTargets, err := rs.appendScanTargets(dstElemValue, nil, rows.FieldDescriptions()) + if err != nil { + return err + } + + for i, t := range scanTargets { + if t == nil { + return fmt.Errorf("struct doesn't have corresponding row field %s", rows.FieldDescriptions()[i].Name) + } + } + + return rows.Scan(scanTargets...) +} + +const structTagKey = "db" + +func fieldPosByName(fldDescs []pgconn.FieldDescription, field string) (i int) { + i = -1 + for i, desc := range fldDescs { + if strings.EqualFold(desc.Name, field) { + return i + } + } + return +} + +func (rs *namedStructRowScanner) appendScanTargets(dstElemValue reflect.Value, scanTargets []any, fldDescs []pgconn.FieldDescription) ([]any, error) { + var err error + dstElemType := dstElemValue.Type() + + if scanTargets == nil { + scanTargets = make([]any, len(fldDescs)) + } + + for i := 0; i < dstElemType.NumField(); i++ { + sf := dstElemType.Field(i) + if sf.PkgPath != "" && !sf.Anonymous { + // Field is unexported, skip it. + continue + } + // Handle anoymous struct embedding, but do not try to handle embedded pointers. + if sf.Anonymous && sf.Type.Kind() == reflect.Struct { + scanTargets, err = rs.appendScanTargets(dstElemValue.Field(i), scanTargets, fldDescs) + if err != nil { + return nil, err + } + } else { + dbTag, dbTagPresent := sf.Tag.Lookup(structTagKey) + if dbTagPresent { + dbTag = strings.Split(dbTag, ",")[0] + } + if dbTag == "-" { + // Field is ignored, skip it. + continue + } + colName := dbTag + if !dbTagPresent { + colName = sf.Name + } + fpos := fieldPosByName(fldDescs, colName) + if fpos == -1 { + if rs.lax { + continue + } + return nil, fmt.Errorf("cannot find field %s in returned row", colName) + } + if fpos >= len(scanTargets) && !rs.lax { + return nil, fmt.Errorf("cannot find field %s in returned row", colName) + } + scanTargets[fpos] = dstElemValue.Field(i).Addr().Interface() + } + } + + return scanTargets, err +} diff --git a/vendor/github.com/jackc/pgx/v5/stdlib/sql.go b/vendor/github.com/jackc/pgx/v5/stdlib/sql.go new file mode 100644 index 00000000000..97ecc9b2bd7 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/stdlib/sql.go @@ -0,0 +1,797 @@ +// Package stdlib is the compatibility layer from pgx to database/sql. +// +// A database/sql connection can be established through sql.Open. +// +// db, err := sql.Open("pgx", "postgres://pgx_md5:secret@localhost:5432/pgx_test?sslmode=disable") +// if err != nil { +// return err +// } +// +// Or from a DSN string. +// +// db, err := sql.Open("pgx", "user=postgres password=secret host=localhost port=5432 database=pgx_test sslmode=disable") +// if err != nil { +// return err +// } +// +// Or a pgx.ConnConfig can be used to set configuration not accessible via connection string. In this case the +// pgx.ConnConfig must first be registered with the driver. This registration returns a connection string which is used +// with sql.Open. +// +// connConfig, _ := pgx.ParseConfig(os.Getenv("DATABASE_URL")) +// connConfig.Logger = myLogger +// connStr := stdlib.RegisterConnConfig(connConfig) +// db, _ := sql.Open("pgx", connStr) +// +// pgx uses standard PostgreSQL positional parameters in queries. e.g. $1, $2. It does not support named parameters. +// +// db.QueryRow("select * from users where id=$1", userID) +// +// (*sql.Conn) Raw() can be used to get a *pgx.Conn from the standard database/sql.DB connection pool. This allows +// operations that use pgx specific functionality. +// +// // Given db is a *sql.DB +// conn, err := db.Conn(context.Background()) +// if err != nil { +// // handle error from acquiring connection from DB pool +// } +// +// err = conn.Raw(func(driverConn any) error { +// conn := driverConn.(*stdlib.Conn).Conn() // conn is a *pgx.Conn +// // Do pgx specific stuff with conn +// conn.CopyFrom(...) +// return nil +// }) +// if err != nil { +// // handle error that occurred while using *pgx.Conn +// } +// +// # PostgreSQL Specific Data Types +// +// The pgtype package provides support for PostgreSQL specific types. *pgtype.Map.SQLScanner is an adapter that makes +// these types usable as a sql.Scanner. +// +// m := pgtype.NewMap() +// var a []int64 +// err := db.QueryRow("select '{1,2,3}'::bigint[]").Scan(m.SQLScanner(&a)) +package stdlib + +import ( + "context" + "database/sql" + "database/sql/driver" + "errors" + "fmt" + "io" + "math" + "math/rand" + "reflect" + "strconv" + "strings" + "sync" + "time" + + "github.com/jackc/pgx/v5" + "github.com/jackc/pgx/v5/pgconn" + "github.com/jackc/pgx/v5/pgtype" +) + +// Only intrinsic types should be binary format with database/sql. +var databaseSQLResultFormats pgx.QueryResultFormatsByOID + +var pgxDriver *Driver + +func init() { + pgxDriver = &Driver{ + configs: make(map[string]*pgx.ConnConfig), + } + + // if pgx driver was already registered by different pgx major version then we + // skip registration under the default name. + if !contains(sql.Drivers(), "pgx") { + sql.Register("pgx", pgxDriver) + } + sql.Register("pgx/v5", pgxDriver) + + databaseSQLResultFormats = pgx.QueryResultFormatsByOID{ + pgtype.BoolOID: 1, + pgtype.ByteaOID: 1, + pgtype.CIDOID: 1, + pgtype.DateOID: 1, + pgtype.Float4OID: 1, + pgtype.Float8OID: 1, + pgtype.Int2OID: 1, + pgtype.Int4OID: 1, + pgtype.Int8OID: 1, + pgtype.OIDOID: 1, + pgtype.TimestampOID: 1, + pgtype.TimestamptzOID: 1, + pgtype.XIDOID: 1, + } +} + +// TODO replace by slices.Contains when experimental package will be merged to stdlib +// https://pkg.go.dev/golang.org/x/exp/slices#Contains +func contains(list []string, y string) bool { + for _, x := range list { + if x == y { + return true + } + } + return false +} + +// OptionOpenDB options for configuring the driver when opening a new db pool. +type OptionOpenDB func(*connector) + +// OptionBeforeConnect provides a callback for before connect. It is passed a shallow copy of the ConnConfig that will +// be used to connect, so only its immediate members should be modified. +func OptionBeforeConnect(bc func(context.Context, *pgx.ConnConfig) error) OptionOpenDB { + return func(dc *connector) { + dc.BeforeConnect = bc + } +} + +// OptionAfterConnect provides a callback for after connect. +func OptionAfterConnect(ac func(context.Context, *pgx.Conn) error) OptionOpenDB { + return func(dc *connector) { + dc.AfterConnect = ac + } +} + +// OptionResetSession provides a callback that can be used to add custom logic prior to executing a query on the +// connection if the connection has been used before. +// If ResetSessionFunc returns ErrBadConn error the connection will be discarded. +func OptionResetSession(rs func(context.Context, *pgx.Conn) error) OptionOpenDB { + return func(dc *connector) { + dc.ResetSession = rs + } +} + +// RandomizeHostOrderFunc is a BeforeConnect hook that randomizes the host order in the provided connConfig, so that a +// new host becomes primary each time. This is useful to distribute connections for multi-master databases like +// CockroachDB. If you use this you likely should set https://golang.org/pkg/database/sql/#DB.SetConnMaxLifetime as well +// to ensure that connections are periodically rebalanced across your nodes. +func RandomizeHostOrderFunc(ctx context.Context, connConfig *pgx.ConnConfig) error { + if len(connConfig.Fallbacks) == 0 { + return nil + } + + newFallbacks := append([]*pgconn.FallbackConfig{{ + Host: connConfig.Host, + Port: connConfig.Port, + TLSConfig: connConfig.TLSConfig, + }}, connConfig.Fallbacks...) + + rand.Shuffle(len(newFallbacks), func(i, j int) { + newFallbacks[i], newFallbacks[j] = newFallbacks[j], newFallbacks[i] + }) + + // Use the one that sorted last as the primary and keep the rest as the fallbacks + newPrimary := newFallbacks[len(newFallbacks)-1] + connConfig.Host = newPrimary.Host + connConfig.Port = newPrimary.Port + connConfig.TLSConfig = newPrimary.TLSConfig + connConfig.Fallbacks = newFallbacks[:len(newFallbacks)-1] + return nil +} + +func GetConnector(config pgx.ConnConfig, opts ...OptionOpenDB) driver.Connector { + c := connector{ + ConnConfig: config, + BeforeConnect: func(context.Context, *pgx.ConnConfig) error { return nil }, // noop before connect by default + AfterConnect: func(context.Context, *pgx.Conn) error { return nil }, // noop after connect by default + ResetSession: func(context.Context, *pgx.Conn) error { return nil }, // noop reset session by default + driver: pgxDriver, + } + + for _, opt := range opts { + opt(&c) + } + return c +} + +func OpenDB(config pgx.ConnConfig, opts ...OptionOpenDB) *sql.DB { + c := GetConnector(config, opts...) + return sql.OpenDB(c) +} + +type connector struct { + pgx.ConnConfig + BeforeConnect func(context.Context, *pgx.ConnConfig) error // function to call before creation of every new connection + AfterConnect func(context.Context, *pgx.Conn) error // function to call after creation of every new connection + ResetSession func(context.Context, *pgx.Conn) error // function is called before a connection is reused + driver *Driver +} + +// Connect implement driver.Connector interface +func (c connector) Connect(ctx context.Context) (driver.Conn, error) { + var ( + err error + conn *pgx.Conn + ) + + // Create a shallow copy of the config, so that BeforeConnect can safely modify it + connConfig := c.ConnConfig + if err = c.BeforeConnect(ctx, &connConfig); err != nil { + return nil, err + } + + if conn, err = pgx.ConnectConfig(ctx, &connConfig); err != nil { + return nil, err + } + + if err = c.AfterConnect(ctx, conn); err != nil { + return nil, err + } + + return &Conn{conn: conn, driver: c.driver, connConfig: connConfig, resetSessionFunc: c.ResetSession}, nil +} + +// Driver implement driver.Connector interface +func (c connector) Driver() driver.Driver { + return c.driver +} + +// GetDefaultDriver returns the driver initialized in the init function +// and used when the pgx driver is registered. +func GetDefaultDriver() driver.Driver { + return pgxDriver +} + +type Driver struct { + configMutex sync.Mutex + configs map[string]*pgx.ConnConfig + sequence int +} + +func (d *Driver) Open(name string) (driver.Conn, error) { + ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second) // Ensure eventual timeout + defer cancel() + + connector, err := d.OpenConnector(name) + if err != nil { + return nil, err + } + return connector.Connect(ctx) +} + +func (d *Driver) OpenConnector(name string) (driver.Connector, error) { + return &driverConnector{driver: d, name: name}, nil +} + +func (d *Driver) registerConnConfig(c *pgx.ConnConfig) string { + d.configMutex.Lock() + connStr := fmt.Sprintf("registeredConnConfig%d", d.sequence) + d.sequence++ + d.configs[connStr] = c + d.configMutex.Unlock() + return connStr +} + +func (d *Driver) unregisterConnConfig(connStr string) { + d.configMutex.Lock() + delete(d.configs, connStr) + d.configMutex.Unlock() +} + +type driverConnector struct { + driver *Driver + name string +} + +func (dc *driverConnector) Connect(ctx context.Context) (driver.Conn, error) { + var connConfig *pgx.ConnConfig + + dc.driver.configMutex.Lock() + connConfig = dc.driver.configs[dc.name] + dc.driver.configMutex.Unlock() + + if connConfig == nil { + var err error + connConfig, err = pgx.ParseConfig(dc.name) + if err != nil { + return nil, err + } + } + + conn, err := pgx.ConnectConfig(ctx, connConfig) + if err != nil { + return nil, err + } + + c := &Conn{ + conn: conn, + driver: dc.driver, + connConfig: *connConfig, + resetSessionFunc: func(context.Context, *pgx.Conn) error { return nil }, + } + + return c, nil +} + +func (dc *driverConnector) Driver() driver.Driver { + return dc.driver +} + +// RegisterConnConfig registers a ConnConfig and returns the connection string to use with Open. +func RegisterConnConfig(c *pgx.ConnConfig) string { + return pgxDriver.registerConnConfig(c) +} + +// UnregisterConnConfig removes the ConnConfig registration for connStr. +func UnregisterConnConfig(connStr string) { + pgxDriver.unregisterConnConfig(connStr) +} + +type Conn struct { + conn *pgx.Conn + psCount int64 // Counter used for creating unique prepared statement names + driver *Driver + connConfig pgx.ConnConfig + resetSessionFunc func(context.Context, *pgx.Conn) error // Function is called before a connection is reused + lastResetSessionTime time.Time +} + +// Conn returns the underlying *pgx.Conn +func (c *Conn) Conn() *pgx.Conn { + return c.conn +} + +func (c *Conn) Prepare(query string) (driver.Stmt, error) { + return c.PrepareContext(context.Background(), query) +} + +func (c *Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { + if c.conn.IsClosed() { + return nil, driver.ErrBadConn + } + + name := fmt.Sprintf("pgx_%d", c.psCount) + c.psCount++ + + sd, err := c.conn.Prepare(ctx, name, query) + if err != nil { + return nil, err + } + + return &Stmt{sd: sd, conn: c}, nil +} + +func (c *Conn) Close() error { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + return c.conn.Close(ctx) +} + +func (c *Conn) Begin() (driver.Tx, error) { + return c.BeginTx(context.Background(), driver.TxOptions{}) +} + +func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { + if c.conn.IsClosed() { + return nil, driver.ErrBadConn + } + + var pgxOpts pgx.TxOptions + switch sql.IsolationLevel(opts.Isolation) { + case sql.LevelDefault: + case sql.LevelReadUncommitted: + pgxOpts.IsoLevel = pgx.ReadUncommitted + case sql.LevelReadCommitted: + pgxOpts.IsoLevel = pgx.ReadCommitted + case sql.LevelRepeatableRead, sql.LevelSnapshot: + pgxOpts.IsoLevel = pgx.RepeatableRead + case sql.LevelSerializable: + pgxOpts.IsoLevel = pgx.Serializable + default: + return nil, fmt.Errorf("unsupported isolation: %v", opts.Isolation) + } + + if opts.ReadOnly { + pgxOpts.AccessMode = pgx.ReadOnly + } + + tx, err := c.conn.BeginTx(ctx, pgxOpts) + if err != nil { + return nil, err + } + + return wrapTx{ctx: ctx, tx: tx}, nil +} + +func (c *Conn) ExecContext(ctx context.Context, query string, argsV []driver.NamedValue) (driver.Result, error) { + if c.conn.IsClosed() { + return nil, driver.ErrBadConn + } + + args := namedValueToInterface(argsV) + + commandTag, err := c.conn.Exec(ctx, query, args...) + // if we got a network error before we had a chance to send the query, retry + if err != nil { + if pgconn.SafeToRetry(err) { + return nil, driver.ErrBadConn + } + } + return driver.RowsAffected(commandTag.RowsAffected()), err +} + +func (c *Conn) QueryContext(ctx context.Context, query string, argsV []driver.NamedValue) (driver.Rows, error) { + if c.conn.IsClosed() { + return nil, driver.ErrBadConn + } + + args := []any{databaseSQLResultFormats} + args = append(args, namedValueToInterface(argsV)...) + + rows, err := c.conn.Query(ctx, query, args...) + if err != nil { + if pgconn.SafeToRetry(err) { + return nil, driver.ErrBadConn + } + return nil, err + } + + // Preload first row because otherwise we won't know what columns are available when database/sql asks. + more := rows.Next() + if err = rows.Err(); err != nil { + rows.Close() + return nil, err + } + return &Rows{conn: c, rows: rows, skipNext: true, skipNextMore: more}, nil +} + +func (c *Conn) Ping(ctx context.Context) error { + if c.conn.IsClosed() { + return driver.ErrBadConn + } + + err := c.conn.Ping(ctx) + if err != nil { + // A Ping failure implies some sort of fatal state. The connection is almost certainly already closed by the + // failure, but manually close it just to be sure. + c.Close() + return driver.ErrBadConn + } + + return nil +} + +func (c *Conn) CheckNamedValue(*driver.NamedValue) error { + // Underlying pgx supports sql.Scanner and driver.Valuer interfaces natively. So everything can be passed through directly. + return nil +} + +func (c *Conn) ResetSession(ctx context.Context) error { + if c.conn.IsClosed() { + return driver.ErrBadConn + } + + now := time.Now() + if now.Sub(c.lastResetSessionTime) > time.Second { + if err := c.conn.PgConn().CheckConn(); err != nil { + return driver.ErrBadConn + } + } + c.lastResetSessionTime = now + + return c.resetSessionFunc(ctx, c.conn) +} + +type Stmt struct { + sd *pgconn.StatementDescription + conn *Conn +} + +func (s *Stmt) Close() error { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + return s.conn.conn.Deallocate(ctx, s.sd.Name) +} + +func (s *Stmt) NumInput() int { + return len(s.sd.ParamOIDs) +} + +func (s *Stmt) Exec(argsV []driver.Value) (driver.Result, error) { + return nil, errors.New("Stmt.Exec deprecated and not implemented") +} + +func (s *Stmt) ExecContext(ctx context.Context, argsV []driver.NamedValue) (driver.Result, error) { + return s.conn.ExecContext(ctx, s.sd.Name, argsV) +} + +func (s *Stmt) Query(argsV []driver.Value) (driver.Rows, error) { + return nil, errors.New("Stmt.Query deprecated and not implemented") +} + +func (s *Stmt) QueryContext(ctx context.Context, argsV []driver.NamedValue) (driver.Rows, error) { + return s.conn.QueryContext(ctx, s.sd.Name, argsV) +} + +type rowValueFunc func(src []byte) (driver.Value, error) + +type Rows struct { + conn *Conn + rows pgx.Rows + valueFuncs []rowValueFunc + skipNext bool + skipNextMore bool + + columnNames []string +} + +func (r *Rows) Columns() []string { + if r.columnNames == nil { + fields := r.rows.FieldDescriptions() + r.columnNames = make([]string, len(fields)) + for i, fd := range fields { + r.columnNames[i] = string(fd.Name) + } + } + + return r.columnNames +} + +// ColumnTypeDatabaseTypeName returns the database system type name. If the name is unknown the OID is returned. +func (r *Rows) ColumnTypeDatabaseTypeName(index int) string { + if dt, ok := r.conn.conn.TypeMap().TypeForOID(r.rows.FieldDescriptions()[index].DataTypeOID); ok { + return strings.ToUpper(dt.Name) + } + + return strconv.FormatInt(int64(r.rows.FieldDescriptions()[index].DataTypeOID), 10) +} + +const varHeaderSize = 4 + +// ColumnTypeLength returns the length of the column type if the column is a +// variable length type. If the column is not a variable length type ok +// should return false. +func (r *Rows) ColumnTypeLength(index int) (int64, bool) { + fd := r.rows.FieldDescriptions()[index] + + switch fd.DataTypeOID { + case pgtype.TextOID, pgtype.ByteaOID: + return math.MaxInt64, true + case pgtype.VarcharOID, pgtype.BPCharArrayOID: + return int64(fd.TypeModifier - varHeaderSize), true + default: + return 0, false + } +} + +// ColumnTypePrecisionScale should return the precision and scale for decimal +// types. If not applicable, ok should be false. +func (r *Rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { + fd := r.rows.FieldDescriptions()[index] + + switch fd.DataTypeOID { + case pgtype.NumericOID: + mod := fd.TypeModifier - varHeaderSize + precision = int64((mod >> 16) & 0xffff) + scale = int64(mod & 0xffff) + return precision, scale, true + default: + return 0, 0, false + } +} + +// ColumnTypeScanType returns the value type that can be used to scan types into. +func (r *Rows) ColumnTypeScanType(index int) reflect.Type { + fd := r.rows.FieldDescriptions()[index] + + switch fd.DataTypeOID { + case pgtype.Float8OID: + return reflect.TypeOf(float64(0)) + case pgtype.Float4OID: + return reflect.TypeOf(float32(0)) + case pgtype.Int8OID: + return reflect.TypeOf(int64(0)) + case pgtype.Int4OID: + return reflect.TypeOf(int32(0)) + case pgtype.Int2OID: + return reflect.TypeOf(int16(0)) + case pgtype.BoolOID: + return reflect.TypeOf(false) + case pgtype.NumericOID: + return reflect.TypeOf(float64(0)) + case pgtype.DateOID, pgtype.TimestampOID, pgtype.TimestamptzOID: + return reflect.TypeOf(time.Time{}) + case pgtype.ByteaOID: + return reflect.TypeOf([]byte(nil)) + default: + return reflect.TypeOf("") + } +} + +func (r *Rows) Close() error { + r.rows.Close() + return r.rows.Err() +} + +func (r *Rows) Next(dest []driver.Value) error { + m := r.conn.conn.TypeMap() + fieldDescriptions := r.rows.FieldDescriptions() + + if r.valueFuncs == nil { + r.valueFuncs = make([]rowValueFunc, len(fieldDescriptions)) + + for i, fd := range fieldDescriptions { + dataTypeOID := fd.DataTypeOID + format := fd.Format + + switch fd.DataTypeOID { + case pgtype.BoolOID: + var d bool + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return d, err + } + case pgtype.ByteaOID: + var d []byte + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return d, err + } + case pgtype.CIDOID, pgtype.OIDOID, pgtype.XIDOID: + var d pgtype.Uint32 + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + if err != nil { + return nil, err + } + return d.Value() + } + case pgtype.DateOID: + var d pgtype.Date + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + if err != nil { + return nil, err + } + return d.Value() + } + case pgtype.Float4OID: + var d float32 + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return float64(d), err + } + case pgtype.Float8OID: + var d float64 + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return d, err + } + case pgtype.Int2OID: + var d int16 + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return int64(d), err + } + case pgtype.Int4OID: + var d int32 + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return int64(d), err + } + case pgtype.Int8OID: + var d int64 + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return d, err + } + case pgtype.JSONOID, pgtype.JSONBOID: + var d []byte + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + if err != nil { + return nil, err + } + return d, nil + } + case pgtype.TimestampOID: + var d pgtype.Timestamp + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + if err != nil { + return nil, err + } + return d.Value() + } + case pgtype.TimestamptzOID: + var d pgtype.Timestamptz + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + if err != nil { + return nil, err + } + return d.Value() + } + default: + var d string + scanPlan := m.PlanScan(dataTypeOID, format, &d) + r.valueFuncs[i] = func(src []byte) (driver.Value, error) { + err := scanPlan.Scan(src, &d) + return d, err + } + } + } + } + + var more bool + if r.skipNext { + more = r.skipNextMore + r.skipNext = false + } else { + more = r.rows.Next() + } + + if !more { + if r.rows.Err() == nil { + return io.EOF + } else { + return r.rows.Err() + } + } + + for i, rv := range r.rows.RawValues() { + if rv != nil { + var err error + dest[i], err = r.valueFuncs[i](rv) + if err != nil { + return fmt.Errorf("convert field %d failed: %v", i, err) + } + } else { + dest[i] = nil + } + } + + return nil +} + +func valueToInterface(argsV []driver.Value) []any { + args := make([]any, 0, len(argsV)) + for _, v := range argsV { + if v != nil { + args = append(args, v.(any)) + } else { + args = append(args, nil) + } + } + return args +} + +func namedValueToInterface(argsV []driver.NamedValue) []any { + args := make([]any, 0, len(argsV)) + for _, v := range argsV { + if v.Value != nil { + args = append(args, v.Value.(any)) + } else { + args = append(args, nil) + } + } + return args +} + +type wrapTx struct { + ctx context.Context + tx pgx.Tx +} + +func (wtx wrapTx) Commit() error { return wtx.tx.Commit(wtx.ctx) } + +func (wtx wrapTx) Rollback() error { return wtx.tx.Rollback(wtx.ctx) } diff --git a/vendor/github.com/jackc/pgx/v5/tracer.go b/vendor/github.com/jackc/pgx/v5/tracer.go new file mode 100644 index 00000000000..58ca99f7e00 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/tracer.go @@ -0,0 +1,107 @@ +package pgx + +import ( + "context" + + "github.com/jackc/pgx/v5/pgconn" +) + +// QueryTracer traces Query, QueryRow, and Exec. +type QueryTracer interface { + // TraceQueryStart is called at the beginning of Query, QueryRow, and Exec calls. The returned context is used for the + // rest of the call and will be passed to TraceQueryEnd. + TraceQueryStart(ctx context.Context, conn *Conn, data TraceQueryStartData) context.Context + + TraceQueryEnd(ctx context.Context, conn *Conn, data TraceQueryEndData) +} + +type TraceQueryStartData struct { + SQL string + Args []any +} + +type TraceQueryEndData struct { + CommandTag pgconn.CommandTag + Err error +} + +// BatchTracer traces SendBatch. +type BatchTracer interface { + // TraceBatchStart is called at the beginning of SendBatch calls. The returned context is used for the + // rest of the call and will be passed to TraceBatchQuery and TraceBatchEnd. + TraceBatchStart(ctx context.Context, conn *Conn, data TraceBatchStartData) context.Context + + TraceBatchQuery(ctx context.Context, conn *Conn, data TraceBatchQueryData) + TraceBatchEnd(ctx context.Context, conn *Conn, data TraceBatchEndData) +} + +type TraceBatchStartData struct { + Batch *Batch +} + +type TraceBatchQueryData struct { + SQL string + Args []any + CommandTag pgconn.CommandTag + Err error +} + +type TraceBatchEndData struct { + Err error +} + +// CopyFromTracer traces CopyFrom. +type CopyFromTracer interface { + // TraceCopyFromStart is called at the beginning of CopyFrom calls. The returned context is used for the + // rest of the call and will be passed to TraceCopyFromEnd. + TraceCopyFromStart(ctx context.Context, conn *Conn, data TraceCopyFromStartData) context.Context + + TraceCopyFromEnd(ctx context.Context, conn *Conn, data TraceCopyFromEndData) +} + +type TraceCopyFromStartData struct { + TableName Identifier + ColumnNames []string +} + +type TraceCopyFromEndData struct { + CommandTag pgconn.CommandTag + Err error +} + +// PrepareTracer traces Prepare. +type PrepareTracer interface { + // TracePrepareStart is called at the beginning of Prepare calls. The returned context is used for the + // rest of the call and will be passed to TracePrepareEnd. + TracePrepareStart(ctx context.Context, conn *Conn, data TracePrepareStartData) context.Context + + TracePrepareEnd(ctx context.Context, conn *Conn, data TracePrepareEndData) +} + +type TracePrepareStartData struct { + Name string + SQL string +} + +type TracePrepareEndData struct { + AlreadyPrepared bool + Err error +} + +// ConnectTracer traces Connect and ConnectConfig. +type ConnectTracer interface { + // TraceConnectStart is called at the beginning of Connect and ConnectConfig calls. The returned context is used for + // the rest of the call and will be passed to TraceConnectEnd. + TraceConnectStart(ctx context.Context, data TraceConnectStartData) context.Context + + TraceConnectEnd(ctx context.Context, data TraceConnectEndData) +} + +type TraceConnectStartData struct { + ConnConfig *ConnConfig +} + +type TraceConnectEndData struct { + Conn *Conn + Err error +} diff --git a/vendor/github.com/jackc/pgx/v5/tx.go b/vendor/github.com/jackc/pgx/v5/tx.go new file mode 100644 index 00000000000..e57142a6191 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/tx.go @@ -0,0 +1,425 @@ +package pgx + +import ( + "context" + "errors" + "fmt" + "strconv" + "strings" + + "github.com/jackc/pgx/v5/pgconn" +) + +// TxIsoLevel is the transaction isolation level (serializable, repeatable read, read committed or read uncommitted) +type TxIsoLevel string + +// Transaction isolation levels +const ( + Serializable TxIsoLevel = "serializable" + RepeatableRead TxIsoLevel = "repeatable read" + ReadCommitted TxIsoLevel = "read committed" + ReadUncommitted TxIsoLevel = "read uncommitted" +) + +// TxAccessMode is the transaction access mode (read write or read only) +type TxAccessMode string + +// Transaction access modes +const ( + ReadWrite TxAccessMode = "read write" + ReadOnly TxAccessMode = "read only" +) + +// TxDeferrableMode is the transaction deferrable mode (deferrable or not deferrable) +type TxDeferrableMode string + +// Transaction deferrable modes +const ( + Deferrable TxDeferrableMode = "deferrable" + NotDeferrable TxDeferrableMode = "not deferrable" +) + +// TxOptions are transaction modes within a transaction block +type TxOptions struct { + IsoLevel TxIsoLevel + AccessMode TxAccessMode + DeferrableMode TxDeferrableMode +} + +var emptyTxOptions TxOptions + +func (txOptions TxOptions) beginSQL() string { + if txOptions == emptyTxOptions { + return "begin" + } + + var buf strings.Builder + buf.Grow(64) // 64 - maximum length of string with available options + buf.WriteString("begin") + + if txOptions.IsoLevel != "" { + buf.WriteString(" isolation level ") + buf.WriteString(string(txOptions.IsoLevel)) + } + if txOptions.AccessMode != "" { + buf.WriteByte(' ') + buf.WriteString(string(txOptions.AccessMode)) + } + if txOptions.DeferrableMode != "" { + buf.WriteByte(' ') + buf.WriteString(string(txOptions.DeferrableMode)) + } + + return buf.String() +} + +var ErrTxClosed = errors.New("tx is closed") + +// ErrTxCommitRollback occurs when an error has occurred in a transaction and +// Commit() is called. PostgreSQL accepts COMMIT on aborted transactions, but +// it is treated as ROLLBACK. +var ErrTxCommitRollback = errors.New("commit unexpectedly resulted in rollback") + +// Begin starts a transaction. Unlike database/sql, the context only affects the begin command. i.e. there is no +// auto-rollback on context cancellation. +func (c *Conn) Begin(ctx context.Context) (Tx, error) { + return c.BeginTx(ctx, TxOptions{}) +} + +// BeginTx starts a transaction with txOptions determining the transaction mode. Unlike database/sql, the context only +// affects the begin command. i.e. there is no auto-rollback on context cancellation. +func (c *Conn) BeginTx(ctx context.Context, txOptions TxOptions) (Tx, error) { + _, err := c.Exec(ctx, txOptions.beginSQL()) + if err != nil { + // begin should never fail unless there is an underlying connection issue or + // a context timeout. In either case, the connection is possibly broken. + c.die(errors.New("failed to begin transaction")) + return nil, err + } + + return &dbTx{conn: c}, nil +} + +// Tx represents a database transaction. +// +// Tx is an interface instead of a struct to enable connection pools to be implemented without relying on internal pgx +// state, to support pseudo-nested transactions with savepoints, and to allow tests to mock transactions. However, +// adding a method to an interface is technically a breaking change. If new methods are added to Conn it may be +// desirable to add them to Tx as well. Because of this the Tx interface is partially excluded from semantic version +// requirements. Methods will not be removed or changed, but new methods may be added. +type Tx interface { + // Begin starts a pseudo nested transaction. + Begin(ctx context.Context) (Tx, error) + + // Commit commits the transaction if this is a real transaction or releases the savepoint if this is a pseudo nested + // transaction. Commit will return an error where errors.Is(ErrTxClosed) is true if the Tx is already closed, but is + // otherwise safe to call multiple times. If the commit fails with a rollback status (e.g. the transaction was already + // in a broken state) then an error where errors.Is(ErrTxCommitRollback) is true will be returned. + Commit(ctx context.Context) error + + // Rollback rolls back the transaction if this is a real transaction or rolls back to the savepoint if this is a + // pseudo nested transaction. Rollback will return an error where errors.Is(ErrTxClosed) is true if the Tx is already + // closed, but is otherwise safe to call multiple times. Hence, a defer tx.Rollback() is safe even if tx.Commit() will + // be called first in a non-error condition. Any other failure of a real transaction will result in the connection + // being closed. + Rollback(ctx context.Context) error + + CopyFrom(ctx context.Context, tableName Identifier, columnNames []string, rowSrc CopyFromSource) (int64, error) + SendBatch(ctx context.Context, b *Batch) BatchResults + LargeObjects() LargeObjects + + Prepare(ctx context.Context, name, sql string) (*pgconn.StatementDescription, error) + + Exec(ctx context.Context, sql string, arguments ...any) (commandTag pgconn.CommandTag, err error) + Query(ctx context.Context, sql string, args ...any) (Rows, error) + QueryRow(ctx context.Context, sql string, args ...any) Row + + // Conn returns the underlying *Conn that on which this transaction is executing. + Conn() *Conn +} + +// dbTx represents a database transaction. +// +// All dbTx methods return ErrTxClosed if Commit or Rollback has already been +// called on the dbTx. +type dbTx struct { + conn *Conn + err error + savepointNum int64 + closed bool +} + +// Begin starts a pseudo nested transaction implemented with a savepoint. +func (tx *dbTx) Begin(ctx context.Context) (Tx, error) { + if tx.closed { + return nil, ErrTxClosed + } + + tx.savepointNum++ + _, err := tx.conn.Exec(ctx, "savepoint sp_"+strconv.FormatInt(tx.savepointNum, 10)) + if err != nil { + return nil, err + } + + return &dbSimulatedNestedTx{tx: tx, savepointNum: tx.savepointNum}, nil +} + +// Commit commits the transaction. +func (tx *dbTx) Commit(ctx context.Context) error { + if tx.closed { + return ErrTxClosed + } + + commandTag, err := tx.conn.Exec(ctx, "commit") + tx.closed = true + if err != nil { + if tx.conn.PgConn().TxStatus() != 'I' { + _ = tx.conn.Close(ctx) // already have error to return + } + return err + } + if commandTag.String() == "ROLLBACK" { + return ErrTxCommitRollback + } + + return nil +} + +// Rollback rolls back the transaction. Rollback will return ErrTxClosed if the +// Tx is already closed, but is otherwise safe to call multiple times. Hence, a +// defer tx.Rollback() is safe even if tx.Commit() will be called first in a +// non-error condition. +func (tx *dbTx) Rollback(ctx context.Context) error { + if tx.closed { + return ErrTxClosed + } + + _, err := tx.conn.Exec(ctx, "rollback") + tx.closed = true + if err != nil { + // A rollback failure leaves the connection in an undefined state + tx.conn.die(fmt.Errorf("rollback failed: %w", err)) + return err + } + + return nil +} + +// Exec delegates to the underlying *Conn +func (tx *dbTx) Exec(ctx context.Context, sql string, arguments ...any) (commandTag pgconn.CommandTag, err error) { + if tx.closed { + return pgconn.CommandTag{}, ErrTxClosed + } + + return tx.conn.Exec(ctx, sql, arguments...) +} + +// Prepare delegates to the underlying *Conn +func (tx *dbTx) Prepare(ctx context.Context, name, sql string) (*pgconn.StatementDescription, error) { + if tx.closed { + return nil, ErrTxClosed + } + + return tx.conn.Prepare(ctx, name, sql) +} + +// Query delegates to the underlying *Conn +func (tx *dbTx) Query(ctx context.Context, sql string, args ...any) (Rows, error) { + if tx.closed { + // Because checking for errors can be deferred to the *Rows, build one with the error + err := ErrTxClosed + return &baseRows{closed: true, err: err}, err + } + + return tx.conn.Query(ctx, sql, args...) +} + +// QueryRow delegates to the underlying *Conn +func (tx *dbTx) QueryRow(ctx context.Context, sql string, args ...any) Row { + rows, _ := tx.Query(ctx, sql, args...) + return (*connRow)(rows.(*baseRows)) +} + +// CopyFrom delegates to the underlying *Conn +func (tx *dbTx) CopyFrom(ctx context.Context, tableName Identifier, columnNames []string, rowSrc CopyFromSource) (int64, error) { + if tx.closed { + return 0, ErrTxClosed + } + + return tx.conn.CopyFrom(ctx, tableName, columnNames, rowSrc) +} + +// SendBatch delegates to the underlying *Conn +func (tx *dbTx) SendBatch(ctx context.Context, b *Batch) BatchResults { + if tx.closed { + return &batchResults{err: ErrTxClosed} + } + + return tx.conn.SendBatch(ctx, b) +} + +// LargeObjects returns a LargeObjects instance for the transaction. +func (tx *dbTx) LargeObjects() LargeObjects { + return LargeObjects{tx: tx} +} + +func (tx *dbTx) Conn() *Conn { + return tx.conn +} + +// dbSimulatedNestedTx represents a simulated nested transaction implemented by a savepoint. +type dbSimulatedNestedTx struct { + tx Tx + savepointNum int64 + closed bool +} + +// Begin starts a pseudo nested transaction implemented with a savepoint. +func (sp *dbSimulatedNestedTx) Begin(ctx context.Context) (Tx, error) { + if sp.closed { + return nil, ErrTxClosed + } + + return sp.tx.Begin(ctx) +} + +// Commit releases the savepoint essentially committing the pseudo nested transaction. +func (sp *dbSimulatedNestedTx) Commit(ctx context.Context) error { + if sp.closed { + return ErrTxClosed + } + + _, err := sp.Exec(ctx, "release savepoint sp_"+strconv.FormatInt(sp.savepointNum, 10)) + sp.closed = true + return err +} + +// Rollback rolls back to the savepoint essentially rolling back the pseudo nested transaction. Rollback will return +// ErrTxClosed if the dbSavepoint is already closed, but is otherwise safe to call multiple times. Hence, a defer sp.Rollback() +// is safe even if sp.Commit() will be called first in a non-error condition. +func (sp *dbSimulatedNestedTx) Rollback(ctx context.Context) error { + if sp.closed { + return ErrTxClosed + } + + _, err := sp.Exec(ctx, "rollback to savepoint sp_"+strconv.FormatInt(sp.savepointNum, 10)) + sp.closed = true + return err +} + +// Exec delegates to the underlying Tx +func (sp *dbSimulatedNestedTx) Exec(ctx context.Context, sql string, arguments ...any) (commandTag pgconn.CommandTag, err error) { + if sp.closed { + return pgconn.CommandTag{}, ErrTxClosed + } + + return sp.tx.Exec(ctx, sql, arguments...) +} + +// Prepare delegates to the underlying Tx +func (sp *dbSimulatedNestedTx) Prepare(ctx context.Context, name, sql string) (*pgconn.StatementDescription, error) { + if sp.closed { + return nil, ErrTxClosed + } + + return sp.tx.Prepare(ctx, name, sql) +} + +// Query delegates to the underlying Tx +func (sp *dbSimulatedNestedTx) Query(ctx context.Context, sql string, args ...any) (Rows, error) { + if sp.closed { + // Because checking for errors can be deferred to the *Rows, build one with the error + err := ErrTxClosed + return &baseRows{closed: true, err: err}, err + } + + return sp.tx.Query(ctx, sql, args...) +} + +// QueryRow delegates to the underlying Tx +func (sp *dbSimulatedNestedTx) QueryRow(ctx context.Context, sql string, args ...any) Row { + rows, _ := sp.Query(ctx, sql, args...) + return (*connRow)(rows.(*baseRows)) +} + +// CopyFrom delegates to the underlying *Conn +func (sp *dbSimulatedNestedTx) CopyFrom(ctx context.Context, tableName Identifier, columnNames []string, rowSrc CopyFromSource) (int64, error) { + if sp.closed { + return 0, ErrTxClosed + } + + return sp.tx.CopyFrom(ctx, tableName, columnNames, rowSrc) +} + +// SendBatch delegates to the underlying *Conn +func (sp *dbSimulatedNestedTx) SendBatch(ctx context.Context, b *Batch) BatchResults { + if sp.closed { + return &batchResults{err: ErrTxClosed} + } + + return sp.tx.SendBatch(ctx, b) +} + +func (sp *dbSimulatedNestedTx) LargeObjects() LargeObjects { + return LargeObjects{tx: sp} +} + +func (sp *dbSimulatedNestedTx) Conn() *Conn { + return sp.tx.Conn() +} + +// BeginFunc calls Begin on db and then calls fn. If fn does not return an error then it calls Commit on db. If fn +// returns an error it calls Rollback on db. The context will be used when executing the transaction control statements +// (BEGIN, ROLLBACK, and COMMIT) but does not otherwise affect the execution of fn. +func BeginFunc( + ctx context.Context, + db interface { + Begin(ctx context.Context) (Tx, error) + }, + fn func(Tx) error, +) (err error) { + var tx Tx + tx, err = db.Begin(ctx) + if err != nil { + return err + } + + return beginFuncExec(ctx, tx, fn) +} + +// BeginTxFunc calls BeginTx on db and then calls fn. If fn does not return an error then it calls Commit on db. If fn +// returns an error it calls Rollback on db. The context will be used when executing the transaction control statements +// (BEGIN, ROLLBACK, and COMMIT) but does not otherwise affect the execution of fn. +func BeginTxFunc( + ctx context.Context, + db interface { + BeginTx(ctx context.Context, txOptions TxOptions) (Tx, error) + }, + txOptions TxOptions, + fn func(Tx) error, +) (err error) { + var tx Tx + tx, err = db.BeginTx(ctx, txOptions) + if err != nil { + return err + } + + return beginFuncExec(ctx, tx, fn) +} + +func beginFuncExec(ctx context.Context, tx Tx, fn func(Tx) error) (err error) { + defer func() { + rollbackErr := tx.Rollback(ctx) + if rollbackErr != nil && !errors.Is(rollbackErr, ErrTxClosed) { + err = rollbackErr + } + }() + + fErr := fn(tx) + if fErr != nil { + _ = tx.Rollback(ctx) // ignore rollback error as there is already an error to return + return fErr + } + + return tx.Commit(ctx) +} diff --git a/vendor/github.com/jackc/pgx/v5/values.go b/vendor/github.com/jackc/pgx/v5/values.go new file mode 100644 index 00000000000..19c642fa927 --- /dev/null +++ b/vendor/github.com/jackc/pgx/v5/values.go @@ -0,0 +1,68 @@ +package pgx + +import ( + "errors" + + "github.com/jackc/pgx/v5/internal/anynil" + "github.com/jackc/pgx/v5/internal/pgio" + "github.com/jackc/pgx/v5/pgtype" +) + +// PostgreSQL format codes +const ( + TextFormatCode = 0 + BinaryFormatCode = 1 +) + +func convertSimpleArgument(m *pgtype.Map, arg any) (any, error) { + if anynil.Is(arg) { + return nil, nil + } + + buf, err := m.Encode(0, TextFormatCode, arg, []byte{}) + if err != nil { + return nil, err + } + if buf == nil { + return nil, nil + } + return string(buf), nil +} + +func encodeCopyValue(m *pgtype.Map, buf []byte, oid uint32, arg any) ([]byte, error) { + if anynil.Is(arg) { + return pgio.AppendInt32(buf, -1), nil + } + + sp := len(buf) + buf = pgio.AppendInt32(buf, -1) + argBuf, err := m.Encode(oid, BinaryFormatCode, arg, buf) + if err != nil { + if argBuf2, err2 := tryScanStringCopyValueThenEncode(m, buf, oid, arg); err2 == nil { + argBuf = argBuf2 + } else { + return nil, err + } + } + + if argBuf != nil { + buf = argBuf + pgio.SetInt32(buf[sp:], int32(len(buf[sp:])-4)) + } + return buf, nil +} + +func tryScanStringCopyValueThenEncode(m *pgtype.Map, buf []byte, oid uint32, arg any) ([]byte, error) { + s, ok := arg.(string) + if !ok { + return nil, errors.New("not a string") + } + + var v any + err := m.Scan(oid, TextFormatCode, []byte(s), &v) + if err != nil { + return nil, err + } + + return m.Encode(oid, BinaryFormatCode, v, buf) +} diff --git a/vendor/github.com/lib/pq/.gitignore b/vendor/github.com/lib/pq/.gitignore deleted file mode 100644 index 3243952a4d6..00000000000 --- a/vendor/github.com/lib/pq/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -.db -*.test -*~ -*.swp -.idea -.vscode \ No newline at end of file diff --git a/vendor/github.com/lib/pq/LICENSE.md b/vendor/github.com/lib/pq/LICENSE.md deleted file mode 100644 index 5773904a30e..00000000000 --- a/vendor/github.com/lib/pq/LICENSE.md +++ /dev/null @@ -1,8 +0,0 @@ -Copyright (c) 2011-2013, 'pq' Contributors -Portions Copyright (C) 2011 Blake Mizerany - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/lib/pq/README.md b/vendor/github.com/lib/pq/README.md deleted file mode 100644 index 126ee5d35d1..00000000000 --- a/vendor/github.com/lib/pq/README.md +++ /dev/null @@ -1,36 +0,0 @@ -# pq - A pure Go postgres driver for Go's database/sql package - -[![GoDoc](https://godoc.org/github.com/lib/pq?status.svg)](https://pkg.go.dev/github.com/lib/pq?tab=doc) - -## Install - - go get github.com/lib/pq - -## Features - -* SSL -* Handles bad connections for `database/sql` -* Scan `time.Time` correctly (i.e. `timestamp[tz]`, `time[tz]`, `date`) -* Scan binary blobs correctly (i.e. `bytea`) -* Package for `hstore` support -* COPY FROM support -* pq.ParseURL for converting urls to connection strings for sql.Open. -* Many libpq compatible environment variables -* Unix socket support -* Notifications: `LISTEN`/`NOTIFY` -* pgpass support -* GSS (Kerberos) auth - -## Tests - -`go test` is used for testing. See [TESTS.md](TESTS.md) for more details. - -## Status - -This package is currently in maintenance mode, which means: -1. It generally does not accept new features. -2. It does accept bug fixes and version compatability changes provided by the community. -3. Maintainers usually do not resolve reported issues. -4. Community members are encouraged to help each other with reported issues. - -For users that require new features or reliable resolution of reported bugs, we recommend using [pgx](https://github.com/jackc/pgx) which is under active development. diff --git a/vendor/github.com/lib/pq/TESTS.md b/vendor/github.com/lib/pq/TESTS.md deleted file mode 100644 index f05021115be..00000000000 --- a/vendor/github.com/lib/pq/TESTS.md +++ /dev/null @@ -1,33 +0,0 @@ -# Tests - -## Running Tests - -`go test` is used for testing. A running PostgreSQL -server is required, with the ability to log in. The -database to connect to test with is "pqgotest," on -"localhost" but these can be overridden using [environment -variables](https://www.postgresql.org/docs/9.3/static/libpq-envars.html). - -Example: - - PGHOST=/run/postgresql go test - -## Benchmarks - -A benchmark suite can be run as part of the tests: - - go test -bench . - -## Example setup (Docker) - -Run a postgres container: - -``` -docker run --expose 5432:5432 postgres -``` - -Run tests: - -``` -PGHOST=localhost PGPORT=5432 PGUSER=postgres PGSSLMODE=disable PGDATABASE=postgres go test -``` diff --git a/vendor/github.com/lib/pq/array.go b/vendor/github.com/lib/pq/array.go deleted file mode 100644 index 39c8f7e2e03..00000000000 --- a/vendor/github.com/lib/pq/array.go +++ /dev/null @@ -1,895 +0,0 @@ -package pq - -import ( - "bytes" - "database/sql" - "database/sql/driver" - "encoding/hex" - "fmt" - "reflect" - "strconv" - "strings" -) - -var typeByteSlice = reflect.TypeOf([]byte{}) -var typeDriverValuer = reflect.TypeOf((*driver.Valuer)(nil)).Elem() -var typeSQLScanner = reflect.TypeOf((*sql.Scanner)(nil)).Elem() - -// Array returns the optimal driver.Valuer and sql.Scanner for an array or -// slice of any dimension. -// -// For example: -// db.Query(`SELECT * FROM t WHERE id = ANY($1)`, pq.Array([]int{235, 401})) -// -// var x []sql.NullInt64 -// db.QueryRow(`SELECT ARRAY[235, 401]`).Scan(pq.Array(&x)) -// -// Scanning multi-dimensional arrays is not supported. Arrays where the lower -// bound is not one (such as `[0:0]={1}') are not supported. -func Array(a interface{}) interface { - driver.Valuer - sql.Scanner -} { - switch a := a.(type) { - case []bool: - return (*BoolArray)(&a) - case []float64: - return (*Float64Array)(&a) - case []float32: - return (*Float32Array)(&a) - case []int64: - return (*Int64Array)(&a) - case []int32: - return (*Int32Array)(&a) - case []string: - return (*StringArray)(&a) - case [][]byte: - return (*ByteaArray)(&a) - - case *[]bool: - return (*BoolArray)(a) - case *[]float64: - return (*Float64Array)(a) - case *[]float32: - return (*Float32Array)(a) - case *[]int64: - return (*Int64Array)(a) - case *[]int32: - return (*Int32Array)(a) - case *[]string: - return (*StringArray)(a) - case *[][]byte: - return (*ByteaArray)(a) - } - - return GenericArray{a} -} - -// ArrayDelimiter may be optionally implemented by driver.Valuer or sql.Scanner -// to override the array delimiter used by GenericArray. -type ArrayDelimiter interface { - // ArrayDelimiter returns the delimiter character(s) for this element's type. - ArrayDelimiter() string -} - -// BoolArray represents a one-dimensional array of the PostgreSQL boolean type. -type BoolArray []bool - -// Scan implements the sql.Scanner interface. -func (a *BoolArray) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - return a.scanBytes(src) - case string: - return a.scanBytes([]byte(src)) - case nil: - *a = nil - return nil - } - - return fmt.Errorf("pq: cannot convert %T to BoolArray", src) -} - -func (a *BoolArray) scanBytes(src []byte) error { - elems, err := scanLinearArray(src, []byte{','}, "BoolArray") - if err != nil { - return err - } - if *a != nil && len(elems) == 0 { - *a = (*a)[:0] - } else { - b := make(BoolArray, len(elems)) - for i, v := range elems { - if len(v) != 1 { - return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", i, v) - } - switch v[0] { - case 't': - b[i] = true - case 'f': - b[i] = false - default: - return fmt.Errorf("pq: could not parse boolean array index %d: invalid boolean %q", i, v) - } - } - *a = b - } - return nil -} - -// Value implements the driver.Valuer interface. -func (a BoolArray) Value() (driver.Value, error) { - if a == nil { - return nil, nil - } - - if n := len(a); n > 0 { - // There will be exactly two curly brackets, N bytes of values, - // and N-1 bytes of delimiters. - b := make([]byte, 1+2*n) - - for i := 0; i < n; i++ { - b[2*i] = ',' - if a[i] { - b[1+2*i] = 't' - } else { - b[1+2*i] = 'f' - } - } - - b[0] = '{' - b[2*n] = '}' - - return string(b), nil - } - - return "{}", nil -} - -// ByteaArray represents a one-dimensional array of the PostgreSQL bytea type. -type ByteaArray [][]byte - -// Scan implements the sql.Scanner interface. -func (a *ByteaArray) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - return a.scanBytes(src) - case string: - return a.scanBytes([]byte(src)) - case nil: - *a = nil - return nil - } - - return fmt.Errorf("pq: cannot convert %T to ByteaArray", src) -} - -func (a *ByteaArray) scanBytes(src []byte) error { - elems, err := scanLinearArray(src, []byte{','}, "ByteaArray") - if err != nil { - return err - } - if *a != nil && len(elems) == 0 { - *a = (*a)[:0] - } else { - b := make(ByteaArray, len(elems)) - for i, v := range elems { - b[i], err = parseBytea(v) - if err != nil { - return fmt.Errorf("could not parse bytea array index %d: %s", i, err.Error()) - } - } - *a = b - } - return nil -} - -// Value implements the driver.Valuer interface. It uses the "hex" format which -// is only supported on PostgreSQL 9.0 or newer. -func (a ByteaArray) Value() (driver.Value, error) { - if a == nil { - return nil, nil - } - - if n := len(a); n > 0 { - // There will be at least two curly brackets, 2*N bytes of quotes, - // 3*N bytes of hex formatting, and N-1 bytes of delimiters. - size := 1 + 6*n - for _, x := range a { - size += hex.EncodedLen(len(x)) - } - - b := make([]byte, size) - - for i, s := 0, b; i < n; i++ { - o := copy(s, `,"\\x`) - o += hex.Encode(s[o:], a[i]) - s[o] = '"' - s = s[o+1:] - } - - b[0] = '{' - b[size-1] = '}' - - return string(b), nil - } - - return "{}", nil -} - -// Float64Array represents a one-dimensional array of the PostgreSQL double -// precision type. -type Float64Array []float64 - -// Scan implements the sql.Scanner interface. -func (a *Float64Array) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - return a.scanBytes(src) - case string: - return a.scanBytes([]byte(src)) - case nil: - *a = nil - return nil - } - - return fmt.Errorf("pq: cannot convert %T to Float64Array", src) -} - -func (a *Float64Array) scanBytes(src []byte) error { - elems, err := scanLinearArray(src, []byte{','}, "Float64Array") - if err != nil { - return err - } - if *a != nil && len(elems) == 0 { - *a = (*a)[:0] - } else { - b := make(Float64Array, len(elems)) - for i, v := range elems { - if b[i], err = strconv.ParseFloat(string(v), 64); err != nil { - return fmt.Errorf("pq: parsing array element index %d: %v", i, err) - } - } - *a = b - } - return nil -} - -// Value implements the driver.Valuer interface. -func (a Float64Array) Value() (driver.Value, error) { - if a == nil { - return nil, nil - } - - if n := len(a); n > 0 { - // There will be at least two curly brackets, N bytes of values, - // and N-1 bytes of delimiters. - b := make([]byte, 1, 1+2*n) - b[0] = '{' - - b = strconv.AppendFloat(b, a[0], 'f', -1, 64) - for i := 1; i < n; i++ { - b = append(b, ',') - b = strconv.AppendFloat(b, a[i], 'f', -1, 64) - } - - return string(append(b, '}')), nil - } - - return "{}", nil -} - -// Float32Array represents a one-dimensional array of the PostgreSQL double -// precision type. -type Float32Array []float32 - -// Scan implements the sql.Scanner interface. -func (a *Float32Array) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - return a.scanBytes(src) - case string: - return a.scanBytes([]byte(src)) - case nil: - *a = nil - return nil - } - - return fmt.Errorf("pq: cannot convert %T to Float32Array", src) -} - -func (a *Float32Array) scanBytes(src []byte) error { - elems, err := scanLinearArray(src, []byte{','}, "Float32Array") - if err != nil { - return err - } - if *a != nil && len(elems) == 0 { - *a = (*a)[:0] - } else { - b := make(Float32Array, len(elems)) - for i, v := range elems { - var x float64 - if x, err = strconv.ParseFloat(string(v), 32); err != nil { - return fmt.Errorf("pq: parsing array element index %d: %v", i, err) - } - b[i] = float32(x) - } - *a = b - } - return nil -} - -// Value implements the driver.Valuer interface. -func (a Float32Array) Value() (driver.Value, error) { - if a == nil { - return nil, nil - } - - if n := len(a); n > 0 { - // There will be at least two curly brackets, N bytes of values, - // and N-1 bytes of delimiters. - b := make([]byte, 1, 1+2*n) - b[0] = '{' - - b = strconv.AppendFloat(b, float64(a[0]), 'f', -1, 32) - for i := 1; i < n; i++ { - b = append(b, ',') - b = strconv.AppendFloat(b, float64(a[i]), 'f', -1, 32) - } - - return string(append(b, '}')), nil - } - - return "{}", nil -} - -// GenericArray implements the driver.Valuer and sql.Scanner interfaces for -// an array or slice of any dimension. -type GenericArray struct{ A interface{} } - -func (GenericArray) evaluateDestination(rt reflect.Type) (reflect.Type, func([]byte, reflect.Value) error, string) { - var assign func([]byte, reflect.Value) error - var del = "," - - // TODO calculate the assign function for other types - // TODO repeat this section on the element type of arrays or slices (multidimensional) - { - if reflect.PtrTo(rt).Implements(typeSQLScanner) { - // dest is always addressable because it is an element of a slice. - assign = func(src []byte, dest reflect.Value) (err error) { - ss := dest.Addr().Interface().(sql.Scanner) - if src == nil { - err = ss.Scan(nil) - } else { - err = ss.Scan(src) - } - return - } - goto FoundType - } - - assign = func([]byte, reflect.Value) error { - return fmt.Errorf("pq: scanning to %s is not implemented; only sql.Scanner", rt) - } - } - -FoundType: - - if ad, ok := reflect.Zero(rt).Interface().(ArrayDelimiter); ok { - del = ad.ArrayDelimiter() - } - - return rt, assign, del -} - -// Scan implements the sql.Scanner interface. -func (a GenericArray) Scan(src interface{}) error { - dpv := reflect.ValueOf(a.A) - switch { - case dpv.Kind() != reflect.Ptr: - return fmt.Errorf("pq: destination %T is not a pointer to array or slice", a.A) - case dpv.IsNil(): - return fmt.Errorf("pq: destination %T is nil", a.A) - } - - dv := dpv.Elem() - switch dv.Kind() { - case reflect.Slice: - case reflect.Array: - default: - return fmt.Errorf("pq: destination %T is not a pointer to array or slice", a.A) - } - - switch src := src.(type) { - case []byte: - return a.scanBytes(src, dv) - case string: - return a.scanBytes([]byte(src), dv) - case nil: - if dv.Kind() == reflect.Slice { - dv.Set(reflect.Zero(dv.Type())) - return nil - } - } - - return fmt.Errorf("pq: cannot convert %T to %s", src, dv.Type()) -} - -func (a GenericArray) scanBytes(src []byte, dv reflect.Value) error { - dtype, assign, del := a.evaluateDestination(dv.Type().Elem()) - dims, elems, err := parseArray(src, []byte(del)) - if err != nil { - return err - } - - // TODO allow multidimensional - - if len(dims) > 1 { - return fmt.Errorf("pq: scanning from multidimensional ARRAY%s is not implemented", - strings.Replace(fmt.Sprint(dims), " ", "][", -1)) - } - - // Treat a zero-dimensional array like an array with a single dimension of zero. - if len(dims) == 0 { - dims = append(dims, 0) - } - - for i, rt := 0, dv.Type(); i < len(dims); i, rt = i+1, rt.Elem() { - switch rt.Kind() { - case reflect.Slice: - case reflect.Array: - if rt.Len() != dims[i] { - return fmt.Errorf("pq: cannot convert ARRAY%s to %s", - strings.Replace(fmt.Sprint(dims), " ", "][", -1), dv.Type()) - } - default: - // TODO handle multidimensional - } - } - - values := reflect.MakeSlice(reflect.SliceOf(dtype), len(elems), len(elems)) - for i, e := range elems { - if err := assign(e, values.Index(i)); err != nil { - return fmt.Errorf("pq: parsing array element index %d: %v", i, err) - } - } - - // TODO handle multidimensional - - switch dv.Kind() { - case reflect.Slice: - dv.Set(values.Slice(0, dims[0])) - case reflect.Array: - for i := 0; i < dims[0]; i++ { - dv.Index(i).Set(values.Index(i)) - } - } - - return nil -} - -// Value implements the driver.Valuer interface. -func (a GenericArray) Value() (driver.Value, error) { - if a.A == nil { - return nil, nil - } - - rv := reflect.ValueOf(a.A) - - switch rv.Kind() { - case reflect.Slice: - if rv.IsNil() { - return nil, nil - } - case reflect.Array: - default: - return nil, fmt.Errorf("pq: Unable to convert %T to array", a.A) - } - - if n := rv.Len(); n > 0 { - // There will be at least two curly brackets, N bytes of values, - // and N-1 bytes of delimiters. - b := make([]byte, 0, 1+2*n) - - b, _, err := appendArray(b, rv, n) - return string(b), err - } - - return "{}", nil -} - -// Int64Array represents a one-dimensional array of the PostgreSQL integer types. -type Int64Array []int64 - -// Scan implements the sql.Scanner interface. -func (a *Int64Array) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - return a.scanBytes(src) - case string: - return a.scanBytes([]byte(src)) - case nil: - *a = nil - return nil - } - - return fmt.Errorf("pq: cannot convert %T to Int64Array", src) -} - -func (a *Int64Array) scanBytes(src []byte) error { - elems, err := scanLinearArray(src, []byte{','}, "Int64Array") - if err != nil { - return err - } - if *a != nil && len(elems) == 0 { - *a = (*a)[:0] - } else { - b := make(Int64Array, len(elems)) - for i, v := range elems { - if b[i], err = strconv.ParseInt(string(v), 10, 64); err != nil { - return fmt.Errorf("pq: parsing array element index %d: %v", i, err) - } - } - *a = b - } - return nil -} - -// Value implements the driver.Valuer interface. -func (a Int64Array) Value() (driver.Value, error) { - if a == nil { - return nil, nil - } - - if n := len(a); n > 0 { - // There will be at least two curly brackets, N bytes of values, - // and N-1 bytes of delimiters. - b := make([]byte, 1, 1+2*n) - b[0] = '{' - - b = strconv.AppendInt(b, a[0], 10) - for i := 1; i < n; i++ { - b = append(b, ',') - b = strconv.AppendInt(b, a[i], 10) - } - - return string(append(b, '}')), nil - } - - return "{}", nil -} - -// Int32Array represents a one-dimensional array of the PostgreSQL integer types. -type Int32Array []int32 - -// Scan implements the sql.Scanner interface. -func (a *Int32Array) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - return a.scanBytes(src) - case string: - return a.scanBytes([]byte(src)) - case nil: - *a = nil - return nil - } - - return fmt.Errorf("pq: cannot convert %T to Int32Array", src) -} - -func (a *Int32Array) scanBytes(src []byte) error { - elems, err := scanLinearArray(src, []byte{','}, "Int32Array") - if err != nil { - return err - } - if *a != nil && len(elems) == 0 { - *a = (*a)[:0] - } else { - b := make(Int32Array, len(elems)) - for i, v := range elems { - x, err := strconv.ParseInt(string(v), 10, 32) - if err != nil { - return fmt.Errorf("pq: parsing array element index %d: %v", i, err) - } - b[i] = int32(x) - } - *a = b - } - return nil -} - -// Value implements the driver.Valuer interface. -func (a Int32Array) Value() (driver.Value, error) { - if a == nil { - return nil, nil - } - - if n := len(a); n > 0 { - // There will be at least two curly brackets, N bytes of values, - // and N-1 bytes of delimiters. - b := make([]byte, 1, 1+2*n) - b[0] = '{' - - b = strconv.AppendInt(b, int64(a[0]), 10) - for i := 1; i < n; i++ { - b = append(b, ',') - b = strconv.AppendInt(b, int64(a[i]), 10) - } - - return string(append(b, '}')), nil - } - - return "{}", nil -} - -// StringArray represents a one-dimensional array of the PostgreSQL character types. -type StringArray []string - -// Scan implements the sql.Scanner interface. -func (a *StringArray) Scan(src interface{}) error { - switch src := src.(type) { - case []byte: - return a.scanBytes(src) - case string: - return a.scanBytes([]byte(src)) - case nil: - *a = nil - return nil - } - - return fmt.Errorf("pq: cannot convert %T to StringArray", src) -} - -func (a *StringArray) scanBytes(src []byte) error { - elems, err := scanLinearArray(src, []byte{','}, "StringArray") - if err != nil { - return err - } - if *a != nil && len(elems) == 0 { - *a = (*a)[:0] - } else { - b := make(StringArray, len(elems)) - for i, v := range elems { - if b[i] = string(v); v == nil { - return fmt.Errorf("pq: parsing array element index %d: cannot convert nil to string", i) - } - } - *a = b - } - return nil -} - -// Value implements the driver.Valuer interface. -func (a StringArray) Value() (driver.Value, error) { - if a == nil { - return nil, nil - } - - if n := len(a); n > 0 { - // There will be at least two curly brackets, 2*N bytes of quotes, - // and N-1 bytes of delimiters. - b := make([]byte, 1, 1+3*n) - b[0] = '{' - - b = appendArrayQuotedBytes(b, []byte(a[0])) - for i := 1; i < n; i++ { - b = append(b, ',') - b = appendArrayQuotedBytes(b, []byte(a[i])) - } - - return string(append(b, '}')), nil - } - - return "{}", nil -} - -// appendArray appends rv to the buffer, returning the extended buffer and -// the delimiter used between elements. -// -// It panics when n <= 0 or rv's Kind is not reflect.Array nor reflect.Slice. -func appendArray(b []byte, rv reflect.Value, n int) ([]byte, string, error) { - var del string - var err error - - b = append(b, '{') - - if b, del, err = appendArrayElement(b, rv.Index(0)); err != nil { - return b, del, err - } - - for i := 1; i < n; i++ { - b = append(b, del...) - if b, del, err = appendArrayElement(b, rv.Index(i)); err != nil { - return b, del, err - } - } - - return append(b, '}'), del, nil -} - -// appendArrayElement appends rv to the buffer, returning the extended buffer -// and the delimiter to use before the next element. -// -// When rv's Kind is neither reflect.Array nor reflect.Slice, it is converted -// using driver.DefaultParameterConverter and the resulting []byte or string -// is double-quoted. -// -// See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO -func appendArrayElement(b []byte, rv reflect.Value) ([]byte, string, error) { - if k := rv.Kind(); k == reflect.Array || k == reflect.Slice { - if t := rv.Type(); t != typeByteSlice && !t.Implements(typeDriverValuer) { - if n := rv.Len(); n > 0 { - return appendArray(b, rv, n) - } - - return b, "", nil - } - } - - var del = "," - var err error - var iv interface{} = rv.Interface() - - if ad, ok := iv.(ArrayDelimiter); ok { - del = ad.ArrayDelimiter() - } - - if iv, err = driver.DefaultParameterConverter.ConvertValue(iv); err != nil { - return b, del, err - } - - switch v := iv.(type) { - case nil: - return append(b, "NULL"...), del, nil - case []byte: - return appendArrayQuotedBytes(b, v), del, nil - case string: - return appendArrayQuotedBytes(b, []byte(v)), del, nil - } - - b, err = appendValue(b, iv) - return b, del, err -} - -func appendArrayQuotedBytes(b, v []byte) []byte { - b = append(b, '"') - for { - i := bytes.IndexAny(v, `"\`) - if i < 0 { - b = append(b, v...) - break - } - if i > 0 { - b = append(b, v[:i]...) - } - b = append(b, '\\', v[i]) - v = v[i+1:] - } - return append(b, '"') -} - -func appendValue(b []byte, v driver.Value) ([]byte, error) { - return append(b, encode(nil, v, 0)...), nil -} - -// parseArray extracts the dimensions and elements of an array represented in -// text format. Only representations emitted by the backend are supported. -// Notably, whitespace around brackets and delimiters is significant, and NULL -// is case-sensitive. -// -// See http://www.postgresql.org/docs/current/static/arrays.html#ARRAYS-IO -func parseArray(src, del []byte) (dims []int, elems [][]byte, err error) { - var depth, i int - - if len(src) < 1 || src[0] != '{' { - return nil, nil, fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '{', 0) - } - -Open: - for i < len(src) { - switch src[i] { - case '{': - depth++ - i++ - case '}': - elems = make([][]byte, 0) - goto Close - default: - break Open - } - } - dims = make([]int, i) - -Element: - for i < len(src) { - switch src[i] { - case '{': - if depth == len(dims) { - break Element - } - depth++ - dims[depth-1] = 0 - i++ - case '"': - var elem = []byte{} - var escape bool - for i++; i < len(src); i++ { - if escape { - elem = append(elem, src[i]) - escape = false - } else { - switch src[i] { - default: - elem = append(elem, src[i]) - case '\\': - escape = true - case '"': - elems = append(elems, elem) - i++ - break Element - } - } - } - default: - for start := i; i < len(src); i++ { - if bytes.HasPrefix(src[i:], del) || src[i] == '}' { - elem := src[start:i] - if len(elem) == 0 { - return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i) - } - if bytes.Equal(elem, []byte("NULL")) { - elem = nil - } - elems = append(elems, elem) - break Element - } - } - } - } - - for i < len(src) { - if bytes.HasPrefix(src[i:], del) && depth > 0 { - dims[depth-1]++ - i += len(del) - goto Element - } else if src[i] == '}' && depth > 0 { - dims[depth-1]++ - depth-- - i++ - } else { - return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i) - } - } - -Close: - for i < len(src) { - if src[i] == '}' && depth > 0 { - depth-- - i++ - } else { - return nil, nil, fmt.Errorf("pq: unable to parse array; unexpected %q at offset %d", src[i], i) - } - } - if depth > 0 { - err = fmt.Errorf("pq: unable to parse array; expected %q at offset %d", '}', i) - } - if err == nil { - for _, d := range dims { - if (len(elems) % d) != 0 { - err = fmt.Errorf("pq: multidimensional arrays must have elements with matching dimensions") - } - } - } - return -} - -func scanLinearArray(src, del []byte, typ string) (elems [][]byte, err error) { - dims, elems, err := parseArray(src, del) - if err != nil { - return nil, err - } - if len(dims) > 1 { - return nil, fmt.Errorf("pq: cannot convert ARRAY%s to %s", strings.Replace(fmt.Sprint(dims), " ", "][", -1), typ) - } - return elems, err -} diff --git a/vendor/github.com/lib/pq/buf.go b/vendor/github.com/lib/pq/buf.go deleted file mode 100644 index 4b0a0a8f7e9..00000000000 --- a/vendor/github.com/lib/pq/buf.go +++ /dev/null @@ -1,91 +0,0 @@ -package pq - -import ( - "bytes" - "encoding/binary" - - "github.com/lib/pq/oid" -) - -type readBuf []byte - -func (b *readBuf) int32() (n int) { - n = int(int32(binary.BigEndian.Uint32(*b))) - *b = (*b)[4:] - return -} - -func (b *readBuf) oid() (n oid.Oid) { - n = oid.Oid(binary.BigEndian.Uint32(*b)) - *b = (*b)[4:] - return -} - -// N.B: this is actually an unsigned 16-bit integer, unlike int32 -func (b *readBuf) int16() (n int) { - n = int(binary.BigEndian.Uint16(*b)) - *b = (*b)[2:] - return -} - -func (b *readBuf) string() string { - i := bytes.IndexByte(*b, 0) - if i < 0 { - errorf("invalid message format; expected string terminator") - } - s := (*b)[:i] - *b = (*b)[i+1:] - return string(s) -} - -func (b *readBuf) next(n int) (v []byte) { - v = (*b)[:n] - *b = (*b)[n:] - return -} - -func (b *readBuf) byte() byte { - return b.next(1)[0] -} - -type writeBuf struct { - buf []byte - pos int -} - -func (b *writeBuf) int32(n int) { - x := make([]byte, 4) - binary.BigEndian.PutUint32(x, uint32(n)) - b.buf = append(b.buf, x...) -} - -func (b *writeBuf) int16(n int) { - x := make([]byte, 2) - binary.BigEndian.PutUint16(x, uint16(n)) - b.buf = append(b.buf, x...) -} - -func (b *writeBuf) string(s string) { - b.buf = append(append(b.buf, s...), '\000') -} - -func (b *writeBuf) byte(c byte) { - b.buf = append(b.buf, c) -} - -func (b *writeBuf) bytes(v []byte) { - b.buf = append(b.buf, v...) -} - -func (b *writeBuf) wrap() []byte { - p := b.buf[b.pos:] - binary.BigEndian.PutUint32(p, uint32(len(p))) - return b.buf -} - -func (b *writeBuf) next(c byte) { - p := b.buf[b.pos:] - binary.BigEndian.PutUint32(p, uint32(len(p))) - b.pos = len(b.buf) + 1 - b.buf = append(b.buf, c, 0, 0, 0, 0) -} diff --git a/vendor/github.com/lib/pq/conn.go b/vendor/github.com/lib/pq/conn.go deleted file mode 100644 index da4ff9de603..00000000000 --- a/vendor/github.com/lib/pq/conn.go +++ /dev/null @@ -1,2112 +0,0 @@ -package pq - -import ( - "bufio" - "bytes" - "context" - "crypto/md5" - "crypto/sha256" - "database/sql" - "database/sql/driver" - "encoding/binary" - "errors" - "fmt" - "io" - "net" - "os" - "os/user" - "path" - "path/filepath" - "strconv" - "strings" - "sync" - "time" - "unicode" - - "github.com/lib/pq/oid" - "github.com/lib/pq/scram" -) - -// Common error types -var ( - ErrNotSupported = errors.New("pq: Unsupported command") - ErrInFailedTransaction = errors.New("pq: Could not complete operation in a failed transaction") - ErrSSLNotSupported = errors.New("pq: SSL is not enabled on the server") - ErrSSLKeyUnknownOwnership = errors.New("pq: Could not get owner information for private key, may not be properly protected") - ErrSSLKeyHasWorldPermissions = errors.New("pq: Private key has world access. Permissions should be u=rw,g=r (0640) if owned by root, or u=rw (0600), or less") - - ErrCouldNotDetectUsername = errors.New("pq: Could not detect default username. Please provide one explicitly") - - errUnexpectedReady = errors.New("unexpected ReadyForQuery") - errNoRowsAffected = errors.New("no RowsAffected available after the empty statement") - errNoLastInsertID = errors.New("no LastInsertId available after the empty statement") -) - -// Compile time validation that our types implement the expected interfaces -var ( - _ driver.Driver = Driver{} -) - -// Driver is the Postgres database driver. -type Driver struct{} - -// Open opens a new connection to the database. name is a connection string. -// Most users should only use it through database/sql package from the standard -// library. -func (d Driver) Open(name string) (driver.Conn, error) { - return Open(name) -} - -func init() { - sql.Register("postgres", &Driver{}) -} - -type parameterStatus struct { - // server version in the same format as server_version_num, or 0 if - // unavailable - serverVersion int - - // the current location based on the TimeZone value of the session, if - // available - currentLocation *time.Location -} - -type transactionStatus byte - -const ( - txnStatusIdle transactionStatus = 'I' - txnStatusIdleInTransaction transactionStatus = 'T' - txnStatusInFailedTransaction transactionStatus = 'E' -) - -func (s transactionStatus) String() string { - switch s { - case txnStatusIdle: - return "idle" - case txnStatusIdleInTransaction: - return "idle in transaction" - case txnStatusInFailedTransaction: - return "in a failed transaction" - default: - errorf("unknown transactionStatus %d", s) - } - - panic("not reached") -} - -// Dialer is the dialer interface. It can be used to obtain more control over -// how pq creates network connections. -type Dialer interface { - Dial(network, address string) (net.Conn, error) - DialTimeout(network, address string, timeout time.Duration) (net.Conn, error) -} - -// DialerContext is the context-aware dialer interface. -type DialerContext interface { - DialContext(ctx context.Context, network, address string) (net.Conn, error) -} - -type defaultDialer struct { - d net.Dialer -} - -func (d defaultDialer) Dial(network, address string) (net.Conn, error) { - return d.d.Dial(network, address) -} -func (d defaultDialer) DialTimeout( - network, address string, timeout time.Duration, -) (net.Conn, error) { - ctx, cancel := context.WithTimeout(context.Background(), timeout) - defer cancel() - return d.DialContext(ctx, network, address) -} -func (d defaultDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { - return d.d.DialContext(ctx, network, address) -} - -type conn struct { - c net.Conn - buf *bufio.Reader - namei int - scratch [512]byte - txnStatus transactionStatus - txnFinish func() - - // Save connection arguments to use during CancelRequest. - dialer Dialer - opts values - - // Cancellation key data for use with CancelRequest messages. - processID int - secretKey int - - parameterStatus parameterStatus - - saveMessageType byte - saveMessageBuffer []byte - - // If an error is set, this connection is bad and all public-facing - // functions should return the appropriate error by calling get() - // (ErrBadConn) or getForNext(). - err syncErr - - // If set, this connection should never use the binary format when - // receiving query results from prepared statements. Only provided for - // debugging. - disablePreparedBinaryResult bool - - // Whether to always send []byte parameters over as binary. Enables single - // round-trip mode for non-prepared Query calls. - binaryParameters bool - - // If true this connection is in the middle of a COPY - inCopy bool - - // If not nil, notices will be synchronously sent here - noticeHandler func(*Error) - - // If not nil, notifications will be synchronously sent here - notificationHandler func(*Notification) - - // GSSAPI context - gss GSS -} - -type syncErr struct { - err error - sync.Mutex -} - -// Return ErrBadConn if connection is bad. -func (e *syncErr) get() error { - e.Lock() - defer e.Unlock() - if e.err != nil { - return driver.ErrBadConn - } - return nil -} - -// Return the error set on the connection. Currently only used by rows.Next. -func (e *syncErr) getForNext() error { - e.Lock() - defer e.Unlock() - return e.err -} - -// Set error, only if it isn't set yet. -func (e *syncErr) set(err error) { - if err == nil { - panic("attempt to set nil err") - } - e.Lock() - defer e.Unlock() - if e.err == nil { - e.err = err - } -} - -// Handle driver-side settings in parsed connection string. -func (cn *conn) handleDriverSettings(o values) (err error) { - boolSetting := func(key string, val *bool) error { - if value, ok := o[key]; ok { - if value == "yes" { - *val = true - } else if value == "no" { - *val = false - } else { - return fmt.Errorf("unrecognized value %q for %s", value, key) - } - } - return nil - } - - err = boolSetting("disable_prepared_binary_result", &cn.disablePreparedBinaryResult) - if err != nil { - return err - } - return boolSetting("binary_parameters", &cn.binaryParameters) -} - -func (cn *conn) handlePgpass(o values) { - // if a password was supplied, do not process .pgpass - if _, ok := o["password"]; ok { - return - } - filename := os.Getenv("PGPASSFILE") - if filename == "" { - // XXX this code doesn't work on Windows where the default filename is - // XXX %APPDATA%\postgresql\pgpass.conf - // Prefer $HOME over user.Current due to glibc bug: golang.org/issue/13470 - userHome := os.Getenv("HOME") - if userHome == "" { - user, err := user.Current() - if err != nil { - return - } - userHome = user.HomeDir - } - filename = filepath.Join(userHome, ".pgpass") - } - fileinfo, err := os.Stat(filename) - if err != nil { - return - } - mode := fileinfo.Mode() - if mode&(0x77) != 0 { - // XXX should warn about incorrect .pgpass permissions as psql does - return - } - file, err := os.Open(filename) - if err != nil { - return - } - defer file.Close() - scanner := bufio.NewScanner(io.Reader(file)) - // From: https://github.com/tg/pgpass/blob/master/reader.go - for scanner.Scan() { - if scanText(scanner.Text(), o) { - break - } - } -} - -// GetFields is a helper function for scanText. -func getFields(s string) []string { - fs := make([]string, 0, 5) - f := make([]rune, 0, len(s)) - - var esc bool - for _, c := range s { - switch { - case esc: - f = append(f, c) - esc = false - case c == '\\': - esc = true - case c == ':': - fs = append(fs, string(f)) - f = f[:0] - default: - f = append(f, c) - } - } - return append(fs, string(f)) -} - -// ScanText assists HandlePgpass in it's objective. -func scanText(line string, o values) bool { - hostname := o["host"] - ntw, _ := network(o) - port := o["port"] - db := o["dbname"] - username := o["user"] - if len(line) == 0 || line[0] == '#' { - return false - } - split := getFields(line) - if len(split) != 5 { - return false - } - if (split[0] == "*" || split[0] == hostname || (split[0] == "localhost" && (hostname == "" || ntw == "unix"))) && (split[1] == "*" || split[1] == port) && (split[2] == "*" || split[2] == db) && (split[3] == "*" || split[3] == username) { - o["password"] = split[4] - return true - } - return false -} - -func (cn *conn) writeBuf(b byte) *writeBuf { - cn.scratch[0] = b - return &writeBuf{ - buf: cn.scratch[:5], - pos: 1, - } -} - -// Open opens a new connection to the database. dsn is a connection string. -// Most users should only use it through database/sql package from the standard -// library. -func Open(dsn string) (_ driver.Conn, err error) { - return DialOpen(defaultDialer{}, dsn) -} - -// DialOpen opens a new connection to the database using a dialer. -func DialOpen(d Dialer, dsn string) (_ driver.Conn, err error) { - c, err := NewConnector(dsn) - if err != nil { - return nil, err - } - c.Dialer(d) - return c.open(context.Background()) -} - -func (c *Connector) open(ctx context.Context) (cn *conn, err error) { - // Handle any panics during connection initialization. Note that we - // specifically do *not* want to use errRecover(), as that would turn any - // connection errors into ErrBadConns, hiding the real error message from - // the user. - defer errRecoverNoErrBadConn(&err) - - // Create a new values map (copy). This makes it so maps in different - // connections do not reference the same underlying data structure, so it - // is safe for multiple connections to concurrently write to their opts. - o := make(values) - for k, v := range c.opts { - o[k] = v - } - - cn = &conn{ - opts: o, - dialer: c.dialer, - } - err = cn.handleDriverSettings(o) - if err != nil { - return nil, err - } - cn.handlePgpass(o) - - cn.c, err = dial(ctx, c.dialer, o) - if err != nil { - return nil, err - } - - err = cn.ssl(o) - if err != nil { - if cn.c != nil { - cn.c.Close() - } - return nil, err - } - - // cn.startup panics on error. Make sure we don't leak cn.c. - panicking := true - defer func() { - if panicking { - cn.c.Close() - } - }() - - cn.buf = bufio.NewReader(cn.c) - cn.startup(o) - - // reset the deadline, in case one was set (see dial) - if timeout, ok := o["connect_timeout"]; ok && timeout != "0" { - err = cn.c.SetDeadline(time.Time{}) - } - panicking = false - return cn, err -} - -func dial(ctx context.Context, d Dialer, o values) (net.Conn, error) { - network, address := network(o) - - // Zero or not specified means wait indefinitely. - if timeout, ok := o["connect_timeout"]; ok && timeout != "0" { - seconds, err := strconv.ParseInt(timeout, 10, 0) - if err != nil { - return nil, fmt.Errorf("invalid value for parameter connect_timeout: %s", err) - } - duration := time.Duration(seconds) * time.Second - - // connect_timeout should apply to the entire connection establishment - // procedure, so we both use a timeout for the TCP connection - // establishment and set a deadline for doing the initial handshake. - // The deadline is then reset after startup() is done. - deadline := time.Now().Add(duration) - var conn net.Conn - if dctx, ok := d.(DialerContext); ok { - ctx, cancel := context.WithTimeout(ctx, duration) - defer cancel() - conn, err = dctx.DialContext(ctx, network, address) - } else { - conn, err = d.DialTimeout(network, address, duration) - } - if err != nil { - return nil, err - } - err = conn.SetDeadline(deadline) - return conn, err - } - if dctx, ok := d.(DialerContext); ok { - return dctx.DialContext(ctx, network, address) - } - return d.Dial(network, address) -} - -func network(o values) (string, string) { - host := o["host"] - - if strings.HasPrefix(host, "/") { - sockPath := path.Join(host, ".s.PGSQL."+o["port"]) - return "unix", sockPath - } - - return "tcp", net.JoinHostPort(host, o["port"]) -} - -type values map[string]string - -// scanner implements a tokenizer for libpq-style option strings. -type scanner struct { - s []rune - i int -} - -// newScanner returns a new scanner initialized with the option string s. -func newScanner(s string) *scanner { - return &scanner{[]rune(s), 0} -} - -// Next returns the next rune. -// It returns 0, false if the end of the text has been reached. -func (s *scanner) Next() (rune, bool) { - if s.i >= len(s.s) { - return 0, false - } - r := s.s[s.i] - s.i++ - return r, true -} - -// SkipSpaces returns the next non-whitespace rune. -// It returns 0, false if the end of the text has been reached. -func (s *scanner) SkipSpaces() (rune, bool) { - r, ok := s.Next() - for unicode.IsSpace(r) && ok { - r, ok = s.Next() - } - return r, ok -} - -// parseOpts parses the options from name and adds them to the values. -// -// The parsing code is based on conninfo_parse from libpq's fe-connect.c -func parseOpts(name string, o values) error { - s := newScanner(name) - - for { - var ( - keyRunes, valRunes []rune - r rune - ok bool - ) - - if r, ok = s.SkipSpaces(); !ok { - break - } - - // Scan the key - for !unicode.IsSpace(r) && r != '=' { - keyRunes = append(keyRunes, r) - if r, ok = s.Next(); !ok { - break - } - } - - // Skip any whitespace if we're not at the = yet - if r != '=' { - r, ok = s.SkipSpaces() - } - - // The current character should be = - if r != '=' || !ok { - return fmt.Errorf(`missing "=" after %q in connection info string"`, string(keyRunes)) - } - - // Skip any whitespace after the = - if r, ok = s.SkipSpaces(); !ok { - // If we reach the end here, the last value is just an empty string as per libpq. - o[string(keyRunes)] = "" - break - } - - if r != '\'' { - for !unicode.IsSpace(r) { - if r == '\\' { - if r, ok = s.Next(); !ok { - return fmt.Errorf(`missing character after backslash`) - } - } - valRunes = append(valRunes, r) - - if r, ok = s.Next(); !ok { - break - } - } - } else { - quote: - for { - if r, ok = s.Next(); !ok { - return fmt.Errorf(`unterminated quoted string literal in connection string`) - } - switch r { - case '\'': - break quote - case '\\': - r, _ = s.Next() - fallthrough - default: - valRunes = append(valRunes, r) - } - } - } - - o[string(keyRunes)] = string(valRunes) - } - - return nil -} - -func (cn *conn) isInTransaction() bool { - return cn.txnStatus == txnStatusIdleInTransaction || - cn.txnStatus == txnStatusInFailedTransaction -} - -func (cn *conn) checkIsInTransaction(intxn bool) { - if cn.isInTransaction() != intxn { - cn.err.set(driver.ErrBadConn) - errorf("unexpected transaction status %v", cn.txnStatus) - } -} - -func (cn *conn) Begin() (_ driver.Tx, err error) { - return cn.begin("") -} - -func (cn *conn) begin(mode string) (_ driver.Tx, err error) { - if err := cn.err.get(); err != nil { - return nil, err - } - defer cn.errRecover(&err) - - cn.checkIsInTransaction(false) - _, commandTag, err := cn.simpleExec("BEGIN" + mode) - if err != nil { - return nil, err - } - if commandTag != "BEGIN" { - cn.err.set(driver.ErrBadConn) - return nil, fmt.Errorf("unexpected command tag %s", commandTag) - } - if cn.txnStatus != txnStatusIdleInTransaction { - cn.err.set(driver.ErrBadConn) - return nil, fmt.Errorf("unexpected transaction status %v", cn.txnStatus) - } - return cn, nil -} - -func (cn *conn) closeTxn() { - if finish := cn.txnFinish; finish != nil { - finish() - } -} - -func (cn *conn) Commit() (err error) { - defer cn.closeTxn() - if err := cn.err.get(); err != nil { - return err - } - defer cn.errRecover(&err) - - cn.checkIsInTransaction(true) - // We don't want the client to think that everything is okay if it tries - // to commit a failed transaction. However, no matter what we return, - // database/sql will release this connection back into the free connection - // pool so we have to abort the current transaction here. Note that you - // would get the same behaviour if you issued a COMMIT in a failed - // transaction, so it's also the least surprising thing to do here. - if cn.txnStatus == txnStatusInFailedTransaction { - if err := cn.rollback(); err != nil { - return err - } - return ErrInFailedTransaction - } - - _, commandTag, err := cn.simpleExec("COMMIT") - if err != nil { - if cn.isInTransaction() { - cn.err.set(driver.ErrBadConn) - } - return err - } - if commandTag != "COMMIT" { - cn.err.set(driver.ErrBadConn) - return fmt.Errorf("unexpected command tag %s", commandTag) - } - cn.checkIsInTransaction(false) - return nil -} - -func (cn *conn) Rollback() (err error) { - defer cn.closeTxn() - if err := cn.err.get(); err != nil { - return err - } - defer cn.errRecover(&err) - return cn.rollback() -} - -func (cn *conn) rollback() (err error) { - cn.checkIsInTransaction(true) - _, commandTag, err := cn.simpleExec("ROLLBACK") - if err != nil { - if cn.isInTransaction() { - cn.err.set(driver.ErrBadConn) - } - return err - } - if commandTag != "ROLLBACK" { - return fmt.Errorf("unexpected command tag %s", commandTag) - } - cn.checkIsInTransaction(false) - return nil -} - -func (cn *conn) gname() string { - cn.namei++ - return strconv.FormatInt(int64(cn.namei), 10) -} - -func (cn *conn) simpleExec(q string) (res driver.Result, commandTag string, err error) { - b := cn.writeBuf('Q') - b.string(q) - cn.send(b) - - for { - t, r := cn.recv1() - switch t { - case 'C': - res, commandTag = cn.parseComplete(r.string()) - case 'Z': - cn.processReadyForQuery(r) - if res == nil && err == nil { - err = errUnexpectedReady - } - // done - return - case 'E': - err = parseError(r) - case 'I': - res = emptyRows - case 'T', 'D': - // ignore any results - default: - cn.err.set(driver.ErrBadConn) - errorf("unknown response for simple query: %q", t) - } - } -} - -func (cn *conn) simpleQuery(q string) (res *rows, err error) { - defer cn.errRecover(&err) - - b := cn.writeBuf('Q') - b.string(q) - cn.send(b) - - for { - t, r := cn.recv1() - switch t { - case 'C', 'I': - // We allow queries which don't return any results through Query as - // well as Exec. We still have to give database/sql a rows object - // the user can close, though, to avoid connections from being - // leaked. A "rows" with done=true works fine for that purpose. - if err != nil { - cn.err.set(driver.ErrBadConn) - errorf("unexpected message %q in simple query execution", t) - } - if res == nil { - res = &rows{ - cn: cn, - } - } - // Set the result and tag to the last command complete if there wasn't a - // query already run. Although queries usually return from here and cede - // control to Next, a query with zero results does not. - if t == 'C' { - res.result, res.tag = cn.parseComplete(r.string()) - if res.colNames != nil { - return - } - } - res.done = true - case 'Z': - cn.processReadyForQuery(r) - // done - return - case 'E': - res = nil - err = parseError(r) - case 'D': - if res == nil { - cn.err.set(driver.ErrBadConn) - errorf("unexpected DataRow in simple query execution") - } - // the query didn't fail; kick off to Next - cn.saveMessage(t, r) - return - case 'T': - // res might be non-nil here if we received a previous - // CommandComplete, but that's fine; just overwrite it - res = &rows{cn: cn} - res.rowsHeader = parsePortalRowDescribe(r) - - // To work around a bug in QueryRow in Go 1.2 and earlier, wait - // until the first DataRow has been received. - default: - cn.err.set(driver.ErrBadConn) - errorf("unknown response for simple query: %q", t) - } - } -} - -type noRows struct{} - -var emptyRows noRows - -var _ driver.Result = noRows{} - -func (noRows) LastInsertId() (int64, error) { - return 0, errNoLastInsertID -} - -func (noRows) RowsAffected() (int64, error) { - return 0, errNoRowsAffected -} - -// Decides which column formats to use for a prepared statement. The input is -// an array of type oids, one element per result column. -func decideColumnFormats( - colTyps []fieldDesc, forceText bool, -) (colFmts []format, colFmtData []byte) { - if len(colTyps) == 0 { - return nil, colFmtDataAllText - } - - colFmts = make([]format, len(colTyps)) - if forceText { - return colFmts, colFmtDataAllText - } - - allBinary := true - allText := true - for i, t := range colTyps { - switch t.OID { - // This is the list of types to use binary mode for when receiving them - // through a prepared statement. If a type appears in this list, it - // must also be implemented in binaryDecode in encode.go. - case oid.T_bytea: - fallthrough - case oid.T_int8: - fallthrough - case oid.T_int4: - fallthrough - case oid.T_int2: - fallthrough - case oid.T_uuid: - colFmts[i] = formatBinary - allText = false - - default: - allBinary = false - } - } - - if allBinary { - return colFmts, colFmtDataAllBinary - } else if allText { - return colFmts, colFmtDataAllText - } else { - colFmtData = make([]byte, 2+len(colFmts)*2) - binary.BigEndian.PutUint16(colFmtData, uint16(len(colFmts))) - for i, v := range colFmts { - binary.BigEndian.PutUint16(colFmtData[2+i*2:], uint16(v)) - } - return colFmts, colFmtData - } -} - -func (cn *conn) prepareTo(q, stmtName string) *stmt { - st := &stmt{cn: cn, name: stmtName} - - b := cn.writeBuf('P') - b.string(st.name) - b.string(q) - b.int16(0) - - b.next('D') - b.byte('S') - b.string(st.name) - - b.next('S') - cn.send(b) - - cn.readParseResponse() - st.paramTyps, st.colNames, st.colTyps = cn.readStatementDescribeResponse() - st.colFmts, st.colFmtData = decideColumnFormats(st.colTyps, cn.disablePreparedBinaryResult) - cn.readReadyForQuery() - return st -} - -func (cn *conn) Prepare(q string) (_ driver.Stmt, err error) { - if err := cn.err.get(); err != nil { - return nil, err - } - defer cn.errRecover(&err) - - if len(q) >= 4 && strings.EqualFold(q[:4], "COPY") { - s, err := cn.prepareCopyIn(q) - if err == nil { - cn.inCopy = true - } - return s, err - } - return cn.prepareTo(q, cn.gname()), nil -} - -func (cn *conn) Close() (err error) { - // Skip cn.bad return here because we always want to close a connection. - defer cn.errRecover(&err) - - // Ensure that cn.c.Close is always run. Since error handling is done with - // panics and cn.errRecover, the Close must be in a defer. - defer func() { - cerr := cn.c.Close() - if err == nil { - err = cerr - } - }() - - // Don't go through send(); ListenerConn relies on us not scribbling on the - // scratch buffer of this connection. - return cn.sendSimpleMessage('X') -} - -// Implement the "Queryer" interface -func (cn *conn) Query(query string, args []driver.Value) (driver.Rows, error) { - return cn.query(query, args) -} - -func (cn *conn) query(query string, args []driver.Value) (_ *rows, err error) { - if err := cn.err.get(); err != nil { - return nil, err - } - if cn.inCopy { - return nil, errCopyInProgress - } - defer cn.errRecover(&err) - - // Check to see if we can use the "simpleQuery" interface, which is - // *much* faster than going through prepare/exec - if len(args) == 0 { - return cn.simpleQuery(query) - } - - if cn.binaryParameters { - cn.sendBinaryModeQuery(query, args) - - cn.readParseResponse() - cn.readBindResponse() - rows := &rows{cn: cn} - rows.rowsHeader = cn.readPortalDescribeResponse() - cn.postExecuteWorkaround() - return rows, nil - } - st := cn.prepareTo(query, "") - st.exec(args) - return &rows{ - cn: cn, - rowsHeader: st.rowsHeader, - }, nil -} - -// Implement the optional "Execer" interface for one-shot queries -func (cn *conn) Exec(query string, args []driver.Value) (res driver.Result, err error) { - if err := cn.err.get(); err != nil { - return nil, err - } - defer cn.errRecover(&err) - - // Check to see if we can use the "simpleExec" interface, which is - // *much* faster than going through prepare/exec - if len(args) == 0 { - // ignore commandTag, our caller doesn't care - r, _, err := cn.simpleExec(query) - return r, err - } - - if cn.binaryParameters { - cn.sendBinaryModeQuery(query, args) - - cn.readParseResponse() - cn.readBindResponse() - cn.readPortalDescribeResponse() - cn.postExecuteWorkaround() - res, _, err = cn.readExecuteResponse("Execute") - return res, err - } - // Use the unnamed statement to defer planning until bind - // time, or else value-based selectivity estimates cannot be - // used. - st := cn.prepareTo(query, "") - r, err := st.Exec(args) - if err != nil { - panic(err) - } - return r, err -} - -type safeRetryError struct { - Err error -} - -func (se *safeRetryError) Error() string { - return se.Err.Error() -} - -func (cn *conn) send(m *writeBuf) { - n, err := cn.c.Write(m.wrap()) - if err != nil { - if n == 0 { - err = &safeRetryError{Err: err} - } - panic(err) - } -} - -func (cn *conn) sendStartupPacket(m *writeBuf) error { - _, err := cn.c.Write((m.wrap())[1:]) - return err -} - -// Send a message of type typ to the server on the other end of cn. The -// message should have no payload. This method does not use the scratch -// buffer. -func (cn *conn) sendSimpleMessage(typ byte) (err error) { - _, err = cn.c.Write([]byte{typ, '\x00', '\x00', '\x00', '\x04'}) - return err -} - -// saveMessage memorizes a message and its buffer in the conn struct. -// recvMessage will then return these values on the next call to it. This -// method is useful in cases where you have to see what the next message is -// going to be (e.g. to see whether it's an error or not) but you can't handle -// the message yourself. -func (cn *conn) saveMessage(typ byte, buf *readBuf) { - if cn.saveMessageType != 0 { - cn.err.set(driver.ErrBadConn) - errorf("unexpected saveMessageType %d", cn.saveMessageType) - } - cn.saveMessageType = typ - cn.saveMessageBuffer = *buf -} - -// recvMessage receives any message from the backend, or returns an error if -// a problem occurred while reading the message. -func (cn *conn) recvMessage(r *readBuf) (byte, error) { - // workaround for a QueryRow bug, see exec - if cn.saveMessageType != 0 { - t := cn.saveMessageType - *r = cn.saveMessageBuffer - cn.saveMessageType = 0 - cn.saveMessageBuffer = nil - return t, nil - } - - x := cn.scratch[:5] - _, err := io.ReadFull(cn.buf, x) - if err != nil { - return 0, err - } - - // read the type and length of the message that follows - t := x[0] - n := int(binary.BigEndian.Uint32(x[1:])) - 4 - var y []byte - if n <= len(cn.scratch) { - y = cn.scratch[:n] - } else { - y = make([]byte, n) - } - _, err = io.ReadFull(cn.buf, y) - if err != nil { - return 0, err - } - *r = y - return t, nil -} - -// recv receives a message from the backend, but if an error happened while -// reading the message or the received message was an ErrorResponse, it panics. -// NoticeResponses are ignored. This function should generally be used only -// during the startup sequence. -func (cn *conn) recv() (t byte, r *readBuf) { - for { - var err error - r = &readBuf{} - t, err = cn.recvMessage(r) - if err != nil { - panic(err) - } - switch t { - case 'E': - panic(parseError(r)) - case 'N': - if n := cn.noticeHandler; n != nil { - n(parseError(r)) - } - case 'A': - if n := cn.notificationHandler; n != nil { - n(recvNotification(r)) - } - default: - return - } - } -} - -// recv1Buf is exactly equivalent to recv1, except it uses a buffer supplied by -// the caller to avoid an allocation. -func (cn *conn) recv1Buf(r *readBuf) byte { - for { - t, err := cn.recvMessage(r) - if err != nil { - panic(err) - } - - switch t { - case 'A': - if n := cn.notificationHandler; n != nil { - n(recvNotification(r)) - } - case 'N': - if n := cn.noticeHandler; n != nil { - n(parseError(r)) - } - case 'S': - cn.processParameterStatus(r) - default: - return t - } - } -} - -// recv1 receives a message from the backend, panicking if an error occurs -// while attempting to read it. All asynchronous messages are ignored, with -// the exception of ErrorResponse. -func (cn *conn) recv1() (t byte, r *readBuf) { - r = &readBuf{} - t = cn.recv1Buf(r) - return t, r -} - -func (cn *conn) ssl(o values) error { - upgrade, err := ssl(o) - if err != nil { - return err - } - - if upgrade == nil { - // Nothing to do - return nil - } - - w := cn.writeBuf(0) - w.int32(80877103) - if err = cn.sendStartupPacket(w); err != nil { - return err - } - - b := cn.scratch[:1] - _, err = io.ReadFull(cn.c, b) - if err != nil { - return err - } - - if b[0] != 'S' { - return ErrSSLNotSupported - } - - cn.c, err = upgrade(cn.c) - return err -} - -// isDriverSetting returns true iff a setting is purely for configuring the -// driver's options and should not be sent to the server in the connection -// startup packet. -func isDriverSetting(key string) bool { - switch key { - case "host", "port": - return true - case "password": - return true - case "sslmode", "sslcert", "sslkey", "sslrootcert", "sslinline", "sslsni": - return true - case "fallback_application_name": - return true - case "connect_timeout": - return true - case "disable_prepared_binary_result": - return true - case "binary_parameters": - return true - case "krbsrvname": - return true - case "krbspn": - return true - default: - return false - } -} - -func (cn *conn) startup(o values) { - w := cn.writeBuf(0) - w.int32(196608) - // Send the backend the name of the database we want to connect to, and the - // user we want to connect as. Additionally, we send over any run-time - // parameters potentially included in the connection string. If the server - // doesn't recognize any of them, it will reply with an error. - for k, v := range o { - if isDriverSetting(k) { - // skip options which can't be run-time parameters - continue - } - // The protocol requires us to supply the database name as "database" - // instead of "dbname". - if k == "dbname" { - k = "database" - } - w.string(k) - w.string(v) - } - w.string("") - if err := cn.sendStartupPacket(w); err != nil { - panic(err) - } - - for { - t, r := cn.recv() - switch t { - case 'K': - cn.processBackendKeyData(r) - case 'S': - cn.processParameterStatus(r) - case 'R': - cn.auth(r, o) - case 'Z': - cn.processReadyForQuery(r) - return - default: - errorf("unknown response for startup: %q", t) - } - } -} - -func (cn *conn) auth(r *readBuf, o values) { - switch code := r.int32(); code { - case 0: - // OK - case 3: - w := cn.writeBuf('p') - w.string(o["password"]) - cn.send(w) - - t, r := cn.recv() - if t != 'R' { - errorf("unexpected password response: %q", t) - } - - if r.int32() != 0 { - errorf("unexpected authentication response: %q", t) - } - case 5: - s := string(r.next(4)) - w := cn.writeBuf('p') - w.string("md5" + md5s(md5s(o["password"]+o["user"])+s)) - cn.send(w) - - t, r := cn.recv() - if t != 'R' { - errorf("unexpected password response: %q", t) - } - - if r.int32() != 0 { - errorf("unexpected authentication response: %q", t) - } - case 7: // GSSAPI, startup - if newGss == nil { - errorf("kerberos error: no GSSAPI provider registered (import github.com/lib/pq/auth/kerberos if you need Kerberos support)") - } - cli, err := newGss() - if err != nil { - errorf("kerberos error: %s", err.Error()) - } - - var token []byte - - if spn, ok := o["krbspn"]; ok { - // Use the supplied SPN if provided.. - token, err = cli.GetInitTokenFromSpn(spn) - } else { - // Allow the kerberos service name to be overridden - service := "postgres" - if val, ok := o["krbsrvname"]; ok { - service = val - } - - token, err = cli.GetInitToken(o["host"], service) - } - - if err != nil { - errorf("failed to get Kerberos ticket: %q", err) - } - - w := cn.writeBuf('p') - w.bytes(token) - cn.send(w) - - // Store for GSSAPI continue message - cn.gss = cli - - case 8: // GSSAPI continue - - if cn.gss == nil { - errorf("GSSAPI protocol error") - } - - b := []byte(*r) - - done, tokOut, err := cn.gss.Continue(b) - if err == nil && !done { - w := cn.writeBuf('p') - w.bytes(tokOut) - cn.send(w) - } - - // Errors fall through and read the more detailed message - // from the server.. - - case 10: - sc := scram.NewClient(sha256.New, o["user"], o["password"]) - sc.Step(nil) - if sc.Err() != nil { - errorf("SCRAM-SHA-256 error: %s", sc.Err().Error()) - } - scOut := sc.Out() - - w := cn.writeBuf('p') - w.string("SCRAM-SHA-256") - w.int32(len(scOut)) - w.bytes(scOut) - cn.send(w) - - t, r := cn.recv() - if t != 'R' { - errorf("unexpected password response: %q", t) - } - - if r.int32() != 11 { - errorf("unexpected authentication response: %q", t) - } - - nextStep := r.next(len(*r)) - sc.Step(nextStep) - if sc.Err() != nil { - errorf("SCRAM-SHA-256 error: %s", sc.Err().Error()) - } - - scOut = sc.Out() - w = cn.writeBuf('p') - w.bytes(scOut) - cn.send(w) - - t, r = cn.recv() - if t != 'R' { - errorf("unexpected password response: %q", t) - } - - if r.int32() != 12 { - errorf("unexpected authentication response: %q", t) - } - - nextStep = r.next(len(*r)) - sc.Step(nextStep) - if sc.Err() != nil { - errorf("SCRAM-SHA-256 error: %s", sc.Err().Error()) - } - - default: - errorf("unknown authentication response: %d", code) - } -} - -type format int - -const formatText format = 0 -const formatBinary format = 1 - -// One result-column format code with the value 1 (i.e. all binary). -var colFmtDataAllBinary = []byte{0, 1, 0, 1} - -// No result-column format codes (i.e. all text). -var colFmtDataAllText = []byte{0, 0} - -type stmt struct { - cn *conn - name string - rowsHeader - colFmtData []byte - paramTyps []oid.Oid - closed bool -} - -func (st *stmt) Close() (err error) { - if st.closed { - return nil - } - if err := st.cn.err.get(); err != nil { - return err - } - defer st.cn.errRecover(&err) - - w := st.cn.writeBuf('C') - w.byte('S') - w.string(st.name) - st.cn.send(w) - - st.cn.send(st.cn.writeBuf('S')) - - t, _ := st.cn.recv1() - if t != '3' { - st.cn.err.set(driver.ErrBadConn) - errorf("unexpected close response: %q", t) - } - st.closed = true - - t, r := st.cn.recv1() - if t != 'Z' { - st.cn.err.set(driver.ErrBadConn) - errorf("expected ready for query, but got: %q", t) - } - st.cn.processReadyForQuery(r) - - return nil -} - -func (st *stmt) Query(v []driver.Value) (r driver.Rows, err error) { - return st.query(v) -} - -func (st *stmt) query(v []driver.Value) (r *rows, err error) { - if err := st.cn.err.get(); err != nil { - return nil, err - } - defer st.cn.errRecover(&err) - - st.exec(v) - return &rows{ - cn: st.cn, - rowsHeader: st.rowsHeader, - }, nil -} - -func (st *stmt) Exec(v []driver.Value) (res driver.Result, err error) { - if err := st.cn.err.get(); err != nil { - return nil, err - } - defer st.cn.errRecover(&err) - - st.exec(v) - res, _, err = st.cn.readExecuteResponse("simple query") - return res, err -} - -func (st *stmt) exec(v []driver.Value) { - if len(v) >= 65536 { - errorf("got %d parameters but PostgreSQL only supports 65535 parameters", len(v)) - } - if len(v) != len(st.paramTyps) { - errorf("got %d parameters but the statement requires %d", len(v), len(st.paramTyps)) - } - - cn := st.cn - w := cn.writeBuf('B') - w.byte(0) // unnamed portal - w.string(st.name) - - if cn.binaryParameters { - cn.sendBinaryParameters(w, v) - } else { - w.int16(0) - w.int16(len(v)) - for i, x := range v { - if x == nil { - w.int32(-1) - } else { - b := encode(&cn.parameterStatus, x, st.paramTyps[i]) - w.int32(len(b)) - w.bytes(b) - } - } - } - w.bytes(st.colFmtData) - - w.next('E') - w.byte(0) - w.int32(0) - - w.next('S') - cn.send(w) - - cn.readBindResponse() - cn.postExecuteWorkaround() - -} - -func (st *stmt) NumInput() int { - return len(st.paramTyps) -} - -// parseComplete parses the "command tag" from a CommandComplete message, and -// returns the number of rows affected (if applicable) and a string -// identifying only the command that was executed, e.g. "ALTER TABLE". If the -// command tag could not be parsed, parseComplete panics. -func (cn *conn) parseComplete(commandTag string) (driver.Result, string) { - commandsWithAffectedRows := []string{ - "SELECT ", - // INSERT is handled below - "UPDATE ", - "DELETE ", - "FETCH ", - "MOVE ", - "COPY ", - } - - var affectedRows *string - for _, tag := range commandsWithAffectedRows { - if strings.HasPrefix(commandTag, tag) { - t := commandTag[len(tag):] - affectedRows = &t - commandTag = tag[:len(tag)-1] - break - } - } - // INSERT also includes the oid of the inserted row in its command tag. - // Oids in user tables are deprecated, and the oid is only returned when - // exactly one row is inserted, so it's unlikely to be of value to any - // real-world application and we can ignore it. - if affectedRows == nil && strings.HasPrefix(commandTag, "INSERT ") { - parts := strings.Split(commandTag, " ") - if len(parts) != 3 { - cn.err.set(driver.ErrBadConn) - errorf("unexpected INSERT command tag %s", commandTag) - } - affectedRows = &parts[len(parts)-1] - commandTag = "INSERT" - } - // There should be no affected rows attached to the tag, just return it - if affectedRows == nil { - return driver.RowsAffected(0), commandTag - } - n, err := strconv.ParseInt(*affectedRows, 10, 64) - if err != nil { - cn.err.set(driver.ErrBadConn) - errorf("could not parse commandTag: %s", err) - } - return driver.RowsAffected(n), commandTag -} - -type rowsHeader struct { - colNames []string - colTyps []fieldDesc - colFmts []format -} - -type rows struct { - cn *conn - finish func() - rowsHeader - done bool - rb readBuf - result driver.Result - tag string - - next *rowsHeader -} - -func (rs *rows) Close() error { - if finish := rs.finish; finish != nil { - defer finish() - } - // no need to look at cn.bad as Next() will - for { - err := rs.Next(nil) - switch err { - case nil: - case io.EOF: - // rs.Next can return io.EOF on both 'Z' (ready for query) and 'T' (row - // description, used with HasNextResultSet). We need to fetch messages until - // we hit a 'Z', which is done by waiting for done to be set. - if rs.done { - return nil - } - default: - return err - } - } -} - -func (rs *rows) Columns() []string { - return rs.colNames -} - -func (rs *rows) Result() driver.Result { - if rs.result == nil { - return emptyRows - } - return rs.result -} - -func (rs *rows) Tag() string { - return rs.tag -} - -func (rs *rows) Next(dest []driver.Value) (err error) { - if rs.done { - return io.EOF - } - - conn := rs.cn - if err := conn.err.getForNext(); err != nil { - return err - } - defer conn.errRecover(&err) - - for { - t := conn.recv1Buf(&rs.rb) - switch t { - case 'E': - err = parseError(&rs.rb) - case 'C', 'I': - if t == 'C' { - rs.result, rs.tag = conn.parseComplete(rs.rb.string()) - } - continue - case 'Z': - conn.processReadyForQuery(&rs.rb) - rs.done = true - if err != nil { - return err - } - return io.EOF - case 'D': - n := rs.rb.int16() - if err != nil { - conn.err.set(driver.ErrBadConn) - errorf("unexpected DataRow after error %s", err) - } - if n < len(dest) { - dest = dest[:n] - } - for i := range dest { - l := rs.rb.int32() - if l == -1 { - dest[i] = nil - continue - } - dest[i] = decode(&conn.parameterStatus, rs.rb.next(l), rs.colTyps[i].OID, rs.colFmts[i]) - } - return - case 'T': - next := parsePortalRowDescribe(&rs.rb) - rs.next = &next - return io.EOF - default: - errorf("unexpected message after execute: %q", t) - } - } -} - -func (rs *rows) HasNextResultSet() bool { - hasNext := rs.next != nil && !rs.done - return hasNext -} - -func (rs *rows) NextResultSet() error { - if rs.next == nil { - return io.EOF - } - rs.rowsHeader = *rs.next - rs.next = nil - return nil -} - -// QuoteIdentifier quotes an "identifier" (e.g. a table or a column name) to be -// used as part of an SQL statement. For example: -// -// tblname := "my_table" -// data := "my_data" -// quoted := pq.QuoteIdentifier(tblname) -// err := db.Exec(fmt.Sprintf("INSERT INTO %s VALUES ($1)", quoted), data) -// -// Any double quotes in name will be escaped. The quoted identifier will be -// case sensitive when used in a query. If the input string contains a zero -// byte, the result will be truncated immediately before it. -func QuoteIdentifier(name string) string { - end := strings.IndexRune(name, 0) - if end > -1 { - name = name[:end] - } - return `"` + strings.Replace(name, `"`, `""`, -1) + `"` -} - -// BufferQuoteIdentifier satisfies the same purpose as QuoteIdentifier, but backed by a -// byte buffer. -func BufferQuoteIdentifier(name string, buffer *bytes.Buffer) { - end := strings.IndexRune(name, 0) - if end > -1 { - name = name[:end] - } - buffer.WriteRune('"') - buffer.WriteString(strings.Replace(name, `"`, `""`, -1)) - buffer.WriteRune('"') -} - -// QuoteLiteral quotes a 'literal' (e.g. a parameter, often used to pass literal -// to DDL and other statements that do not accept parameters) to be used as part -// of an SQL statement. For example: -// -// exp_date := pq.QuoteLiteral("2023-01-05 15:00:00Z") -// err := db.Exec(fmt.Sprintf("CREATE ROLE my_user VALID UNTIL %s", exp_date)) -// -// Any single quotes in name will be escaped. Any backslashes (i.e. "\") will be -// replaced by two backslashes (i.e. "\\") and the C-style escape identifier -// that PostgreSQL provides ('E') will be prepended to the string. -func QuoteLiteral(literal string) string { - // This follows the PostgreSQL internal algorithm for handling quoted literals - // from libpq, which can be found in the "PQEscapeStringInternal" function, - // which is found in the libpq/fe-exec.c source file: - // https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/interfaces/libpq/fe-exec.c - // - // substitute any single-quotes (') with two single-quotes ('') - literal = strings.Replace(literal, `'`, `''`, -1) - // determine if the string has any backslashes (\) in it. - // if it does, replace any backslashes (\) with two backslashes (\\) - // then, we need to wrap the entire string with a PostgreSQL - // C-style escape. Per how "PQEscapeStringInternal" handles this case, we - // also add a space before the "E" - if strings.Contains(literal, `\`) { - literal = strings.Replace(literal, `\`, `\\`, -1) - literal = ` E'` + literal + `'` - } else { - // otherwise, we can just wrap the literal with a pair of single quotes - literal = `'` + literal + `'` - } - return literal -} - -func md5s(s string) string { - h := md5.New() - h.Write([]byte(s)) - return fmt.Sprintf("%x", h.Sum(nil)) -} - -func (cn *conn) sendBinaryParameters(b *writeBuf, args []driver.Value) { - // Do one pass over the parameters to see if we're going to send any of - // them over in binary. If we are, create a paramFormats array at the - // same time. - var paramFormats []int - for i, x := range args { - _, ok := x.([]byte) - if ok { - if paramFormats == nil { - paramFormats = make([]int, len(args)) - } - paramFormats[i] = 1 - } - } - if paramFormats == nil { - b.int16(0) - } else { - b.int16(len(paramFormats)) - for _, x := range paramFormats { - b.int16(x) - } - } - - b.int16(len(args)) - for _, x := range args { - if x == nil { - b.int32(-1) - } else { - datum := binaryEncode(&cn.parameterStatus, x) - b.int32(len(datum)) - b.bytes(datum) - } - } -} - -func (cn *conn) sendBinaryModeQuery(query string, args []driver.Value) { - if len(args) >= 65536 { - errorf("got %d parameters but PostgreSQL only supports 65535 parameters", len(args)) - } - - b := cn.writeBuf('P') - b.byte(0) // unnamed statement - b.string(query) - b.int16(0) - - b.next('B') - b.int16(0) // unnamed portal and statement - cn.sendBinaryParameters(b, args) - b.bytes(colFmtDataAllText) - - b.next('D') - b.byte('P') - b.byte(0) // unnamed portal - - b.next('E') - b.byte(0) - b.int32(0) - - b.next('S') - cn.send(b) -} - -func (cn *conn) processParameterStatus(r *readBuf) { - var err error - - param := r.string() - switch param { - case "server_version": - var major1 int - var major2 int - _, err = fmt.Sscanf(r.string(), "%d.%d", &major1, &major2) - if err == nil { - cn.parameterStatus.serverVersion = major1*10000 + major2*100 - } - - case "TimeZone": - cn.parameterStatus.currentLocation, err = time.LoadLocation(r.string()) - if err != nil { - cn.parameterStatus.currentLocation = nil - } - - default: - // ignore - } -} - -func (cn *conn) processReadyForQuery(r *readBuf) { - cn.txnStatus = transactionStatus(r.byte()) -} - -func (cn *conn) readReadyForQuery() { - t, r := cn.recv1() - switch t { - case 'Z': - cn.processReadyForQuery(r) - return - default: - cn.err.set(driver.ErrBadConn) - errorf("unexpected message %q; expected ReadyForQuery", t) - } -} - -func (cn *conn) processBackendKeyData(r *readBuf) { - cn.processID = r.int32() - cn.secretKey = r.int32() -} - -func (cn *conn) readParseResponse() { - t, r := cn.recv1() - switch t { - case '1': - return - case 'E': - err := parseError(r) - cn.readReadyForQuery() - panic(err) - default: - cn.err.set(driver.ErrBadConn) - errorf("unexpected Parse response %q", t) - } -} - -func (cn *conn) readStatementDescribeResponse() ( - paramTyps []oid.Oid, - colNames []string, - colTyps []fieldDesc, -) { - for { - t, r := cn.recv1() - switch t { - case 't': - nparams := r.int16() - paramTyps = make([]oid.Oid, nparams) - for i := range paramTyps { - paramTyps[i] = r.oid() - } - case 'n': - return paramTyps, nil, nil - case 'T': - colNames, colTyps = parseStatementRowDescribe(r) - return paramTyps, colNames, colTyps - case 'E': - err := parseError(r) - cn.readReadyForQuery() - panic(err) - default: - cn.err.set(driver.ErrBadConn) - errorf("unexpected Describe statement response %q", t) - } - } -} - -func (cn *conn) readPortalDescribeResponse() rowsHeader { - t, r := cn.recv1() - switch t { - case 'T': - return parsePortalRowDescribe(r) - case 'n': - return rowsHeader{} - case 'E': - err := parseError(r) - cn.readReadyForQuery() - panic(err) - default: - cn.err.set(driver.ErrBadConn) - errorf("unexpected Describe response %q", t) - } - panic("not reached") -} - -func (cn *conn) readBindResponse() { - t, r := cn.recv1() - switch t { - case '2': - return - case 'E': - err := parseError(r) - cn.readReadyForQuery() - panic(err) - default: - cn.err.set(driver.ErrBadConn) - errorf("unexpected Bind response %q", t) - } -} - -func (cn *conn) postExecuteWorkaround() { - // Work around a bug in sql.DB.QueryRow: in Go 1.2 and earlier it ignores - // any errors from rows.Next, which masks errors that happened during the - // execution of the query. To avoid the problem in common cases, we wait - // here for one more message from the database. If it's not an error the - // query will likely succeed (or perhaps has already, if it's a - // CommandComplete), so we push the message into the conn struct; recv1 - // will return it as the next message for rows.Next or rows.Close. - // However, if it's an error, we wait until ReadyForQuery and then return - // the error to our caller. - for { - t, r := cn.recv1() - switch t { - case 'E': - err := parseError(r) - cn.readReadyForQuery() - panic(err) - case 'C', 'D', 'I': - // the query didn't fail, but we can't process this message - cn.saveMessage(t, r) - return - default: - cn.err.set(driver.ErrBadConn) - errorf("unexpected message during extended query execution: %q", t) - } - } -} - -// Only for Exec(), since we ignore the returned data -func (cn *conn) readExecuteResponse( - protocolState string, -) (res driver.Result, commandTag string, err error) { - for { - t, r := cn.recv1() - switch t { - case 'C': - if err != nil { - cn.err.set(driver.ErrBadConn) - errorf("unexpected CommandComplete after error %s", err) - } - res, commandTag = cn.parseComplete(r.string()) - case 'Z': - cn.processReadyForQuery(r) - if res == nil && err == nil { - err = errUnexpectedReady - } - return res, commandTag, err - case 'E': - err = parseError(r) - case 'T', 'D', 'I': - if err != nil { - cn.err.set(driver.ErrBadConn) - errorf("unexpected %q after error %s", t, err) - } - if t == 'I' { - res = emptyRows - } - // ignore any results - default: - cn.err.set(driver.ErrBadConn) - errorf("unknown %s response: %q", protocolState, t) - } - } -} - -func parseStatementRowDescribe(r *readBuf) (colNames []string, colTyps []fieldDesc) { - n := r.int16() - colNames = make([]string, n) - colTyps = make([]fieldDesc, n) - for i := range colNames { - colNames[i] = r.string() - r.next(6) - colTyps[i].OID = r.oid() - colTyps[i].Len = r.int16() - colTyps[i].Mod = r.int32() - // format code not known when describing a statement; always 0 - r.next(2) - } - return -} - -func parsePortalRowDescribe(r *readBuf) rowsHeader { - n := r.int16() - colNames := make([]string, n) - colFmts := make([]format, n) - colTyps := make([]fieldDesc, n) - for i := range colNames { - colNames[i] = r.string() - r.next(6) - colTyps[i].OID = r.oid() - colTyps[i].Len = r.int16() - colTyps[i].Mod = r.int32() - colFmts[i] = format(r.int16()) - } - return rowsHeader{ - colNames: colNames, - colFmts: colFmts, - colTyps: colTyps, - } -} - -// parseEnviron tries to mimic some of libpq's environment handling -// -// To ease testing, it does not directly reference os.Environ, but is -// designed to accept its output. -// -// Environment-set connection information is intended to have a higher -// precedence than a library default but lower than any explicitly -// passed information (such as in the URL or connection string). -func parseEnviron(env []string) (out map[string]string) { - out = make(map[string]string) - - for _, v := range env { - parts := strings.SplitN(v, "=", 2) - - accrue := func(keyname string) { - out[keyname] = parts[1] - } - unsupported := func() { - panic(fmt.Sprintf("setting %v not supported", parts[0])) - } - - // The order of these is the same as is seen in the - // PostgreSQL 9.1 manual. Unsupported but well-defined - // keys cause a panic; these should be unset prior to - // execution. Options which pq expects to be set to a - // certain value are allowed, but must be set to that - // value if present (they can, of course, be absent). - switch parts[0] { - case "PGHOST": - accrue("host") - case "PGHOSTADDR": - unsupported() - case "PGPORT": - accrue("port") - case "PGDATABASE": - accrue("dbname") - case "PGUSER": - accrue("user") - case "PGPASSWORD": - accrue("password") - case "PGSERVICE", "PGSERVICEFILE", "PGREALM": - unsupported() - case "PGOPTIONS": - accrue("options") - case "PGAPPNAME": - accrue("application_name") - case "PGSSLMODE": - accrue("sslmode") - case "PGSSLCERT": - accrue("sslcert") - case "PGSSLKEY": - accrue("sslkey") - case "PGSSLROOTCERT": - accrue("sslrootcert") - case "PGSSLSNI": - accrue("sslsni") - case "PGREQUIRESSL", "PGSSLCRL": - unsupported() - case "PGREQUIREPEER": - unsupported() - case "PGKRBSRVNAME", "PGGSSLIB": - unsupported() - case "PGCONNECT_TIMEOUT": - accrue("connect_timeout") - case "PGCLIENTENCODING": - accrue("client_encoding") - case "PGDATESTYLE": - accrue("datestyle") - case "PGTZ": - accrue("timezone") - case "PGGEQO": - accrue("geqo") - case "PGSYSCONFDIR", "PGLOCALEDIR": - unsupported() - } - } - - return out -} - -// isUTF8 returns whether name is a fuzzy variation of the string "UTF-8". -func isUTF8(name string) bool { - // Recognize all sorts of silly things as "UTF-8", like Postgres does - s := strings.Map(alnumLowerASCII, name) - return s == "utf8" || s == "unicode" -} - -func alnumLowerASCII(ch rune) rune { - if 'A' <= ch && ch <= 'Z' { - return ch + ('a' - 'A') - } - if 'a' <= ch && ch <= 'z' || '0' <= ch && ch <= '9' { - return ch - } - return -1 // discard -} - -// The database/sql/driver package says: -// All Conn implementations should implement the following interfaces: Pinger, SessionResetter, and Validator. -var _ driver.Pinger = &conn{} -var _ driver.SessionResetter = &conn{} - -func (cn *conn) ResetSession(ctx context.Context) error { - // Ensure bad connections are reported: From database/sql/driver: - // If a connection is never returned to the connection pool but immediately reused, then - // ResetSession is called prior to reuse but IsValid is not called. - return cn.err.get() -} - -func (cn *conn) IsValid() bool { - return cn.err.get() == nil -} diff --git a/vendor/github.com/lib/pq/conn_go115.go b/vendor/github.com/lib/pq/conn_go115.go deleted file mode 100644 index f4ef030f990..00000000000 --- a/vendor/github.com/lib/pq/conn_go115.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build go1.15 -// +build go1.15 - -package pq - -import "database/sql/driver" - -var _ driver.Validator = &conn{} diff --git a/vendor/github.com/lib/pq/conn_go18.go b/vendor/github.com/lib/pq/conn_go18.go deleted file mode 100644 index 63d4ca6aaa0..00000000000 --- a/vendor/github.com/lib/pq/conn_go18.go +++ /dev/null @@ -1,247 +0,0 @@ -package pq - -import ( - "context" - "database/sql" - "database/sql/driver" - "fmt" - "io" - "io/ioutil" - "time" -) - -const ( - watchCancelDialContextTimeout = time.Second * 10 -) - -// Implement the "QueryerContext" interface -func (cn *conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { - list := make([]driver.Value, len(args)) - for i, nv := range args { - list[i] = nv.Value - } - finish := cn.watchCancel(ctx) - r, err := cn.query(query, list) - if err != nil { - if finish != nil { - finish() - } - return nil, err - } - r.finish = finish - return r, nil -} - -// Implement the "ExecerContext" interface -func (cn *conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { - list := make([]driver.Value, len(args)) - for i, nv := range args { - list[i] = nv.Value - } - - if finish := cn.watchCancel(ctx); finish != nil { - defer finish() - } - - return cn.Exec(query, list) -} - -// Implement the "ConnPrepareContext" interface -func (cn *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { - if finish := cn.watchCancel(ctx); finish != nil { - defer finish() - } - return cn.Prepare(query) -} - -// Implement the "ConnBeginTx" interface -func (cn *conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) { - var mode string - - switch sql.IsolationLevel(opts.Isolation) { - case sql.LevelDefault: - // Don't touch mode: use the server's default - case sql.LevelReadUncommitted: - mode = " ISOLATION LEVEL READ UNCOMMITTED" - case sql.LevelReadCommitted: - mode = " ISOLATION LEVEL READ COMMITTED" - case sql.LevelRepeatableRead: - mode = " ISOLATION LEVEL REPEATABLE READ" - case sql.LevelSerializable: - mode = " ISOLATION LEVEL SERIALIZABLE" - default: - return nil, fmt.Errorf("pq: isolation level not supported: %d", opts.Isolation) - } - - if opts.ReadOnly { - mode += " READ ONLY" - } else { - mode += " READ WRITE" - } - - tx, err := cn.begin(mode) - if err != nil { - return nil, err - } - cn.txnFinish = cn.watchCancel(ctx) - return tx, nil -} - -func (cn *conn) Ping(ctx context.Context) error { - if finish := cn.watchCancel(ctx); finish != nil { - defer finish() - } - rows, err := cn.simpleQuery(";") - if err != nil { - return driver.ErrBadConn // https://golang.org/pkg/database/sql/driver/#Pinger - } - rows.Close() - return nil -} - -func (cn *conn) watchCancel(ctx context.Context) func() { - if done := ctx.Done(); done != nil { - finished := make(chan struct{}, 1) - go func() { - select { - case <-done: - select { - case finished <- struct{}{}: - default: - // We raced with the finish func, let the next query handle this with the - // context. - return - } - - // Set the connection state to bad so it does not get reused. - cn.err.set(ctx.Err()) - - // At this point the function level context is canceled, - // so it must not be used for the additional network - // request to cancel the query. - // Create a new context to pass into the dial. - ctxCancel, cancel := context.WithTimeout(context.Background(), watchCancelDialContextTimeout) - defer cancel() - - _ = cn.cancel(ctxCancel) - case <-finished: - } - }() - return func() { - select { - case <-finished: - cn.err.set(ctx.Err()) - cn.Close() - case finished <- struct{}{}: - } - } - } - return nil -} - -func (cn *conn) cancel(ctx context.Context) error { - // Create a new values map (copy). This makes sure the connection created - // in this method cannot write to the same underlying data, which could - // cause a concurrent map write panic. This is necessary because cancel - // is called from a goroutine in watchCancel. - o := make(values) - for k, v := range cn.opts { - o[k] = v - } - - c, err := dial(ctx, cn.dialer, o) - if err != nil { - return err - } - defer c.Close() - - { - can := conn{ - c: c, - } - err = can.ssl(o) - if err != nil { - return err - } - - w := can.writeBuf(0) - w.int32(80877102) // cancel request code - w.int32(cn.processID) - w.int32(cn.secretKey) - - if err := can.sendStartupPacket(w); err != nil { - return err - } - } - - // Read until EOF to ensure that the server received the cancel. - { - _, err := io.Copy(ioutil.Discard, c) - return err - } -} - -// Implement the "StmtQueryContext" interface -func (st *stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { - list := make([]driver.Value, len(args)) - for i, nv := range args { - list[i] = nv.Value - } - finish := st.watchCancel(ctx) - r, err := st.query(list) - if err != nil { - if finish != nil { - finish() - } - return nil, err - } - r.finish = finish - return r, nil -} - -// Implement the "StmtExecContext" interface -func (st *stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { - list := make([]driver.Value, len(args)) - for i, nv := range args { - list[i] = nv.Value - } - - if finish := st.watchCancel(ctx); finish != nil { - defer finish() - } - - return st.Exec(list) -} - -// watchCancel is implemented on stmt in order to not mark the parent conn as bad -func (st *stmt) watchCancel(ctx context.Context) func() { - if done := ctx.Done(); done != nil { - finished := make(chan struct{}) - go func() { - select { - case <-done: - // At this point the function level context is canceled, - // so it must not be used for the additional network - // request to cancel the query. - // Create a new context to pass into the dial. - ctxCancel, cancel := context.WithTimeout(context.Background(), watchCancelDialContextTimeout) - defer cancel() - - _ = st.cancel(ctxCancel) - finished <- struct{}{} - case <-finished: - } - }() - return func() { - select { - case <-finished: - case finished <- struct{}{}: - } - } - } - return nil -} - -func (st *stmt) cancel(ctx context.Context) error { - return st.cn.cancel(ctx) -} diff --git a/vendor/github.com/lib/pq/connector.go b/vendor/github.com/lib/pq/connector.go deleted file mode 100644 index 1145e12257a..00000000000 --- a/vendor/github.com/lib/pq/connector.go +++ /dev/null @@ -1,120 +0,0 @@ -package pq - -import ( - "context" - "database/sql/driver" - "errors" - "fmt" - "os" - "strings" -) - -// Connector represents a fixed configuration for the pq driver with a given -// name. Connector satisfies the database/sql/driver Connector interface and -// can be used to create any number of DB Conn's via the database/sql OpenDB -// function. -// -// See https://golang.org/pkg/database/sql/driver/#Connector. -// See https://golang.org/pkg/database/sql/#OpenDB. -type Connector struct { - opts values - dialer Dialer -} - -// Connect returns a connection to the database using the fixed configuration -// of this Connector. Context is not used. -func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) { - return c.open(ctx) -} - -// Dialer allows change the dialer used to open connections. -func (c *Connector) Dialer(dialer Dialer) { - c.dialer = dialer -} - -// Driver returns the underlying driver of this Connector. -func (c *Connector) Driver() driver.Driver { - return &Driver{} -} - -// NewConnector returns a connector for the pq driver in a fixed configuration -// with the given dsn. The returned connector can be used to create any number -// of equivalent Conn's. The returned connector is intended to be used with -// database/sql.OpenDB. -// -// See https://golang.org/pkg/database/sql/driver/#Connector. -// See https://golang.org/pkg/database/sql/#OpenDB. -func NewConnector(dsn string) (*Connector, error) { - var err error - o := make(values) - - // A number of defaults are applied here, in this order: - // - // * Very low precedence defaults applied in every situation - // * Environment variables - // * Explicitly passed connection information - o["host"] = "localhost" - o["port"] = "5432" - // N.B.: Extra float digits should be set to 3, but that breaks - // Postgres 8.4 and older, where the max is 2. - o["extra_float_digits"] = "2" - for k, v := range parseEnviron(os.Environ()) { - o[k] = v - } - - if strings.HasPrefix(dsn, "postgres://") || strings.HasPrefix(dsn, "postgresql://") { - dsn, err = ParseURL(dsn) - if err != nil { - return nil, err - } - } - - if err := parseOpts(dsn, o); err != nil { - return nil, err - } - - // Use the "fallback" application name if necessary - if fallback, ok := o["fallback_application_name"]; ok { - if _, ok := o["application_name"]; !ok { - o["application_name"] = fallback - } - } - - // We can't work with any client_encoding other than UTF-8 currently. - // However, we have historically allowed the user to set it to UTF-8 - // explicitly, and there's no reason to break such programs, so allow that. - // Note that the "options" setting could also set client_encoding, but - // parsing its value is not worth it. Instead, we always explicitly send - // client_encoding as a separate run-time parameter, which should override - // anything set in options. - if enc, ok := o["client_encoding"]; ok && !isUTF8(enc) { - return nil, errors.New("client_encoding must be absent or 'UTF8'") - } - o["client_encoding"] = "UTF8" - // DateStyle needs a similar treatment. - if datestyle, ok := o["datestyle"]; ok { - if datestyle != "ISO, MDY" { - return nil, fmt.Errorf("setting datestyle must be absent or %v; got %v", "ISO, MDY", datestyle) - } - } else { - o["datestyle"] = "ISO, MDY" - } - - // If a user is not provided by any other means, the last - // resort is to use the current operating system provided user - // name. - if _, ok := o["user"]; !ok { - u, err := userCurrent() - if err != nil { - return nil, err - } - o["user"] = u - } - - // SSL is not necessary or supported over UNIX domain sockets - if network, _ := network(o); network == "unix" { - o["sslmode"] = "disable" - } - - return &Connector{opts: o, dialer: defaultDialer{}}, nil -} diff --git a/vendor/github.com/lib/pq/copy.go b/vendor/github.com/lib/pq/copy.go deleted file mode 100644 index a8f16b2b26b..00000000000 --- a/vendor/github.com/lib/pq/copy.go +++ /dev/null @@ -1,348 +0,0 @@ -package pq - -import ( - "bytes" - "context" - "database/sql/driver" - "encoding/binary" - "errors" - "fmt" - "sync" -) - -var ( - errCopyInClosed = errors.New("pq: copyin statement has already been closed") - errBinaryCopyNotSupported = errors.New("pq: only text format supported for COPY") - errCopyToNotSupported = errors.New("pq: COPY TO is not supported") - errCopyNotSupportedOutsideTxn = errors.New("pq: COPY is only allowed inside a transaction") - errCopyInProgress = errors.New("pq: COPY in progress") -) - -// CopyIn creates a COPY FROM statement which can be prepared with -// Tx.Prepare(). The target table should be visible in search_path. -func CopyIn(table string, columns ...string) string { - buffer := bytes.NewBufferString("COPY ") - BufferQuoteIdentifier(table, buffer) - buffer.WriteString(" (") - makeStmt(buffer, columns...) - return buffer.String() -} - -// MakeStmt makes the stmt string for CopyIn and CopyInSchema. -func makeStmt(buffer *bytes.Buffer, columns ...string) { - //s := bytes.NewBufferString() - for i, col := range columns { - if i != 0 { - buffer.WriteString(", ") - } - BufferQuoteIdentifier(col, buffer) - } - buffer.WriteString(") FROM STDIN") -} - -// CopyInSchema creates a COPY FROM statement which can be prepared with -// Tx.Prepare(). -func CopyInSchema(schema, table string, columns ...string) string { - buffer := bytes.NewBufferString("COPY ") - BufferQuoteIdentifier(schema, buffer) - buffer.WriteRune('.') - BufferQuoteIdentifier(table, buffer) - buffer.WriteString(" (") - makeStmt(buffer, columns...) - return buffer.String() -} - -type copyin struct { - cn *conn - buffer []byte - rowData chan []byte - done chan bool - - closed bool - - mu struct { - sync.Mutex - err error - driver.Result - } -} - -const ciBufferSize = 64 * 1024 - -// flush buffer before the buffer is filled up and needs reallocation -const ciBufferFlushSize = 63 * 1024 - -func (cn *conn) prepareCopyIn(q string) (_ driver.Stmt, err error) { - if !cn.isInTransaction() { - return nil, errCopyNotSupportedOutsideTxn - } - - ci := ©in{ - cn: cn, - buffer: make([]byte, 0, ciBufferSize), - rowData: make(chan []byte), - done: make(chan bool, 1), - } - // add CopyData identifier + 4 bytes for message length - ci.buffer = append(ci.buffer, 'd', 0, 0, 0, 0) - - b := cn.writeBuf('Q') - b.string(q) - cn.send(b) - -awaitCopyInResponse: - for { - t, r := cn.recv1() - switch t { - case 'G': - if r.byte() != 0 { - err = errBinaryCopyNotSupported - break awaitCopyInResponse - } - go ci.resploop() - return ci, nil - case 'H': - err = errCopyToNotSupported - break awaitCopyInResponse - case 'E': - err = parseError(r) - case 'Z': - if err == nil { - ci.setBad(driver.ErrBadConn) - errorf("unexpected ReadyForQuery in response to COPY") - } - cn.processReadyForQuery(r) - return nil, err - default: - ci.setBad(driver.ErrBadConn) - errorf("unknown response for copy query: %q", t) - } - } - - // something went wrong, abort COPY before we return - b = cn.writeBuf('f') - b.string(err.Error()) - cn.send(b) - - for { - t, r := cn.recv1() - switch t { - case 'c', 'C', 'E': - case 'Z': - // correctly aborted, we're done - cn.processReadyForQuery(r) - return nil, err - default: - ci.setBad(driver.ErrBadConn) - errorf("unknown response for CopyFail: %q", t) - } - } -} - -func (ci *copyin) flush(buf []byte) { - // set message length (without message identifier) - binary.BigEndian.PutUint32(buf[1:], uint32(len(buf)-1)) - - _, err := ci.cn.c.Write(buf) - if err != nil { - panic(err) - } -} - -func (ci *copyin) resploop() { - for { - var r readBuf - t, err := ci.cn.recvMessage(&r) - if err != nil { - ci.setBad(driver.ErrBadConn) - ci.setError(err) - ci.done <- true - return - } - switch t { - case 'C': - // complete - res, _ := ci.cn.parseComplete(r.string()) - ci.setResult(res) - case 'N': - if n := ci.cn.noticeHandler; n != nil { - n(parseError(&r)) - } - case 'Z': - ci.cn.processReadyForQuery(&r) - ci.done <- true - return - case 'E': - err := parseError(&r) - ci.setError(err) - default: - ci.setBad(driver.ErrBadConn) - ci.setError(fmt.Errorf("unknown response during CopyIn: %q", t)) - ci.done <- true - return - } - } -} - -func (ci *copyin) setBad(err error) { - ci.cn.err.set(err) -} - -func (ci *copyin) getBad() error { - return ci.cn.err.get() -} - -func (ci *copyin) err() error { - ci.mu.Lock() - err := ci.mu.err - ci.mu.Unlock() - return err -} - -// setError() sets ci.err if one has not been set already. Caller must not be -// holding ci.Mutex. -func (ci *copyin) setError(err error) { - ci.mu.Lock() - if ci.mu.err == nil { - ci.mu.err = err - } - ci.mu.Unlock() -} - -func (ci *copyin) setResult(result driver.Result) { - ci.mu.Lock() - ci.mu.Result = result - ci.mu.Unlock() -} - -func (ci *copyin) getResult() driver.Result { - ci.mu.Lock() - result := ci.mu.Result - ci.mu.Unlock() - if result == nil { - return driver.RowsAffected(0) - } - return result -} - -func (ci *copyin) NumInput() int { - return -1 -} - -func (ci *copyin) Query(v []driver.Value) (r driver.Rows, err error) { - return nil, ErrNotSupported -} - -// Exec inserts values into the COPY stream. The insert is asynchronous -// and Exec can return errors from previous Exec calls to the same -// COPY stmt. -// -// You need to call Exec(nil) to sync the COPY stream and to get any -// errors from pending data, since Stmt.Close() doesn't return errors -// to the user. -func (ci *copyin) Exec(v []driver.Value) (r driver.Result, err error) { - if ci.closed { - return nil, errCopyInClosed - } - - if err := ci.getBad(); err != nil { - return nil, err - } - defer ci.cn.errRecover(&err) - - if err := ci.err(); err != nil { - return nil, err - } - - if len(v) == 0 { - if err := ci.Close(); err != nil { - return driver.RowsAffected(0), err - } - - return ci.getResult(), nil - } - - numValues := len(v) - for i, value := range v { - ci.buffer = appendEncodedText(&ci.cn.parameterStatus, ci.buffer, value) - if i < numValues-1 { - ci.buffer = append(ci.buffer, '\t') - } - } - - ci.buffer = append(ci.buffer, '\n') - - if len(ci.buffer) > ciBufferFlushSize { - ci.flush(ci.buffer) - // reset buffer, keep bytes for message identifier and length - ci.buffer = ci.buffer[:5] - } - - return driver.RowsAffected(0), nil -} - -// CopyData inserts a raw string into the COPY stream. The insert is -// asynchronous and CopyData can return errors from previous CopyData calls to -// the same COPY stmt. -// -// You need to call Exec(nil) to sync the COPY stream and to get any -// errors from pending data, since Stmt.Close() doesn't return errors -// to the user. -func (ci *copyin) CopyData(ctx context.Context, line string) (r driver.Result, err error) { - if ci.closed { - return nil, errCopyInClosed - } - - if finish := ci.cn.watchCancel(ctx); finish != nil { - defer finish() - } - - if err := ci.getBad(); err != nil { - return nil, err - } - defer ci.cn.errRecover(&err) - - if err := ci.err(); err != nil { - return nil, err - } - - ci.buffer = append(ci.buffer, []byte(line)...) - ci.buffer = append(ci.buffer, '\n') - - if len(ci.buffer) > ciBufferFlushSize { - ci.flush(ci.buffer) - // reset buffer, keep bytes for message identifier and length - ci.buffer = ci.buffer[:5] - } - - return driver.RowsAffected(0), nil -} - -func (ci *copyin) Close() (err error) { - if ci.closed { // Don't do anything, we're already closed - return nil - } - ci.closed = true - - if err := ci.getBad(); err != nil { - return err - } - defer ci.cn.errRecover(&err) - - if len(ci.buffer) > 0 { - ci.flush(ci.buffer) - } - // Avoid touching the scratch buffer as resploop could be using it. - err = ci.cn.sendSimpleMessage('c') - if err != nil { - return err - } - - <-ci.done - ci.cn.inCopy = false - - if err := ci.err(); err != nil { - return err - } - return nil -} diff --git a/vendor/github.com/lib/pq/doc.go b/vendor/github.com/lib/pq/doc.go deleted file mode 100644 index b57184801ba..00000000000 --- a/vendor/github.com/lib/pq/doc.go +++ /dev/null @@ -1,268 +0,0 @@ -/* -Package pq is a pure Go Postgres driver for the database/sql package. - -In most cases clients will use the database/sql package instead of -using this package directly. For example: - - import ( - "database/sql" - - _ "github.com/lib/pq" - ) - - func main() { - connStr := "user=pqgotest dbname=pqgotest sslmode=verify-full" - db, err := sql.Open("postgres", connStr) - if err != nil { - log.Fatal(err) - } - - age := 21 - rows, err := db.Query("SELECT name FROM users WHERE age = $1", age) - … - } - -You can also connect to a database using a URL. For example: - - connStr := "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full" - db, err := sql.Open("postgres", connStr) - - -Connection String Parameters - - -Similarly to libpq, when establishing a connection using pq you are expected to -supply a connection string containing zero or more parameters. -A subset of the connection parameters supported by libpq are also supported by pq. -Additionally, pq also lets you specify run-time parameters (such as search_path or work_mem) -directly in the connection string. This is different from libpq, which does not allow -run-time parameters in the connection string, instead requiring you to supply -them in the options parameter. - -For compatibility with libpq, the following special connection parameters are -supported: - - * dbname - The name of the database to connect to - * user - The user to sign in as - * password - The user's password - * host - The host to connect to. Values that start with / are for unix - domain sockets. (default is localhost) - * port - The port to bind to. (default is 5432) - * sslmode - Whether or not to use SSL (default is require, this is not - the default for libpq) - * fallback_application_name - An application_name to fall back to if one isn't provided. - * connect_timeout - Maximum wait for connection, in seconds. Zero or - not specified means wait indefinitely. - * sslcert - Cert file location. The file must contain PEM encoded data. - * sslkey - Key file location. The file must contain PEM encoded data. - * sslrootcert - The location of the root certificate file. The file - must contain PEM encoded data. - -Valid values for sslmode are: - - * disable - No SSL - * require - Always SSL (skip verification) - * verify-ca - Always SSL (verify that the certificate presented by the - server was signed by a trusted CA) - * verify-full - Always SSL (verify that the certification presented by - the server was signed by a trusted CA and the server host name - matches the one in the certificate) - -See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING -for more information about connection string parameters. - -Use single quotes for values that contain whitespace: - - "user=pqgotest password='with spaces'" - -A backslash will escape the next character in values: - - "user=space\ man password='it\'s valid'" - -Note that the connection parameter client_encoding (which sets the -text encoding for the connection) may be set but must be "UTF8", -matching with the same rules as Postgres. It is an error to provide -any other value. - -In addition to the parameters listed above, any run-time parameter that can be -set at backend start time can be set in the connection string. For more -information, see -http://www.postgresql.org/docs/current/static/runtime-config.html. - -Most environment variables as specified at http://www.postgresql.org/docs/current/static/libpq-envars.html -supported by libpq are also supported by pq. If any of the environment -variables not supported by pq are set, pq will panic during connection -establishment. Environment variables have a lower precedence than explicitly -provided connection parameters. - -The pgpass mechanism as described in http://www.postgresql.org/docs/current/static/libpq-pgpass.html -is supported, but on Windows PGPASSFILE must be specified explicitly. - - -Queries - - -database/sql does not dictate any specific format for parameter -markers in query strings, and pq uses the Postgres-native ordinal markers, -as shown above. The same marker can be reused for the same parameter: - - rows, err := db.Query(`SELECT name FROM users WHERE favorite_fruit = $1 - OR age BETWEEN $2 AND $2 + 3`, "orange", 64) - -pq does not support the LastInsertId() method of the Result type in database/sql. -To return the identifier of an INSERT (or UPDATE or DELETE), use the Postgres -RETURNING clause with a standard Query or QueryRow call: - - var userid int - err := db.QueryRow(`INSERT INTO users(name, favorite_fruit, age) - VALUES('beatrice', 'starfruit', 93) RETURNING id`).Scan(&userid) - -For more details on RETURNING, see the Postgres documentation: - - http://www.postgresql.org/docs/current/static/sql-insert.html - http://www.postgresql.org/docs/current/static/sql-update.html - http://www.postgresql.org/docs/current/static/sql-delete.html - -For additional instructions on querying see the documentation for the database/sql package. - - -Data Types - - -Parameters pass through driver.DefaultParameterConverter before they are handled -by this package. When the binary_parameters connection option is enabled, -[]byte values are sent directly to the backend as data in binary format. - -This package returns the following types for values from the PostgreSQL backend: - - - integer types smallint, integer, and bigint are returned as int64 - - floating-point types real and double precision are returned as float64 - - character types char, varchar, and text are returned as string - - temporal types date, time, timetz, timestamp, and timestamptz are - returned as time.Time - - the boolean type is returned as bool - - the bytea type is returned as []byte - -All other types are returned directly from the backend as []byte values in text format. - - -Errors - - -pq may return errors of type *pq.Error which can be interrogated for error details: - - if err, ok := err.(*pq.Error); ok { - fmt.Println("pq error:", err.Code.Name()) - } - -See the pq.Error type for details. - - -Bulk imports - -You can perform bulk imports by preparing a statement returned by pq.CopyIn (or -pq.CopyInSchema) in an explicit transaction (sql.Tx). The returned statement -handle can then be repeatedly "executed" to copy data into the target table. -After all data has been processed you should call Exec() once with no arguments -to flush all buffered data. Any call to Exec() might return an error which -should be handled appropriately, but because of the internal buffering an error -returned by Exec() might not be related to the data passed in the call that -failed. - -CopyIn uses COPY FROM internally. It is not possible to COPY outside of an -explicit transaction in pq. - -Usage example: - - txn, err := db.Begin() - if err != nil { - log.Fatal(err) - } - - stmt, err := txn.Prepare(pq.CopyIn("users", "name", "age")) - if err != nil { - log.Fatal(err) - } - - for _, user := range users { - _, err = stmt.Exec(user.Name, int64(user.Age)) - if err != nil { - log.Fatal(err) - } - } - - _, err = stmt.Exec() - if err != nil { - log.Fatal(err) - } - - err = stmt.Close() - if err != nil { - log.Fatal(err) - } - - err = txn.Commit() - if err != nil { - log.Fatal(err) - } - - -Notifications - - -PostgreSQL supports a simple publish/subscribe model over database -connections. See http://www.postgresql.org/docs/current/static/sql-notify.html -for more information about the general mechanism. - -To start listening for notifications, you first have to open a new connection -to the database by calling NewListener. This connection can not be used for -anything other than LISTEN / NOTIFY. Calling Listen will open a "notification -channel"; once a notification channel is open, a notification generated on that -channel will effect a send on the Listener.Notify channel. A notification -channel will remain open until Unlisten is called, though connection loss might -result in some notifications being lost. To solve this problem, Listener sends -a nil pointer over the Notify channel any time the connection is re-established -following a connection loss. The application can get information about the -state of the underlying connection by setting an event callback in the call to -NewListener. - -A single Listener can safely be used from concurrent goroutines, which means -that there is often no need to create more than one Listener in your -application. However, a Listener is always connected to a single database, so -you will need to create a new Listener instance for every database you want to -receive notifications in. - -The channel name in both Listen and Unlisten is case sensitive, and can contain -any characters legal in an identifier (see -http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS -for more information). Note that the channel name will be truncated to 63 -bytes by the PostgreSQL server. - -You can find a complete, working example of Listener usage at -https://godoc.org/github.com/lib/pq/example/listen. - - -Kerberos Support - - -If you need support for Kerberos authentication, add the following to your main -package: - - import "github.com/lib/pq/auth/kerberos" - - func init() { - pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() }) - } - -This package is in a separate module so that users who don't need Kerberos -don't have to download unnecessary dependencies. - -When imported, additional connection string parameters are supported: - - * krbsrvname - GSS (Kerberos) service name when constructing the - SPN (default is `postgres`). This will be combined with the host - to form the full SPN: `krbsrvname/host`. - * krbspn - GSS (Kerberos) SPN. This takes priority over - `krbsrvname` if present. -*/ -package pq diff --git a/vendor/github.com/lib/pq/encode.go b/vendor/github.com/lib/pq/encode.go deleted file mode 100644 index bffe6096aff..00000000000 --- a/vendor/github.com/lib/pq/encode.go +++ /dev/null @@ -1,632 +0,0 @@ -package pq - -import ( - "bytes" - "database/sql/driver" - "encoding/binary" - "encoding/hex" - "errors" - "fmt" - "math" - "regexp" - "strconv" - "strings" - "sync" - "time" - - "github.com/lib/pq/oid" -) - -var time2400Regex = regexp.MustCompile(`^(24:00(?::00(?:\.0+)?)?)(?:[Z+-].*)?$`) - -func binaryEncode(parameterStatus *parameterStatus, x interface{}) []byte { - switch v := x.(type) { - case []byte: - return v - default: - return encode(parameterStatus, x, oid.T_unknown) - } -} - -func encode(parameterStatus *parameterStatus, x interface{}, pgtypOid oid.Oid) []byte { - switch v := x.(type) { - case int64: - return strconv.AppendInt(nil, v, 10) - case float64: - return strconv.AppendFloat(nil, v, 'f', -1, 64) - case []byte: - if pgtypOid == oid.T_bytea { - return encodeBytea(parameterStatus.serverVersion, v) - } - - return v - case string: - if pgtypOid == oid.T_bytea { - return encodeBytea(parameterStatus.serverVersion, []byte(v)) - } - - return []byte(v) - case bool: - return strconv.AppendBool(nil, v) - case time.Time: - return formatTs(v) - - default: - errorf("encode: unknown type for %T", v) - } - - panic("not reached") -} - -func decode(parameterStatus *parameterStatus, s []byte, typ oid.Oid, f format) interface{} { - switch f { - case formatBinary: - return binaryDecode(parameterStatus, s, typ) - case formatText: - return textDecode(parameterStatus, s, typ) - default: - panic("not reached") - } -} - -func binaryDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} { - switch typ { - case oid.T_bytea: - return s - case oid.T_int8: - return int64(binary.BigEndian.Uint64(s)) - case oid.T_int4: - return int64(int32(binary.BigEndian.Uint32(s))) - case oid.T_int2: - return int64(int16(binary.BigEndian.Uint16(s))) - case oid.T_uuid: - b, err := decodeUUIDBinary(s) - if err != nil { - panic(err) - } - return b - - default: - errorf("don't know how to decode binary parameter of type %d", uint32(typ)) - } - - panic("not reached") -} - -func textDecode(parameterStatus *parameterStatus, s []byte, typ oid.Oid) interface{} { - switch typ { - case oid.T_char, oid.T_varchar, oid.T_text: - return string(s) - case oid.T_bytea: - b, err := parseBytea(s) - if err != nil { - errorf("%s", err) - } - return b - case oid.T_timestamptz: - return parseTs(parameterStatus.currentLocation, string(s)) - case oid.T_timestamp, oid.T_date: - return parseTs(nil, string(s)) - case oid.T_time: - return mustParse("15:04:05", typ, s) - case oid.T_timetz: - return mustParse("15:04:05-07", typ, s) - case oid.T_bool: - return s[0] == 't' - case oid.T_int8, oid.T_int4, oid.T_int2: - i, err := strconv.ParseInt(string(s), 10, 64) - if err != nil { - errorf("%s", err) - } - return i - case oid.T_float4, oid.T_float8: - // We always use 64 bit parsing, regardless of whether the input text is for - // a float4 or float8, because clients expect float64s for all float datatypes - // and returning a 32-bit parsed float64 produces lossy results. - f, err := strconv.ParseFloat(string(s), 64) - if err != nil { - errorf("%s", err) - } - return f - } - - return s -} - -// appendEncodedText encodes item in text format as required by COPY -// and appends to buf -func appendEncodedText(parameterStatus *parameterStatus, buf []byte, x interface{}) []byte { - switch v := x.(type) { - case int64: - return strconv.AppendInt(buf, v, 10) - case float64: - return strconv.AppendFloat(buf, v, 'f', -1, 64) - case []byte: - encodedBytea := encodeBytea(parameterStatus.serverVersion, v) - return appendEscapedText(buf, string(encodedBytea)) - case string: - return appendEscapedText(buf, v) - case bool: - return strconv.AppendBool(buf, v) - case time.Time: - return append(buf, formatTs(v)...) - case nil: - return append(buf, "\\N"...) - default: - errorf("encode: unknown type for %T", v) - } - - panic("not reached") -} - -func appendEscapedText(buf []byte, text string) []byte { - escapeNeeded := false - startPos := 0 - var c byte - - // check if we need to escape - for i := 0; i < len(text); i++ { - c = text[i] - if c == '\\' || c == '\n' || c == '\r' || c == '\t' { - escapeNeeded = true - startPos = i - break - } - } - if !escapeNeeded { - return append(buf, text...) - } - - // copy till first char to escape, iterate the rest - result := append(buf, text[:startPos]...) - for i := startPos; i < len(text); i++ { - c = text[i] - switch c { - case '\\': - result = append(result, '\\', '\\') - case '\n': - result = append(result, '\\', 'n') - case '\r': - result = append(result, '\\', 'r') - case '\t': - result = append(result, '\\', 't') - default: - result = append(result, c) - } - } - return result -} - -func mustParse(f string, typ oid.Oid, s []byte) time.Time { - str := string(s) - - // Check for a minute and second offset in the timezone. - if typ == oid.T_timestamptz || typ == oid.T_timetz { - for i := 3; i <= 6; i += 3 { - if str[len(str)-i] == ':' { - f += ":00" - continue - } - break - } - } - - // Special case for 24:00 time. - // Unfortunately, golang does not parse 24:00 as a proper time. - // In this case, we want to try "round to the next day", to differentiate. - // As such, we find if the 24:00 time matches at the beginning; if so, - // we default it back to 00:00 but add a day later. - var is2400Time bool - switch typ { - case oid.T_timetz, oid.T_time: - if matches := time2400Regex.FindStringSubmatch(str); matches != nil { - // Concatenate timezone information at the back. - str = "00:00:00" + str[len(matches[1]):] - is2400Time = true - } - } - t, err := time.Parse(f, str) - if err != nil { - errorf("decode: %s", err) - } - if is2400Time { - t = t.Add(24 * time.Hour) - } - return t -} - -var errInvalidTimestamp = errors.New("invalid timestamp") - -type timestampParser struct { - err error -} - -func (p *timestampParser) expect(str string, char byte, pos int) { - if p.err != nil { - return - } - if pos+1 > len(str) { - p.err = errInvalidTimestamp - return - } - if c := str[pos]; c != char && p.err == nil { - p.err = fmt.Errorf("expected '%v' at position %v; got '%v'", char, pos, c) - } -} - -func (p *timestampParser) mustAtoi(str string, begin int, end int) int { - if p.err != nil { - return 0 - } - if begin < 0 || end < 0 || begin > end || end > len(str) { - p.err = errInvalidTimestamp - return 0 - } - result, err := strconv.Atoi(str[begin:end]) - if err != nil { - if p.err == nil { - p.err = fmt.Errorf("expected number; got '%v'", str) - } - return 0 - } - return result -} - -// The location cache caches the time zones typically used by the client. -type locationCache struct { - cache map[int]*time.Location - lock sync.Mutex -} - -// All connections share the same list of timezones. Benchmarking shows that -// about 5% speed could be gained by putting the cache in the connection and -// losing the mutex, at the cost of a small amount of memory and a somewhat -// significant increase in code complexity. -var globalLocationCache = newLocationCache() - -func newLocationCache() *locationCache { - return &locationCache{cache: make(map[int]*time.Location)} -} - -// Returns the cached timezone for the specified offset, creating and caching -// it if necessary. -func (c *locationCache) getLocation(offset int) *time.Location { - c.lock.Lock() - defer c.lock.Unlock() - - location, ok := c.cache[offset] - if !ok { - location = time.FixedZone("", offset) - c.cache[offset] = location - } - - return location -} - -var infinityTsEnabled = false -var infinityTsNegative time.Time -var infinityTsPositive time.Time - -const ( - infinityTsEnabledAlready = "pq: infinity timestamp enabled already" - infinityTsNegativeMustBeSmaller = "pq: infinity timestamp: negative value must be smaller (before) than positive" -) - -// EnableInfinityTs controls the handling of Postgres' "-infinity" and -// "infinity" "timestamp"s. -// -// If EnableInfinityTs is not called, "-infinity" and "infinity" will return -// []byte("-infinity") and []byte("infinity") respectively, and potentially -// cause error "sql: Scan error on column index 0: unsupported driver -> Scan -// pair: []uint8 -> *time.Time", when scanning into a time.Time value. -// -// Once EnableInfinityTs has been called, all connections created using this -// driver will decode Postgres' "-infinity" and "infinity" for "timestamp", -// "timestamp with time zone" and "date" types to the predefined minimum and -// maximum times, respectively. When encoding time.Time values, any time which -// equals or precedes the predefined minimum time will be encoded to -// "-infinity". Any values at or past the maximum time will similarly be -// encoded to "infinity". -// -// If EnableInfinityTs is called with negative >= positive, it will panic. -// Calling EnableInfinityTs after a connection has been established results in -// undefined behavior. If EnableInfinityTs is called more than once, it will -// panic. -func EnableInfinityTs(negative time.Time, positive time.Time) { - if infinityTsEnabled { - panic(infinityTsEnabledAlready) - } - if !negative.Before(positive) { - panic(infinityTsNegativeMustBeSmaller) - } - infinityTsEnabled = true - infinityTsNegative = negative - infinityTsPositive = positive -} - -/* - * Testing might want to toggle infinityTsEnabled - */ -func disableInfinityTs() { - infinityTsEnabled = false -} - -// This is a time function specific to the Postgres default DateStyle -// setting ("ISO, MDY"), the only one we currently support. This -// accounts for the discrepancies between the parsing available with -// time.Parse and the Postgres date formatting quirks. -func parseTs(currentLocation *time.Location, str string) interface{} { - switch str { - case "-infinity": - if infinityTsEnabled { - return infinityTsNegative - } - return []byte(str) - case "infinity": - if infinityTsEnabled { - return infinityTsPositive - } - return []byte(str) - } - t, err := ParseTimestamp(currentLocation, str) - if err != nil { - panic(err) - } - return t -} - -// ParseTimestamp parses Postgres' text format. It returns a time.Time in -// currentLocation iff that time's offset agrees with the offset sent from the -// Postgres server. Otherwise, ParseTimestamp returns a time.Time with the -// fixed offset offset provided by the Postgres server. -func ParseTimestamp(currentLocation *time.Location, str string) (time.Time, error) { - p := timestampParser{} - - monSep := strings.IndexRune(str, '-') - // this is Gregorian year, not ISO Year - // In Gregorian system, the year 1 BC is followed by AD 1 - year := p.mustAtoi(str, 0, monSep) - daySep := monSep + 3 - month := p.mustAtoi(str, monSep+1, daySep) - p.expect(str, '-', daySep) - timeSep := daySep + 3 - day := p.mustAtoi(str, daySep+1, timeSep) - - minLen := monSep + len("01-01") + 1 - - isBC := strings.HasSuffix(str, " BC") - if isBC { - minLen += 3 - } - - var hour, minute, second int - if len(str) > minLen { - p.expect(str, ' ', timeSep) - minSep := timeSep + 3 - p.expect(str, ':', minSep) - hour = p.mustAtoi(str, timeSep+1, minSep) - secSep := minSep + 3 - p.expect(str, ':', secSep) - minute = p.mustAtoi(str, minSep+1, secSep) - secEnd := secSep + 3 - second = p.mustAtoi(str, secSep+1, secEnd) - } - remainderIdx := monSep + len("01-01 00:00:00") + 1 - // Three optional (but ordered) sections follow: the - // fractional seconds, the time zone offset, and the BC - // designation. We set them up here and adjust the other - // offsets if the preceding sections exist. - - nanoSec := 0 - tzOff := 0 - - if remainderIdx < len(str) && str[remainderIdx] == '.' { - fracStart := remainderIdx + 1 - fracOff := strings.IndexAny(str[fracStart:], "-+Z ") - if fracOff < 0 { - fracOff = len(str) - fracStart - } - fracSec := p.mustAtoi(str, fracStart, fracStart+fracOff) - nanoSec = fracSec * (1000000000 / int(math.Pow(10, float64(fracOff)))) - - remainderIdx += fracOff + 1 - } - if tzStart := remainderIdx; tzStart < len(str) && (str[tzStart] == '-' || str[tzStart] == '+') { - // time zone separator is always '-' or '+' or 'Z' (UTC is +00) - var tzSign int - switch c := str[tzStart]; c { - case '-': - tzSign = -1 - case '+': - tzSign = +1 - default: - return time.Time{}, fmt.Errorf("expected '-' or '+' at position %v; got %v", tzStart, c) - } - tzHours := p.mustAtoi(str, tzStart+1, tzStart+3) - remainderIdx += 3 - var tzMin, tzSec int - if remainderIdx < len(str) && str[remainderIdx] == ':' { - tzMin = p.mustAtoi(str, remainderIdx+1, remainderIdx+3) - remainderIdx += 3 - } - if remainderIdx < len(str) && str[remainderIdx] == ':' { - tzSec = p.mustAtoi(str, remainderIdx+1, remainderIdx+3) - remainderIdx += 3 - } - tzOff = tzSign * ((tzHours * 60 * 60) + (tzMin * 60) + tzSec) - } else if tzStart < len(str) && str[tzStart] == 'Z' { - // time zone Z separator indicates UTC is +00 - remainderIdx += 1 - } - - var isoYear int - - if isBC { - isoYear = 1 - year - remainderIdx += 3 - } else { - isoYear = year - } - if remainderIdx < len(str) { - return time.Time{}, fmt.Errorf("expected end of input, got %v", str[remainderIdx:]) - } - t := time.Date(isoYear, time.Month(month), day, - hour, minute, second, nanoSec, - globalLocationCache.getLocation(tzOff)) - - if currentLocation != nil { - // Set the location of the returned Time based on the session's - // TimeZone value, but only if the local time zone database agrees with - // the remote database on the offset. - lt := t.In(currentLocation) - _, newOff := lt.Zone() - if newOff == tzOff { - t = lt - } - } - - return t, p.err -} - -// formatTs formats t into a format postgres understands. -func formatTs(t time.Time) []byte { - if infinityTsEnabled { - // t <= -infinity : ! (t > -infinity) - if !t.After(infinityTsNegative) { - return []byte("-infinity") - } - // t >= infinity : ! (!t < infinity) - if !t.Before(infinityTsPositive) { - return []byte("infinity") - } - } - return FormatTimestamp(t) -} - -// FormatTimestamp formats t into Postgres' text format for timestamps. -func FormatTimestamp(t time.Time) []byte { - // Need to send dates before 0001 A.D. with " BC" suffix, instead of the - // minus sign preferred by Go. - // Beware, "0000" in ISO is "1 BC", "-0001" is "2 BC" and so on - bc := false - if t.Year() <= 0 { - // flip year sign, and add 1, e.g: "0" will be "1", and "-10" will be "11" - t = t.AddDate((-t.Year())*2+1, 0, 0) - bc = true - } - b := []byte(t.Format("2006-01-02 15:04:05.999999999Z07:00")) - - _, offset := t.Zone() - offset %= 60 - if offset != 0 { - // RFC3339Nano already printed the minus sign - if offset < 0 { - offset = -offset - } - - b = append(b, ':') - if offset < 10 { - b = append(b, '0') - } - b = strconv.AppendInt(b, int64(offset), 10) - } - - if bc { - b = append(b, " BC"...) - } - return b -} - -// Parse a bytea value received from the server. Both "hex" and the legacy -// "escape" format are supported. -func parseBytea(s []byte) (result []byte, err error) { - if len(s) >= 2 && bytes.Equal(s[:2], []byte("\\x")) { - // bytea_output = hex - s = s[2:] // trim off leading "\\x" - result = make([]byte, hex.DecodedLen(len(s))) - _, err := hex.Decode(result, s) - if err != nil { - return nil, err - } - } else { - // bytea_output = escape - for len(s) > 0 { - if s[0] == '\\' { - // escaped '\\' - if len(s) >= 2 && s[1] == '\\' { - result = append(result, '\\') - s = s[2:] - continue - } - - // '\\' followed by an octal number - if len(s) < 4 { - return nil, fmt.Errorf("invalid bytea sequence %v", s) - } - r, err := strconv.ParseUint(string(s[1:4]), 8, 8) - if err != nil { - return nil, fmt.Errorf("could not parse bytea value: %s", err.Error()) - } - result = append(result, byte(r)) - s = s[4:] - } else { - // We hit an unescaped, raw byte. Try to read in as many as - // possible in one go. - i := bytes.IndexByte(s, '\\') - if i == -1 { - result = append(result, s...) - break - } - result = append(result, s[:i]...) - s = s[i:] - } - } - } - - return result, nil -} - -func encodeBytea(serverVersion int, v []byte) (result []byte) { - if serverVersion >= 90000 { - // Use the hex format if we know that the server supports it - result = make([]byte, 2+hex.EncodedLen(len(v))) - result[0] = '\\' - result[1] = 'x' - hex.Encode(result[2:], v) - } else { - // .. or resort to "escape" - for _, b := range v { - if b == '\\' { - result = append(result, '\\', '\\') - } else if b < 0x20 || b > 0x7e { - result = append(result, []byte(fmt.Sprintf("\\%03o", b))...) - } else { - result = append(result, b) - } - } - } - - return result -} - -// NullTime represents a time.Time that may be null. NullTime implements the -// sql.Scanner interface so it can be used as a scan destination, similar to -// sql.NullString. -type NullTime struct { - Time time.Time - Valid bool // Valid is true if Time is not NULL -} - -// Scan implements the Scanner interface. -func (nt *NullTime) Scan(value interface{}) error { - nt.Time, nt.Valid = value.(time.Time) - return nil -} - -// Value implements the driver Valuer interface. -func (nt NullTime) Value() (driver.Value, error) { - if !nt.Valid { - return nil, nil - } - return nt.Time, nil -} diff --git a/vendor/github.com/lib/pq/error.go b/vendor/github.com/lib/pq/error.go deleted file mode 100644 index f67c5a5fa64..00000000000 --- a/vendor/github.com/lib/pq/error.go +++ /dev/null @@ -1,523 +0,0 @@ -package pq - -import ( - "database/sql/driver" - "fmt" - "io" - "net" - "runtime" -) - -// Error severities -const ( - Efatal = "FATAL" - Epanic = "PANIC" - Ewarning = "WARNING" - Enotice = "NOTICE" - Edebug = "DEBUG" - Einfo = "INFO" - Elog = "LOG" -) - -// Error represents an error communicating with the server. -// -// See http://www.postgresql.org/docs/current/static/protocol-error-fields.html for details of the fields -type Error struct { - Severity string - Code ErrorCode - Message string - Detail string - Hint string - Position string - InternalPosition string - InternalQuery string - Where string - Schema string - Table string - Column string - DataTypeName string - Constraint string - File string - Line string - Routine string -} - -// ErrorCode is a five-character error code. -type ErrorCode string - -// Name returns a more human friendly rendering of the error code, namely the -// "condition name". -// -// See http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html for -// details. -func (ec ErrorCode) Name() string { - return errorCodeNames[ec] -} - -// ErrorClass is only the class part of an error code. -type ErrorClass string - -// Name returns the condition name of an error class. It is equivalent to the -// condition name of the "standard" error code (i.e. the one having the last -// three characters "000"). -func (ec ErrorClass) Name() string { - return errorCodeNames[ErrorCode(ec+"000")] -} - -// Class returns the error class, e.g. "28". -// -// See http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html for -// details. -func (ec ErrorCode) Class() ErrorClass { - return ErrorClass(ec[0:2]) -} - -// errorCodeNames is a mapping between the five-character error codes and the -// human readable "condition names". It is derived from the list at -// http://www.postgresql.org/docs/9.3/static/errcodes-appendix.html -var errorCodeNames = map[ErrorCode]string{ - // Class 00 - Successful Completion - "00000": "successful_completion", - // Class 01 - Warning - "01000": "warning", - "0100C": "dynamic_result_sets_returned", - "01008": "implicit_zero_bit_padding", - "01003": "null_value_eliminated_in_set_function", - "01007": "privilege_not_granted", - "01006": "privilege_not_revoked", - "01004": "string_data_right_truncation", - "01P01": "deprecated_feature", - // Class 02 - No Data (this is also a warning class per the SQL standard) - "02000": "no_data", - "02001": "no_additional_dynamic_result_sets_returned", - // Class 03 - SQL Statement Not Yet Complete - "03000": "sql_statement_not_yet_complete", - // Class 08 - Connection Exception - "08000": "connection_exception", - "08003": "connection_does_not_exist", - "08006": "connection_failure", - "08001": "sqlclient_unable_to_establish_sqlconnection", - "08004": "sqlserver_rejected_establishment_of_sqlconnection", - "08007": "transaction_resolution_unknown", - "08P01": "protocol_violation", - // Class 09 - Triggered Action Exception - "09000": "triggered_action_exception", - // Class 0A - Feature Not Supported - "0A000": "feature_not_supported", - // Class 0B - Invalid Transaction Initiation - "0B000": "invalid_transaction_initiation", - // Class 0F - Locator Exception - "0F000": "locator_exception", - "0F001": "invalid_locator_specification", - // Class 0L - Invalid Grantor - "0L000": "invalid_grantor", - "0LP01": "invalid_grant_operation", - // Class 0P - Invalid Role Specification - "0P000": "invalid_role_specification", - // Class 0Z - Diagnostics Exception - "0Z000": "diagnostics_exception", - "0Z002": "stacked_diagnostics_accessed_without_active_handler", - // Class 20 - Case Not Found - "20000": "case_not_found", - // Class 21 - Cardinality Violation - "21000": "cardinality_violation", - // Class 22 - Data Exception - "22000": "data_exception", - "2202E": "array_subscript_error", - "22021": "character_not_in_repertoire", - "22008": "datetime_field_overflow", - "22012": "division_by_zero", - "22005": "error_in_assignment", - "2200B": "escape_character_conflict", - "22022": "indicator_overflow", - "22015": "interval_field_overflow", - "2201E": "invalid_argument_for_logarithm", - "22014": "invalid_argument_for_ntile_function", - "22016": "invalid_argument_for_nth_value_function", - "2201F": "invalid_argument_for_power_function", - "2201G": "invalid_argument_for_width_bucket_function", - "22018": "invalid_character_value_for_cast", - "22007": "invalid_datetime_format", - "22019": "invalid_escape_character", - "2200D": "invalid_escape_octet", - "22025": "invalid_escape_sequence", - "22P06": "nonstandard_use_of_escape_character", - "22010": "invalid_indicator_parameter_value", - "22023": "invalid_parameter_value", - "2201B": "invalid_regular_expression", - "2201W": "invalid_row_count_in_limit_clause", - "2201X": "invalid_row_count_in_result_offset_clause", - "22009": "invalid_time_zone_displacement_value", - "2200C": "invalid_use_of_escape_character", - "2200G": "most_specific_type_mismatch", - "22004": "null_value_not_allowed", - "22002": "null_value_no_indicator_parameter", - "22003": "numeric_value_out_of_range", - "2200H": "sequence_generator_limit_exceeded", - "22026": "string_data_length_mismatch", - "22001": "string_data_right_truncation", - "22011": "substring_error", - "22027": "trim_error", - "22024": "unterminated_c_string", - "2200F": "zero_length_character_string", - "22P01": "floating_point_exception", - "22P02": "invalid_text_representation", - "22P03": "invalid_binary_representation", - "22P04": "bad_copy_file_format", - "22P05": "untranslatable_character", - "2200L": "not_an_xml_document", - "2200M": "invalid_xml_document", - "2200N": "invalid_xml_content", - "2200S": "invalid_xml_comment", - "2200T": "invalid_xml_processing_instruction", - // Class 23 - Integrity Constraint Violation - "23000": "integrity_constraint_violation", - "23001": "restrict_violation", - "23502": "not_null_violation", - "23503": "foreign_key_violation", - "23505": "unique_violation", - "23514": "check_violation", - "23P01": "exclusion_violation", - // Class 24 - Invalid Cursor State - "24000": "invalid_cursor_state", - // Class 25 - Invalid Transaction State - "25000": "invalid_transaction_state", - "25001": "active_sql_transaction", - "25002": "branch_transaction_already_active", - "25008": "held_cursor_requires_same_isolation_level", - "25003": "inappropriate_access_mode_for_branch_transaction", - "25004": "inappropriate_isolation_level_for_branch_transaction", - "25005": "no_active_sql_transaction_for_branch_transaction", - "25006": "read_only_sql_transaction", - "25007": "schema_and_data_statement_mixing_not_supported", - "25P01": "no_active_sql_transaction", - "25P02": "in_failed_sql_transaction", - // Class 26 - Invalid SQL Statement Name - "26000": "invalid_sql_statement_name", - // Class 27 - Triggered Data Change Violation - "27000": "triggered_data_change_violation", - // Class 28 - Invalid Authorization Specification - "28000": "invalid_authorization_specification", - "28P01": "invalid_password", - // Class 2B - Dependent Privilege Descriptors Still Exist - "2B000": "dependent_privilege_descriptors_still_exist", - "2BP01": "dependent_objects_still_exist", - // Class 2D - Invalid Transaction Termination - "2D000": "invalid_transaction_termination", - // Class 2F - SQL Routine Exception - "2F000": "sql_routine_exception", - "2F005": "function_executed_no_return_statement", - "2F002": "modifying_sql_data_not_permitted", - "2F003": "prohibited_sql_statement_attempted", - "2F004": "reading_sql_data_not_permitted", - // Class 34 - Invalid Cursor Name - "34000": "invalid_cursor_name", - // Class 38 - External Routine Exception - "38000": "external_routine_exception", - "38001": "containing_sql_not_permitted", - "38002": "modifying_sql_data_not_permitted", - "38003": "prohibited_sql_statement_attempted", - "38004": "reading_sql_data_not_permitted", - // Class 39 - External Routine Invocation Exception - "39000": "external_routine_invocation_exception", - "39001": "invalid_sqlstate_returned", - "39004": "null_value_not_allowed", - "39P01": "trigger_protocol_violated", - "39P02": "srf_protocol_violated", - // Class 3B - Savepoint Exception - "3B000": "savepoint_exception", - "3B001": "invalid_savepoint_specification", - // Class 3D - Invalid Catalog Name - "3D000": "invalid_catalog_name", - // Class 3F - Invalid Schema Name - "3F000": "invalid_schema_name", - // Class 40 - Transaction Rollback - "40000": "transaction_rollback", - "40002": "transaction_integrity_constraint_violation", - "40001": "serialization_failure", - "40003": "statement_completion_unknown", - "40P01": "deadlock_detected", - // Class 42 - Syntax Error or Access Rule Violation - "42000": "syntax_error_or_access_rule_violation", - "42601": "syntax_error", - "42501": "insufficient_privilege", - "42846": "cannot_coerce", - "42803": "grouping_error", - "42P20": "windowing_error", - "42P19": "invalid_recursion", - "42830": "invalid_foreign_key", - "42602": "invalid_name", - "42622": "name_too_long", - "42939": "reserved_name", - "42804": "datatype_mismatch", - "42P18": "indeterminate_datatype", - "42P21": "collation_mismatch", - "42P22": "indeterminate_collation", - "42809": "wrong_object_type", - "42703": "undefined_column", - "42883": "undefined_function", - "42P01": "undefined_table", - "42P02": "undefined_parameter", - "42704": "undefined_object", - "42701": "duplicate_column", - "42P03": "duplicate_cursor", - "42P04": "duplicate_database", - "42723": "duplicate_function", - "42P05": "duplicate_prepared_statement", - "42P06": "duplicate_schema", - "42P07": "duplicate_table", - "42712": "duplicate_alias", - "42710": "duplicate_object", - "42702": "ambiguous_column", - "42725": "ambiguous_function", - "42P08": "ambiguous_parameter", - "42P09": "ambiguous_alias", - "42P10": "invalid_column_reference", - "42611": "invalid_column_definition", - "42P11": "invalid_cursor_definition", - "42P12": "invalid_database_definition", - "42P13": "invalid_function_definition", - "42P14": "invalid_prepared_statement_definition", - "42P15": "invalid_schema_definition", - "42P16": "invalid_table_definition", - "42P17": "invalid_object_definition", - // Class 44 - WITH CHECK OPTION Violation - "44000": "with_check_option_violation", - // Class 53 - Insufficient Resources - "53000": "insufficient_resources", - "53100": "disk_full", - "53200": "out_of_memory", - "53300": "too_many_connections", - "53400": "configuration_limit_exceeded", - // Class 54 - Program Limit Exceeded - "54000": "program_limit_exceeded", - "54001": "statement_too_complex", - "54011": "too_many_columns", - "54023": "too_many_arguments", - // Class 55 - Object Not In Prerequisite State - "55000": "object_not_in_prerequisite_state", - "55006": "object_in_use", - "55P02": "cant_change_runtime_param", - "55P03": "lock_not_available", - // Class 57 - Operator Intervention - "57000": "operator_intervention", - "57014": "query_canceled", - "57P01": "admin_shutdown", - "57P02": "crash_shutdown", - "57P03": "cannot_connect_now", - "57P04": "database_dropped", - // Class 58 - System Error (errors external to PostgreSQL itself) - "58000": "system_error", - "58030": "io_error", - "58P01": "undefined_file", - "58P02": "duplicate_file", - // Class F0 - Configuration File Error - "F0000": "config_file_error", - "F0001": "lock_file_exists", - // Class HV - Foreign Data Wrapper Error (SQL/MED) - "HV000": "fdw_error", - "HV005": "fdw_column_name_not_found", - "HV002": "fdw_dynamic_parameter_value_needed", - "HV010": "fdw_function_sequence_error", - "HV021": "fdw_inconsistent_descriptor_information", - "HV024": "fdw_invalid_attribute_value", - "HV007": "fdw_invalid_column_name", - "HV008": "fdw_invalid_column_number", - "HV004": "fdw_invalid_data_type", - "HV006": "fdw_invalid_data_type_descriptors", - "HV091": "fdw_invalid_descriptor_field_identifier", - "HV00B": "fdw_invalid_handle", - "HV00C": "fdw_invalid_option_index", - "HV00D": "fdw_invalid_option_name", - "HV090": "fdw_invalid_string_length_or_buffer_length", - "HV00A": "fdw_invalid_string_format", - "HV009": "fdw_invalid_use_of_null_pointer", - "HV014": "fdw_too_many_handles", - "HV001": "fdw_out_of_memory", - "HV00P": "fdw_no_schemas", - "HV00J": "fdw_option_name_not_found", - "HV00K": "fdw_reply_handle", - "HV00Q": "fdw_schema_not_found", - "HV00R": "fdw_table_not_found", - "HV00L": "fdw_unable_to_create_execution", - "HV00M": "fdw_unable_to_create_reply", - "HV00N": "fdw_unable_to_establish_connection", - // Class P0 - PL/pgSQL Error - "P0000": "plpgsql_error", - "P0001": "raise_exception", - "P0002": "no_data_found", - "P0003": "too_many_rows", - // Class XX - Internal Error - "XX000": "internal_error", - "XX001": "data_corrupted", - "XX002": "index_corrupted", -} - -func parseError(r *readBuf) *Error { - err := new(Error) - for t := r.byte(); t != 0; t = r.byte() { - msg := r.string() - switch t { - case 'S': - err.Severity = msg - case 'C': - err.Code = ErrorCode(msg) - case 'M': - err.Message = msg - case 'D': - err.Detail = msg - case 'H': - err.Hint = msg - case 'P': - err.Position = msg - case 'p': - err.InternalPosition = msg - case 'q': - err.InternalQuery = msg - case 'W': - err.Where = msg - case 's': - err.Schema = msg - case 't': - err.Table = msg - case 'c': - err.Column = msg - case 'd': - err.DataTypeName = msg - case 'n': - err.Constraint = msg - case 'F': - err.File = msg - case 'L': - err.Line = msg - case 'R': - err.Routine = msg - } - } - return err -} - -// Fatal returns true if the Error Severity is fatal. -func (err *Error) Fatal() bool { - return err.Severity == Efatal -} - -// SQLState returns the SQLState of the error. -func (err *Error) SQLState() string { - return string(err.Code) -} - -// Get implements the legacy PGError interface. New code should use the fields -// of the Error struct directly. -func (err *Error) Get(k byte) (v string) { - switch k { - case 'S': - return err.Severity - case 'C': - return string(err.Code) - case 'M': - return err.Message - case 'D': - return err.Detail - case 'H': - return err.Hint - case 'P': - return err.Position - case 'p': - return err.InternalPosition - case 'q': - return err.InternalQuery - case 'W': - return err.Where - case 's': - return err.Schema - case 't': - return err.Table - case 'c': - return err.Column - case 'd': - return err.DataTypeName - case 'n': - return err.Constraint - case 'F': - return err.File - case 'L': - return err.Line - case 'R': - return err.Routine - } - return "" -} - -func (err *Error) Error() string { - return "pq: " + err.Message -} - -// PGError is an interface used by previous versions of pq. It is provided -// only to support legacy code. New code should use the Error type. -type PGError interface { - Error() string - Fatal() bool - Get(k byte) (v string) -} - -func errorf(s string, args ...interface{}) { - panic(fmt.Errorf("pq: %s", fmt.Sprintf(s, args...))) -} - -// TODO(ainar-g) Rename to errorf after removing panics. -func fmterrorf(s string, args ...interface{}) error { - return fmt.Errorf("pq: %s", fmt.Sprintf(s, args...)) -} - -func errRecoverNoErrBadConn(err *error) { - e := recover() - if e == nil { - // Do nothing - return - } - var ok bool - *err, ok = e.(error) - if !ok { - *err = fmt.Errorf("pq: unexpected error: %#v", e) - } -} - -func (cn *conn) errRecover(err *error) { - e := recover() - switch v := e.(type) { - case nil: - // Do nothing - case runtime.Error: - cn.err.set(driver.ErrBadConn) - panic(v) - case *Error: - if v.Fatal() { - *err = driver.ErrBadConn - } else { - *err = v - } - case *net.OpError: - cn.err.set(driver.ErrBadConn) - *err = v - case *safeRetryError: - cn.err.set(driver.ErrBadConn) - *err = driver.ErrBadConn - case error: - if v == io.EOF || v.Error() == "remote error: handshake failure" { - *err = driver.ErrBadConn - } else { - *err = v - } - - default: - cn.err.set(driver.ErrBadConn) - panic(fmt.Sprintf("unknown error: %#v", e)) - } - - // Any time we return ErrBadConn, we need to remember it since *Tx doesn't - // mark the connection bad in database/sql. - if *err == driver.ErrBadConn { - cn.err.set(driver.ErrBadConn) - } -} diff --git a/vendor/github.com/lib/pq/krb.go b/vendor/github.com/lib/pq/krb.go deleted file mode 100644 index 408ec01f977..00000000000 --- a/vendor/github.com/lib/pq/krb.go +++ /dev/null @@ -1,27 +0,0 @@ -package pq - -// NewGSSFunc creates a GSS authentication provider, for use with -// RegisterGSSProvider. -type NewGSSFunc func() (GSS, error) - -var newGss NewGSSFunc - -// RegisterGSSProvider registers a GSS authentication provider. For example, if -// you need to use Kerberos to authenticate with your server, add this to your -// main package: -// -// import "github.com/lib/pq/auth/kerberos" -// -// func init() { -// pq.RegisterGSSProvider(func() (pq.GSS, error) { return kerberos.NewGSS() }) -// } -func RegisterGSSProvider(newGssArg NewGSSFunc) { - newGss = newGssArg -} - -// GSS provides GSSAPI authentication (e.g., Kerberos). -type GSS interface { - GetInitToken(host string, service string) ([]byte, error) - GetInitTokenFromSpn(spn string) ([]byte, error) - Continue(inToken []byte) (done bool, outToken []byte, err error) -} diff --git a/vendor/github.com/lib/pq/notice.go b/vendor/github.com/lib/pq/notice.go deleted file mode 100644 index 70ad122a7d6..00000000000 --- a/vendor/github.com/lib/pq/notice.go +++ /dev/null @@ -1,72 +0,0 @@ -//go:build go1.10 -// +build go1.10 - -package pq - -import ( - "context" - "database/sql/driver" -) - -// NoticeHandler returns the notice handler on the given connection, if any. A -// runtime panic occurs if c is not a pq connection. This is rarely used -// directly, use ConnectorNoticeHandler and ConnectorWithNoticeHandler instead. -func NoticeHandler(c driver.Conn) func(*Error) { - return c.(*conn).noticeHandler -} - -// SetNoticeHandler sets the given notice handler on the given connection. A -// runtime panic occurs if c is not a pq connection. A nil handler may be used -// to unset it. This is rarely used directly, use ConnectorNoticeHandler and -// ConnectorWithNoticeHandler instead. -// -// Note: Notice handlers are executed synchronously by pq meaning commands -// won't continue to be processed until the handler returns. -func SetNoticeHandler(c driver.Conn, handler func(*Error)) { - c.(*conn).noticeHandler = handler -} - -// NoticeHandlerConnector wraps a regular connector and sets a notice handler -// on it. -type NoticeHandlerConnector struct { - driver.Connector - noticeHandler func(*Error) -} - -// Connect calls the underlying connector's connect method and then sets the -// notice handler. -func (n *NoticeHandlerConnector) Connect(ctx context.Context) (driver.Conn, error) { - c, err := n.Connector.Connect(ctx) - if err == nil { - SetNoticeHandler(c, n.noticeHandler) - } - return c, err -} - -// ConnectorNoticeHandler returns the currently set notice handler, if any. If -// the given connector is not a result of ConnectorWithNoticeHandler, nil is -// returned. -func ConnectorNoticeHandler(c driver.Connector) func(*Error) { - if c, ok := c.(*NoticeHandlerConnector); ok { - return c.noticeHandler - } - return nil -} - -// ConnectorWithNoticeHandler creates or sets the given handler for the given -// connector. If the given connector is a result of calling this function -// previously, it is simply set on the given connector and returned. Otherwise, -// this returns a new connector wrapping the given one and setting the notice -// handler. A nil notice handler may be used to unset it. -// -// The returned connector is intended to be used with database/sql.OpenDB. -// -// Note: Notice handlers are executed synchronously by pq meaning commands -// won't continue to be processed until the handler returns. -func ConnectorWithNoticeHandler(c driver.Connector, handler func(*Error)) *NoticeHandlerConnector { - if c, ok := c.(*NoticeHandlerConnector); ok { - c.noticeHandler = handler - return c - } - return &NoticeHandlerConnector{Connector: c, noticeHandler: handler} -} diff --git a/vendor/github.com/lib/pq/notify.go b/vendor/github.com/lib/pq/notify.go deleted file mode 100644 index 5c421fdb8b5..00000000000 --- a/vendor/github.com/lib/pq/notify.go +++ /dev/null @@ -1,858 +0,0 @@ -package pq - -// Package pq is a pure Go Postgres driver for the database/sql package. -// This module contains support for Postgres LISTEN/NOTIFY. - -import ( - "context" - "database/sql/driver" - "errors" - "fmt" - "sync" - "sync/atomic" - "time" -) - -// Notification represents a single notification from the database. -type Notification struct { - // Process ID (PID) of the notifying postgres backend. - BePid int - // Name of the channel the notification was sent on. - Channel string - // Payload, or the empty string if unspecified. - Extra string -} - -func recvNotification(r *readBuf) *Notification { - bePid := r.int32() - channel := r.string() - extra := r.string() - - return &Notification{bePid, channel, extra} -} - -// SetNotificationHandler sets the given notification handler on the given -// connection. A runtime panic occurs if c is not a pq connection. A nil handler -// may be used to unset it. -// -// Note: Notification handlers are executed synchronously by pq meaning commands -// won't continue to be processed until the handler returns. -func SetNotificationHandler(c driver.Conn, handler func(*Notification)) { - c.(*conn).notificationHandler = handler -} - -// NotificationHandlerConnector wraps a regular connector and sets a notification handler -// on it. -type NotificationHandlerConnector struct { - driver.Connector - notificationHandler func(*Notification) -} - -// Connect calls the underlying connector's connect method and then sets the -// notification handler. -func (n *NotificationHandlerConnector) Connect(ctx context.Context) (driver.Conn, error) { - c, err := n.Connector.Connect(ctx) - if err == nil { - SetNotificationHandler(c, n.notificationHandler) - } - return c, err -} - -// ConnectorNotificationHandler returns the currently set notification handler, if any. If -// the given connector is not a result of ConnectorWithNotificationHandler, nil is -// returned. -func ConnectorNotificationHandler(c driver.Connector) func(*Notification) { - if c, ok := c.(*NotificationHandlerConnector); ok { - return c.notificationHandler - } - return nil -} - -// ConnectorWithNotificationHandler creates or sets the given handler for the given -// connector. If the given connector is a result of calling this function -// previously, it is simply set on the given connector and returned. Otherwise, -// this returns a new connector wrapping the given one and setting the notification -// handler. A nil notification handler may be used to unset it. -// -// The returned connector is intended to be used with database/sql.OpenDB. -// -// Note: Notification handlers are executed synchronously by pq meaning commands -// won't continue to be processed until the handler returns. -func ConnectorWithNotificationHandler(c driver.Connector, handler func(*Notification)) *NotificationHandlerConnector { - if c, ok := c.(*NotificationHandlerConnector); ok { - c.notificationHandler = handler - return c - } - return &NotificationHandlerConnector{Connector: c, notificationHandler: handler} -} - -const ( - connStateIdle int32 = iota - connStateExpectResponse - connStateExpectReadyForQuery -) - -type message struct { - typ byte - err error -} - -var errListenerConnClosed = errors.New("pq: ListenerConn has been closed") - -// ListenerConn is a low-level interface for waiting for notifications. You -// should use Listener instead. -type ListenerConn struct { - // guards cn and err - connectionLock sync.Mutex - cn *conn - err error - - connState int32 - - // the sending goroutine will be holding this lock - senderLock sync.Mutex - - notificationChan chan<- *Notification - - replyChan chan message -} - -// NewListenerConn creates a new ListenerConn. Use NewListener instead. -func NewListenerConn(name string, notificationChan chan<- *Notification) (*ListenerConn, error) { - return newDialListenerConn(defaultDialer{}, name, notificationChan) -} - -func newDialListenerConn(d Dialer, name string, c chan<- *Notification) (*ListenerConn, error) { - cn, err := DialOpen(d, name) - if err != nil { - return nil, err - } - - l := &ListenerConn{ - cn: cn.(*conn), - notificationChan: c, - connState: connStateIdle, - replyChan: make(chan message, 2), - } - - go l.listenerConnMain() - - return l, nil -} - -// We can only allow one goroutine at a time to be running a query on the -// connection for various reasons, so the goroutine sending on the connection -// must be holding senderLock. -// -// Returns an error if an unrecoverable error has occurred and the ListenerConn -// should be abandoned. -func (l *ListenerConn) acquireSenderLock() error { - // we must acquire senderLock first to avoid deadlocks; see ExecSimpleQuery - l.senderLock.Lock() - - l.connectionLock.Lock() - err := l.err - l.connectionLock.Unlock() - if err != nil { - l.senderLock.Unlock() - return err - } - return nil -} - -func (l *ListenerConn) releaseSenderLock() { - l.senderLock.Unlock() -} - -// setState advances the protocol state to newState. Returns false if moving -// to that state from the current state is not allowed. -func (l *ListenerConn) setState(newState int32) bool { - var expectedState int32 - - switch newState { - case connStateIdle: - expectedState = connStateExpectReadyForQuery - case connStateExpectResponse: - expectedState = connStateIdle - case connStateExpectReadyForQuery: - expectedState = connStateExpectResponse - default: - panic(fmt.Sprintf("unexpected listenerConnState %d", newState)) - } - - return atomic.CompareAndSwapInt32(&l.connState, expectedState, newState) -} - -// Main logic is here: receive messages from the postgres backend, forward -// notifications and query replies and keep the internal state in sync with the -// protocol state. Returns when the connection has been lost, is about to go -// away or should be discarded because we couldn't agree on the state with the -// server backend. -func (l *ListenerConn) listenerConnLoop() (err error) { - defer errRecoverNoErrBadConn(&err) - - r := &readBuf{} - for { - t, err := l.cn.recvMessage(r) - if err != nil { - return err - } - - switch t { - case 'A': - // recvNotification copies all the data so we don't need to worry - // about the scratch buffer being overwritten. - l.notificationChan <- recvNotification(r) - - case 'T', 'D': - // only used by tests; ignore - - case 'E': - // We might receive an ErrorResponse even when not in a query; it - // is expected that the server will close the connection after - // that, but we should make sure that the error we display is the - // one from the stray ErrorResponse, not io.ErrUnexpectedEOF. - if !l.setState(connStateExpectReadyForQuery) { - return parseError(r) - } - l.replyChan <- message{t, parseError(r)} - - case 'C', 'I': - if !l.setState(connStateExpectReadyForQuery) { - // protocol out of sync - return fmt.Errorf("unexpected CommandComplete") - } - // ExecSimpleQuery doesn't need to know about this message - - case 'Z': - if !l.setState(connStateIdle) { - // protocol out of sync - return fmt.Errorf("unexpected ReadyForQuery") - } - l.replyChan <- message{t, nil} - - case 'S': - // ignore - case 'N': - if n := l.cn.noticeHandler; n != nil { - n(parseError(r)) - } - default: - return fmt.Errorf("unexpected message %q from server in listenerConnLoop", t) - } - } -} - -// This is the main routine for the goroutine receiving on the database -// connection. Most of the main logic is in listenerConnLoop. -func (l *ListenerConn) listenerConnMain() { - err := l.listenerConnLoop() - - // listenerConnLoop terminated; we're done, but we still have to clean up. - // Make sure nobody tries to start any new queries by making sure the err - // pointer is set. It is important that we do not overwrite its value; a - // connection could be closed by either this goroutine or one sending on - // the connection -- whoever closes the connection is assumed to have the - // more meaningful error message (as the other one will probably get - // net.errClosed), so that goroutine sets the error we expose while the - // other error is discarded. If the connection is lost while two - // goroutines are operating on the socket, it probably doesn't matter which - // error we expose so we don't try to do anything more complex. - l.connectionLock.Lock() - if l.err == nil { - l.err = err - } - l.cn.Close() - l.connectionLock.Unlock() - - // There might be a query in-flight; make sure nobody's waiting for a - // response to it, since there's not going to be one. - close(l.replyChan) - - // let the listener know we're done - close(l.notificationChan) - - // this ListenerConn is done -} - -// Listen sends a LISTEN query to the server. See ExecSimpleQuery. -func (l *ListenerConn) Listen(channel string) (bool, error) { - return l.ExecSimpleQuery("LISTEN " + QuoteIdentifier(channel)) -} - -// Unlisten sends an UNLISTEN query to the server. See ExecSimpleQuery. -func (l *ListenerConn) Unlisten(channel string) (bool, error) { - return l.ExecSimpleQuery("UNLISTEN " + QuoteIdentifier(channel)) -} - -// UnlistenAll sends an `UNLISTEN *` query to the server. See ExecSimpleQuery. -func (l *ListenerConn) UnlistenAll() (bool, error) { - return l.ExecSimpleQuery("UNLISTEN *") -} - -// Ping the remote server to make sure it's alive. Non-nil error means the -// connection has failed and should be abandoned. -func (l *ListenerConn) Ping() error { - sent, err := l.ExecSimpleQuery("") - if !sent { - return err - } - if err != nil { - // shouldn't happen - panic(err) - } - return nil -} - -// Attempt to send a query on the connection. Returns an error if sending the -// query failed, and the caller should initiate closure of this connection. -// The caller must be holding senderLock (see acquireSenderLock and -// releaseSenderLock). -func (l *ListenerConn) sendSimpleQuery(q string) (err error) { - defer errRecoverNoErrBadConn(&err) - - // must set connection state before sending the query - if !l.setState(connStateExpectResponse) { - panic("two queries running at the same time") - } - - // Can't use l.cn.writeBuf here because it uses the scratch buffer which - // might get overwritten by listenerConnLoop. - b := &writeBuf{ - buf: []byte("Q\x00\x00\x00\x00"), - pos: 1, - } - b.string(q) - l.cn.send(b) - - return nil -} - -// ExecSimpleQuery executes a "simple query" (i.e. one with no bindable -// parameters) on the connection. The possible return values are: -// 1) "executed" is true; the query was executed to completion on the -// database server. If the query failed, err will be set to the error -// returned by the database, otherwise err will be nil. -// 2) If "executed" is false, the query could not be executed on the remote -// server. err will be non-nil. -// -// After a call to ExecSimpleQuery has returned an executed=false value, the -// connection has either been closed or will be closed shortly thereafter, and -// all subsequently executed queries will return an error. -func (l *ListenerConn) ExecSimpleQuery(q string) (executed bool, err error) { - if err = l.acquireSenderLock(); err != nil { - return false, err - } - defer l.releaseSenderLock() - - err = l.sendSimpleQuery(q) - if err != nil { - // We can't know what state the protocol is in, so we need to abandon - // this connection. - l.connectionLock.Lock() - // Set the error pointer if it hasn't been set already; see - // listenerConnMain. - if l.err == nil { - l.err = err - } - l.connectionLock.Unlock() - l.cn.c.Close() - return false, err - } - - // now we just wait for a reply.. - for { - m, ok := <-l.replyChan - if !ok { - // We lost the connection to server, don't bother waiting for a - // a response. err should have been set already. - l.connectionLock.Lock() - err := l.err - l.connectionLock.Unlock() - return false, err - } - switch m.typ { - case 'Z': - // sanity check - if m.err != nil { - panic("m.err != nil") - } - // done; err might or might not be set - return true, err - - case 'E': - // sanity check - if m.err == nil { - panic("m.err == nil") - } - // server responded with an error; ReadyForQuery to follow - err = m.err - - default: - return false, fmt.Errorf("unknown response for simple query: %q", m.typ) - } - } -} - -// Close closes the connection. -func (l *ListenerConn) Close() error { - l.connectionLock.Lock() - if l.err != nil { - l.connectionLock.Unlock() - return errListenerConnClosed - } - l.err = errListenerConnClosed - l.connectionLock.Unlock() - // We can't send anything on the connection without holding senderLock. - // Simply close the net.Conn to wake up everyone operating on it. - return l.cn.c.Close() -} - -// Err returns the reason the connection was closed. It is not safe to call -// this function until l.Notify has been closed. -func (l *ListenerConn) Err() error { - return l.err -} - -var errListenerClosed = errors.New("pq: Listener has been closed") - -// ErrChannelAlreadyOpen is returned from Listen when a channel is already -// open. -var ErrChannelAlreadyOpen = errors.New("pq: channel is already open") - -// ErrChannelNotOpen is returned from Unlisten when a channel is not open. -var ErrChannelNotOpen = errors.New("pq: channel is not open") - -// ListenerEventType is an enumeration of listener event types. -type ListenerEventType int - -const ( - // ListenerEventConnected is emitted only when the database connection - // has been initially initialized. The err argument of the callback - // will always be nil. - ListenerEventConnected ListenerEventType = iota - - // ListenerEventDisconnected is emitted after a database connection has - // been lost, either because of an error or because Close has been - // called. The err argument will be set to the reason the database - // connection was lost. - ListenerEventDisconnected - - // ListenerEventReconnected is emitted after a database connection has - // been re-established after connection loss. The err argument of the - // callback will always be nil. After this event has been emitted, a - // nil pq.Notification is sent on the Listener.Notify channel. - ListenerEventReconnected - - // ListenerEventConnectionAttemptFailed is emitted after a connection - // to the database was attempted, but failed. The err argument will be - // set to an error describing why the connection attempt did not - // succeed. - ListenerEventConnectionAttemptFailed -) - -// EventCallbackType is the event callback type. See also ListenerEventType -// constants' documentation. -type EventCallbackType func(event ListenerEventType, err error) - -// Listener provides an interface for listening to notifications from a -// PostgreSQL database. For general usage information, see section -// "Notifications". -// -// Listener can safely be used from concurrently running goroutines. -type Listener struct { - // Channel for receiving notifications from the database. In some cases a - // nil value will be sent. See section "Notifications" above. - Notify chan *Notification - - name string - minReconnectInterval time.Duration - maxReconnectInterval time.Duration - dialer Dialer - eventCallback EventCallbackType - - lock sync.Mutex - isClosed bool - reconnectCond *sync.Cond - cn *ListenerConn - connNotificationChan <-chan *Notification - channels map[string]struct{} -} - -// NewListener creates a new database connection dedicated to LISTEN / NOTIFY. -// -// name should be set to a connection string to be used to establish the -// database connection (see section "Connection String Parameters" above). -// -// minReconnectInterval controls the duration to wait before trying to -// re-establish the database connection after connection loss. After each -// consecutive failure this interval is doubled, until maxReconnectInterval is -// reached. Successfully completing the connection establishment procedure -// resets the interval back to minReconnectInterval. -// -// The last parameter eventCallback can be set to a function which will be -// called by the Listener when the state of the underlying database connection -// changes. This callback will be called by the goroutine which dispatches the -// notifications over the Notify channel, so you should try to avoid doing -// potentially time-consuming operations from the callback. -func NewListener(name string, - minReconnectInterval time.Duration, - maxReconnectInterval time.Duration, - eventCallback EventCallbackType) *Listener { - return NewDialListener(defaultDialer{}, name, minReconnectInterval, maxReconnectInterval, eventCallback) -} - -// NewDialListener is like NewListener but it takes a Dialer. -func NewDialListener(d Dialer, - name string, - minReconnectInterval time.Duration, - maxReconnectInterval time.Duration, - eventCallback EventCallbackType) *Listener { - - l := &Listener{ - name: name, - minReconnectInterval: minReconnectInterval, - maxReconnectInterval: maxReconnectInterval, - dialer: d, - eventCallback: eventCallback, - - channels: make(map[string]struct{}), - - Notify: make(chan *Notification, 32), - } - l.reconnectCond = sync.NewCond(&l.lock) - - go l.listenerMain() - - return l -} - -// NotificationChannel returns the notification channel for this listener. -// This is the same channel as Notify, and will not be recreated during the -// life time of the Listener. -func (l *Listener) NotificationChannel() <-chan *Notification { - return l.Notify -} - -// Listen starts listening for notifications on a channel. Calls to this -// function will block until an acknowledgement has been received from the -// server. Note that Listener automatically re-establishes the connection -// after connection loss, so this function may block indefinitely if the -// connection can not be re-established. -// -// Listen will only fail in three conditions: -// 1) The channel is already open. The returned error will be -// ErrChannelAlreadyOpen. -// 2) The query was executed on the remote server, but PostgreSQL returned an -// error message in response to the query. The returned error will be a -// pq.Error containing the information the server supplied. -// 3) Close is called on the Listener before the request could be completed. -// -// The channel name is case-sensitive. -func (l *Listener) Listen(channel string) error { - l.lock.Lock() - defer l.lock.Unlock() - - if l.isClosed { - return errListenerClosed - } - - // The server allows you to issue a LISTEN on a channel which is already - // open, but it seems useful to be able to detect this case to spot for - // mistakes in application logic. If the application genuinely does't - // care, it can check the exported error and ignore it. - _, exists := l.channels[channel] - if exists { - return ErrChannelAlreadyOpen - } - - if l.cn != nil { - // If gotResponse is true but error is set, the query was executed on - // the remote server, but resulted in an error. This should be - // relatively rare, so it's fine if we just pass the error to our - // caller. However, if gotResponse is false, we could not complete the - // query on the remote server and our underlying connection is about - // to go away, so we only add relname to l.channels, and wait for - // resync() to take care of the rest. - gotResponse, err := l.cn.Listen(channel) - if gotResponse && err != nil { - return err - } - } - - l.channels[channel] = struct{}{} - for l.cn == nil { - l.reconnectCond.Wait() - // we let go of the mutex for a while - if l.isClosed { - return errListenerClosed - } - } - - return nil -} - -// Unlisten removes a channel from the Listener's channel list. Returns -// ErrChannelNotOpen if the Listener is not listening on the specified channel. -// Returns immediately with no error if there is no connection. Note that you -// might still get notifications for this channel even after Unlisten has -// returned. -// -// The channel name is case-sensitive. -func (l *Listener) Unlisten(channel string) error { - l.lock.Lock() - defer l.lock.Unlock() - - if l.isClosed { - return errListenerClosed - } - - // Similarly to LISTEN, this is not an error in Postgres, but it seems - // useful to distinguish from the normal conditions. - _, exists := l.channels[channel] - if !exists { - return ErrChannelNotOpen - } - - if l.cn != nil { - // Similarly to Listen (see comment in that function), the caller - // should only be bothered with an error if it came from the backend as - // a response to our query. - gotResponse, err := l.cn.Unlisten(channel) - if gotResponse && err != nil { - return err - } - } - - // Don't bother waiting for resync if there's no connection. - delete(l.channels, channel) - return nil -} - -// UnlistenAll removes all channels from the Listener's channel list. Returns -// immediately with no error if there is no connection. Note that you might -// still get notifications for any of the deleted channels even after -// UnlistenAll has returned. -func (l *Listener) UnlistenAll() error { - l.lock.Lock() - defer l.lock.Unlock() - - if l.isClosed { - return errListenerClosed - } - - if l.cn != nil { - // Similarly to Listen (see comment in that function), the caller - // should only be bothered with an error if it came from the backend as - // a response to our query. - gotResponse, err := l.cn.UnlistenAll() - if gotResponse && err != nil { - return err - } - } - - // Don't bother waiting for resync if there's no connection. - l.channels = make(map[string]struct{}) - return nil -} - -// Ping the remote server to make sure it's alive. Non-nil return value means -// that there is no active connection. -func (l *Listener) Ping() error { - l.lock.Lock() - defer l.lock.Unlock() - - if l.isClosed { - return errListenerClosed - } - if l.cn == nil { - return errors.New("no connection") - } - - return l.cn.Ping() -} - -// Clean up after losing the server connection. Returns l.cn.Err(), which -// should have the reason the connection was lost. -func (l *Listener) disconnectCleanup() error { - l.lock.Lock() - defer l.lock.Unlock() - - // sanity check; can't look at Err() until the channel has been closed - select { - case _, ok := <-l.connNotificationChan: - if ok { - panic("connNotificationChan not closed") - } - default: - panic("connNotificationChan not closed") - } - - err := l.cn.Err() - l.cn.Close() - l.cn = nil - return err -} - -// Synchronize the list of channels we want to be listening on with the server -// after the connection has been established. -func (l *Listener) resync(cn *ListenerConn, notificationChan <-chan *Notification) error { - doneChan := make(chan error) - go func(notificationChan <-chan *Notification) { - for channel := range l.channels { - // If we got a response, return that error to our caller as it's - // going to be more descriptive than cn.Err(). - gotResponse, err := cn.Listen(channel) - if gotResponse && err != nil { - doneChan <- err - return - } - - // If we couldn't reach the server, wait for notificationChan to - // close and then return the error message from the connection, as - // per ListenerConn's interface. - if err != nil { - for range notificationChan { - } - doneChan <- cn.Err() - return - } - } - doneChan <- nil - }(notificationChan) - - // Ignore notifications while synchronization is going on to avoid - // deadlocks. We have to send a nil notification over Notify anyway as - // we can't possibly know which notifications (if any) were lost while - // the connection was down, so there's no reason to try and process - // these messages at all. - for { - select { - case _, ok := <-notificationChan: - if !ok { - notificationChan = nil - } - - case err := <-doneChan: - return err - } - } -} - -// caller should NOT be holding l.lock -func (l *Listener) closed() bool { - l.lock.Lock() - defer l.lock.Unlock() - - return l.isClosed -} - -func (l *Listener) connect() error { - notificationChan := make(chan *Notification, 32) - cn, err := newDialListenerConn(l.dialer, l.name, notificationChan) - if err != nil { - return err - } - - l.lock.Lock() - defer l.lock.Unlock() - - err = l.resync(cn, notificationChan) - if err != nil { - cn.Close() - return err - } - - l.cn = cn - l.connNotificationChan = notificationChan - l.reconnectCond.Broadcast() - - return nil -} - -// Close disconnects the Listener from the database and shuts it down. -// Subsequent calls to its methods will return an error. Close returns an -// error if the connection has already been closed. -func (l *Listener) Close() error { - l.lock.Lock() - defer l.lock.Unlock() - - if l.isClosed { - return errListenerClosed - } - - if l.cn != nil { - l.cn.Close() - } - l.isClosed = true - - // Unblock calls to Listen() - l.reconnectCond.Broadcast() - - return nil -} - -func (l *Listener) emitEvent(event ListenerEventType, err error) { - if l.eventCallback != nil { - l.eventCallback(event, err) - } -} - -// Main logic here: maintain a connection to the server when possible, wait -// for notifications and emit events. -func (l *Listener) listenerConnLoop() { - var nextReconnect time.Time - - reconnectInterval := l.minReconnectInterval - for { - for { - err := l.connect() - if err == nil { - break - } - - if l.closed() { - return - } - l.emitEvent(ListenerEventConnectionAttemptFailed, err) - - time.Sleep(reconnectInterval) - reconnectInterval *= 2 - if reconnectInterval > l.maxReconnectInterval { - reconnectInterval = l.maxReconnectInterval - } - } - - if nextReconnect.IsZero() { - l.emitEvent(ListenerEventConnected, nil) - } else { - l.emitEvent(ListenerEventReconnected, nil) - l.Notify <- nil - } - - reconnectInterval = l.minReconnectInterval - nextReconnect = time.Now().Add(reconnectInterval) - - for { - notification, ok := <-l.connNotificationChan - if !ok { - // lost connection, loop again - break - } - l.Notify <- notification - } - - err := l.disconnectCleanup() - if l.closed() { - return - } - l.emitEvent(ListenerEventDisconnected, err) - - time.Sleep(time.Until(nextReconnect)) - } -} - -func (l *Listener) listenerMain() { - l.listenerConnLoop() - close(l.Notify) -} diff --git a/vendor/github.com/lib/pq/oid/doc.go b/vendor/github.com/lib/pq/oid/doc.go deleted file mode 100644 index caaede2489d..00000000000 --- a/vendor/github.com/lib/pq/oid/doc.go +++ /dev/null @@ -1,6 +0,0 @@ -// Package oid contains OID constants -// as defined by the Postgres server. -package oid - -// Oid is a Postgres Object ID. -type Oid uint32 diff --git a/vendor/github.com/lib/pq/oid/types.go b/vendor/github.com/lib/pq/oid/types.go deleted file mode 100644 index ecc84c2c862..00000000000 --- a/vendor/github.com/lib/pq/oid/types.go +++ /dev/null @@ -1,343 +0,0 @@ -// Code generated by gen.go. DO NOT EDIT. - -package oid - -const ( - T_bool Oid = 16 - T_bytea Oid = 17 - T_char Oid = 18 - T_name Oid = 19 - T_int8 Oid = 20 - T_int2 Oid = 21 - T_int2vector Oid = 22 - T_int4 Oid = 23 - T_regproc Oid = 24 - T_text Oid = 25 - T_oid Oid = 26 - T_tid Oid = 27 - T_xid Oid = 28 - T_cid Oid = 29 - T_oidvector Oid = 30 - T_pg_ddl_command Oid = 32 - T_pg_type Oid = 71 - T_pg_attribute Oid = 75 - T_pg_proc Oid = 81 - T_pg_class Oid = 83 - T_json Oid = 114 - T_xml Oid = 142 - T__xml Oid = 143 - T_pg_node_tree Oid = 194 - T__json Oid = 199 - T_smgr Oid = 210 - T_index_am_handler Oid = 325 - T_point Oid = 600 - T_lseg Oid = 601 - T_path Oid = 602 - T_box Oid = 603 - T_polygon Oid = 604 - T_line Oid = 628 - T__line Oid = 629 - T_cidr Oid = 650 - T__cidr Oid = 651 - T_float4 Oid = 700 - T_float8 Oid = 701 - T_abstime Oid = 702 - T_reltime Oid = 703 - T_tinterval Oid = 704 - T_unknown Oid = 705 - T_circle Oid = 718 - T__circle Oid = 719 - T_money Oid = 790 - T__money Oid = 791 - T_macaddr Oid = 829 - T_inet Oid = 869 - T__bool Oid = 1000 - T__bytea Oid = 1001 - T__char Oid = 1002 - T__name Oid = 1003 - T__int2 Oid = 1005 - T__int2vector Oid = 1006 - T__int4 Oid = 1007 - T__regproc Oid = 1008 - T__text Oid = 1009 - T__tid Oid = 1010 - T__xid Oid = 1011 - T__cid Oid = 1012 - T__oidvector Oid = 1013 - T__bpchar Oid = 1014 - T__varchar Oid = 1015 - T__int8 Oid = 1016 - T__point Oid = 1017 - T__lseg Oid = 1018 - T__path Oid = 1019 - T__box Oid = 1020 - T__float4 Oid = 1021 - T__float8 Oid = 1022 - T__abstime Oid = 1023 - T__reltime Oid = 1024 - T__tinterval Oid = 1025 - T__polygon Oid = 1027 - T__oid Oid = 1028 - T_aclitem Oid = 1033 - T__aclitem Oid = 1034 - T__macaddr Oid = 1040 - T__inet Oid = 1041 - T_bpchar Oid = 1042 - T_varchar Oid = 1043 - T_date Oid = 1082 - T_time Oid = 1083 - T_timestamp Oid = 1114 - T__timestamp Oid = 1115 - T__date Oid = 1182 - T__time Oid = 1183 - T_timestamptz Oid = 1184 - T__timestamptz Oid = 1185 - T_interval Oid = 1186 - T__interval Oid = 1187 - T__numeric Oid = 1231 - T_pg_database Oid = 1248 - T__cstring Oid = 1263 - T_timetz Oid = 1266 - T__timetz Oid = 1270 - T_bit Oid = 1560 - T__bit Oid = 1561 - T_varbit Oid = 1562 - T__varbit Oid = 1563 - T_numeric Oid = 1700 - T_refcursor Oid = 1790 - T__refcursor Oid = 2201 - T_regprocedure Oid = 2202 - T_regoper Oid = 2203 - T_regoperator Oid = 2204 - T_regclass Oid = 2205 - T_regtype Oid = 2206 - T__regprocedure Oid = 2207 - T__regoper Oid = 2208 - T__regoperator Oid = 2209 - T__regclass Oid = 2210 - T__regtype Oid = 2211 - T_record Oid = 2249 - T_cstring Oid = 2275 - T_any Oid = 2276 - T_anyarray Oid = 2277 - T_void Oid = 2278 - T_trigger Oid = 2279 - T_language_handler Oid = 2280 - T_internal Oid = 2281 - T_opaque Oid = 2282 - T_anyelement Oid = 2283 - T__record Oid = 2287 - T_anynonarray Oid = 2776 - T_pg_authid Oid = 2842 - T_pg_auth_members Oid = 2843 - T__txid_snapshot Oid = 2949 - T_uuid Oid = 2950 - T__uuid Oid = 2951 - T_txid_snapshot Oid = 2970 - T_fdw_handler Oid = 3115 - T_pg_lsn Oid = 3220 - T__pg_lsn Oid = 3221 - T_tsm_handler Oid = 3310 - T_anyenum Oid = 3500 - T_tsvector Oid = 3614 - T_tsquery Oid = 3615 - T_gtsvector Oid = 3642 - T__tsvector Oid = 3643 - T__gtsvector Oid = 3644 - T__tsquery Oid = 3645 - T_regconfig Oid = 3734 - T__regconfig Oid = 3735 - T_regdictionary Oid = 3769 - T__regdictionary Oid = 3770 - T_jsonb Oid = 3802 - T__jsonb Oid = 3807 - T_anyrange Oid = 3831 - T_event_trigger Oid = 3838 - T_int4range Oid = 3904 - T__int4range Oid = 3905 - T_numrange Oid = 3906 - T__numrange Oid = 3907 - T_tsrange Oid = 3908 - T__tsrange Oid = 3909 - T_tstzrange Oid = 3910 - T__tstzrange Oid = 3911 - T_daterange Oid = 3912 - T__daterange Oid = 3913 - T_int8range Oid = 3926 - T__int8range Oid = 3927 - T_pg_shseclabel Oid = 4066 - T_regnamespace Oid = 4089 - T__regnamespace Oid = 4090 - T_regrole Oid = 4096 - T__regrole Oid = 4097 -) - -var TypeName = map[Oid]string{ - T_bool: "BOOL", - T_bytea: "BYTEA", - T_char: "CHAR", - T_name: "NAME", - T_int8: "INT8", - T_int2: "INT2", - T_int2vector: "INT2VECTOR", - T_int4: "INT4", - T_regproc: "REGPROC", - T_text: "TEXT", - T_oid: "OID", - T_tid: "TID", - T_xid: "XID", - T_cid: "CID", - T_oidvector: "OIDVECTOR", - T_pg_ddl_command: "PG_DDL_COMMAND", - T_pg_type: "PG_TYPE", - T_pg_attribute: "PG_ATTRIBUTE", - T_pg_proc: "PG_PROC", - T_pg_class: "PG_CLASS", - T_json: "JSON", - T_xml: "XML", - T__xml: "_XML", - T_pg_node_tree: "PG_NODE_TREE", - T__json: "_JSON", - T_smgr: "SMGR", - T_index_am_handler: "INDEX_AM_HANDLER", - T_point: "POINT", - T_lseg: "LSEG", - T_path: "PATH", - T_box: "BOX", - T_polygon: "POLYGON", - T_line: "LINE", - T__line: "_LINE", - T_cidr: "CIDR", - T__cidr: "_CIDR", - T_float4: "FLOAT4", - T_float8: "FLOAT8", - T_abstime: "ABSTIME", - T_reltime: "RELTIME", - T_tinterval: "TINTERVAL", - T_unknown: "UNKNOWN", - T_circle: "CIRCLE", - T__circle: "_CIRCLE", - T_money: "MONEY", - T__money: "_MONEY", - T_macaddr: "MACADDR", - T_inet: "INET", - T__bool: "_BOOL", - T__bytea: "_BYTEA", - T__char: "_CHAR", - T__name: "_NAME", - T__int2: "_INT2", - T__int2vector: "_INT2VECTOR", - T__int4: "_INT4", - T__regproc: "_REGPROC", - T__text: "_TEXT", - T__tid: "_TID", - T__xid: "_XID", - T__cid: "_CID", - T__oidvector: "_OIDVECTOR", - T__bpchar: "_BPCHAR", - T__varchar: "_VARCHAR", - T__int8: "_INT8", - T__point: "_POINT", - T__lseg: "_LSEG", - T__path: "_PATH", - T__box: "_BOX", - T__float4: "_FLOAT4", - T__float8: "_FLOAT8", - T__abstime: "_ABSTIME", - T__reltime: "_RELTIME", - T__tinterval: "_TINTERVAL", - T__polygon: "_POLYGON", - T__oid: "_OID", - T_aclitem: "ACLITEM", - T__aclitem: "_ACLITEM", - T__macaddr: "_MACADDR", - T__inet: "_INET", - T_bpchar: "BPCHAR", - T_varchar: "VARCHAR", - T_date: "DATE", - T_time: "TIME", - T_timestamp: "TIMESTAMP", - T__timestamp: "_TIMESTAMP", - T__date: "_DATE", - T__time: "_TIME", - T_timestamptz: "TIMESTAMPTZ", - T__timestamptz: "_TIMESTAMPTZ", - T_interval: "INTERVAL", - T__interval: "_INTERVAL", - T__numeric: "_NUMERIC", - T_pg_database: "PG_DATABASE", - T__cstring: "_CSTRING", - T_timetz: "TIMETZ", - T__timetz: "_TIMETZ", - T_bit: "BIT", - T__bit: "_BIT", - T_varbit: "VARBIT", - T__varbit: "_VARBIT", - T_numeric: "NUMERIC", - T_refcursor: "REFCURSOR", - T__refcursor: "_REFCURSOR", - T_regprocedure: "REGPROCEDURE", - T_regoper: "REGOPER", - T_regoperator: "REGOPERATOR", - T_regclass: "REGCLASS", - T_regtype: "REGTYPE", - T__regprocedure: "_REGPROCEDURE", - T__regoper: "_REGOPER", - T__regoperator: "_REGOPERATOR", - T__regclass: "_REGCLASS", - T__regtype: "_REGTYPE", - T_record: "RECORD", - T_cstring: "CSTRING", - T_any: "ANY", - T_anyarray: "ANYARRAY", - T_void: "VOID", - T_trigger: "TRIGGER", - T_language_handler: "LANGUAGE_HANDLER", - T_internal: "INTERNAL", - T_opaque: "OPAQUE", - T_anyelement: "ANYELEMENT", - T__record: "_RECORD", - T_anynonarray: "ANYNONARRAY", - T_pg_authid: "PG_AUTHID", - T_pg_auth_members: "PG_AUTH_MEMBERS", - T__txid_snapshot: "_TXID_SNAPSHOT", - T_uuid: "UUID", - T__uuid: "_UUID", - T_txid_snapshot: "TXID_SNAPSHOT", - T_fdw_handler: "FDW_HANDLER", - T_pg_lsn: "PG_LSN", - T__pg_lsn: "_PG_LSN", - T_tsm_handler: "TSM_HANDLER", - T_anyenum: "ANYENUM", - T_tsvector: "TSVECTOR", - T_tsquery: "TSQUERY", - T_gtsvector: "GTSVECTOR", - T__tsvector: "_TSVECTOR", - T__gtsvector: "_GTSVECTOR", - T__tsquery: "_TSQUERY", - T_regconfig: "REGCONFIG", - T__regconfig: "_REGCONFIG", - T_regdictionary: "REGDICTIONARY", - T__regdictionary: "_REGDICTIONARY", - T_jsonb: "JSONB", - T__jsonb: "_JSONB", - T_anyrange: "ANYRANGE", - T_event_trigger: "EVENT_TRIGGER", - T_int4range: "INT4RANGE", - T__int4range: "_INT4RANGE", - T_numrange: "NUMRANGE", - T__numrange: "_NUMRANGE", - T_tsrange: "TSRANGE", - T__tsrange: "_TSRANGE", - T_tstzrange: "TSTZRANGE", - T__tstzrange: "_TSTZRANGE", - T_daterange: "DATERANGE", - T__daterange: "_DATERANGE", - T_int8range: "INT8RANGE", - T__int8range: "_INT8RANGE", - T_pg_shseclabel: "PG_SHSECLABEL", - T_regnamespace: "REGNAMESPACE", - T__regnamespace: "_REGNAMESPACE", - T_regrole: "REGROLE", - T__regrole: "_REGROLE", -} diff --git a/vendor/github.com/lib/pq/rows.go b/vendor/github.com/lib/pq/rows.go deleted file mode 100644 index c6aa5b9a36a..00000000000 --- a/vendor/github.com/lib/pq/rows.go +++ /dev/null @@ -1,93 +0,0 @@ -package pq - -import ( - "math" - "reflect" - "time" - - "github.com/lib/pq/oid" -) - -const headerSize = 4 - -type fieldDesc struct { - // The object ID of the data type. - OID oid.Oid - // The data type size (see pg_type.typlen). - // Note that negative values denote variable-width types. - Len int - // The type modifier (see pg_attribute.atttypmod). - // The meaning of the modifier is type-specific. - Mod int -} - -func (fd fieldDesc) Type() reflect.Type { - switch fd.OID { - case oid.T_int8: - return reflect.TypeOf(int64(0)) - case oid.T_int4: - return reflect.TypeOf(int32(0)) - case oid.T_int2: - return reflect.TypeOf(int16(0)) - case oid.T_varchar, oid.T_text: - return reflect.TypeOf("") - case oid.T_bool: - return reflect.TypeOf(false) - case oid.T_date, oid.T_time, oid.T_timetz, oid.T_timestamp, oid.T_timestamptz: - return reflect.TypeOf(time.Time{}) - case oid.T_bytea: - return reflect.TypeOf([]byte(nil)) - default: - return reflect.TypeOf(new(interface{})).Elem() - } -} - -func (fd fieldDesc) Name() string { - return oid.TypeName[fd.OID] -} - -func (fd fieldDesc) Length() (length int64, ok bool) { - switch fd.OID { - case oid.T_text, oid.T_bytea: - return math.MaxInt64, true - case oid.T_varchar, oid.T_bpchar: - return int64(fd.Mod - headerSize), true - default: - return 0, false - } -} - -func (fd fieldDesc) PrecisionScale() (precision, scale int64, ok bool) { - switch fd.OID { - case oid.T_numeric, oid.T__numeric: - mod := fd.Mod - headerSize - precision = int64((mod >> 16) & 0xffff) - scale = int64(mod & 0xffff) - return precision, scale, true - default: - return 0, 0, false - } -} - -// ColumnTypeScanType returns the value type that can be used to scan types into. -func (rs *rows) ColumnTypeScanType(index int) reflect.Type { - return rs.colTyps[index].Type() -} - -// ColumnTypeDatabaseTypeName return the database system type name. -func (rs *rows) ColumnTypeDatabaseTypeName(index int) string { - return rs.colTyps[index].Name() -} - -// ColumnTypeLength returns the length of the column type if the column is a -// variable length type. If the column is not a variable length type ok -// should return false. -func (rs *rows) ColumnTypeLength(index int) (length int64, ok bool) { - return rs.colTyps[index].Length() -} - -// ColumnTypePrecisionScale should return the precision and scale for decimal -// types. If not applicable, ok should be false. -func (rs *rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { - return rs.colTyps[index].PrecisionScale() -} diff --git a/vendor/github.com/lib/pq/scram/scram.go b/vendor/github.com/lib/pq/scram/scram.go deleted file mode 100644 index 477216b6008..00000000000 --- a/vendor/github.com/lib/pq/scram/scram.go +++ /dev/null @@ -1,264 +0,0 @@ -// Copyright (c) 2014 - Gustavo Niemeyer -// -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// 2. Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Package scram implements a SCRAM-{SHA-1,etc} client per RFC5802. -// -// http://tools.ietf.org/html/rfc5802 -// -package scram - -import ( - "bytes" - "crypto/hmac" - "crypto/rand" - "encoding/base64" - "fmt" - "hash" - "strconv" - "strings" -) - -// Client implements a SCRAM-* client (SCRAM-SHA-1, SCRAM-SHA-256, etc). -// -// A Client may be used within a SASL conversation with logic resembling: -// -// var in []byte -// var client = scram.NewClient(sha1.New, user, pass) -// for client.Step(in) { -// out := client.Out() -// // send out to server -// in := serverOut -// } -// if client.Err() != nil { -// // auth failed -// } -// -type Client struct { - newHash func() hash.Hash - - user string - pass string - step int - out bytes.Buffer - err error - - clientNonce []byte - serverNonce []byte - saltedPass []byte - authMsg bytes.Buffer -} - -// NewClient returns a new SCRAM-* client with the provided hash algorithm. -// -// For SCRAM-SHA-256, for example, use: -// -// client := scram.NewClient(sha256.New, user, pass) -// -func NewClient(newHash func() hash.Hash, user, pass string) *Client { - c := &Client{ - newHash: newHash, - user: user, - pass: pass, - } - c.out.Grow(256) - c.authMsg.Grow(256) - return c -} - -// Out returns the data to be sent to the server in the current step. -func (c *Client) Out() []byte { - if c.out.Len() == 0 { - return nil - } - return c.out.Bytes() -} - -// Err returns the error that occurred, or nil if there were no errors. -func (c *Client) Err() error { - return c.err -} - -// SetNonce sets the client nonce to the provided value. -// If not set, the nonce is generated automatically out of crypto/rand on the first step. -func (c *Client) SetNonce(nonce []byte) { - c.clientNonce = nonce -} - -var escaper = strings.NewReplacer("=", "=3D", ",", "=2C") - -// Step processes the incoming data from the server and makes the -// next round of data for the server available via Client.Out. -// Step returns false if there are no errors and more data is -// still expected. -func (c *Client) Step(in []byte) bool { - c.out.Reset() - if c.step > 2 || c.err != nil { - return false - } - c.step++ - switch c.step { - case 1: - c.err = c.step1(in) - case 2: - c.err = c.step2(in) - case 3: - c.err = c.step3(in) - } - return c.step > 2 || c.err != nil -} - -func (c *Client) step1(in []byte) error { - if len(c.clientNonce) == 0 { - const nonceLen = 16 - buf := make([]byte, nonceLen+b64.EncodedLen(nonceLen)) - if _, err := rand.Read(buf[:nonceLen]); err != nil { - return fmt.Errorf("cannot read random SCRAM-SHA-256 nonce from operating system: %v", err) - } - c.clientNonce = buf[nonceLen:] - b64.Encode(c.clientNonce, buf[:nonceLen]) - } - c.authMsg.WriteString("n=") - escaper.WriteString(&c.authMsg, c.user) - c.authMsg.WriteString(",r=") - c.authMsg.Write(c.clientNonce) - - c.out.WriteString("n,,") - c.out.Write(c.authMsg.Bytes()) - return nil -} - -var b64 = base64.StdEncoding - -func (c *Client) step2(in []byte) error { - c.authMsg.WriteByte(',') - c.authMsg.Write(in) - - fields := bytes.Split(in, []byte(",")) - if len(fields) != 3 { - return fmt.Errorf("expected 3 fields in first SCRAM-SHA-256 server message, got %d: %q", len(fields), in) - } - if !bytes.HasPrefix(fields[0], []byte("r=")) || len(fields[0]) < 2 { - return fmt.Errorf("server sent an invalid SCRAM-SHA-256 nonce: %q", fields[0]) - } - if !bytes.HasPrefix(fields[1], []byte("s=")) || len(fields[1]) < 6 { - return fmt.Errorf("server sent an invalid SCRAM-SHA-256 salt: %q", fields[1]) - } - if !bytes.HasPrefix(fields[2], []byte("i=")) || len(fields[2]) < 6 { - return fmt.Errorf("server sent an invalid SCRAM-SHA-256 iteration count: %q", fields[2]) - } - - c.serverNonce = fields[0][2:] - if !bytes.HasPrefix(c.serverNonce, c.clientNonce) { - return fmt.Errorf("server SCRAM-SHA-256 nonce is not prefixed by client nonce: got %q, want %q+\"...\"", c.serverNonce, c.clientNonce) - } - - salt := make([]byte, b64.DecodedLen(len(fields[1][2:]))) - n, err := b64.Decode(salt, fields[1][2:]) - if err != nil { - return fmt.Errorf("cannot decode SCRAM-SHA-256 salt sent by server: %q", fields[1]) - } - salt = salt[:n] - iterCount, err := strconv.Atoi(string(fields[2][2:])) - if err != nil { - return fmt.Errorf("server sent an invalid SCRAM-SHA-256 iteration count: %q", fields[2]) - } - c.saltPassword(salt, iterCount) - - c.authMsg.WriteString(",c=biws,r=") - c.authMsg.Write(c.serverNonce) - - c.out.WriteString("c=biws,r=") - c.out.Write(c.serverNonce) - c.out.WriteString(",p=") - c.out.Write(c.clientProof()) - return nil -} - -func (c *Client) step3(in []byte) error { - var isv, ise bool - var fields = bytes.Split(in, []byte(",")) - if len(fields) == 1 { - isv = bytes.HasPrefix(fields[0], []byte("v=")) - ise = bytes.HasPrefix(fields[0], []byte("e=")) - } - if ise { - return fmt.Errorf("SCRAM-SHA-256 authentication error: %s", fields[0][2:]) - } else if !isv { - return fmt.Errorf("unsupported SCRAM-SHA-256 final message from server: %q", in) - } - if !bytes.Equal(c.serverSignature(), fields[0][2:]) { - return fmt.Errorf("cannot authenticate SCRAM-SHA-256 server signature: %q", fields[0][2:]) - } - return nil -} - -func (c *Client) saltPassword(salt []byte, iterCount int) { - mac := hmac.New(c.newHash, []byte(c.pass)) - mac.Write(salt) - mac.Write([]byte{0, 0, 0, 1}) - ui := mac.Sum(nil) - hi := make([]byte, len(ui)) - copy(hi, ui) - for i := 1; i < iterCount; i++ { - mac.Reset() - mac.Write(ui) - mac.Sum(ui[:0]) - for j, b := range ui { - hi[j] ^= b - } - } - c.saltedPass = hi -} - -func (c *Client) clientProof() []byte { - mac := hmac.New(c.newHash, c.saltedPass) - mac.Write([]byte("Client Key")) - clientKey := mac.Sum(nil) - hash := c.newHash() - hash.Write(clientKey) - storedKey := hash.Sum(nil) - mac = hmac.New(c.newHash, storedKey) - mac.Write(c.authMsg.Bytes()) - clientProof := mac.Sum(nil) - for i, b := range clientKey { - clientProof[i] ^= b - } - clientProof64 := make([]byte, b64.EncodedLen(len(clientProof))) - b64.Encode(clientProof64, clientProof) - return clientProof64 -} - -func (c *Client) serverSignature() []byte { - mac := hmac.New(c.newHash, c.saltedPass) - mac.Write([]byte("Server Key")) - serverKey := mac.Sum(nil) - - mac = hmac.New(c.newHash, serverKey) - mac.Write(c.authMsg.Bytes()) - serverSignature := mac.Sum(nil) - - encoded := make([]byte, b64.EncodedLen(len(serverSignature))) - b64.Encode(encoded, serverSignature) - return encoded -} diff --git a/vendor/github.com/lib/pq/ssl.go b/vendor/github.com/lib/pq/ssl.go deleted file mode 100644 index 36b61ba45be..00000000000 --- a/vendor/github.com/lib/pq/ssl.go +++ /dev/null @@ -1,204 +0,0 @@ -package pq - -import ( - "crypto/tls" - "crypto/x509" - "io/ioutil" - "net" - "os" - "os/user" - "path/filepath" - "strings" -) - -// ssl generates a function to upgrade a net.Conn based on the "sslmode" and -// related settings. The function is nil when no upgrade should take place. -func ssl(o values) (func(net.Conn) (net.Conn, error), error) { - verifyCaOnly := false - tlsConf := tls.Config{} - switch mode := o["sslmode"]; mode { - // "require" is the default. - case "", "require": - // We must skip TLS's own verification since it requires full - // verification since Go 1.3. - tlsConf.InsecureSkipVerify = true - - // From http://www.postgresql.org/docs/current/static/libpq-ssl.html: - // - // Note: For backwards compatibility with earlier versions of - // PostgreSQL, if a root CA file exists, the behavior of - // sslmode=require will be the same as that of verify-ca, meaning the - // server certificate is validated against the CA. Relying on this - // behavior is discouraged, and applications that need certificate - // validation should always use verify-ca or verify-full. - if sslrootcert, ok := o["sslrootcert"]; ok { - if _, err := os.Stat(sslrootcert); err == nil { - verifyCaOnly = true - } else { - delete(o, "sslrootcert") - } - } - case "verify-ca": - // We must skip TLS's own verification since it requires full - // verification since Go 1.3. - tlsConf.InsecureSkipVerify = true - verifyCaOnly = true - case "verify-full": - tlsConf.ServerName = o["host"] - case "disable": - return nil, nil - default: - return nil, fmterrorf(`unsupported sslmode %q; only "require" (default), "verify-full", "verify-ca", and "disable" supported`, mode) - } - - // Set Server Name Indication (SNI), if enabled by connection parameters. - // By default SNI is on, any value which is not starting with "1" disables - // SNI -- that is the same check vanilla libpq uses. - if sslsni := o["sslsni"]; sslsni == "" || strings.HasPrefix(sslsni, "1") { - // RFC 6066 asks to not set SNI if the host is a literal IP address (IPv4 - // or IPv6). This check is coded already crypto.tls.hostnameInSNI, so - // just always set ServerName here and let crypto/tls do the filtering. - tlsConf.ServerName = o["host"] - } - - err := sslClientCertificates(&tlsConf, o) - if err != nil { - return nil, err - } - err = sslCertificateAuthority(&tlsConf, o) - if err != nil { - return nil, err - } - - // Accept renegotiation requests initiated by the backend. - // - // Renegotiation was deprecated then removed from PostgreSQL 9.5, but - // the default configuration of older versions has it enabled. Redshift - // also initiates renegotiations and cannot be reconfigured. - tlsConf.Renegotiation = tls.RenegotiateFreelyAsClient - - return func(conn net.Conn) (net.Conn, error) { - client := tls.Client(conn, &tlsConf) - if verifyCaOnly { - err := sslVerifyCertificateAuthority(client, &tlsConf) - if err != nil { - return nil, err - } - } - return client, nil - }, nil -} - -// sslClientCertificates adds the certificate specified in the "sslcert" and -// "sslkey" settings, or if they aren't set, from the .postgresql directory -// in the user's home directory. The configured files must exist and have -// the correct permissions. -func sslClientCertificates(tlsConf *tls.Config, o values) error { - sslinline := o["sslinline"] - if sslinline == "true" { - cert, err := tls.X509KeyPair([]byte(o["sslcert"]), []byte(o["sslkey"])) - if err != nil { - return err - } - tlsConf.Certificates = []tls.Certificate{cert} - return nil - } - - // user.Current() might fail when cross-compiling. We have to ignore the - // error and continue without home directory defaults, since we wouldn't - // know from where to load them. - user, _ := user.Current() - - // In libpq, the client certificate is only loaded if the setting is not blank. - // - // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1036-L1037 - sslcert := o["sslcert"] - if len(sslcert) == 0 && user != nil { - sslcert = filepath.Join(user.HomeDir, ".postgresql", "postgresql.crt") - } - // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1045 - if len(sslcert) == 0 { - return nil - } - // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1050:L1054 - if _, err := os.Stat(sslcert); os.IsNotExist(err) { - return nil - } else if err != nil { - return err - } - - // In libpq, the ssl key is only loaded if the setting is not blank. - // - // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L1123-L1222 - sslkey := o["sslkey"] - if len(sslkey) == 0 && user != nil { - sslkey = filepath.Join(user.HomeDir, ".postgresql", "postgresql.key") - } - - if len(sslkey) > 0 { - if err := sslKeyPermissions(sslkey); err != nil { - return err - } - } - - cert, err := tls.LoadX509KeyPair(sslcert, sslkey) - if err != nil { - return err - } - - tlsConf.Certificates = []tls.Certificate{cert} - return nil -} - -// sslCertificateAuthority adds the RootCA specified in the "sslrootcert" setting. -func sslCertificateAuthority(tlsConf *tls.Config, o values) error { - // In libpq, the root certificate is only loaded if the setting is not blank. - // - // https://github.com/postgres/postgres/blob/REL9_6_2/src/interfaces/libpq/fe-secure-openssl.c#L950-L951 - if sslrootcert := o["sslrootcert"]; len(sslrootcert) > 0 { - tlsConf.RootCAs = x509.NewCertPool() - - sslinline := o["sslinline"] - - var cert []byte - if sslinline == "true" { - cert = []byte(sslrootcert) - } else { - var err error - cert, err = ioutil.ReadFile(sslrootcert) - if err != nil { - return err - } - } - - if !tlsConf.RootCAs.AppendCertsFromPEM(cert) { - return fmterrorf("couldn't parse pem in sslrootcert") - } - } - - return nil -} - -// sslVerifyCertificateAuthority carries out a TLS handshake to the server and -// verifies the presented certificate against the CA, i.e. the one specified in -// sslrootcert or the system CA if sslrootcert was not specified. -func sslVerifyCertificateAuthority(client *tls.Conn, tlsConf *tls.Config) error { - err := client.Handshake() - if err != nil { - return err - } - certs := client.ConnectionState().PeerCertificates - opts := x509.VerifyOptions{ - DNSName: client.ConnectionState().ServerName, - Intermediates: x509.NewCertPool(), - Roots: tlsConf.RootCAs, - } - for i, cert := range certs { - if i == 0 { - continue - } - opts.Intermediates.AddCert(cert) - } - _, err = certs[0].Verify(opts) - return err -} diff --git a/vendor/github.com/lib/pq/ssl_permissions.go b/vendor/github.com/lib/pq/ssl_permissions.go deleted file mode 100644 index d587f102edb..00000000000 --- a/vendor/github.com/lib/pq/ssl_permissions.go +++ /dev/null @@ -1,93 +0,0 @@ -//go:build !windows -// +build !windows - -package pq - -import ( - "errors" - "os" - "syscall" -) - -const ( - rootUserID = uint32(0) - - // The maximum permissions that a private key file owned by a regular user - // is allowed to have. This translates to u=rw. - maxUserOwnedKeyPermissions os.FileMode = 0600 - - // The maximum permissions that a private key file owned by root is allowed - // to have. This translates to u=rw,g=r. - maxRootOwnedKeyPermissions os.FileMode = 0640 -) - -var ( - errSSLKeyHasUnacceptableUserPermissions = errors.New("permissions for files not owned by root should be u=rw (0600) or less") - errSSLKeyHasUnacceptableRootPermissions = errors.New("permissions for root owned files should be u=rw,g=r (0640) or less") -) - -// sslKeyPermissions checks the permissions on user-supplied ssl key files. -// The key file should have very little access. -// -// libpq does not check key file permissions on Windows. -func sslKeyPermissions(sslkey string) error { - info, err := os.Stat(sslkey) - if err != nil { - return err - } - - err = hasCorrectPermissions(info) - - // return ErrSSLKeyHasWorldPermissions for backwards compatability with - // existing code. - if err == errSSLKeyHasUnacceptableUserPermissions || err == errSSLKeyHasUnacceptableRootPermissions { - err = ErrSSLKeyHasWorldPermissions - } - return err -} - -// hasCorrectPermissions checks the file info (and the unix-specific stat_t -// output) to verify that the permissions on the file are correct. -// -// If the file is owned by the same user the process is running as, -// the file should only have 0600 (u=rw). If the file is owned by root, -// and the group matches the group that the process is running in, the -// permissions cannot be more than 0640 (u=rw,g=r). The file should -// never have world permissions. -// -// Returns an error when the permission check fails. -func hasCorrectPermissions(info os.FileInfo) error { - // if file's permission matches 0600, allow access. - userPermissionMask := (os.FileMode(0777) ^ maxUserOwnedKeyPermissions) - - // regardless of if we're running as root or not, 0600 is acceptable, - // so we return if we match the regular user permission mask. - if info.Mode().Perm()&userPermissionMask == 0 { - return nil - } - - // We need to pull the Unix file information to get the file's owner. - // If we can't access it, there's some sort of operating system level error - // and we should fail rather than attempting to use faulty information. - sysInfo := info.Sys() - if sysInfo == nil { - return ErrSSLKeyUnknownOwnership - } - - unixStat, ok := sysInfo.(*syscall.Stat_t) - if !ok { - return ErrSSLKeyUnknownOwnership - } - - // if the file is owned by root, we allow 0640 (u=rw,g=r) to match what - // Postgres does. - if unixStat.Uid == rootUserID { - rootPermissionMask := (os.FileMode(0777) ^ maxRootOwnedKeyPermissions) - if info.Mode().Perm()&rootPermissionMask != 0 { - return errSSLKeyHasUnacceptableRootPermissions - } - return nil - } - - return errSSLKeyHasUnacceptableUserPermissions -} diff --git a/vendor/github.com/lib/pq/ssl_windows.go b/vendor/github.com/lib/pq/ssl_windows.go deleted file mode 100644 index 73663c8f157..00000000000 --- a/vendor/github.com/lib/pq/ssl_windows.go +++ /dev/null @@ -1,10 +0,0 @@ -//go:build windows -// +build windows - -package pq - -// sslKeyPermissions checks the permissions on user-supplied ssl key files. -// The key file should have very little access. -// -// libpq does not check key file permissions on Windows. -func sslKeyPermissions(string) error { return nil } diff --git a/vendor/github.com/lib/pq/url.go b/vendor/github.com/lib/pq/url.go deleted file mode 100644 index aec6e95be8b..00000000000 --- a/vendor/github.com/lib/pq/url.go +++ /dev/null @@ -1,76 +0,0 @@ -package pq - -import ( - "fmt" - "net" - nurl "net/url" - "sort" - "strings" -) - -// ParseURL no longer needs to be used by clients of this library since supplying a URL as a -// connection string to sql.Open() is now supported: -// -// sql.Open("postgres", "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full") -// -// It remains exported here for backwards-compatibility. -// -// ParseURL converts a url to a connection string for driver.Open. -// Example: -// -// "postgres://bob:secret@1.2.3.4:5432/mydb?sslmode=verify-full" -// -// converts to: -// -// "user=bob password=secret host=1.2.3.4 port=5432 dbname=mydb sslmode=verify-full" -// -// A minimal example: -// -// "postgres://" -// -// This will be blank, causing driver.Open to use all of the defaults -func ParseURL(url string) (string, error) { - u, err := nurl.Parse(url) - if err != nil { - return "", err - } - - if u.Scheme != "postgres" && u.Scheme != "postgresql" { - return "", fmt.Errorf("invalid connection protocol: %s", u.Scheme) - } - - var kvs []string - escaper := strings.NewReplacer(`'`, `\'`, `\`, `\\`) - accrue := func(k, v string) { - if v != "" { - kvs = append(kvs, k+"='"+escaper.Replace(v)+"'") - } - } - - if u.User != nil { - v := u.User.Username() - accrue("user", v) - - v, _ = u.User.Password() - accrue("password", v) - } - - if host, port, err := net.SplitHostPort(u.Host); err != nil { - accrue("host", u.Host) - } else { - accrue("host", host) - accrue("port", port) - } - - if u.Path != "" { - accrue("dbname", u.Path[1:]) - } - - q := u.Query() - for k := range q { - accrue(k, q.Get(k)) - } - - sort.Strings(kvs) // Makes testing easier (not a performance concern) - return strings.Join(kvs, " "), nil -} diff --git a/vendor/github.com/lib/pq/user_other.go b/vendor/github.com/lib/pq/user_other.go deleted file mode 100644 index 3dae8f5572b..00000000000 --- a/vendor/github.com/lib/pq/user_other.go +++ /dev/null @@ -1,10 +0,0 @@ -// Package pq is a pure Go Postgres driver for the database/sql package. - -//go:build js || android || hurd || zos -// +build js android hurd zos - -package pq - -func userCurrent() (string, error) { - return "", ErrCouldNotDetectUsername -} diff --git a/vendor/github.com/lib/pq/user_posix.go b/vendor/github.com/lib/pq/user_posix.go deleted file mode 100644 index 5f2d439bc42..00000000000 --- a/vendor/github.com/lib/pq/user_posix.go +++ /dev/null @@ -1,25 +0,0 @@ -// Package pq is a pure Go Postgres driver for the database/sql package. - -//go:build aix || darwin || dragonfly || freebsd || (linux && !android) || nacl || netbsd || openbsd || plan9 || solaris || rumprun || illumos -// +build aix darwin dragonfly freebsd linux,!android nacl netbsd openbsd plan9 solaris rumprun illumos - -package pq - -import ( - "os" - "os/user" -) - -func userCurrent() (string, error) { - u, err := user.Current() - if err == nil { - return u.Username, nil - } - - name := os.Getenv("USER") - if name != "" { - return name, nil - } - - return "", ErrCouldNotDetectUsername -} diff --git a/vendor/github.com/lib/pq/user_windows.go b/vendor/github.com/lib/pq/user_windows.go deleted file mode 100644 index 2b691267b97..00000000000 --- a/vendor/github.com/lib/pq/user_windows.go +++ /dev/null @@ -1,27 +0,0 @@ -// Package pq is a pure Go Postgres driver for the database/sql package. -package pq - -import ( - "path/filepath" - "syscall" -) - -// Perform Windows user name lookup identically to libpq. -// -// The PostgreSQL code makes use of the legacy Win32 function -// GetUserName, and that function has not been imported into stock Go. -// GetUserNameEx is available though, the difference being that a -// wider range of names are available. To get the output to be the -// same as GetUserName, only the base (or last) component of the -// result is returned. -func userCurrent() (string, error) { - pw_name := make([]uint16, 128) - pwname_size := uint32(len(pw_name)) - 1 - err := syscall.GetUserNameEx(syscall.NameSamCompatible, &pw_name[0], &pwname_size) - if err != nil { - return "", ErrCouldNotDetectUsername - } - s := syscall.UTF16ToString(pw_name) - u := filepath.Base(s) - return u, nil -} diff --git a/vendor/github.com/lib/pq/uuid.go b/vendor/github.com/lib/pq/uuid.go deleted file mode 100644 index 9a1b9e0748e..00000000000 --- a/vendor/github.com/lib/pq/uuid.go +++ /dev/null @@ -1,23 +0,0 @@ -package pq - -import ( - "encoding/hex" - "fmt" -) - -// decodeUUIDBinary interprets the binary format of a uuid, returning it in text format. -func decodeUUIDBinary(src []byte) ([]byte, error) { - if len(src) != 16 { - return nil, fmt.Errorf("pq: unable to decode uuid; bad length: %d", len(src)) - } - - dst := make([]byte, 36) - dst[8], dst[13], dst[18], dst[23] = '-', '-', '-', '-' - hex.Encode(dst[0:], src[0:4]) - hex.Encode(dst[9:], src[4:6]) - hex.Encode(dst[14:], src[6:8]) - hex.Encode(dst[19:], src[8:10]) - hex.Encode(dst[24:], src[10:16]) - - return dst, nil -} diff --git a/vendor/golang.org/x/text/secure/precis/class.go b/vendor/golang.org/x/text/secure/precis/class.go new file mode 100644 index 00000000000..f6b56413baf --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/class.go @@ -0,0 +1,36 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package precis + +import ( + "unicode/utf8" +) + +// TODO: Add contextual character rules from Appendix A of RFC5892. + +// A class is a set of characters that match certain derived properties. The +// PRECIS framework defines two classes: The Freeform class and the Identifier +// class. The freeform class should be used for profiles where expressiveness is +// prioritized over safety such as nicknames or passwords. The identifier class +// should be used for profiles where safety is the first priority such as +// addressable network labels and usernames. +type class struct { + validFrom property +} + +// Contains satisfies the runes.Set interface and returns whether the given rune +// is a member of the class. +func (c class) Contains(r rune) bool { + b := make([]byte, 4) + n := utf8.EncodeRune(b, r) + + trieval, _ := dpTrie.lookup(b[:n]) + return c.validFrom <= property(trieval) +} + +var ( + identifier = &class{validFrom: pValid} + freeform = &class{validFrom: idDisOrFreePVal} +) diff --git a/vendor/golang.org/x/text/secure/precis/context.go b/vendor/golang.org/x/text/secure/precis/context.go new file mode 100644 index 00000000000..2dcaf29d7a3 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/context.go @@ -0,0 +1,139 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package precis + +import "errors" + +// This file contains tables and code related to context rules. + +type catBitmap uint16 + +const ( + // These bits, once set depending on the current value, are never unset. + bJapanese catBitmap = 1 << iota + bArabicIndicDigit + bExtendedArabicIndicDigit + + // These bits are set on each iteration depending on the current value. + bJoinStart + bJoinMid + bJoinEnd + bVirama + bLatinSmallL + bGreek + bHebrew + + // These bits indicated which of the permanent bits need to be set at the + // end of the checks. + bMustHaveJapn + + permanent = bJapanese | bArabicIndicDigit | bExtendedArabicIndicDigit | bMustHaveJapn +) + +const finalShift = 10 + +var errContext = errors.New("precis: contextual rule violated") + +func init() { + // Programmatically set these required bits as, manually setting them seems + // too error prone. + for i, ct := range categoryTransitions { + categoryTransitions[i].keep |= permanent + categoryTransitions[i].accept |= ct.term + } +} + +var categoryTransitions = []struct { + keep catBitmap // mask selecting which bits to keep from the previous state + set catBitmap // mask for which bits to set for this transition + + // These bitmaps are used for rules that require lookahead. + // term&accept == term must be true, which is enforced programmatically. + term catBitmap // bits accepted as termination condition + accept catBitmap // bits that pass, but not sufficient as termination + + // The rule function cannot take a *context as an argument, as it would + // cause the context to escape, adding significant overhead. + rule func(beforeBits catBitmap) (doLookahead bool, err error) +}{ + joiningL: {set: bJoinStart}, + joiningD: {set: bJoinStart | bJoinEnd}, + joiningT: {keep: bJoinStart, set: bJoinMid}, + joiningR: {set: bJoinEnd}, + viramaModifier: {set: bVirama}, + viramaJoinT: {set: bVirama | bJoinMid}, + latinSmallL: {set: bLatinSmallL}, + greek: {set: bGreek}, + greekJoinT: {set: bGreek | bJoinMid}, + hebrew: {set: bHebrew}, + hebrewJoinT: {set: bHebrew | bJoinMid}, + japanese: {set: bJapanese}, + katakanaMiddleDot: {set: bMustHaveJapn}, + + zeroWidthNonJoiner: { + term: bJoinEnd, + accept: bJoinMid, + rule: func(before catBitmap) (doLookAhead bool, err error) { + if before&bVirama != 0 { + return false, nil + } + if before&bJoinStart == 0 { + return false, errContext + } + return true, nil + }, + }, + zeroWidthJoiner: { + rule: func(before catBitmap) (doLookAhead bool, err error) { + if before&bVirama == 0 { + err = errContext + } + return false, err + }, + }, + middleDot: { + term: bLatinSmallL, + rule: func(before catBitmap) (doLookAhead bool, err error) { + if before&bLatinSmallL == 0 { + return false, errContext + } + return true, nil + }, + }, + greekLowerNumeralSign: { + set: bGreek, + term: bGreek, + rule: func(before catBitmap) (doLookAhead bool, err error) { + return true, nil + }, + }, + hebrewPreceding: { + set: bHebrew, + rule: func(before catBitmap) (doLookAhead bool, err error) { + if before&bHebrew == 0 { + err = errContext + } + return false, err + }, + }, + arabicIndicDigit: { + set: bArabicIndicDigit, + rule: func(before catBitmap) (doLookAhead bool, err error) { + if before&bExtendedArabicIndicDigit != 0 { + err = errContext + } + return false, err + }, + }, + extendedArabicIndicDigit: { + set: bExtendedArabicIndicDigit, + rule: func(before catBitmap) (doLookAhead bool, err error) { + if before&bArabicIndicDigit != 0 { + err = errContext + } + return false, err + }, + }, +} diff --git a/vendor/golang.org/x/text/secure/precis/doc.go b/vendor/golang.org/x/text/secure/precis/doc.go new file mode 100644 index 00000000000..939ff222d02 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/doc.go @@ -0,0 +1,14 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package precis contains types and functions for the preparation, +// enforcement, and comparison of internationalized strings ("PRECIS") as +// defined in RFC 8264. It also contains several pre-defined profiles for +// passwords, nicknames, and usernames as defined in RFC 8265 and RFC 8266. +// +// BE ADVISED: This package is under construction and the API may change in +// backwards incompatible ways and without notice. +package precis // import "golang.org/x/text/secure/precis" + +//go:generate go run gen.go gen_trieval.go diff --git a/vendor/golang.org/x/text/secure/precis/nickname.go b/vendor/golang.org/x/text/secure/precis/nickname.go new file mode 100644 index 00000000000..11e0ccbb192 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/nickname.go @@ -0,0 +1,72 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package precis + +import ( + "unicode" + "unicode/utf8" + + "golang.org/x/text/transform" +) + +type nickAdditionalMapping struct { + // TODO: This transformer needs to be stateless somehow… + notStart bool + prevSpace bool +} + +func (t *nickAdditionalMapping) Reset() { + t.prevSpace = false + t.notStart = false +} + +func (t *nickAdditionalMapping) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + // RFC 8266 §2.1. Rules + // + // 2. Additional Mapping Rule: The additional mapping rule consists of + // the following sub-rules. + // + // a. Map any instances of non-ASCII space to SPACE (U+0020); a + // non-ASCII space is any Unicode code point having a general + // category of "Zs", naturally with the exception of SPACE + // (U+0020). (The inclusion of only ASCII space prevents + // confusion with various non-ASCII space code points, many of + // which are difficult to reproduce across different input + // methods.) + // + // b. Remove any instances of the ASCII space character at the + // beginning or end of a nickname (e.g., "stpeter " is mapped to + // "stpeter"). + // + // c. Map interior sequences of more than one ASCII space character + // to a single ASCII space character (e.g., "St Peter" is + // mapped to "St Peter"). + for nSrc < len(src) { + r, size := utf8.DecodeRune(src[nSrc:]) + if size == 0 { // Incomplete UTF-8 encoding + if !atEOF { + return nDst, nSrc, transform.ErrShortSrc + } + size = 1 + } + if unicode.Is(unicode.Zs, r) { + t.prevSpace = true + } else { + if t.prevSpace && t.notStart { + dst[nDst] = ' ' + nDst += 1 + } + if size != copy(dst[nDst:], src[nSrc:nSrc+size]) { + nDst += size + return nDst, nSrc, transform.ErrShortDst + } + nDst += size + t.prevSpace = false + t.notStart = true + } + nSrc += size + } + return nDst, nSrc, nil +} diff --git a/vendor/golang.org/x/text/secure/precis/options.go b/vendor/golang.org/x/text/secure/precis/options.go new file mode 100644 index 00000000000..26143db759e --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/options.go @@ -0,0 +1,157 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package precis + +import ( + "golang.org/x/text/cases" + "golang.org/x/text/language" + "golang.org/x/text/runes" + "golang.org/x/text/transform" + "golang.org/x/text/unicode/norm" +) + +// An Option is used to define the behavior and rules of a Profile. +type Option func(*options) + +type options struct { + // Preparation options + foldWidth bool + + // Enforcement options + asciiLower bool + cases transform.SpanningTransformer + disallow runes.Set + norm transform.SpanningTransformer + additional []func() transform.SpanningTransformer + width transform.SpanningTransformer + disallowEmpty bool + bidiRule bool + repeat bool + + // Comparison options + ignorecase bool +} + +func getOpts(o ...Option) (res options) { + for _, f := range o { + f(&res) + } + // Using a SpanningTransformer, instead of norm.Form prevents an allocation + // down the road. + if res.norm == nil { + res.norm = norm.NFC + } + return +} + +var ( + // The IgnoreCase option causes the profile to perform a case insensitive + // comparison during the PRECIS comparison step. + IgnoreCase Option = ignoreCase + + // The FoldWidth option causes the profile to map non-canonical wide and + // narrow variants to their decomposition mapping. This is useful for + // profiles that are based on the identifier class which would otherwise + // disallow such characters. + FoldWidth Option = foldWidth + + // The DisallowEmpty option causes the enforcement step to return an error if + // the resulting string would be empty. + DisallowEmpty Option = disallowEmpty + + // The BidiRule option causes the Bidi Rule defined in RFC 5893 to be + // applied. + BidiRule Option = bidiRule +) + +var ( + ignoreCase = func(o *options) { + o.ignorecase = true + } + foldWidth = func(o *options) { + o.foldWidth = true + } + disallowEmpty = func(o *options) { + o.disallowEmpty = true + } + bidiRule = func(o *options) { + o.bidiRule = true + } + repeat = func(o *options) { + o.repeat = true + } +) + +// TODO: move this logic to package transform + +type spanWrap struct{ transform.Transformer } + +func (s spanWrap) Span(src []byte, atEOF bool) (n int, err error) { + return 0, transform.ErrEndOfSpan +} + +// TODO: allow different types? For instance: +// func() transform.Transformer +// func() transform.SpanningTransformer +// func([]byte) bool // validation only +// +// Also, would be great if we could detect if a transformer is reentrant. + +// The AdditionalMapping option defines the additional mapping rule for the +// Profile by applying Transformer's in sequence. +func AdditionalMapping(t ...func() transform.Transformer) Option { + return func(o *options) { + for _, f := range t { + sf := func() transform.SpanningTransformer { + return f().(transform.SpanningTransformer) + } + if _, ok := f().(transform.SpanningTransformer); !ok { + sf = func() transform.SpanningTransformer { + return spanWrap{f()} + } + } + o.additional = append(o.additional, sf) + } + } +} + +// The Norm option defines a Profile's normalization rule. Defaults to NFC. +func Norm(f norm.Form) Option { + return func(o *options) { + o.norm = f + } +} + +// The FoldCase option defines a Profile's case mapping rule. Options can be +// provided to determine the type of case folding used. +func FoldCase(opts ...cases.Option) Option { + return func(o *options) { + o.asciiLower = true + o.cases = cases.Fold(opts...) + } +} + +// The LowerCase option defines a Profile's case mapping rule. Options can be +// provided to determine the type of case folding used. +func LowerCase(opts ...cases.Option) Option { + return func(o *options) { + o.asciiLower = true + if len(opts) == 0 { + o.cases = cases.Lower(language.Und, cases.HandleFinalSigma(false)) + return + } + + opts = append([]cases.Option{cases.HandleFinalSigma(false)}, opts...) + o.cases = cases.Lower(language.Und, opts...) + } +} + +// The Disallow option further restricts a Profile's allowed characters beyond +// what is disallowed by the underlying string class. +func Disallow(set runes.Set) Option { + return func(o *options) { + o.disallow = set + } +} diff --git a/vendor/golang.org/x/text/secure/precis/profile.go b/vendor/golang.org/x/text/secure/precis/profile.go new file mode 100644 index 00000000000..bdd991bb974 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/profile.go @@ -0,0 +1,412 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package precis + +import ( + "bytes" + "errors" + "unicode/utf8" + + "golang.org/x/text/cases" + "golang.org/x/text/language" + "golang.org/x/text/runes" + "golang.org/x/text/secure/bidirule" + "golang.org/x/text/transform" + "golang.org/x/text/width" +) + +var ( + errDisallowedRune = errors.New("precis: disallowed rune encountered") +) + +var dpTrie = newDerivedPropertiesTrie(0) + +// A Profile represents a set of rules for normalizing and validating strings in +// the PRECIS framework. +type Profile struct { + options + class *class +} + +// NewIdentifier creates a new PRECIS profile based on the Identifier string +// class. Profiles created from this class are suitable for use where safety is +// prioritized over expressiveness like network identifiers, user accounts, chat +// rooms, and file names. +func NewIdentifier(opts ...Option) *Profile { + return &Profile{ + options: getOpts(opts...), + class: identifier, + } +} + +// NewFreeform creates a new PRECIS profile based on the Freeform string class. +// Profiles created from this class are suitable for use where expressiveness is +// prioritized over safety like passwords, and display-elements such as +// nicknames in a chat room. +func NewFreeform(opts ...Option) *Profile { + return &Profile{ + options: getOpts(opts...), + class: freeform, + } +} + +// NewRestrictedProfile creates a new PRECIS profile based on an existing +// profile. +// If the parent profile already had the Disallow option set, the new rule +// overrides the parents rule. +func NewRestrictedProfile(parent *Profile, disallow runes.Set) *Profile { + p := *parent + Disallow(disallow)(&p.options) + return &p +} + +// NewTransformer creates a new transform.Transformer that performs the PRECIS +// preparation and enforcement steps on the given UTF-8 encoded bytes. +func (p *Profile) NewTransformer() *Transformer { + var ts []transform.Transformer + + // These transforms are applied in the order defined in + // https://tools.ietf.org/html/rfc7564#section-7 + + // RFC 8266 §2.1: + // + // Implementation experience has shown that applying the rules for the + // Nickname profile is not an idempotent procedure for all code points. + // Therefore, an implementation SHOULD apply the rules repeatedly until + // the output string is stable; if the output string does not stabilize + // after reapplying the rules three (3) additional times after the first + // application, the implementation SHOULD terminate application of the + // rules and reject the input string as invalid. + // + // There is no known string that will change indefinitely, so repeat 4 times + // and rely on the Span method to keep things relatively performant. + r := 1 + if p.options.repeat { + r = 4 + } + for ; r > 0; r-- { + if p.options.foldWidth { + ts = append(ts, width.Fold) + } + + for _, f := range p.options.additional { + ts = append(ts, f()) + } + + if p.options.cases != nil { + ts = append(ts, p.options.cases) + } + + ts = append(ts, p.options.norm) + + if p.options.bidiRule { + ts = append(ts, bidirule.New()) + } + + ts = append(ts, &checker{p: p, allowed: p.Allowed()}) + } + + // TODO: Add the disallow empty rule with a dummy transformer? + + return &Transformer{transform.Chain(ts...)} +} + +var errEmptyString = errors.New("precis: transformation resulted in empty string") + +type buffers struct { + src []byte + buf [2][]byte + next int +} + +func (b *buffers) apply(t transform.SpanningTransformer) (err error) { + n, err := t.Span(b.src, true) + if err != transform.ErrEndOfSpan { + return err + } + x := b.next & 1 + if b.buf[x] == nil { + b.buf[x] = make([]byte, 0, 8+len(b.src)+len(b.src)>>2) + } + span := append(b.buf[x][:0], b.src[:n]...) + b.src, _, err = transform.Append(t, span, b.src[n:]) + b.buf[x] = b.src + b.next++ + return err +} + +// Pre-allocate transformers when possible. In some cases this avoids allocation. +var ( + foldWidthT transform.SpanningTransformer = width.Fold + lowerCaseT transform.SpanningTransformer = cases.Lower(language.Und, cases.HandleFinalSigma(false)) +) + +// TODO: make this a method on profile. + +func (b *buffers) enforce(p *Profile, src []byte, comparing bool) (str []byte, err error) { + b.src = src + + ascii := true + for _, c := range src { + if c >= utf8.RuneSelf { + ascii = false + break + } + } + // ASCII fast path. + if ascii { + for _, f := range p.options.additional { + if err = b.apply(f()); err != nil { + return nil, err + } + } + switch { + case p.options.asciiLower || (comparing && p.options.ignorecase): + for i, c := range b.src { + if 'A' <= c && c <= 'Z' { + b.src[i] = c ^ 1<<5 + } + } + case p.options.cases != nil: + b.apply(p.options.cases) + } + c := checker{p: p} + if _, err := c.span(b.src, true); err != nil { + return nil, err + } + if p.disallow != nil { + for _, c := range b.src { + if p.disallow.Contains(rune(c)) { + return nil, errDisallowedRune + } + } + } + if p.options.disallowEmpty && len(b.src) == 0 { + return nil, errEmptyString + } + return b.src, nil + } + + // These transforms are applied in the order defined in + // https://tools.ietf.org/html/rfc8264#section-7 + + r := 1 + if p.options.repeat { + r = 4 + } + for ; r > 0; r-- { + // TODO: allow different width transforms options. + if p.options.foldWidth || (p.options.ignorecase && comparing) { + b.apply(foldWidthT) + } + for _, f := range p.options.additional { + if err = b.apply(f()); err != nil { + return nil, err + } + } + if p.options.cases != nil { + b.apply(p.options.cases) + } + if comparing && p.options.ignorecase { + b.apply(lowerCaseT) + } + b.apply(p.norm) + if p.options.bidiRule && !bidirule.Valid(b.src) { + return nil, bidirule.ErrInvalid + } + c := checker{p: p} + if _, err := c.span(b.src, true); err != nil { + return nil, err + } + if p.disallow != nil { + for i := 0; i < len(b.src); { + r, size := utf8.DecodeRune(b.src[i:]) + if p.disallow.Contains(r) { + return nil, errDisallowedRune + } + i += size + } + } + if p.options.disallowEmpty && len(b.src) == 0 { + return nil, errEmptyString + } + } + return b.src, nil +} + +// Append appends the result of applying p to src writing the result to dst. +// It returns an error if the input string is invalid. +func (p *Profile) Append(dst, src []byte) ([]byte, error) { + var buf buffers + b, err := buf.enforce(p, src, false) + if err != nil { + return nil, err + } + return append(dst, b...), nil +} + +func processBytes(p *Profile, b []byte, key bool) ([]byte, error) { + var buf buffers + b, err := buf.enforce(p, b, key) + if err != nil { + return nil, err + } + if buf.next == 0 { + c := make([]byte, len(b)) + copy(c, b) + return c, nil + } + return b, nil +} + +// Bytes returns a new byte slice with the result of applying the profile to b. +func (p *Profile) Bytes(b []byte) ([]byte, error) { + return processBytes(p, b, false) +} + +// AppendCompareKey appends the result of applying p to src (including any +// optional rules to make strings comparable or useful in a map key such as +// applying lowercasing) writing the result to dst. It returns an error if the +// input string is invalid. +func (p *Profile) AppendCompareKey(dst, src []byte) ([]byte, error) { + var buf buffers + b, err := buf.enforce(p, src, true) + if err != nil { + return nil, err + } + return append(dst, b...), nil +} + +func processString(p *Profile, s string, key bool) (string, error) { + var buf buffers + b, err := buf.enforce(p, []byte(s), key) + if err != nil { + return "", err + } + return string(b), nil +} + +// String returns a string with the result of applying the profile to s. +func (p *Profile) String(s string) (string, error) { + return processString(p, s, false) +} + +// CompareKey returns a string that can be used for comparison, hashing, or +// collation. +func (p *Profile) CompareKey(s string) (string, error) { + return processString(p, s, true) +} + +// Compare enforces both strings, and then compares them for bit-string identity +// (byte-for-byte equality). If either string cannot be enforced, the comparison +// is false. +func (p *Profile) Compare(a, b string) bool { + var buf buffers + + akey, err := buf.enforce(p, []byte(a), true) + if err != nil { + return false + } + + buf = buffers{} + bkey, err := buf.enforce(p, []byte(b), true) + if err != nil { + return false + } + + return bytes.Equal(akey, bkey) +} + +// Allowed returns a runes.Set containing every rune that is a member of the +// underlying profile's string class and not disallowed by any profile specific +// rules. +func (p *Profile) Allowed() runes.Set { + if p.options.disallow != nil { + return runes.Predicate(func(r rune) bool { + return p.class.Contains(r) && !p.options.disallow.Contains(r) + }) + } + return p.class +} + +type checker struct { + p *Profile + allowed runes.Set + + beforeBits catBitmap + termBits catBitmap + acceptBits catBitmap +} + +func (c *checker) Reset() { + c.beforeBits = 0 + c.termBits = 0 + c.acceptBits = 0 +} + +func (c *checker) span(src []byte, atEOF bool) (n int, err error) { + for n < len(src) { + e, sz := dpTrie.lookup(src[n:]) + d := categoryTransitions[category(e&catMask)] + if sz == 0 { + if !atEOF { + return n, transform.ErrShortSrc + } + return n, errDisallowedRune + } + doLookAhead := false + if property(e) < c.p.class.validFrom { + if d.rule == nil { + return n, errDisallowedRune + } + doLookAhead, err = d.rule(c.beforeBits) + if err != nil { + return n, err + } + } + c.beforeBits &= d.keep + c.beforeBits |= d.set + if c.termBits != 0 { + // We are currently in an unterminated lookahead. + if c.beforeBits&c.termBits != 0 { + c.termBits = 0 + c.acceptBits = 0 + } else if c.beforeBits&c.acceptBits == 0 { + // Invalid continuation of the unterminated lookahead sequence. + return n, errContext + } + } + if doLookAhead { + if c.termBits != 0 { + // A previous lookahead run has not been terminated yet. + return n, errContext + } + c.termBits = d.term + c.acceptBits = d.accept + } + n += sz + } + if m := c.beforeBits >> finalShift; c.beforeBits&m != m || c.termBits != 0 { + err = errContext + } + return n, err +} + +// TODO: we may get rid of this transform if transform.Chain understands +// something like a Spanner interface. +func (c checker) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + short := false + if len(dst) < len(src) { + src = src[:len(dst)] + atEOF = false + short = true + } + nSrc, err = c.span(src, atEOF) + nDst = copy(dst, src[:nSrc]) + if short && (err == transform.ErrShortSrc || err == nil) { + err = transform.ErrShortDst + } + return nDst, nSrc, err +} diff --git a/vendor/golang.org/x/text/secure/precis/profiles.go b/vendor/golang.org/x/text/secure/precis/profiles.go new file mode 100644 index 00000000000..061936d9851 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/profiles.go @@ -0,0 +1,78 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package precis + +import ( + "unicode" + + "golang.org/x/text/runes" + "golang.org/x/text/transform" + "golang.org/x/text/unicode/norm" +) + +var ( + // Implements the Nickname profile specified in RFC 8266. + Nickname *Profile = nickname + + // Implements the UsernameCaseMapped profile specified in RFC 8265. + UsernameCaseMapped *Profile = usernameCaseMap + + // Implements the UsernameCasePreserved profile specified in RFC 8265. + UsernameCasePreserved *Profile = usernameNoCaseMap + + // Implements the OpaqueString profile defined in RFC 8265 for passwords and + // other secure labels. + OpaqueString *Profile = opaquestring +) + +var ( + nickname = &Profile{ + options: getOpts( + AdditionalMapping(func() transform.Transformer { + return &nickAdditionalMapping{} + }), + IgnoreCase, + Norm(norm.NFKC), + DisallowEmpty, + repeat, + ), + class: freeform, + } + usernameCaseMap = &Profile{ + options: getOpts( + FoldWidth, + LowerCase(), + Norm(norm.NFC), + BidiRule, + ), + class: identifier, + } + usernameNoCaseMap = &Profile{ + options: getOpts( + FoldWidth, + Norm(norm.NFC), + BidiRule, + ), + class: identifier, + } + opaquestring = &Profile{ + options: getOpts( + AdditionalMapping(func() transform.Transformer { + return mapSpaces + }), + Norm(norm.NFC), + DisallowEmpty, + ), + class: freeform, + } +) + +// mapSpaces is a shared value of a runes.Map transformer. +var mapSpaces transform.Transformer = runes.Map(func(r rune) rune { + if unicode.Is(unicode.Zs, r) { + return ' ' + } + return r +}) diff --git a/vendor/golang.org/x/text/secure/precis/tables10.0.0.go b/vendor/golang.org/x/text/secure/precis/tables10.0.0.go new file mode 100644 index 00000000000..81647495025 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/tables10.0.0.go @@ -0,0 +1,3890 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +//go:build go1.10 && !go1.13 +// +build go1.10,!go1.13 + +package precis + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "10.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// derivedPropertiesTrie. Total size: 25920 bytes (25.31 KiB). Checksum: 25eb1c8ad0a9331f. +type derivedPropertiesTrie struct{} + +func newDerivedPropertiesTrie(i int) *derivedPropertiesTrie { + return &derivedPropertiesTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *derivedPropertiesTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(derivedPropertiesValues[n<<6+uint32(b)]) + } +} + +// derivedPropertiesValues: 331 blocks, 21184 entries, 21184 bytes +// The third block is the zero block. +var derivedPropertiesValues = [21184]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x0040, 0x01: 0x0040, 0x02: 0x0040, 0x03: 0x0040, 0x04: 0x0040, 0x05: 0x0040, + 0x06: 0x0040, 0x07: 0x0040, 0x08: 0x0040, 0x09: 0x0040, 0x0a: 0x0040, 0x0b: 0x0040, + 0x0c: 0x0040, 0x0d: 0x0040, 0x0e: 0x0040, 0x0f: 0x0040, 0x10: 0x0040, 0x11: 0x0040, + 0x12: 0x0040, 0x13: 0x0040, 0x14: 0x0040, 0x15: 0x0040, 0x16: 0x0040, 0x17: 0x0040, + 0x18: 0x0040, 0x19: 0x0040, 0x1a: 0x0040, 0x1b: 0x0040, 0x1c: 0x0040, 0x1d: 0x0040, + 0x1e: 0x0040, 0x1f: 0x0040, 0x20: 0x0080, 0x21: 0x00c0, 0x22: 0x00c0, 0x23: 0x00c0, + 0x24: 0x00c0, 0x25: 0x00c0, 0x26: 0x00c0, 0x27: 0x00c0, 0x28: 0x00c0, 0x29: 0x00c0, + 0x2a: 0x00c0, 0x2b: 0x00c0, 0x2c: 0x00c0, 0x2d: 0x00c0, 0x2e: 0x00c0, 0x2f: 0x00c0, + 0x30: 0x00c0, 0x31: 0x00c0, 0x32: 0x00c0, 0x33: 0x00c0, 0x34: 0x00c0, 0x35: 0x00c0, + 0x36: 0x00c0, 0x37: 0x00c0, 0x38: 0x00c0, 0x39: 0x00c0, 0x3a: 0x00c0, 0x3b: 0x00c0, + 0x3c: 0x00c0, 0x3d: 0x00c0, 0x3e: 0x00c0, 0x3f: 0x00c0, + // Block 0x1, offset 0x40 + 0x40: 0x00c0, 0x41: 0x00c0, 0x42: 0x00c0, 0x43: 0x00c0, 0x44: 0x00c0, 0x45: 0x00c0, + 0x46: 0x00c0, 0x47: 0x00c0, 0x48: 0x00c0, 0x49: 0x00c0, 0x4a: 0x00c0, 0x4b: 0x00c0, + 0x4c: 0x00c0, 0x4d: 0x00c0, 0x4e: 0x00c0, 0x4f: 0x00c0, 0x50: 0x00c0, 0x51: 0x00c0, + 0x52: 0x00c0, 0x53: 0x00c0, 0x54: 0x00c0, 0x55: 0x00c0, 0x56: 0x00c0, 0x57: 0x00c0, + 0x58: 0x00c0, 0x59: 0x00c0, 0x5a: 0x00c0, 0x5b: 0x00c0, 0x5c: 0x00c0, 0x5d: 0x00c0, + 0x5e: 0x00c0, 0x5f: 0x00c0, 0x60: 0x00c0, 0x61: 0x00c0, 0x62: 0x00c0, 0x63: 0x00c0, + 0x64: 0x00c0, 0x65: 0x00c0, 0x66: 0x00c0, 0x67: 0x00c0, 0x68: 0x00c0, 0x69: 0x00c0, + 0x6a: 0x00c0, 0x6b: 0x00c0, 0x6c: 0x00c7, 0x6d: 0x00c0, 0x6e: 0x00c0, 0x6f: 0x00c0, + 0x70: 0x00c0, 0x71: 0x00c0, 0x72: 0x00c0, 0x73: 0x00c0, 0x74: 0x00c0, 0x75: 0x00c0, + 0x76: 0x00c0, 0x77: 0x00c0, 0x78: 0x00c0, 0x79: 0x00c0, 0x7a: 0x00c0, 0x7b: 0x00c0, + 0x7c: 0x00c0, 0x7d: 0x00c0, 0x7e: 0x00c0, 0x7f: 0x0040, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x0080, 0xe1: 0x0080, 0xe2: 0x0080, 0xe3: 0x0080, + 0xe4: 0x0080, 0xe5: 0x0080, 0xe6: 0x0080, 0xe7: 0x0080, 0xe8: 0x0080, 0xe9: 0x0080, + 0xea: 0x0080, 0xeb: 0x0080, 0xec: 0x0080, 0xed: 0x0040, 0xee: 0x0080, 0xef: 0x0080, + 0xf0: 0x0080, 0xf1: 0x0080, 0xf2: 0x0080, 0xf3: 0x0080, 0xf4: 0x0080, 0xf5: 0x0080, + 0xf6: 0x0080, 0xf7: 0x004f, 0xf8: 0x0080, 0xf9: 0x0080, 0xfa: 0x0080, 0xfb: 0x0080, + 0xfc: 0x0080, 0xfd: 0x0080, 0xfe: 0x0080, 0xff: 0x0080, + // Block 0x4, offset 0x100 + 0x100: 0x00c0, 0x101: 0x00c0, 0x102: 0x00c0, 0x103: 0x00c0, 0x104: 0x00c0, 0x105: 0x00c0, + 0x106: 0x00c0, 0x107: 0x00c0, 0x108: 0x00c0, 0x109: 0x00c0, 0x10a: 0x00c0, 0x10b: 0x00c0, + 0x10c: 0x00c0, 0x10d: 0x00c0, 0x10e: 0x00c0, 0x10f: 0x00c0, 0x110: 0x00c0, 0x111: 0x00c0, + 0x112: 0x00c0, 0x113: 0x00c0, 0x114: 0x00c0, 0x115: 0x00c0, 0x116: 0x00c0, 0x117: 0x0080, + 0x118: 0x00c0, 0x119: 0x00c0, 0x11a: 0x00c0, 0x11b: 0x00c0, 0x11c: 0x00c0, 0x11d: 0x00c0, + 0x11e: 0x00c0, 0x11f: 0x00c0, 0x120: 0x00c0, 0x121: 0x00c0, 0x122: 0x00c0, 0x123: 0x00c0, + 0x124: 0x00c0, 0x125: 0x00c0, 0x126: 0x00c0, 0x127: 0x00c0, 0x128: 0x00c0, 0x129: 0x00c0, + 0x12a: 0x00c0, 0x12b: 0x00c0, 0x12c: 0x00c0, 0x12d: 0x00c0, 0x12e: 0x00c0, 0x12f: 0x00c0, + 0x130: 0x00c0, 0x131: 0x00c0, 0x132: 0x00c0, 0x133: 0x00c0, 0x134: 0x00c0, 0x135: 0x00c0, + 0x136: 0x00c0, 0x137: 0x0080, 0x138: 0x00c0, 0x139: 0x00c0, 0x13a: 0x00c0, 0x13b: 0x00c0, + 0x13c: 0x00c0, 0x13d: 0x00c0, 0x13e: 0x00c0, 0x13f: 0x00c0, + // Block 0x5, offset 0x140 + 0x140: 0x00c0, 0x141: 0x00c0, 0x142: 0x00c0, 0x143: 0x00c0, 0x144: 0x00c0, 0x145: 0x00c0, + 0x146: 0x00c0, 0x147: 0x00c0, 0x148: 0x00c0, 0x149: 0x00c0, 0x14a: 0x00c0, 0x14b: 0x00c0, + 0x14c: 0x00c0, 0x14d: 0x00c0, 0x14e: 0x00c0, 0x14f: 0x00c0, 0x150: 0x00c0, 0x151: 0x00c0, + 0x152: 0x00c0, 0x153: 0x00c0, 0x154: 0x00c0, 0x155: 0x00c0, 0x156: 0x00c0, 0x157: 0x00c0, + 0x158: 0x00c0, 0x159: 0x00c0, 0x15a: 0x00c0, 0x15b: 0x00c0, 0x15c: 0x00c0, 0x15d: 0x00c0, + 0x15e: 0x00c0, 0x15f: 0x00c0, 0x160: 0x00c0, 0x161: 0x00c0, 0x162: 0x00c0, 0x163: 0x00c0, + 0x164: 0x00c0, 0x165: 0x00c0, 0x166: 0x00c0, 0x167: 0x00c0, 0x168: 0x00c0, 0x169: 0x00c0, + 0x16a: 0x00c0, 0x16b: 0x00c0, 0x16c: 0x00c0, 0x16d: 0x00c0, 0x16e: 0x00c0, 0x16f: 0x00c0, + 0x170: 0x00c0, 0x171: 0x00c0, 0x172: 0x0080, 0x173: 0x0080, 0x174: 0x00c0, 0x175: 0x00c0, + 0x176: 0x00c0, 0x177: 0x00c0, 0x178: 0x00c0, 0x179: 0x00c0, 0x17a: 0x00c0, 0x17b: 0x00c0, + 0x17c: 0x00c0, 0x17d: 0x00c0, 0x17e: 0x00c0, 0x17f: 0x0080, + // Block 0x6, offset 0x180 + 0x180: 0x0080, 0x181: 0x00c0, 0x182: 0x00c0, 0x183: 0x00c0, 0x184: 0x00c0, 0x185: 0x00c0, + 0x186: 0x00c0, 0x187: 0x00c0, 0x188: 0x00c0, 0x189: 0x0080, 0x18a: 0x00c0, 0x18b: 0x00c0, + 0x18c: 0x00c0, 0x18d: 0x00c0, 0x18e: 0x00c0, 0x18f: 0x00c0, 0x190: 0x00c0, 0x191: 0x00c0, + 0x192: 0x00c0, 0x193: 0x00c0, 0x194: 0x00c0, 0x195: 0x00c0, 0x196: 0x00c0, 0x197: 0x00c0, + 0x198: 0x00c0, 0x199: 0x00c0, 0x19a: 0x00c0, 0x19b: 0x00c0, 0x19c: 0x00c0, 0x19d: 0x00c0, + 0x19e: 0x00c0, 0x19f: 0x00c0, 0x1a0: 0x00c0, 0x1a1: 0x00c0, 0x1a2: 0x00c0, 0x1a3: 0x00c0, + 0x1a4: 0x00c0, 0x1a5: 0x00c0, 0x1a6: 0x00c0, 0x1a7: 0x00c0, 0x1a8: 0x00c0, 0x1a9: 0x00c0, + 0x1aa: 0x00c0, 0x1ab: 0x00c0, 0x1ac: 0x00c0, 0x1ad: 0x00c0, 0x1ae: 0x00c0, 0x1af: 0x00c0, + 0x1b0: 0x00c0, 0x1b1: 0x00c0, 0x1b2: 0x00c0, 0x1b3: 0x00c0, 0x1b4: 0x00c0, 0x1b5: 0x00c0, + 0x1b6: 0x00c0, 0x1b7: 0x00c0, 0x1b8: 0x00c0, 0x1b9: 0x00c0, 0x1ba: 0x00c0, 0x1bb: 0x00c0, + 0x1bc: 0x00c0, 0x1bd: 0x00c0, 0x1be: 0x00c0, 0x1bf: 0x0080, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x00c0, 0x1c1: 0x00c0, 0x1c2: 0x00c0, 0x1c3: 0x00c0, 0x1c4: 0x00c0, 0x1c5: 0x00c0, + 0x1c6: 0x00c0, 0x1c7: 0x00c0, 0x1c8: 0x00c0, 0x1c9: 0x00c0, 0x1ca: 0x00c0, 0x1cb: 0x00c0, + 0x1cc: 0x00c0, 0x1cd: 0x00c0, 0x1ce: 0x00c0, 0x1cf: 0x00c0, 0x1d0: 0x00c0, 0x1d1: 0x00c0, + 0x1d2: 0x00c0, 0x1d3: 0x00c0, 0x1d4: 0x00c0, 0x1d5: 0x00c0, 0x1d6: 0x00c0, 0x1d7: 0x00c0, + 0x1d8: 0x00c0, 0x1d9: 0x00c0, 0x1da: 0x00c0, 0x1db: 0x00c0, 0x1dc: 0x00c0, 0x1dd: 0x00c0, + 0x1de: 0x00c0, 0x1df: 0x00c0, 0x1e0: 0x00c0, 0x1e1: 0x00c0, 0x1e2: 0x00c0, 0x1e3: 0x00c0, + 0x1e4: 0x00c0, 0x1e5: 0x00c0, 0x1e6: 0x00c0, 0x1e7: 0x00c0, 0x1e8: 0x00c0, 0x1e9: 0x00c0, + 0x1ea: 0x00c0, 0x1eb: 0x00c0, 0x1ec: 0x00c0, 0x1ed: 0x00c0, 0x1ee: 0x00c0, 0x1ef: 0x00c0, + 0x1f0: 0x00c0, 0x1f1: 0x00c0, 0x1f2: 0x00c0, 0x1f3: 0x00c0, 0x1f4: 0x00c0, 0x1f5: 0x00c0, + 0x1f6: 0x00c0, 0x1f7: 0x00c0, 0x1f8: 0x00c0, 0x1f9: 0x00c0, 0x1fa: 0x00c0, 0x1fb: 0x00c0, + 0x1fc: 0x00c0, 0x1fd: 0x00c0, 0x1fe: 0x00c0, 0x1ff: 0x00c0, + // Block 0x8, offset 0x200 + 0x200: 0x00c0, 0x201: 0x00c0, 0x202: 0x00c0, 0x203: 0x00c0, 0x204: 0x0080, 0x205: 0x0080, + 0x206: 0x0080, 0x207: 0x0080, 0x208: 0x0080, 0x209: 0x0080, 0x20a: 0x0080, 0x20b: 0x0080, + 0x20c: 0x0080, 0x20d: 0x00c0, 0x20e: 0x00c0, 0x20f: 0x00c0, 0x210: 0x00c0, 0x211: 0x00c0, + 0x212: 0x00c0, 0x213: 0x00c0, 0x214: 0x00c0, 0x215: 0x00c0, 0x216: 0x00c0, 0x217: 0x00c0, + 0x218: 0x00c0, 0x219: 0x00c0, 0x21a: 0x00c0, 0x21b: 0x00c0, 0x21c: 0x00c0, 0x21d: 0x00c0, + 0x21e: 0x00c0, 0x21f: 0x00c0, 0x220: 0x00c0, 0x221: 0x00c0, 0x222: 0x00c0, 0x223: 0x00c0, + 0x224: 0x00c0, 0x225: 0x00c0, 0x226: 0x00c0, 0x227: 0x00c0, 0x228: 0x00c0, 0x229: 0x00c0, + 0x22a: 0x00c0, 0x22b: 0x00c0, 0x22c: 0x00c0, 0x22d: 0x00c0, 0x22e: 0x00c0, 0x22f: 0x00c0, + 0x230: 0x00c0, 0x231: 0x0080, 0x232: 0x0080, 0x233: 0x0080, 0x234: 0x00c0, 0x235: 0x00c0, + 0x236: 0x00c0, 0x237: 0x00c0, 0x238: 0x00c0, 0x239: 0x00c0, 0x23a: 0x00c0, 0x23b: 0x00c0, + 0x23c: 0x00c0, 0x23d: 0x00c0, 0x23e: 0x00c0, 0x23f: 0x00c0, + // Block 0x9, offset 0x240 + 0x240: 0x00c0, 0x241: 0x00c0, 0x242: 0x00c0, 0x243: 0x00c0, 0x244: 0x00c0, 0x245: 0x00c0, + 0x246: 0x00c0, 0x247: 0x00c0, 0x248: 0x00c0, 0x249: 0x00c0, 0x24a: 0x00c0, 0x24b: 0x00c0, + 0x24c: 0x00c0, 0x24d: 0x00c0, 0x24e: 0x00c0, 0x24f: 0x00c0, 0x250: 0x00c0, 0x251: 0x00c0, + 0x252: 0x00c0, 0x253: 0x00c0, 0x254: 0x00c0, 0x255: 0x00c0, 0x256: 0x00c0, 0x257: 0x00c0, + 0x258: 0x00c0, 0x259: 0x00c0, 0x25a: 0x00c0, 0x25b: 0x00c0, 0x25c: 0x00c0, 0x25d: 0x00c0, + 0x25e: 0x00c0, 0x25f: 0x00c0, 0x260: 0x00c0, 0x261: 0x00c0, 0x262: 0x00c0, 0x263: 0x00c0, + 0x264: 0x00c0, 0x265: 0x00c0, 0x266: 0x00c0, 0x267: 0x00c0, 0x268: 0x00c0, 0x269: 0x00c0, + 0x26a: 0x00c0, 0x26b: 0x00c0, 0x26c: 0x00c0, 0x26d: 0x00c0, 0x26e: 0x00c0, 0x26f: 0x00c0, + 0x270: 0x0080, 0x271: 0x0080, 0x272: 0x0080, 0x273: 0x0080, 0x274: 0x0080, 0x275: 0x0080, + 0x276: 0x0080, 0x277: 0x0080, 0x278: 0x0080, 0x279: 0x00c0, 0x27a: 0x00c0, 0x27b: 0x00c0, + 0x27c: 0x00c0, 0x27d: 0x00c0, 0x27e: 0x00c0, 0x27f: 0x00c0, + // Block 0xa, offset 0x280 + 0x280: 0x00c0, 0x281: 0x00c0, 0x282: 0x0080, 0x283: 0x0080, 0x284: 0x0080, 0x285: 0x0080, + 0x286: 0x00c0, 0x287: 0x00c0, 0x288: 0x00c0, 0x289: 0x00c0, 0x28a: 0x00c0, 0x28b: 0x00c0, + 0x28c: 0x00c0, 0x28d: 0x00c0, 0x28e: 0x00c0, 0x28f: 0x00c0, 0x290: 0x00c0, 0x291: 0x00c0, + 0x292: 0x0080, 0x293: 0x0080, 0x294: 0x0080, 0x295: 0x0080, 0x296: 0x0080, 0x297: 0x0080, + 0x298: 0x0080, 0x299: 0x0080, 0x29a: 0x0080, 0x29b: 0x0080, 0x29c: 0x0080, 0x29d: 0x0080, + 0x29e: 0x0080, 0x29f: 0x0080, 0x2a0: 0x0080, 0x2a1: 0x0080, 0x2a2: 0x0080, 0x2a3: 0x0080, + 0x2a4: 0x0080, 0x2a5: 0x0080, 0x2a6: 0x0080, 0x2a7: 0x0080, 0x2a8: 0x0080, 0x2a9: 0x0080, + 0x2aa: 0x0080, 0x2ab: 0x0080, 0x2ac: 0x00c0, 0x2ad: 0x0080, 0x2ae: 0x00c0, 0x2af: 0x0080, + 0x2b0: 0x0080, 0x2b1: 0x0080, 0x2b2: 0x0080, 0x2b3: 0x0080, 0x2b4: 0x0080, 0x2b5: 0x0080, + 0x2b6: 0x0080, 0x2b7: 0x0080, 0x2b8: 0x0080, 0x2b9: 0x0080, 0x2ba: 0x0080, 0x2bb: 0x0080, + 0x2bc: 0x0080, 0x2bd: 0x0080, 0x2be: 0x0080, 0x2bf: 0x0080, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x00c3, 0x2c1: 0x00c3, 0x2c2: 0x00c3, 0x2c3: 0x00c3, 0x2c4: 0x00c3, 0x2c5: 0x00c3, + 0x2c6: 0x00c3, 0x2c7: 0x00c3, 0x2c8: 0x00c3, 0x2c9: 0x00c3, 0x2ca: 0x00c3, 0x2cb: 0x00c3, + 0x2cc: 0x00c3, 0x2cd: 0x00c3, 0x2ce: 0x00c3, 0x2cf: 0x00c3, 0x2d0: 0x00c3, 0x2d1: 0x00c3, + 0x2d2: 0x00c3, 0x2d3: 0x00c3, 0x2d4: 0x00c3, 0x2d5: 0x00c3, 0x2d6: 0x00c3, 0x2d7: 0x00c3, + 0x2d8: 0x00c3, 0x2d9: 0x00c3, 0x2da: 0x00c3, 0x2db: 0x00c3, 0x2dc: 0x00c3, 0x2dd: 0x00c3, + 0x2de: 0x00c3, 0x2df: 0x00c3, 0x2e0: 0x00c3, 0x2e1: 0x00c3, 0x2e2: 0x00c3, 0x2e3: 0x00c3, + 0x2e4: 0x00c3, 0x2e5: 0x00c3, 0x2e6: 0x00c3, 0x2e7: 0x00c3, 0x2e8: 0x00c3, 0x2e9: 0x00c3, + 0x2ea: 0x00c3, 0x2eb: 0x00c3, 0x2ec: 0x00c3, 0x2ed: 0x00c3, 0x2ee: 0x00c3, 0x2ef: 0x00c3, + 0x2f0: 0x00c3, 0x2f1: 0x00c3, 0x2f2: 0x00c3, 0x2f3: 0x00c3, 0x2f4: 0x00c3, 0x2f5: 0x00c3, + 0x2f6: 0x00c3, 0x2f7: 0x00c3, 0x2f8: 0x00c3, 0x2f9: 0x00c3, 0x2fa: 0x00c3, 0x2fb: 0x00c3, + 0x2fc: 0x00c3, 0x2fd: 0x00c3, 0x2fe: 0x00c3, 0x2ff: 0x00c3, + // Block 0xc, offset 0x300 + 0x300: 0x0083, 0x301: 0x0083, 0x302: 0x00c3, 0x303: 0x0083, 0x304: 0x0083, 0x305: 0x00c3, + 0x306: 0x00c3, 0x307: 0x00c3, 0x308: 0x00c3, 0x309: 0x00c3, 0x30a: 0x00c3, 0x30b: 0x00c3, + 0x30c: 0x00c3, 0x30d: 0x00c3, 0x30e: 0x00c3, 0x30f: 0x0040, 0x310: 0x00c3, 0x311: 0x00c3, + 0x312: 0x00c3, 0x313: 0x00c3, 0x314: 0x00c3, 0x315: 0x00c3, 0x316: 0x00c3, 0x317: 0x00c3, + 0x318: 0x00c3, 0x319: 0x00c3, 0x31a: 0x00c3, 0x31b: 0x00c3, 0x31c: 0x00c3, 0x31d: 0x00c3, + 0x31e: 0x00c3, 0x31f: 0x00c3, 0x320: 0x00c3, 0x321: 0x00c3, 0x322: 0x00c3, 0x323: 0x00c3, + 0x324: 0x00c3, 0x325: 0x00c3, 0x326: 0x00c3, 0x327: 0x00c3, 0x328: 0x00c3, 0x329: 0x00c3, + 0x32a: 0x00c3, 0x32b: 0x00c3, 0x32c: 0x00c3, 0x32d: 0x00c3, 0x32e: 0x00c3, 0x32f: 0x00c3, + 0x330: 0x00c8, 0x331: 0x00c8, 0x332: 0x00c8, 0x333: 0x00c8, 0x334: 0x0080, 0x335: 0x0050, + 0x336: 0x00c8, 0x337: 0x00c8, 0x33a: 0x0088, 0x33b: 0x00c8, + 0x33c: 0x00c8, 0x33d: 0x00c8, 0x33e: 0x0080, 0x33f: 0x00c8, + // Block 0xd, offset 0x340 + 0x344: 0x0088, 0x345: 0x0080, + 0x346: 0x00c8, 0x347: 0x0080, 0x348: 0x00c8, 0x349: 0x00c8, 0x34a: 0x00c8, + 0x34c: 0x00c8, 0x34e: 0x00c8, 0x34f: 0x00c8, 0x350: 0x00c8, 0x351: 0x00c8, + 0x352: 0x00c8, 0x353: 0x00c8, 0x354: 0x00c8, 0x355: 0x00c8, 0x356: 0x00c8, 0x357: 0x00c8, + 0x358: 0x00c8, 0x359: 0x00c8, 0x35a: 0x00c8, 0x35b: 0x00c8, 0x35c: 0x00c8, 0x35d: 0x00c8, + 0x35e: 0x00c8, 0x35f: 0x00c8, 0x360: 0x00c8, 0x361: 0x00c8, 0x363: 0x00c8, + 0x364: 0x00c8, 0x365: 0x00c8, 0x366: 0x00c8, 0x367: 0x00c8, 0x368: 0x00c8, 0x369: 0x00c8, + 0x36a: 0x00c8, 0x36b: 0x00c8, 0x36c: 0x00c8, 0x36d: 0x00c8, 0x36e: 0x00c8, 0x36f: 0x00c8, + 0x370: 0x00c8, 0x371: 0x00c8, 0x372: 0x00c8, 0x373: 0x00c8, 0x374: 0x00c8, 0x375: 0x00c8, + 0x376: 0x00c8, 0x377: 0x00c8, 0x378: 0x00c8, 0x379: 0x00c8, 0x37a: 0x00c8, 0x37b: 0x00c8, + 0x37c: 0x00c8, 0x37d: 0x00c8, 0x37e: 0x00c8, 0x37f: 0x00c8, + // Block 0xe, offset 0x380 + 0x380: 0x00c8, 0x381: 0x00c8, 0x382: 0x00c8, 0x383: 0x00c8, 0x384: 0x00c8, 0x385: 0x00c8, + 0x386: 0x00c8, 0x387: 0x00c8, 0x388: 0x00c8, 0x389: 0x00c8, 0x38a: 0x00c8, 0x38b: 0x00c8, + 0x38c: 0x00c8, 0x38d: 0x00c8, 0x38e: 0x00c8, 0x38f: 0x00c8, 0x390: 0x0088, 0x391: 0x0088, + 0x392: 0x0088, 0x393: 0x0088, 0x394: 0x0088, 0x395: 0x0088, 0x396: 0x0088, 0x397: 0x00c8, + 0x398: 0x00c8, 0x399: 0x00c8, 0x39a: 0x00c8, 0x39b: 0x00c8, 0x39c: 0x00c8, 0x39d: 0x00c8, + 0x39e: 0x00c8, 0x39f: 0x00c8, 0x3a0: 0x00c8, 0x3a1: 0x00c8, 0x3a2: 0x00c0, 0x3a3: 0x00c0, + 0x3a4: 0x00c0, 0x3a5: 0x00c0, 0x3a6: 0x00c0, 0x3a7: 0x00c0, 0x3a8: 0x00c0, 0x3a9: 0x00c0, + 0x3aa: 0x00c0, 0x3ab: 0x00c0, 0x3ac: 0x00c0, 0x3ad: 0x00c0, 0x3ae: 0x00c0, 0x3af: 0x00c0, + 0x3b0: 0x0088, 0x3b1: 0x0088, 0x3b2: 0x0088, 0x3b3: 0x00c8, 0x3b4: 0x0088, 0x3b5: 0x0088, + 0x3b6: 0x0088, 0x3b7: 0x00c8, 0x3b8: 0x00c8, 0x3b9: 0x0088, 0x3ba: 0x00c8, 0x3bb: 0x00c8, + 0x3bc: 0x00c8, 0x3bd: 0x00c8, 0x3be: 0x00c8, 0x3bf: 0x00c8, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x00c0, 0x3c1: 0x00c0, 0x3c2: 0x0080, 0x3c3: 0x00c3, 0x3c4: 0x00c3, 0x3c5: 0x00c3, + 0x3c6: 0x00c3, 0x3c7: 0x00c3, 0x3c8: 0x0083, 0x3c9: 0x0083, 0x3ca: 0x00c0, 0x3cb: 0x00c0, + 0x3cc: 0x00c0, 0x3cd: 0x00c0, 0x3ce: 0x00c0, 0x3cf: 0x00c0, 0x3d0: 0x00c0, 0x3d1: 0x00c0, + 0x3d2: 0x00c0, 0x3d3: 0x00c0, 0x3d4: 0x00c0, 0x3d5: 0x00c0, 0x3d6: 0x00c0, 0x3d7: 0x00c0, + 0x3d8: 0x00c0, 0x3d9: 0x00c0, 0x3da: 0x00c0, 0x3db: 0x00c0, 0x3dc: 0x00c0, 0x3dd: 0x00c0, + 0x3de: 0x00c0, 0x3df: 0x00c0, 0x3e0: 0x00c0, 0x3e1: 0x00c0, 0x3e2: 0x00c0, 0x3e3: 0x00c0, + 0x3e4: 0x00c0, 0x3e5: 0x00c0, 0x3e6: 0x00c0, 0x3e7: 0x00c0, 0x3e8: 0x00c0, 0x3e9: 0x00c0, + 0x3ea: 0x00c0, 0x3eb: 0x00c0, 0x3ec: 0x00c0, 0x3ed: 0x00c0, 0x3ee: 0x00c0, 0x3ef: 0x00c0, + 0x3f0: 0x00c0, 0x3f1: 0x00c0, 0x3f2: 0x00c0, 0x3f3: 0x00c0, 0x3f4: 0x00c0, 0x3f5: 0x00c0, + 0x3f6: 0x00c0, 0x3f7: 0x00c0, 0x3f8: 0x00c0, 0x3f9: 0x00c0, 0x3fa: 0x00c0, 0x3fb: 0x00c0, + 0x3fc: 0x00c0, 0x3fd: 0x00c0, 0x3fe: 0x00c0, 0x3ff: 0x00c0, + // Block 0x10, offset 0x400 + 0x400: 0x00c0, 0x401: 0x00c0, 0x402: 0x00c0, 0x403: 0x00c0, 0x404: 0x00c0, 0x405: 0x00c0, + 0x406: 0x00c0, 0x407: 0x00c0, 0x408: 0x00c0, 0x409: 0x00c0, 0x40a: 0x00c0, 0x40b: 0x00c0, + 0x40c: 0x00c0, 0x40d: 0x00c0, 0x40e: 0x00c0, 0x40f: 0x00c0, 0x410: 0x00c0, 0x411: 0x00c0, + 0x412: 0x00c0, 0x413: 0x00c0, 0x414: 0x00c0, 0x415: 0x00c0, 0x416: 0x00c0, 0x417: 0x00c0, + 0x418: 0x00c0, 0x419: 0x00c0, 0x41a: 0x00c0, 0x41b: 0x00c0, 0x41c: 0x00c0, 0x41d: 0x00c0, + 0x41e: 0x00c0, 0x41f: 0x00c0, 0x420: 0x00c0, 0x421: 0x00c0, 0x422: 0x00c0, 0x423: 0x00c0, + 0x424: 0x00c0, 0x425: 0x00c0, 0x426: 0x00c0, 0x427: 0x00c0, 0x428: 0x00c0, 0x429: 0x00c0, + 0x42a: 0x00c0, 0x42b: 0x00c0, 0x42c: 0x00c0, 0x42d: 0x00c0, 0x42e: 0x00c0, 0x42f: 0x00c0, + 0x431: 0x00c0, 0x432: 0x00c0, 0x433: 0x00c0, 0x434: 0x00c0, 0x435: 0x00c0, + 0x436: 0x00c0, 0x437: 0x00c0, 0x438: 0x00c0, 0x439: 0x00c0, 0x43a: 0x00c0, 0x43b: 0x00c0, + 0x43c: 0x00c0, 0x43d: 0x00c0, 0x43e: 0x00c0, 0x43f: 0x00c0, + // Block 0x11, offset 0x440 + 0x440: 0x00c0, 0x441: 0x00c0, 0x442: 0x00c0, 0x443: 0x00c0, 0x444: 0x00c0, 0x445: 0x00c0, + 0x446: 0x00c0, 0x447: 0x00c0, 0x448: 0x00c0, 0x449: 0x00c0, 0x44a: 0x00c0, 0x44b: 0x00c0, + 0x44c: 0x00c0, 0x44d: 0x00c0, 0x44e: 0x00c0, 0x44f: 0x00c0, 0x450: 0x00c0, 0x451: 0x00c0, + 0x452: 0x00c0, 0x453: 0x00c0, 0x454: 0x00c0, 0x455: 0x00c0, 0x456: 0x00c0, + 0x459: 0x00c0, 0x45a: 0x0080, 0x45b: 0x0080, 0x45c: 0x0080, 0x45d: 0x0080, + 0x45e: 0x0080, 0x45f: 0x0080, 0x461: 0x00c0, 0x462: 0x00c0, 0x463: 0x00c0, + 0x464: 0x00c0, 0x465: 0x00c0, 0x466: 0x00c0, 0x467: 0x00c0, 0x468: 0x00c0, 0x469: 0x00c0, + 0x46a: 0x00c0, 0x46b: 0x00c0, 0x46c: 0x00c0, 0x46d: 0x00c0, 0x46e: 0x00c0, 0x46f: 0x00c0, + 0x470: 0x00c0, 0x471: 0x00c0, 0x472: 0x00c0, 0x473: 0x00c0, 0x474: 0x00c0, 0x475: 0x00c0, + 0x476: 0x00c0, 0x477: 0x00c0, 0x478: 0x00c0, 0x479: 0x00c0, 0x47a: 0x00c0, 0x47b: 0x00c0, + 0x47c: 0x00c0, 0x47d: 0x00c0, 0x47e: 0x00c0, 0x47f: 0x00c0, + // Block 0x12, offset 0x480 + 0x480: 0x00c0, 0x481: 0x00c0, 0x482: 0x00c0, 0x483: 0x00c0, 0x484: 0x00c0, 0x485: 0x00c0, + 0x486: 0x00c0, 0x487: 0x0080, 0x489: 0x0080, 0x48a: 0x0080, + 0x48d: 0x0080, 0x48e: 0x0080, 0x48f: 0x0080, 0x491: 0x00cb, + 0x492: 0x00cb, 0x493: 0x00cb, 0x494: 0x00cb, 0x495: 0x00cb, 0x496: 0x00cb, 0x497: 0x00cb, + 0x498: 0x00cb, 0x499: 0x00cb, 0x49a: 0x00cb, 0x49b: 0x00cb, 0x49c: 0x00cb, 0x49d: 0x00cb, + 0x49e: 0x00cb, 0x49f: 0x00cb, 0x4a0: 0x00cb, 0x4a1: 0x00cb, 0x4a2: 0x00cb, 0x4a3: 0x00cb, + 0x4a4: 0x00cb, 0x4a5: 0x00cb, 0x4a6: 0x00cb, 0x4a7: 0x00cb, 0x4a8: 0x00cb, 0x4a9: 0x00cb, + 0x4aa: 0x00cb, 0x4ab: 0x00cb, 0x4ac: 0x00cb, 0x4ad: 0x00cb, 0x4ae: 0x00cb, 0x4af: 0x00cb, + 0x4b0: 0x00cb, 0x4b1: 0x00cb, 0x4b2: 0x00cb, 0x4b3: 0x00cb, 0x4b4: 0x00cb, 0x4b5: 0x00cb, + 0x4b6: 0x00cb, 0x4b7: 0x00cb, 0x4b8: 0x00cb, 0x4b9: 0x00cb, 0x4ba: 0x00cb, 0x4bb: 0x00cb, + 0x4bc: 0x00cb, 0x4bd: 0x00cb, 0x4be: 0x008a, 0x4bf: 0x00cb, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x008a, 0x4c1: 0x00cb, 0x4c2: 0x00cb, 0x4c3: 0x008a, 0x4c4: 0x00cb, 0x4c5: 0x00cb, + 0x4c6: 0x008a, 0x4c7: 0x00cb, + 0x4d0: 0x00ca, 0x4d1: 0x00ca, + 0x4d2: 0x00ca, 0x4d3: 0x00ca, 0x4d4: 0x00ca, 0x4d5: 0x00ca, 0x4d6: 0x00ca, 0x4d7: 0x00ca, + 0x4d8: 0x00ca, 0x4d9: 0x00ca, 0x4da: 0x00ca, 0x4db: 0x00ca, 0x4dc: 0x00ca, 0x4dd: 0x00ca, + 0x4de: 0x00ca, 0x4df: 0x00ca, 0x4e0: 0x00ca, 0x4e1: 0x00ca, 0x4e2: 0x00ca, 0x4e3: 0x00ca, + 0x4e4: 0x00ca, 0x4e5: 0x00ca, 0x4e6: 0x00ca, 0x4e7: 0x00ca, 0x4e8: 0x00ca, 0x4e9: 0x00ca, + 0x4ea: 0x00ca, + 0x4f0: 0x00ca, 0x4f1: 0x00ca, 0x4f2: 0x00ca, 0x4f3: 0x0051, 0x4f4: 0x0051, + // Block 0x14, offset 0x500 + 0x500: 0x0040, 0x501: 0x0040, 0x502: 0x0040, 0x503: 0x0040, 0x504: 0x0040, 0x505: 0x0040, + 0x506: 0x0080, 0x507: 0x0080, 0x508: 0x0080, 0x509: 0x0080, 0x50a: 0x0080, 0x50b: 0x0080, + 0x50c: 0x0080, 0x50d: 0x0080, 0x50e: 0x0080, 0x50f: 0x0080, 0x510: 0x00c3, 0x511: 0x00c3, + 0x512: 0x00c3, 0x513: 0x00c3, 0x514: 0x00c3, 0x515: 0x00c3, 0x516: 0x00c3, 0x517: 0x00c3, + 0x518: 0x00c3, 0x519: 0x00c3, 0x51a: 0x00c3, 0x51b: 0x0080, 0x51c: 0x0040, + 0x51e: 0x0080, 0x51f: 0x0080, 0x520: 0x00c2, 0x521: 0x00c0, 0x522: 0x00c4, 0x523: 0x00c4, + 0x524: 0x00c4, 0x525: 0x00c4, 0x526: 0x00c2, 0x527: 0x00c4, 0x528: 0x00c2, 0x529: 0x00c4, + 0x52a: 0x00c2, 0x52b: 0x00c2, 0x52c: 0x00c2, 0x52d: 0x00c2, 0x52e: 0x00c2, 0x52f: 0x00c4, + 0x530: 0x00c4, 0x531: 0x00c4, 0x532: 0x00c4, 0x533: 0x00c2, 0x534: 0x00c2, 0x535: 0x00c2, + 0x536: 0x00c2, 0x537: 0x00c2, 0x538: 0x00c2, 0x539: 0x00c2, 0x53a: 0x00c2, 0x53b: 0x00c2, + 0x53c: 0x00c2, 0x53d: 0x00c2, 0x53e: 0x00c2, 0x53f: 0x00c2, + // Block 0x15, offset 0x540 + 0x540: 0x0040, 0x541: 0x00c2, 0x542: 0x00c2, 0x543: 0x00c2, 0x544: 0x00c2, 0x545: 0x00c2, + 0x546: 0x00c2, 0x547: 0x00c2, 0x548: 0x00c4, 0x549: 0x00c2, 0x54a: 0x00c2, 0x54b: 0x00c3, + 0x54c: 0x00c3, 0x54d: 0x00c3, 0x54e: 0x00c3, 0x54f: 0x00c3, 0x550: 0x00c3, 0x551: 0x00c3, + 0x552: 0x00c3, 0x553: 0x00c3, 0x554: 0x00c3, 0x555: 0x00c3, 0x556: 0x00c3, 0x557: 0x00c3, + 0x558: 0x00c3, 0x559: 0x00c3, 0x55a: 0x00c3, 0x55b: 0x00c3, 0x55c: 0x00c3, 0x55d: 0x00c3, + 0x55e: 0x00c3, 0x55f: 0x00c3, 0x560: 0x0053, 0x561: 0x0053, 0x562: 0x0053, 0x563: 0x0053, + 0x564: 0x0053, 0x565: 0x0053, 0x566: 0x0053, 0x567: 0x0053, 0x568: 0x0053, 0x569: 0x0053, + 0x56a: 0x0080, 0x56b: 0x0080, 0x56c: 0x0080, 0x56d: 0x0080, 0x56e: 0x00c2, 0x56f: 0x00c2, + 0x570: 0x00c3, 0x571: 0x00c4, 0x572: 0x00c4, 0x573: 0x00c4, 0x574: 0x00c0, 0x575: 0x0084, + 0x576: 0x0084, 0x577: 0x0084, 0x578: 0x0082, 0x579: 0x00c2, 0x57a: 0x00c2, 0x57b: 0x00c2, + 0x57c: 0x00c2, 0x57d: 0x00c2, 0x57e: 0x00c2, 0x57f: 0x00c2, + // Block 0x16, offset 0x580 + 0x580: 0x00c2, 0x581: 0x00c2, 0x582: 0x00c2, 0x583: 0x00c2, 0x584: 0x00c2, 0x585: 0x00c2, + 0x586: 0x00c2, 0x587: 0x00c2, 0x588: 0x00c4, 0x589: 0x00c4, 0x58a: 0x00c4, 0x58b: 0x00c4, + 0x58c: 0x00c4, 0x58d: 0x00c4, 0x58e: 0x00c4, 0x58f: 0x00c4, 0x590: 0x00c4, 0x591: 0x00c4, + 0x592: 0x00c4, 0x593: 0x00c4, 0x594: 0x00c4, 0x595: 0x00c4, 0x596: 0x00c4, 0x597: 0x00c4, + 0x598: 0x00c4, 0x599: 0x00c4, 0x59a: 0x00c2, 0x59b: 0x00c2, 0x59c: 0x00c2, 0x59d: 0x00c2, + 0x59e: 0x00c2, 0x59f: 0x00c2, 0x5a0: 0x00c2, 0x5a1: 0x00c2, 0x5a2: 0x00c2, 0x5a3: 0x00c2, + 0x5a4: 0x00c2, 0x5a5: 0x00c2, 0x5a6: 0x00c2, 0x5a7: 0x00c2, 0x5a8: 0x00c2, 0x5a9: 0x00c2, + 0x5aa: 0x00c2, 0x5ab: 0x00c2, 0x5ac: 0x00c2, 0x5ad: 0x00c2, 0x5ae: 0x00c2, 0x5af: 0x00c2, + 0x5b0: 0x00c2, 0x5b1: 0x00c2, 0x5b2: 0x00c2, 0x5b3: 0x00c2, 0x5b4: 0x00c2, 0x5b5: 0x00c2, + 0x5b6: 0x00c2, 0x5b7: 0x00c2, 0x5b8: 0x00c2, 0x5b9: 0x00c2, 0x5ba: 0x00c2, 0x5bb: 0x00c2, + 0x5bc: 0x00c2, 0x5bd: 0x00c2, 0x5be: 0x00c2, 0x5bf: 0x00c2, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x00c4, 0x5c1: 0x00c2, 0x5c2: 0x00c2, 0x5c3: 0x00c4, 0x5c4: 0x00c4, 0x5c5: 0x00c4, + 0x5c6: 0x00c4, 0x5c7: 0x00c4, 0x5c8: 0x00c4, 0x5c9: 0x00c4, 0x5ca: 0x00c4, 0x5cb: 0x00c4, + 0x5cc: 0x00c2, 0x5cd: 0x00c4, 0x5ce: 0x00c2, 0x5cf: 0x00c4, 0x5d0: 0x00c2, 0x5d1: 0x00c2, + 0x5d2: 0x00c4, 0x5d3: 0x00c4, 0x5d4: 0x0080, 0x5d5: 0x00c4, 0x5d6: 0x00c3, 0x5d7: 0x00c3, + 0x5d8: 0x00c3, 0x5d9: 0x00c3, 0x5da: 0x00c3, 0x5db: 0x00c3, 0x5dc: 0x00c3, 0x5dd: 0x0040, + 0x5de: 0x0080, 0x5df: 0x00c3, 0x5e0: 0x00c3, 0x5e1: 0x00c3, 0x5e2: 0x00c3, 0x5e3: 0x00c3, + 0x5e4: 0x00c3, 0x5e5: 0x00c0, 0x5e6: 0x00c0, 0x5e7: 0x00c3, 0x5e8: 0x00c3, 0x5e9: 0x0080, + 0x5ea: 0x00c3, 0x5eb: 0x00c3, 0x5ec: 0x00c3, 0x5ed: 0x00c3, 0x5ee: 0x00c4, 0x5ef: 0x00c4, + 0x5f0: 0x0054, 0x5f1: 0x0054, 0x5f2: 0x0054, 0x5f3: 0x0054, 0x5f4: 0x0054, 0x5f5: 0x0054, + 0x5f6: 0x0054, 0x5f7: 0x0054, 0x5f8: 0x0054, 0x5f9: 0x0054, 0x5fa: 0x00c2, 0x5fb: 0x00c2, + 0x5fc: 0x00c2, 0x5fd: 0x00c0, 0x5fe: 0x00c0, 0x5ff: 0x00c2, + // Block 0x18, offset 0x600 + 0x600: 0x0080, 0x601: 0x0080, 0x602: 0x0080, 0x603: 0x0080, 0x604: 0x0080, 0x605: 0x0080, + 0x606: 0x0080, 0x607: 0x0080, 0x608: 0x0080, 0x609: 0x0080, 0x60a: 0x0080, 0x60b: 0x0080, + 0x60c: 0x0080, 0x60d: 0x0080, 0x60f: 0x0040, 0x610: 0x00c4, 0x611: 0x00c3, + 0x612: 0x00c2, 0x613: 0x00c2, 0x614: 0x00c2, 0x615: 0x00c4, 0x616: 0x00c4, 0x617: 0x00c4, + 0x618: 0x00c4, 0x619: 0x00c4, 0x61a: 0x00c2, 0x61b: 0x00c2, 0x61c: 0x00c2, 0x61d: 0x00c2, + 0x61e: 0x00c4, 0x61f: 0x00c2, 0x620: 0x00c2, 0x621: 0x00c2, 0x622: 0x00c2, 0x623: 0x00c2, + 0x624: 0x00c2, 0x625: 0x00c2, 0x626: 0x00c2, 0x627: 0x00c2, 0x628: 0x00c4, 0x629: 0x00c2, + 0x62a: 0x00c4, 0x62b: 0x00c2, 0x62c: 0x00c4, 0x62d: 0x00c2, 0x62e: 0x00c2, 0x62f: 0x00c4, + 0x630: 0x00c3, 0x631: 0x00c3, 0x632: 0x00c3, 0x633: 0x00c3, 0x634: 0x00c3, 0x635: 0x00c3, + 0x636: 0x00c3, 0x637: 0x00c3, 0x638: 0x00c3, 0x639: 0x00c3, 0x63a: 0x00c3, 0x63b: 0x00c3, + 0x63c: 0x00c3, 0x63d: 0x00c3, 0x63e: 0x00c3, 0x63f: 0x00c3, + // Block 0x19, offset 0x640 + 0x640: 0x00c3, 0x641: 0x00c3, 0x642: 0x00c3, 0x643: 0x00c3, 0x644: 0x00c3, 0x645: 0x00c3, + 0x646: 0x00c3, 0x647: 0x00c3, 0x648: 0x00c3, 0x649: 0x00c3, 0x64a: 0x00c3, + 0x64d: 0x00c4, 0x64e: 0x00c2, 0x64f: 0x00c2, 0x650: 0x00c2, 0x651: 0x00c2, + 0x652: 0x00c2, 0x653: 0x00c2, 0x654: 0x00c2, 0x655: 0x00c2, 0x656: 0x00c2, 0x657: 0x00c2, + 0x658: 0x00c2, 0x659: 0x00c4, 0x65a: 0x00c4, 0x65b: 0x00c4, 0x65c: 0x00c2, 0x65d: 0x00c2, + 0x65e: 0x00c2, 0x65f: 0x00c2, 0x660: 0x00c2, 0x661: 0x00c2, 0x662: 0x00c2, 0x663: 0x00c2, + 0x664: 0x00c2, 0x665: 0x00c2, 0x666: 0x00c2, 0x667: 0x00c2, 0x668: 0x00c2, 0x669: 0x00c2, + 0x66a: 0x00c2, 0x66b: 0x00c4, 0x66c: 0x00c4, 0x66d: 0x00c2, 0x66e: 0x00c2, 0x66f: 0x00c2, + 0x670: 0x00c2, 0x671: 0x00c4, 0x672: 0x00c2, 0x673: 0x00c4, 0x674: 0x00c4, 0x675: 0x00c2, + 0x676: 0x00c2, 0x677: 0x00c2, 0x678: 0x00c4, 0x679: 0x00c4, 0x67a: 0x00c2, 0x67b: 0x00c2, + 0x67c: 0x00c2, 0x67d: 0x00c2, 0x67e: 0x00c2, 0x67f: 0x00c2, + // Block 0x1a, offset 0x680 + 0x680: 0x00c0, 0x681: 0x00c0, 0x682: 0x00c0, 0x683: 0x00c0, 0x684: 0x00c0, 0x685: 0x00c0, + 0x686: 0x00c0, 0x687: 0x00c0, 0x688: 0x00c0, 0x689: 0x00c0, 0x68a: 0x00c0, 0x68b: 0x00c0, + 0x68c: 0x00c0, 0x68d: 0x00c0, 0x68e: 0x00c0, 0x68f: 0x00c0, 0x690: 0x00c0, 0x691: 0x00c0, + 0x692: 0x00c0, 0x693: 0x00c0, 0x694: 0x00c0, 0x695: 0x00c0, 0x696: 0x00c0, 0x697: 0x00c0, + 0x698: 0x00c0, 0x699: 0x00c0, 0x69a: 0x00c0, 0x69b: 0x00c0, 0x69c: 0x00c0, 0x69d: 0x00c0, + 0x69e: 0x00c0, 0x69f: 0x00c0, 0x6a0: 0x00c0, 0x6a1: 0x00c0, 0x6a2: 0x00c0, 0x6a3: 0x00c0, + 0x6a4: 0x00c0, 0x6a5: 0x00c0, 0x6a6: 0x00c3, 0x6a7: 0x00c3, 0x6a8: 0x00c3, 0x6a9: 0x00c3, + 0x6aa: 0x00c3, 0x6ab: 0x00c3, 0x6ac: 0x00c3, 0x6ad: 0x00c3, 0x6ae: 0x00c3, 0x6af: 0x00c3, + 0x6b0: 0x00c3, 0x6b1: 0x00c0, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x00c0, 0x6c1: 0x00c0, 0x6c2: 0x00c0, 0x6c3: 0x00c0, 0x6c4: 0x00c0, 0x6c5: 0x00c0, + 0x6c6: 0x00c0, 0x6c7: 0x00c0, 0x6c8: 0x00c0, 0x6c9: 0x00c0, 0x6ca: 0x00c2, 0x6cb: 0x00c2, + 0x6cc: 0x00c2, 0x6cd: 0x00c2, 0x6ce: 0x00c2, 0x6cf: 0x00c2, 0x6d0: 0x00c2, 0x6d1: 0x00c2, + 0x6d2: 0x00c2, 0x6d3: 0x00c2, 0x6d4: 0x00c2, 0x6d5: 0x00c2, 0x6d6: 0x00c2, 0x6d7: 0x00c2, + 0x6d8: 0x00c2, 0x6d9: 0x00c2, 0x6da: 0x00c2, 0x6db: 0x00c2, 0x6dc: 0x00c2, 0x6dd: 0x00c2, + 0x6de: 0x00c2, 0x6df: 0x00c2, 0x6e0: 0x00c2, 0x6e1: 0x00c2, 0x6e2: 0x00c2, 0x6e3: 0x00c2, + 0x6e4: 0x00c2, 0x6e5: 0x00c2, 0x6e6: 0x00c2, 0x6e7: 0x00c2, 0x6e8: 0x00c2, 0x6e9: 0x00c2, + 0x6ea: 0x00c2, 0x6eb: 0x00c3, 0x6ec: 0x00c3, 0x6ed: 0x00c3, 0x6ee: 0x00c3, 0x6ef: 0x00c3, + 0x6f0: 0x00c3, 0x6f1: 0x00c3, 0x6f2: 0x00c3, 0x6f3: 0x00c3, 0x6f4: 0x00c0, 0x6f5: 0x00c0, + 0x6f6: 0x0080, 0x6f7: 0x0080, 0x6f8: 0x0080, 0x6f9: 0x0080, 0x6fa: 0x0040, + // Block 0x1c, offset 0x700 + 0x700: 0x00c0, 0x701: 0x00c0, 0x702: 0x00c0, 0x703: 0x00c0, 0x704: 0x00c0, 0x705: 0x00c0, + 0x706: 0x00c0, 0x707: 0x00c0, 0x708: 0x00c0, 0x709: 0x00c0, 0x70a: 0x00c0, 0x70b: 0x00c0, + 0x70c: 0x00c0, 0x70d: 0x00c0, 0x70e: 0x00c0, 0x70f: 0x00c0, 0x710: 0x00c0, 0x711: 0x00c0, + 0x712: 0x00c0, 0x713: 0x00c0, 0x714: 0x00c0, 0x715: 0x00c0, 0x716: 0x00c3, 0x717: 0x00c3, + 0x718: 0x00c3, 0x719: 0x00c3, 0x71a: 0x00c0, 0x71b: 0x00c3, 0x71c: 0x00c3, 0x71d: 0x00c3, + 0x71e: 0x00c3, 0x71f: 0x00c3, 0x720: 0x00c3, 0x721: 0x00c3, 0x722: 0x00c3, 0x723: 0x00c3, + 0x724: 0x00c0, 0x725: 0x00c3, 0x726: 0x00c3, 0x727: 0x00c3, 0x728: 0x00c0, 0x729: 0x00c3, + 0x72a: 0x00c3, 0x72b: 0x00c3, 0x72c: 0x00c3, 0x72d: 0x00c3, + 0x730: 0x0080, 0x731: 0x0080, 0x732: 0x0080, 0x733: 0x0080, 0x734: 0x0080, 0x735: 0x0080, + 0x736: 0x0080, 0x737: 0x0080, 0x738: 0x0080, 0x739: 0x0080, 0x73a: 0x0080, 0x73b: 0x0080, + 0x73c: 0x0080, 0x73d: 0x0080, 0x73e: 0x0080, + // Block 0x1d, offset 0x740 + 0x740: 0x00c4, 0x741: 0x00c2, 0x742: 0x00c2, 0x743: 0x00c2, 0x744: 0x00c2, 0x745: 0x00c2, + 0x746: 0x00c4, 0x747: 0x00c4, 0x748: 0x00c2, 0x749: 0x00c4, 0x74a: 0x00c2, 0x74b: 0x00c2, + 0x74c: 0x00c2, 0x74d: 0x00c2, 0x74e: 0x00c2, 0x74f: 0x00c2, 0x750: 0x00c2, 0x751: 0x00c2, + 0x752: 0x00c2, 0x753: 0x00c2, 0x754: 0x00c4, 0x755: 0x00c2, 0x756: 0x00c0, 0x757: 0x00c0, + 0x758: 0x00c0, 0x759: 0x00c3, 0x75a: 0x00c3, 0x75b: 0x00c3, + 0x75e: 0x0080, 0x760: 0x00c2, 0x761: 0x00c0, 0x762: 0x00c2, 0x763: 0x00c2, + 0x764: 0x00c2, 0x765: 0x00c2, 0x766: 0x00c0, 0x767: 0x00c4, 0x768: 0x00c2, 0x769: 0x00c4, + 0x76a: 0x00c4, + // Block 0x1e, offset 0x780 + 0x7a0: 0x00c2, 0x7a1: 0x00c2, 0x7a2: 0x00c2, 0x7a3: 0x00c2, + 0x7a4: 0x00c2, 0x7a5: 0x00c2, 0x7a6: 0x00c2, 0x7a7: 0x00c2, 0x7a8: 0x00c2, 0x7a9: 0x00c2, + 0x7aa: 0x00c4, 0x7ab: 0x00c4, 0x7ac: 0x00c4, 0x7ad: 0x00c0, 0x7ae: 0x00c4, 0x7af: 0x00c2, + 0x7b0: 0x00c2, 0x7b1: 0x00c4, 0x7b2: 0x00c4, 0x7b3: 0x00c2, 0x7b4: 0x00c2, + 0x7b6: 0x00c2, 0x7b7: 0x00c2, 0x7b8: 0x00c2, 0x7b9: 0x00c4, 0x7ba: 0x00c2, 0x7bb: 0x00c2, + 0x7bc: 0x00c2, 0x7bd: 0x00c2, + // Block 0x1f, offset 0x7c0 + 0x7d4: 0x00c3, 0x7d5: 0x00c3, 0x7d6: 0x00c3, 0x7d7: 0x00c3, + 0x7d8: 0x00c3, 0x7d9: 0x00c3, 0x7da: 0x00c3, 0x7db: 0x00c3, 0x7dc: 0x00c3, 0x7dd: 0x00c3, + 0x7de: 0x00c3, 0x7df: 0x00c3, 0x7e0: 0x00c3, 0x7e1: 0x00c3, 0x7e2: 0x0040, 0x7e3: 0x00c3, + 0x7e4: 0x00c3, 0x7e5: 0x00c3, 0x7e6: 0x00c3, 0x7e7: 0x00c3, 0x7e8: 0x00c3, 0x7e9: 0x00c3, + 0x7ea: 0x00c3, 0x7eb: 0x00c3, 0x7ec: 0x00c3, 0x7ed: 0x00c3, 0x7ee: 0x00c3, 0x7ef: 0x00c3, + 0x7f0: 0x00c3, 0x7f1: 0x00c3, 0x7f2: 0x00c3, 0x7f3: 0x00c3, 0x7f4: 0x00c3, 0x7f5: 0x00c3, + 0x7f6: 0x00c3, 0x7f7: 0x00c3, 0x7f8: 0x00c3, 0x7f9: 0x00c3, 0x7fa: 0x00c3, 0x7fb: 0x00c3, + 0x7fc: 0x00c3, 0x7fd: 0x00c3, 0x7fe: 0x00c3, 0x7ff: 0x00c3, + // Block 0x20, offset 0x800 + 0x800: 0x00c3, 0x801: 0x00c3, 0x802: 0x00c3, 0x803: 0x00c0, 0x804: 0x00c0, 0x805: 0x00c0, + 0x806: 0x00c0, 0x807: 0x00c0, 0x808: 0x00c0, 0x809: 0x00c0, 0x80a: 0x00c0, 0x80b: 0x00c0, + 0x80c: 0x00c0, 0x80d: 0x00c0, 0x80e: 0x00c0, 0x80f: 0x00c0, 0x810: 0x00c0, 0x811: 0x00c0, + 0x812: 0x00c0, 0x813: 0x00c0, 0x814: 0x00c0, 0x815: 0x00c0, 0x816: 0x00c0, 0x817: 0x00c0, + 0x818: 0x00c0, 0x819: 0x00c0, 0x81a: 0x00c0, 0x81b: 0x00c0, 0x81c: 0x00c0, 0x81d: 0x00c0, + 0x81e: 0x00c0, 0x81f: 0x00c0, 0x820: 0x00c0, 0x821: 0x00c0, 0x822: 0x00c0, 0x823: 0x00c0, + 0x824: 0x00c0, 0x825: 0x00c0, 0x826: 0x00c0, 0x827: 0x00c0, 0x828: 0x00c0, 0x829: 0x00c0, + 0x82a: 0x00c0, 0x82b: 0x00c0, 0x82c: 0x00c0, 0x82d: 0x00c0, 0x82e: 0x00c0, 0x82f: 0x00c0, + 0x830: 0x00c0, 0x831: 0x00c0, 0x832: 0x00c0, 0x833: 0x00c0, 0x834: 0x00c0, 0x835: 0x00c0, + 0x836: 0x00c0, 0x837: 0x00c0, 0x838: 0x00c0, 0x839: 0x00c0, 0x83a: 0x00c3, 0x83b: 0x00c0, + 0x83c: 0x00c3, 0x83d: 0x00c0, 0x83e: 0x00c0, 0x83f: 0x00c0, + // Block 0x21, offset 0x840 + 0x840: 0x00c0, 0x841: 0x00c3, 0x842: 0x00c3, 0x843: 0x00c3, 0x844: 0x00c3, 0x845: 0x00c3, + 0x846: 0x00c3, 0x847: 0x00c3, 0x848: 0x00c3, 0x849: 0x00c0, 0x84a: 0x00c0, 0x84b: 0x00c0, + 0x84c: 0x00c0, 0x84d: 0x00c6, 0x84e: 0x00c0, 0x84f: 0x00c0, 0x850: 0x00c0, 0x851: 0x00c3, + 0x852: 0x00c3, 0x853: 0x00c3, 0x854: 0x00c3, 0x855: 0x00c3, 0x856: 0x00c3, 0x857: 0x00c3, + 0x858: 0x0080, 0x859: 0x0080, 0x85a: 0x0080, 0x85b: 0x0080, 0x85c: 0x0080, 0x85d: 0x0080, + 0x85e: 0x0080, 0x85f: 0x0080, 0x860: 0x00c0, 0x861: 0x00c0, 0x862: 0x00c3, 0x863: 0x00c3, + 0x864: 0x0080, 0x865: 0x0080, 0x866: 0x00c0, 0x867: 0x00c0, 0x868: 0x00c0, 0x869: 0x00c0, + 0x86a: 0x00c0, 0x86b: 0x00c0, 0x86c: 0x00c0, 0x86d: 0x00c0, 0x86e: 0x00c0, 0x86f: 0x00c0, + 0x870: 0x0080, 0x871: 0x00c0, 0x872: 0x00c0, 0x873: 0x00c0, 0x874: 0x00c0, 0x875: 0x00c0, + 0x876: 0x00c0, 0x877: 0x00c0, 0x878: 0x00c0, 0x879: 0x00c0, 0x87a: 0x00c0, 0x87b: 0x00c0, + 0x87c: 0x00c0, 0x87d: 0x00c0, 0x87e: 0x00c0, 0x87f: 0x00c0, + // Block 0x22, offset 0x880 + 0x880: 0x00c0, 0x881: 0x00c3, 0x882: 0x00c0, 0x883: 0x00c0, 0x885: 0x00c0, + 0x886: 0x00c0, 0x887: 0x00c0, 0x888: 0x00c0, 0x889: 0x00c0, 0x88a: 0x00c0, 0x88b: 0x00c0, + 0x88c: 0x00c0, 0x88f: 0x00c0, 0x890: 0x00c0, + 0x893: 0x00c0, 0x894: 0x00c0, 0x895: 0x00c0, 0x896: 0x00c0, 0x897: 0x00c0, + 0x898: 0x00c0, 0x899: 0x00c0, 0x89a: 0x00c0, 0x89b: 0x00c0, 0x89c: 0x00c0, 0x89d: 0x00c0, + 0x89e: 0x00c0, 0x89f: 0x00c0, 0x8a0: 0x00c0, 0x8a1: 0x00c0, 0x8a2: 0x00c0, 0x8a3: 0x00c0, + 0x8a4: 0x00c0, 0x8a5: 0x00c0, 0x8a6: 0x00c0, 0x8a7: 0x00c0, 0x8a8: 0x00c0, + 0x8aa: 0x00c0, 0x8ab: 0x00c0, 0x8ac: 0x00c0, 0x8ad: 0x00c0, 0x8ae: 0x00c0, 0x8af: 0x00c0, + 0x8b0: 0x00c0, 0x8b2: 0x00c0, + 0x8b6: 0x00c0, 0x8b7: 0x00c0, 0x8b8: 0x00c0, 0x8b9: 0x00c0, + 0x8bc: 0x00c3, 0x8bd: 0x00c0, 0x8be: 0x00c0, 0x8bf: 0x00c0, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x00c0, 0x8c1: 0x00c3, 0x8c2: 0x00c3, 0x8c3: 0x00c3, 0x8c4: 0x00c3, + 0x8c7: 0x00c0, 0x8c8: 0x00c0, 0x8cb: 0x00c0, + 0x8cc: 0x00c0, 0x8cd: 0x00c6, 0x8ce: 0x00c0, + 0x8d7: 0x00c0, + 0x8dc: 0x0080, 0x8dd: 0x0080, + 0x8df: 0x0080, 0x8e0: 0x00c0, 0x8e1: 0x00c0, 0x8e2: 0x00c3, 0x8e3: 0x00c3, + 0x8e6: 0x00c0, 0x8e7: 0x00c0, 0x8e8: 0x00c0, 0x8e9: 0x00c0, + 0x8ea: 0x00c0, 0x8eb: 0x00c0, 0x8ec: 0x00c0, 0x8ed: 0x00c0, 0x8ee: 0x00c0, 0x8ef: 0x00c0, + 0x8f0: 0x00c0, 0x8f1: 0x00c0, 0x8f2: 0x0080, 0x8f3: 0x0080, 0x8f4: 0x0080, 0x8f5: 0x0080, + 0x8f6: 0x0080, 0x8f7: 0x0080, 0x8f8: 0x0080, 0x8f9: 0x0080, 0x8fa: 0x0080, 0x8fb: 0x0080, + 0x8fc: 0x00c0, 0x8fd: 0x0080, + // Block 0x24, offset 0x900 + 0x901: 0x00c3, 0x902: 0x00c3, 0x903: 0x00c0, 0x905: 0x00c0, + 0x906: 0x00c0, 0x907: 0x00c0, 0x908: 0x00c0, 0x909: 0x00c0, 0x90a: 0x00c0, + 0x90f: 0x00c0, 0x910: 0x00c0, + 0x913: 0x00c0, 0x914: 0x00c0, 0x915: 0x00c0, 0x916: 0x00c0, 0x917: 0x00c0, + 0x918: 0x00c0, 0x919: 0x00c0, 0x91a: 0x00c0, 0x91b: 0x00c0, 0x91c: 0x00c0, 0x91d: 0x00c0, + 0x91e: 0x00c0, 0x91f: 0x00c0, 0x920: 0x00c0, 0x921: 0x00c0, 0x922: 0x00c0, 0x923: 0x00c0, + 0x924: 0x00c0, 0x925: 0x00c0, 0x926: 0x00c0, 0x927: 0x00c0, 0x928: 0x00c0, + 0x92a: 0x00c0, 0x92b: 0x00c0, 0x92c: 0x00c0, 0x92d: 0x00c0, 0x92e: 0x00c0, 0x92f: 0x00c0, + 0x930: 0x00c0, 0x932: 0x00c0, 0x933: 0x0080, 0x935: 0x00c0, + 0x936: 0x0080, 0x938: 0x00c0, 0x939: 0x00c0, + 0x93c: 0x00c3, 0x93e: 0x00c0, 0x93f: 0x00c0, + // Block 0x25, offset 0x940 + 0x940: 0x00c0, 0x941: 0x00c3, 0x942: 0x00c3, + 0x947: 0x00c3, 0x948: 0x00c3, 0x94b: 0x00c3, + 0x94c: 0x00c3, 0x94d: 0x00c6, 0x951: 0x00c3, + 0x959: 0x0080, 0x95a: 0x0080, 0x95b: 0x0080, 0x95c: 0x00c0, + 0x95e: 0x0080, + 0x966: 0x00c0, 0x967: 0x00c0, 0x968: 0x00c0, 0x969: 0x00c0, + 0x96a: 0x00c0, 0x96b: 0x00c0, 0x96c: 0x00c0, 0x96d: 0x00c0, 0x96e: 0x00c0, 0x96f: 0x00c0, + 0x970: 0x00c3, 0x971: 0x00c3, 0x972: 0x00c0, 0x973: 0x00c0, 0x974: 0x00c0, 0x975: 0x00c3, + // Block 0x26, offset 0x980 + 0x981: 0x00c3, 0x982: 0x00c3, 0x983: 0x00c0, 0x985: 0x00c0, + 0x986: 0x00c0, 0x987: 0x00c0, 0x988: 0x00c0, 0x989: 0x00c0, 0x98a: 0x00c0, 0x98b: 0x00c0, + 0x98c: 0x00c0, 0x98d: 0x00c0, 0x98f: 0x00c0, 0x990: 0x00c0, 0x991: 0x00c0, + 0x993: 0x00c0, 0x994: 0x00c0, 0x995: 0x00c0, 0x996: 0x00c0, 0x997: 0x00c0, + 0x998: 0x00c0, 0x999: 0x00c0, 0x99a: 0x00c0, 0x99b: 0x00c0, 0x99c: 0x00c0, 0x99d: 0x00c0, + 0x99e: 0x00c0, 0x99f: 0x00c0, 0x9a0: 0x00c0, 0x9a1: 0x00c0, 0x9a2: 0x00c0, 0x9a3: 0x00c0, + 0x9a4: 0x00c0, 0x9a5: 0x00c0, 0x9a6: 0x00c0, 0x9a7: 0x00c0, 0x9a8: 0x00c0, + 0x9aa: 0x00c0, 0x9ab: 0x00c0, 0x9ac: 0x00c0, 0x9ad: 0x00c0, 0x9ae: 0x00c0, 0x9af: 0x00c0, + 0x9b0: 0x00c0, 0x9b2: 0x00c0, 0x9b3: 0x00c0, 0x9b5: 0x00c0, + 0x9b6: 0x00c0, 0x9b7: 0x00c0, 0x9b8: 0x00c0, 0x9b9: 0x00c0, + 0x9bc: 0x00c3, 0x9bd: 0x00c0, 0x9be: 0x00c0, 0x9bf: 0x00c0, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x00c0, 0x9c1: 0x00c3, 0x9c2: 0x00c3, 0x9c3: 0x00c3, 0x9c4: 0x00c3, 0x9c5: 0x00c3, + 0x9c7: 0x00c3, 0x9c8: 0x00c3, 0x9c9: 0x00c0, 0x9cb: 0x00c0, + 0x9cc: 0x00c0, 0x9cd: 0x00c6, 0x9d0: 0x00c0, + 0x9e0: 0x00c0, 0x9e1: 0x00c0, 0x9e2: 0x00c3, 0x9e3: 0x00c3, + 0x9e6: 0x00c0, 0x9e7: 0x00c0, 0x9e8: 0x00c0, 0x9e9: 0x00c0, + 0x9ea: 0x00c0, 0x9eb: 0x00c0, 0x9ec: 0x00c0, 0x9ed: 0x00c0, 0x9ee: 0x00c0, 0x9ef: 0x00c0, + 0x9f0: 0x0080, 0x9f1: 0x0080, + 0x9f9: 0x00c0, 0x9fa: 0x00c3, 0x9fb: 0x00c3, + 0x9fc: 0x00c3, 0x9fd: 0x00c3, 0x9fe: 0x00c3, 0x9ff: 0x00c3, + // Block 0x28, offset 0xa00 + 0xa01: 0x00c3, 0xa02: 0x00c0, 0xa03: 0x00c0, 0xa05: 0x00c0, + 0xa06: 0x00c0, 0xa07: 0x00c0, 0xa08: 0x00c0, 0xa09: 0x00c0, 0xa0a: 0x00c0, 0xa0b: 0x00c0, + 0xa0c: 0x00c0, 0xa0f: 0x00c0, 0xa10: 0x00c0, + 0xa13: 0x00c0, 0xa14: 0x00c0, 0xa15: 0x00c0, 0xa16: 0x00c0, 0xa17: 0x00c0, + 0xa18: 0x00c0, 0xa19: 0x00c0, 0xa1a: 0x00c0, 0xa1b: 0x00c0, 0xa1c: 0x00c0, 0xa1d: 0x00c0, + 0xa1e: 0x00c0, 0xa1f: 0x00c0, 0xa20: 0x00c0, 0xa21: 0x00c0, 0xa22: 0x00c0, 0xa23: 0x00c0, + 0xa24: 0x00c0, 0xa25: 0x00c0, 0xa26: 0x00c0, 0xa27: 0x00c0, 0xa28: 0x00c0, + 0xa2a: 0x00c0, 0xa2b: 0x00c0, 0xa2c: 0x00c0, 0xa2d: 0x00c0, 0xa2e: 0x00c0, 0xa2f: 0x00c0, + 0xa30: 0x00c0, 0xa32: 0x00c0, 0xa33: 0x00c0, 0xa35: 0x00c0, + 0xa36: 0x00c0, 0xa37: 0x00c0, 0xa38: 0x00c0, 0xa39: 0x00c0, + 0xa3c: 0x00c3, 0xa3d: 0x00c0, 0xa3e: 0x00c0, 0xa3f: 0x00c3, + // Block 0x29, offset 0xa40 + 0xa40: 0x00c0, 0xa41: 0x00c3, 0xa42: 0x00c3, 0xa43: 0x00c3, 0xa44: 0x00c3, + 0xa47: 0x00c0, 0xa48: 0x00c0, 0xa4b: 0x00c0, + 0xa4c: 0x00c0, 0xa4d: 0x00c6, + 0xa56: 0x00c3, 0xa57: 0x00c0, + 0xa5c: 0x0080, 0xa5d: 0x0080, + 0xa5f: 0x00c0, 0xa60: 0x00c0, 0xa61: 0x00c0, 0xa62: 0x00c3, 0xa63: 0x00c3, + 0xa66: 0x00c0, 0xa67: 0x00c0, 0xa68: 0x00c0, 0xa69: 0x00c0, + 0xa6a: 0x00c0, 0xa6b: 0x00c0, 0xa6c: 0x00c0, 0xa6d: 0x00c0, 0xa6e: 0x00c0, 0xa6f: 0x00c0, + 0xa70: 0x0080, 0xa71: 0x00c0, 0xa72: 0x0080, 0xa73: 0x0080, 0xa74: 0x0080, 0xa75: 0x0080, + 0xa76: 0x0080, 0xa77: 0x0080, + // Block 0x2a, offset 0xa80 + 0xa82: 0x00c3, 0xa83: 0x00c0, 0xa85: 0x00c0, + 0xa86: 0x00c0, 0xa87: 0x00c0, 0xa88: 0x00c0, 0xa89: 0x00c0, 0xa8a: 0x00c0, + 0xa8e: 0x00c0, 0xa8f: 0x00c0, 0xa90: 0x00c0, + 0xa92: 0x00c0, 0xa93: 0x00c0, 0xa94: 0x00c0, 0xa95: 0x00c0, + 0xa99: 0x00c0, 0xa9a: 0x00c0, 0xa9c: 0x00c0, + 0xa9e: 0x00c0, 0xa9f: 0x00c0, 0xaa3: 0x00c0, + 0xaa4: 0x00c0, 0xaa8: 0x00c0, 0xaa9: 0x00c0, + 0xaaa: 0x00c0, 0xaae: 0x00c0, 0xaaf: 0x00c0, + 0xab0: 0x00c0, 0xab1: 0x00c0, 0xab2: 0x00c0, 0xab3: 0x00c0, 0xab4: 0x00c0, 0xab5: 0x00c0, + 0xab6: 0x00c0, 0xab7: 0x00c0, 0xab8: 0x00c0, 0xab9: 0x00c0, + 0xabe: 0x00c0, 0xabf: 0x00c0, + // Block 0x2b, offset 0xac0 + 0xac0: 0x00c3, 0xac1: 0x00c0, 0xac2: 0x00c0, + 0xac6: 0x00c0, 0xac7: 0x00c0, 0xac8: 0x00c0, 0xaca: 0x00c0, 0xacb: 0x00c0, + 0xacc: 0x00c0, 0xacd: 0x00c6, 0xad0: 0x00c0, + 0xad7: 0x00c0, + 0xae6: 0x00c0, 0xae7: 0x00c0, 0xae8: 0x00c0, 0xae9: 0x00c0, + 0xaea: 0x00c0, 0xaeb: 0x00c0, 0xaec: 0x00c0, 0xaed: 0x00c0, 0xaee: 0x00c0, 0xaef: 0x00c0, + 0xaf0: 0x0080, 0xaf1: 0x0080, 0xaf2: 0x0080, 0xaf3: 0x0080, 0xaf4: 0x0080, 0xaf5: 0x0080, + 0xaf6: 0x0080, 0xaf7: 0x0080, 0xaf8: 0x0080, 0xaf9: 0x0080, 0xafa: 0x0080, + // Block 0x2c, offset 0xb00 + 0xb00: 0x00c3, 0xb01: 0x00c0, 0xb02: 0x00c0, 0xb03: 0x00c0, 0xb05: 0x00c0, + 0xb06: 0x00c0, 0xb07: 0x00c0, 0xb08: 0x00c0, 0xb09: 0x00c0, 0xb0a: 0x00c0, 0xb0b: 0x00c0, + 0xb0c: 0x00c0, 0xb0e: 0x00c0, 0xb0f: 0x00c0, 0xb10: 0x00c0, + 0xb12: 0x00c0, 0xb13: 0x00c0, 0xb14: 0x00c0, 0xb15: 0x00c0, 0xb16: 0x00c0, 0xb17: 0x00c0, + 0xb18: 0x00c0, 0xb19: 0x00c0, 0xb1a: 0x00c0, 0xb1b: 0x00c0, 0xb1c: 0x00c0, 0xb1d: 0x00c0, + 0xb1e: 0x00c0, 0xb1f: 0x00c0, 0xb20: 0x00c0, 0xb21: 0x00c0, 0xb22: 0x00c0, 0xb23: 0x00c0, + 0xb24: 0x00c0, 0xb25: 0x00c0, 0xb26: 0x00c0, 0xb27: 0x00c0, 0xb28: 0x00c0, + 0xb2a: 0x00c0, 0xb2b: 0x00c0, 0xb2c: 0x00c0, 0xb2d: 0x00c0, 0xb2e: 0x00c0, 0xb2f: 0x00c0, + 0xb30: 0x00c0, 0xb31: 0x00c0, 0xb32: 0x00c0, 0xb33: 0x00c0, 0xb34: 0x00c0, 0xb35: 0x00c0, + 0xb36: 0x00c0, 0xb37: 0x00c0, 0xb38: 0x00c0, 0xb39: 0x00c0, + 0xb3d: 0x00c0, 0xb3e: 0x00c3, 0xb3f: 0x00c3, + // Block 0x2d, offset 0xb40 + 0xb40: 0x00c3, 0xb41: 0x00c0, 0xb42: 0x00c0, 0xb43: 0x00c0, 0xb44: 0x00c0, + 0xb46: 0x00c3, 0xb47: 0x00c3, 0xb48: 0x00c3, 0xb4a: 0x00c3, 0xb4b: 0x00c3, + 0xb4c: 0x00c3, 0xb4d: 0x00c6, + 0xb55: 0x00c3, 0xb56: 0x00c3, + 0xb58: 0x00c0, 0xb59: 0x00c0, 0xb5a: 0x00c0, + 0xb60: 0x00c0, 0xb61: 0x00c0, 0xb62: 0x00c3, 0xb63: 0x00c3, + 0xb66: 0x00c0, 0xb67: 0x00c0, 0xb68: 0x00c0, 0xb69: 0x00c0, + 0xb6a: 0x00c0, 0xb6b: 0x00c0, 0xb6c: 0x00c0, 0xb6d: 0x00c0, 0xb6e: 0x00c0, 0xb6f: 0x00c0, + 0xb78: 0x0080, 0xb79: 0x0080, 0xb7a: 0x0080, 0xb7b: 0x0080, + 0xb7c: 0x0080, 0xb7d: 0x0080, 0xb7e: 0x0080, 0xb7f: 0x0080, + // Block 0x2e, offset 0xb80 + 0xb80: 0x00c0, 0xb81: 0x00c3, 0xb82: 0x00c0, 0xb83: 0x00c0, 0xb85: 0x00c0, + 0xb86: 0x00c0, 0xb87: 0x00c0, 0xb88: 0x00c0, 0xb89: 0x00c0, 0xb8a: 0x00c0, 0xb8b: 0x00c0, + 0xb8c: 0x00c0, 0xb8e: 0x00c0, 0xb8f: 0x00c0, 0xb90: 0x00c0, + 0xb92: 0x00c0, 0xb93: 0x00c0, 0xb94: 0x00c0, 0xb95: 0x00c0, 0xb96: 0x00c0, 0xb97: 0x00c0, + 0xb98: 0x00c0, 0xb99: 0x00c0, 0xb9a: 0x00c0, 0xb9b: 0x00c0, 0xb9c: 0x00c0, 0xb9d: 0x00c0, + 0xb9e: 0x00c0, 0xb9f: 0x00c0, 0xba0: 0x00c0, 0xba1: 0x00c0, 0xba2: 0x00c0, 0xba3: 0x00c0, + 0xba4: 0x00c0, 0xba5: 0x00c0, 0xba6: 0x00c0, 0xba7: 0x00c0, 0xba8: 0x00c0, + 0xbaa: 0x00c0, 0xbab: 0x00c0, 0xbac: 0x00c0, 0xbad: 0x00c0, 0xbae: 0x00c0, 0xbaf: 0x00c0, + 0xbb0: 0x00c0, 0xbb1: 0x00c0, 0xbb2: 0x00c0, 0xbb3: 0x00c0, 0xbb5: 0x00c0, + 0xbb6: 0x00c0, 0xbb7: 0x00c0, 0xbb8: 0x00c0, 0xbb9: 0x00c0, + 0xbbc: 0x00c3, 0xbbd: 0x00c0, 0xbbe: 0x00c0, 0xbbf: 0x00c3, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x00c0, 0xbc1: 0x00c0, 0xbc2: 0x00c0, 0xbc3: 0x00c0, 0xbc4: 0x00c0, + 0xbc6: 0x00c3, 0xbc7: 0x00c0, 0xbc8: 0x00c0, 0xbca: 0x00c0, 0xbcb: 0x00c0, + 0xbcc: 0x00c3, 0xbcd: 0x00c6, + 0xbd5: 0x00c0, 0xbd6: 0x00c0, + 0xbde: 0x00c0, 0xbe0: 0x00c0, 0xbe1: 0x00c0, 0xbe2: 0x00c3, 0xbe3: 0x00c3, + 0xbe6: 0x00c0, 0xbe7: 0x00c0, 0xbe8: 0x00c0, 0xbe9: 0x00c0, + 0xbea: 0x00c0, 0xbeb: 0x00c0, 0xbec: 0x00c0, 0xbed: 0x00c0, 0xbee: 0x00c0, 0xbef: 0x00c0, + 0xbf1: 0x00c0, 0xbf2: 0x00c0, + // Block 0x30, offset 0xc00 + 0xc00: 0x00c3, 0xc01: 0x00c3, 0xc02: 0x00c0, 0xc03: 0x00c0, 0xc05: 0x00c0, + 0xc06: 0x00c0, 0xc07: 0x00c0, 0xc08: 0x00c0, 0xc09: 0x00c0, 0xc0a: 0x00c0, 0xc0b: 0x00c0, + 0xc0c: 0x00c0, 0xc0e: 0x00c0, 0xc0f: 0x00c0, 0xc10: 0x00c0, + 0xc12: 0x00c0, 0xc13: 0x00c0, 0xc14: 0x00c0, 0xc15: 0x00c0, 0xc16: 0x00c0, 0xc17: 0x00c0, + 0xc18: 0x00c0, 0xc19: 0x00c0, 0xc1a: 0x00c0, 0xc1b: 0x00c0, 0xc1c: 0x00c0, 0xc1d: 0x00c0, + 0xc1e: 0x00c0, 0xc1f: 0x00c0, 0xc20: 0x00c0, 0xc21: 0x00c0, 0xc22: 0x00c0, 0xc23: 0x00c0, + 0xc24: 0x00c0, 0xc25: 0x00c0, 0xc26: 0x00c0, 0xc27: 0x00c0, 0xc28: 0x00c0, 0xc29: 0x00c0, + 0xc2a: 0x00c0, 0xc2b: 0x00c0, 0xc2c: 0x00c0, 0xc2d: 0x00c0, 0xc2e: 0x00c0, 0xc2f: 0x00c0, + 0xc30: 0x00c0, 0xc31: 0x00c0, 0xc32: 0x00c0, 0xc33: 0x00c0, 0xc34: 0x00c0, 0xc35: 0x00c0, + 0xc36: 0x00c0, 0xc37: 0x00c0, 0xc38: 0x00c0, 0xc39: 0x00c0, 0xc3a: 0x00c0, 0xc3b: 0x00c6, + 0xc3c: 0x00c6, 0xc3d: 0x00c0, 0xc3e: 0x00c0, 0xc3f: 0x00c0, + // Block 0x31, offset 0xc40 + 0xc40: 0x00c0, 0xc41: 0x00c3, 0xc42: 0x00c3, 0xc43: 0x00c3, 0xc44: 0x00c3, + 0xc46: 0x00c0, 0xc47: 0x00c0, 0xc48: 0x00c0, 0xc4a: 0x00c0, 0xc4b: 0x00c0, + 0xc4c: 0x00c0, 0xc4d: 0x00c6, 0xc4e: 0x00c0, 0xc4f: 0x0080, + 0xc54: 0x00c0, 0xc55: 0x00c0, 0xc56: 0x00c0, 0xc57: 0x00c0, + 0xc58: 0x0080, 0xc59: 0x0080, 0xc5a: 0x0080, 0xc5b: 0x0080, 0xc5c: 0x0080, 0xc5d: 0x0080, + 0xc5e: 0x0080, 0xc5f: 0x00c0, 0xc60: 0x00c0, 0xc61: 0x00c0, 0xc62: 0x00c3, 0xc63: 0x00c3, + 0xc66: 0x00c0, 0xc67: 0x00c0, 0xc68: 0x00c0, 0xc69: 0x00c0, + 0xc6a: 0x00c0, 0xc6b: 0x00c0, 0xc6c: 0x00c0, 0xc6d: 0x00c0, 0xc6e: 0x00c0, 0xc6f: 0x00c0, + 0xc70: 0x0080, 0xc71: 0x0080, 0xc72: 0x0080, 0xc73: 0x0080, 0xc74: 0x0080, 0xc75: 0x0080, + 0xc76: 0x0080, 0xc77: 0x0080, 0xc78: 0x0080, 0xc79: 0x0080, 0xc7a: 0x00c0, 0xc7b: 0x00c0, + 0xc7c: 0x00c0, 0xc7d: 0x00c0, 0xc7e: 0x00c0, 0xc7f: 0x00c0, + // Block 0x32, offset 0xc80 + 0xc82: 0x00c0, 0xc83: 0x00c0, 0xc85: 0x00c0, + 0xc86: 0x00c0, 0xc87: 0x00c0, 0xc88: 0x00c0, 0xc89: 0x00c0, 0xc8a: 0x00c0, 0xc8b: 0x00c0, + 0xc8c: 0x00c0, 0xc8d: 0x00c0, 0xc8e: 0x00c0, 0xc8f: 0x00c0, 0xc90: 0x00c0, 0xc91: 0x00c0, + 0xc92: 0x00c0, 0xc93: 0x00c0, 0xc94: 0x00c0, 0xc95: 0x00c0, 0xc96: 0x00c0, + 0xc9a: 0x00c0, 0xc9b: 0x00c0, 0xc9c: 0x00c0, 0xc9d: 0x00c0, + 0xc9e: 0x00c0, 0xc9f: 0x00c0, 0xca0: 0x00c0, 0xca1: 0x00c0, 0xca2: 0x00c0, 0xca3: 0x00c0, + 0xca4: 0x00c0, 0xca5: 0x00c0, 0xca6: 0x00c0, 0xca7: 0x00c0, 0xca8: 0x00c0, 0xca9: 0x00c0, + 0xcaa: 0x00c0, 0xcab: 0x00c0, 0xcac: 0x00c0, 0xcad: 0x00c0, 0xcae: 0x00c0, 0xcaf: 0x00c0, + 0xcb0: 0x00c0, 0xcb1: 0x00c0, 0xcb3: 0x00c0, 0xcb4: 0x00c0, 0xcb5: 0x00c0, + 0xcb6: 0x00c0, 0xcb7: 0x00c0, 0xcb8: 0x00c0, 0xcb9: 0x00c0, 0xcba: 0x00c0, 0xcbb: 0x00c0, + 0xcbd: 0x00c0, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x00c0, 0xcc1: 0x00c0, 0xcc2: 0x00c0, 0xcc3: 0x00c0, 0xcc4: 0x00c0, 0xcc5: 0x00c0, + 0xcc6: 0x00c0, 0xcca: 0x00c6, + 0xccf: 0x00c0, 0xcd0: 0x00c0, 0xcd1: 0x00c0, + 0xcd2: 0x00c3, 0xcd3: 0x00c3, 0xcd4: 0x00c3, 0xcd6: 0x00c3, + 0xcd8: 0x00c0, 0xcd9: 0x00c0, 0xcda: 0x00c0, 0xcdb: 0x00c0, 0xcdc: 0x00c0, 0xcdd: 0x00c0, + 0xcde: 0x00c0, 0xcdf: 0x00c0, + 0xce6: 0x00c0, 0xce7: 0x00c0, 0xce8: 0x00c0, 0xce9: 0x00c0, + 0xcea: 0x00c0, 0xceb: 0x00c0, 0xcec: 0x00c0, 0xced: 0x00c0, 0xcee: 0x00c0, 0xcef: 0x00c0, + 0xcf2: 0x00c0, 0xcf3: 0x00c0, 0xcf4: 0x0080, + // Block 0x34, offset 0xd00 + 0xd01: 0x00c0, 0xd02: 0x00c0, 0xd03: 0x00c0, 0xd04: 0x00c0, 0xd05: 0x00c0, + 0xd06: 0x00c0, 0xd07: 0x00c0, 0xd08: 0x00c0, 0xd09: 0x00c0, 0xd0a: 0x00c0, 0xd0b: 0x00c0, + 0xd0c: 0x00c0, 0xd0d: 0x00c0, 0xd0e: 0x00c0, 0xd0f: 0x00c0, 0xd10: 0x00c0, 0xd11: 0x00c0, + 0xd12: 0x00c0, 0xd13: 0x00c0, 0xd14: 0x00c0, 0xd15: 0x00c0, 0xd16: 0x00c0, 0xd17: 0x00c0, + 0xd18: 0x00c0, 0xd19: 0x00c0, 0xd1a: 0x00c0, 0xd1b: 0x00c0, 0xd1c: 0x00c0, 0xd1d: 0x00c0, + 0xd1e: 0x00c0, 0xd1f: 0x00c0, 0xd20: 0x00c0, 0xd21: 0x00c0, 0xd22: 0x00c0, 0xd23: 0x00c0, + 0xd24: 0x00c0, 0xd25: 0x00c0, 0xd26: 0x00c0, 0xd27: 0x00c0, 0xd28: 0x00c0, 0xd29: 0x00c0, + 0xd2a: 0x00c0, 0xd2b: 0x00c0, 0xd2c: 0x00c0, 0xd2d: 0x00c0, 0xd2e: 0x00c0, 0xd2f: 0x00c0, + 0xd30: 0x00c0, 0xd31: 0x00c3, 0xd32: 0x00c0, 0xd33: 0x0080, 0xd34: 0x00c3, 0xd35: 0x00c3, + 0xd36: 0x00c3, 0xd37: 0x00c3, 0xd38: 0x00c3, 0xd39: 0x00c3, 0xd3a: 0x00c6, + 0xd3f: 0x0080, + // Block 0x35, offset 0xd40 + 0xd40: 0x00c0, 0xd41: 0x00c0, 0xd42: 0x00c0, 0xd43: 0x00c0, 0xd44: 0x00c0, 0xd45: 0x00c0, + 0xd46: 0x00c0, 0xd47: 0x00c3, 0xd48: 0x00c3, 0xd49: 0x00c3, 0xd4a: 0x00c3, 0xd4b: 0x00c3, + 0xd4c: 0x00c3, 0xd4d: 0x00c3, 0xd4e: 0x00c3, 0xd4f: 0x0080, 0xd50: 0x00c0, 0xd51: 0x00c0, + 0xd52: 0x00c0, 0xd53: 0x00c0, 0xd54: 0x00c0, 0xd55: 0x00c0, 0xd56: 0x00c0, 0xd57: 0x00c0, + 0xd58: 0x00c0, 0xd59: 0x00c0, 0xd5a: 0x0080, 0xd5b: 0x0080, + // Block 0x36, offset 0xd80 + 0xd81: 0x00c0, 0xd82: 0x00c0, 0xd84: 0x00c0, + 0xd87: 0x00c0, 0xd88: 0x00c0, 0xd8a: 0x00c0, + 0xd8d: 0x00c0, + 0xd94: 0x00c0, 0xd95: 0x00c0, 0xd96: 0x00c0, 0xd97: 0x00c0, + 0xd99: 0x00c0, 0xd9a: 0x00c0, 0xd9b: 0x00c0, 0xd9c: 0x00c0, 0xd9d: 0x00c0, + 0xd9e: 0x00c0, 0xd9f: 0x00c0, 0xda1: 0x00c0, 0xda2: 0x00c0, 0xda3: 0x00c0, + 0xda5: 0x00c0, 0xda7: 0x00c0, + 0xdaa: 0x00c0, 0xdab: 0x00c0, 0xdad: 0x00c0, 0xdae: 0x00c0, 0xdaf: 0x00c0, + 0xdb0: 0x00c0, 0xdb1: 0x00c3, 0xdb2: 0x00c0, 0xdb3: 0x0080, 0xdb4: 0x00c3, 0xdb5: 0x00c3, + 0xdb6: 0x00c3, 0xdb7: 0x00c3, 0xdb8: 0x00c3, 0xdb9: 0x00c3, 0xdbb: 0x00c3, + 0xdbc: 0x00c3, 0xdbd: 0x00c0, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x00c0, 0xdc1: 0x00c0, 0xdc2: 0x00c0, 0xdc3: 0x00c0, 0xdc4: 0x00c0, + 0xdc6: 0x00c0, 0xdc8: 0x00c3, 0xdc9: 0x00c3, 0xdca: 0x00c3, 0xdcb: 0x00c3, + 0xdcc: 0x00c3, 0xdcd: 0x00c3, 0xdd0: 0x00c0, 0xdd1: 0x00c0, + 0xdd2: 0x00c0, 0xdd3: 0x00c0, 0xdd4: 0x00c0, 0xdd5: 0x00c0, 0xdd6: 0x00c0, 0xdd7: 0x00c0, + 0xdd8: 0x00c0, 0xdd9: 0x00c0, 0xddc: 0x0080, 0xddd: 0x0080, + 0xdde: 0x00c0, 0xddf: 0x00c0, + // Block 0x38, offset 0xe00 + 0xe00: 0x00c0, 0xe01: 0x0080, 0xe02: 0x0080, 0xe03: 0x0080, 0xe04: 0x0080, 0xe05: 0x0080, + 0xe06: 0x0080, 0xe07: 0x0080, 0xe08: 0x0080, 0xe09: 0x0080, 0xe0a: 0x0080, 0xe0b: 0x00c0, + 0xe0c: 0x0080, 0xe0d: 0x0080, 0xe0e: 0x0080, 0xe0f: 0x0080, 0xe10: 0x0080, 0xe11: 0x0080, + 0xe12: 0x0080, 0xe13: 0x0080, 0xe14: 0x0080, 0xe15: 0x0080, 0xe16: 0x0080, 0xe17: 0x0080, + 0xe18: 0x00c3, 0xe19: 0x00c3, 0xe1a: 0x0080, 0xe1b: 0x0080, 0xe1c: 0x0080, 0xe1d: 0x0080, + 0xe1e: 0x0080, 0xe1f: 0x0080, 0xe20: 0x00c0, 0xe21: 0x00c0, 0xe22: 0x00c0, 0xe23: 0x00c0, + 0xe24: 0x00c0, 0xe25: 0x00c0, 0xe26: 0x00c0, 0xe27: 0x00c0, 0xe28: 0x00c0, 0xe29: 0x00c0, + 0xe2a: 0x0080, 0xe2b: 0x0080, 0xe2c: 0x0080, 0xe2d: 0x0080, 0xe2e: 0x0080, 0xe2f: 0x0080, + 0xe30: 0x0080, 0xe31: 0x0080, 0xe32: 0x0080, 0xe33: 0x0080, 0xe34: 0x0080, 0xe35: 0x00c3, + 0xe36: 0x0080, 0xe37: 0x00c3, 0xe38: 0x0080, 0xe39: 0x00c3, 0xe3a: 0x0080, 0xe3b: 0x0080, + 0xe3c: 0x0080, 0xe3d: 0x0080, 0xe3e: 0x00c0, 0xe3f: 0x00c0, + // Block 0x39, offset 0xe40 + 0xe40: 0x00c0, 0xe41: 0x00c0, 0xe42: 0x00c0, 0xe43: 0x0080, 0xe44: 0x00c0, 0xe45: 0x00c0, + 0xe46: 0x00c0, 0xe47: 0x00c0, 0xe49: 0x00c0, 0xe4a: 0x00c0, 0xe4b: 0x00c0, + 0xe4c: 0x00c0, 0xe4d: 0x0080, 0xe4e: 0x00c0, 0xe4f: 0x00c0, 0xe50: 0x00c0, 0xe51: 0x00c0, + 0xe52: 0x0080, 0xe53: 0x00c0, 0xe54: 0x00c0, 0xe55: 0x00c0, 0xe56: 0x00c0, 0xe57: 0x0080, + 0xe58: 0x00c0, 0xe59: 0x00c0, 0xe5a: 0x00c0, 0xe5b: 0x00c0, 0xe5c: 0x0080, 0xe5d: 0x00c0, + 0xe5e: 0x00c0, 0xe5f: 0x00c0, 0xe60: 0x00c0, 0xe61: 0x00c0, 0xe62: 0x00c0, 0xe63: 0x00c0, + 0xe64: 0x00c0, 0xe65: 0x00c0, 0xe66: 0x00c0, 0xe67: 0x00c0, 0xe68: 0x00c0, 0xe69: 0x0080, + 0xe6a: 0x00c0, 0xe6b: 0x00c0, 0xe6c: 0x00c0, + 0xe71: 0x00c3, 0xe72: 0x00c3, 0xe73: 0x0083, 0xe74: 0x00c3, 0xe75: 0x0083, + 0xe76: 0x0083, 0xe77: 0x0083, 0xe78: 0x0083, 0xe79: 0x0083, 0xe7a: 0x00c3, 0xe7b: 0x00c3, + 0xe7c: 0x00c3, 0xe7d: 0x00c3, 0xe7e: 0x00c3, 0xe7f: 0x00c0, + // Block 0x3a, offset 0xe80 + 0xe80: 0x00c3, 0xe81: 0x0083, 0xe82: 0x00c3, 0xe83: 0x00c3, 0xe84: 0x00c6, 0xe85: 0x0080, + 0xe86: 0x00c3, 0xe87: 0x00c3, 0xe88: 0x00c0, 0xe89: 0x00c0, 0xe8a: 0x00c0, 0xe8b: 0x00c0, + 0xe8c: 0x00c0, 0xe8d: 0x00c3, 0xe8e: 0x00c3, 0xe8f: 0x00c3, 0xe90: 0x00c3, 0xe91: 0x00c3, + 0xe92: 0x00c3, 0xe93: 0x0083, 0xe94: 0x00c3, 0xe95: 0x00c3, 0xe96: 0x00c3, 0xe97: 0x00c3, + 0xe99: 0x00c3, 0xe9a: 0x00c3, 0xe9b: 0x00c3, 0xe9c: 0x00c3, 0xe9d: 0x0083, + 0xe9e: 0x00c3, 0xe9f: 0x00c3, 0xea0: 0x00c3, 0xea1: 0x00c3, 0xea2: 0x0083, 0xea3: 0x00c3, + 0xea4: 0x00c3, 0xea5: 0x00c3, 0xea6: 0x00c3, 0xea7: 0x0083, 0xea8: 0x00c3, 0xea9: 0x00c3, + 0xeaa: 0x00c3, 0xeab: 0x00c3, 0xeac: 0x0083, 0xead: 0x00c3, 0xeae: 0x00c3, 0xeaf: 0x00c3, + 0xeb0: 0x00c3, 0xeb1: 0x00c3, 0xeb2: 0x00c3, 0xeb3: 0x00c3, 0xeb4: 0x00c3, 0xeb5: 0x00c3, + 0xeb6: 0x00c3, 0xeb7: 0x00c3, 0xeb8: 0x00c3, 0xeb9: 0x0083, 0xeba: 0x00c3, 0xebb: 0x00c3, + 0xebc: 0x00c3, 0xebe: 0x0080, 0xebf: 0x0080, + // Block 0x3b, offset 0xec0 + 0xec0: 0x0080, 0xec1: 0x0080, 0xec2: 0x0080, 0xec3: 0x0080, 0xec4: 0x0080, 0xec5: 0x0080, + 0xec6: 0x00c3, 0xec7: 0x0080, 0xec8: 0x0080, 0xec9: 0x0080, 0xeca: 0x0080, 0xecb: 0x0080, + 0xecc: 0x0080, 0xece: 0x0080, 0xecf: 0x0080, 0xed0: 0x0080, 0xed1: 0x0080, + 0xed2: 0x0080, 0xed3: 0x0080, 0xed4: 0x0080, 0xed5: 0x0080, 0xed6: 0x0080, 0xed7: 0x0080, + 0xed8: 0x0080, 0xed9: 0x0080, 0xeda: 0x0080, + // Block 0x3c, offset 0xf00 + 0xf00: 0x00c0, 0xf01: 0x00c0, 0xf02: 0x00c0, 0xf03: 0x00c0, 0xf04: 0x00c0, 0xf05: 0x00c0, + 0xf06: 0x00c0, 0xf07: 0x00c0, 0xf08: 0x00c0, 0xf09: 0x00c0, 0xf0a: 0x00c0, 0xf0b: 0x00c0, + 0xf0c: 0x00c0, 0xf0d: 0x00c0, 0xf0e: 0x00c0, 0xf0f: 0x00c0, 0xf10: 0x00c0, 0xf11: 0x00c0, + 0xf12: 0x00c0, 0xf13: 0x00c0, 0xf14: 0x00c0, 0xf15: 0x00c0, 0xf16: 0x00c0, 0xf17: 0x00c0, + 0xf18: 0x00c0, 0xf19: 0x00c0, 0xf1a: 0x00c0, 0xf1b: 0x00c0, 0xf1c: 0x00c0, 0xf1d: 0x00c0, + 0xf1e: 0x00c0, 0xf1f: 0x00c0, 0xf20: 0x00c0, 0xf21: 0x00c0, 0xf22: 0x00c0, 0xf23: 0x00c0, + 0xf24: 0x00c0, 0xf25: 0x00c0, 0xf26: 0x00c0, 0xf27: 0x00c0, 0xf28: 0x00c0, 0xf29: 0x00c0, + 0xf2a: 0x00c0, 0xf2b: 0x00c0, 0xf2c: 0x00c0, 0xf2d: 0x00c3, 0xf2e: 0x00c3, 0xf2f: 0x00c3, + 0xf30: 0x00c3, 0xf31: 0x00c0, 0xf32: 0x00c3, 0xf33: 0x00c3, 0xf34: 0x00c3, 0xf35: 0x00c3, + 0xf36: 0x00c3, 0xf37: 0x00c3, 0xf38: 0x00c0, 0xf39: 0x00c6, 0xf3a: 0x00c6, 0xf3b: 0x00c0, + 0xf3c: 0x00c0, 0xf3d: 0x00c3, 0xf3e: 0x00c3, 0xf3f: 0x00c0, + // Block 0x3d, offset 0xf40 + 0xf40: 0x00c0, 0xf41: 0x00c0, 0xf42: 0x00c0, 0xf43: 0x00c0, 0xf44: 0x00c0, 0xf45: 0x00c0, + 0xf46: 0x00c0, 0xf47: 0x00c0, 0xf48: 0x00c0, 0xf49: 0x00c0, 0xf4a: 0x0080, 0xf4b: 0x0080, + 0xf4c: 0x0080, 0xf4d: 0x0080, 0xf4e: 0x0080, 0xf4f: 0x0080, 0xf50: 0x00c0, 0xf51: 0x00c0, + 0xf52: 0x00c0, 0xf53: 0x00c0, 0xf54: 0x00c0, 0xf55: 0x00c0, 0xf56: 0x00c0, 0xf57: 0x00c0, + 0xf58: 0x00c3, 0xf59: 0x00c3, 0xf5a: 0x00c0, 0xf5b: 0x00c0, 0xf5c: 0x00c0, 0xf5d: 0x00c0, + 0xf5e: 0x00c3, 0xf5f: 0x00c3, 0xf60: 0x00c3, 0xf61: 0x00c0, 0xf62: 0x00c0, 0xf63: 0x00c0, + 0xf64: 0x00c0, 0xf65: 0x00c0, 0xf66: 0x00c0, 0xf67: 0x00c0, 0xf68: 0x00c0, 0xf69: 0x00c0, + 0xf6a: 0x00c0, 0xf6b: 0x00c0, 0xf6c: 0x00c0, 0xf6d: 0x00c0, 0xf6e: 0x00c0, 0xf6f: 0x00c0, + 0xf70: 0x00c0, 0xf71: 0x00c3, 0xf72: 0x00c3, 0xf73: 0x00c3, 0xf74: 0x00c3, 0xf75: 0x00c0, + 0xf76: 0x00c0, 0xf77: 0x00c0, 0xf78: 0x00c0, 0xf79: 0x00c0, 0xf7a: 0x00c0, 0xf7b: 0x00c0, + 0xf7c: 0x00c0, 0xf7d: 0x00c0, 0xf7e: 0x00c0, 0xf7f: 0x00c0, + // Block 0x3e, offset 0xf80 + 0xf80: 0x00c0, 0xf81: 0x00c0, 0xf82: 0x00c3, 0xf83: 0x00c0, 0xf84: 0x00c0, 0xf85: 0x00c3, + 0xf86: 0x00c3, 0xf87: 0x00c0, 0xf88: 0x00c0, 0xf89: 0x00c0, 0xf8a: 0x00c0, 0xf8b: 0x00c0, + 0xf8c: 0x00c0, 0xf8d: 0x00c3, 0xf8e: 0x00c0, 0xf8f: 0x00c0, 0xf90: 0x00c0, 0xf91: 0x00c0, + 0xf92: 0x00c0, 0xf93: 0x00c0, 0xf94: 0x00c0, 0xf95: 0x00c0, 0xf96: 0x00c0, 0xf97: 0x00c0, + 0xf98: 0x00c0, 0xf99: 0x00c0, 0xf9a: 0x00c0, 0xf9b: 0x00c0, 0xf9c: 0x00c0, 0xf9d: 0x00c3, + 0xf9e: 0x0080, 0xf9f: 0x0080, 0xfa0: 0x00c0, 0xfa1: 0x00c0, 0xfa2: 0x00c0, 0xfa3: 0x00c0, + 0xfa4: 0x00c0, 0xfa5: 0x00c0, 0xfa6: 0x00c0, 0xfa7: 0x00c0, 0xfa8: 0x00c0, 0xfa9: 0x00c0, + 0xfaa: 0x00c0, 0xfab: 0x00c0, 0xfac: 0x00c0, 0xfad: 0x00c0, 0xfae: 0x00c0, 0xfaf: 0x00c0, + 0xfb0: 0x00c0, 0xfb1: 0x00c0, 0xfb2: 0x00c0, 0xfb3: 0x00c0, 0xfb4: 0x00c0, 0xfb5: 0x00c0, + 0xfb6: 0x00c0, 0xfb7: 0x00c0, 0xfb8: 0x00c0, 0xfb9: 0x00c0, 0xfba: 0x00c0, 0xfbb: 0x00c0, + 0xfbc: 0x00c0, 0xfbd: 0x00c0, 0xfbe: 0x00c0, 0xfbf: 0x00c0, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x00c0, 0xfc1: 0x00c0, 0xfc2: 0x00c0, 0xfc3: 0x00c0, 0xfc4: 0x00c0, 0xfc5: 0x00c0, + 0xfc7: 0x00c0, + 0xfcd: 0x00c0, 0xfd0: 0x00c0, 0xfd1: 0x00c0, + 0xfd2: 0x00c0, 0xfd3: 0x00c0, 0xfd4: 0x00c0, 0xfd5: 0x00c0, 0xfd6: 0x00c0, 0xfd7: 0x00c0, + 0xfd8: 0x00c0, 0xfd9: 0x00c0, 0xfda: 0x00c0, 0xfdb: 0x00c0, 0xfdc: 0x00c0, 0xfdd: 0x00c0, + 0xfde: 0x00c0, 0xfdf: 0x00c0, 0xfe0: 0x00c0, 0xfe1: 0x00c0, 0xfe2: 0x00c0, 0xfe3: 0x00c0, + 0xfe4: 0x00c0, 0xfe5: 0x00c0, 0xfe6: 0x00c0, 0xfe7: 0x00c0, 0xfe8: 0x00c0, 0xfe9: 0x00c0, + 0xfea: 0x00c0, 0xfeb: 0x00c0, 0xfec: 0x00c0, 0xfed: 0x00c0, 0xfee: 0x00c0, 0xfef: 0x00c0, + 0xff0: 0x00c0, 0xff1: 0x00c0, 0xff2: 0x00c0, 0xff3: 0x00c0, 0xff4: 0x00c0, 0xff5: 0x00c0, + 0xff6: 0x00c0, 0xff7: 0x00c0, 0xff8: 0x00c0, 0xff9: 0x00c0, 0xffa: 0x00c0, 0xffb: 0x0080, + 0xffc: 0x0080, 0xffd: 0x00c0, 0xffe: 0x00c0, 0xfff: 0x00c0, + // Block 0x40, offset 0x1000 + 0x1000: 0x0040, 0x1001: 0x0040, 0x1002: 0x0040, 0x1003: 0x0040, 0x1004: 0x0040, 0x1005: 0x0040, + 0x1006: 0x0040, 0x1007: 0x0040, 0x1008: 0x0040, 0x1009: 0x0040, 0x100a: 0x0040, 0x100b: 0x0040, + 0x100c: 0x0040, 0x100d: 0x0040, 0x100e: 0x0040, 0x100f: 0x0040, 0x1010: 0x0040, 0x1011: 0x0040, + 0x1012: 0x0040, 0x1013: 0x0040, 0x1014: 0x0040, 0x1015: 0x0040, 0x1016: 0x0040, 0x1017: 0x0040, + 0x1018: 0x0040, 0x1019: 0x0040, 0x101a: 0x0040, 0x101b: 0x0040, 0x101c: 0x0040, 0x101d: 0x0040, + 0x101e: 0x0040, 0x101f: 0x0040, 0x1020: 0x0040, 0x1021: 0x0040, 0x1022: 0x0040, 0x1023: 0x0040, + 0x1024: 0x0040, 0x1025: 0x0040, 0x1026: 0x0040, 0x1027: 0x0040, 0x1028: 0x0040, 0x1029: 0x0040, + 0x102a: 0x0040, 0x102b: 0x0040, 0x102c: 0x0040, 0x102d: 0x0040, 0x102e: 0x0040, 0x102f: 0x0040, + 0x1030: 0x0040, 0x1031: 0x0040, 0x1032: 0x0040, 0x1033: 0x0040, 0x1034: 0x0040, 0x1035: 0x0040, + 0x1036: 0x0040, 0x1037: 0x0040, 0x1038: 0x0040, 0x1039: 0x0040, 0x103a: 0x0040, 0x103b: 0x0040, + 0x103c: 0x0040, 0x103d: 0x0040, 0x103e: 0x0040, 0x103f: 0x0040, + // Block 0x41, offset 0x1040 + 0x1040: 0x00c0, 0x1041: 0x00c0, 0x1042: 0x00c0, 0x1043: 0x00c0, 0x1044: 0x00c0, 0x1045: 0x00c0, + 0x1046: 0x00c0, 0x1047: 0x00c0, 0x1048: 0x00c0, 0x104a: 0x00c0, 0x104b: 0x00c0, + 0x104c: 0x00c0, 0x104d: 0x00c0, 0x1050: 0x00c0, 0x1051: 0x00c0, + 0x1052: 0x00c0, 0x1053: 0x00c0, 0x1054: 0x00c0, 0x1055: 0x00c0, 0x1056: 0x00c0, + 0x1058: 0x00c0, 0x105a: 0x00c0, 0x105b: 0x00c0, 0x105c: 0x00c0, 0x105d: 0x00c0, + 0x1060: 0x00c0, 0x1061: 0x00c0, 0x1062: 0x00c0, 0x1063: 0x00c0, + 0x1064: 0x00c0, 0x1065: 0x00c0, 0x1066: 0x00c0, 0x1067: 0x00c0, 0x1068: 0x00c0, 0x1069: 0x00c0, + 0x106a: 0x00c0, 0x106b: 0x00c0, 0x106c: 0x00c0, 0x106d: 0x00c0, 0x106e: 0x00c0, 0x106f: 0x00c0, + 0x1070: 0x00c0, 0x1071: 0x00c0, 0x1072: 0x00c0, 0x1073: 0x00c0, 0x1074: 0x00c0, 0x1075: 0x00c0, + 0x1076: 0x00c0, 0x1077: 0x00c0, 0x1078: 0x00c0, 0x1079: 0x00c0, 0x107a: 0x00c0, 0x107b: 0x00c0, + 0x107c: 0x00c0, 0x107d: 0x00c0, 0x107e: 0x00c0, 0x107f: 0x00c0, + // Block 0x42, offset 0x1080 + 0x1080: 0x00c0, 0x1081: 0x00c0, 0x1082: 0x00c0, 0x1083: 0x00c0, 0x1084: 0x00c0, 0x1085: 0x00c0, + 0x1086: 0x00c0, 0x1087: 0x00c0, 0x1088: 0x00c0, 0x108a: 0x00c0, 0x108b: 0x00c0, + 0x108c: 0x00c0, 0x108d: 0x00c0, 0x1090: 0x00c0, 0x1091: 0x00c0, + 0x1092: 0x00c0, 0x1093: 0x00c0, 0x1094: 0x00c0, 0x1095: 0x00c0, 0x1096: 0x00c0, 0x1097: 0x00c0, + 0x1098: 0x00c0, 0x1099: 0x00c0, 0x109a: 0x00c0, 0x109b: 0x00c0, 0x109c: 0x00c0, 0x109d: 0x00c0, + 0x109e: 0x00c0, 0x109f: 0x00c0, 0x10a0: 0x00c0, 0x10a1: 0x00c0, 0x10a2: 0x00c0, 0x10a3: 0x00c0, + 0x10a4: 0x00c0, 0x10a5: 0x00c0, 0x10a6: 0x00c0, 0x10a7: 0x00c0, 0x10a8: 0x00c0, 0x10a9: 0x00c0, + 0x10aa: 0x00c0, 0x10ab: 0x00c0, 0x10ac: 0x00c0, 0x10ad: 0x00c0, 0x10ae: 0x00c0, 0x10af: 0x00c0, + 0x10b0: 0x00c0, 0x10b2: 0x00c0, 0x10b3: 0x00c0, 0x10b4: 0x00c0, 0x10b5: 0x00c0, + 0x10b8: 0x00c0, 0x10b9: 0x00c0, 0x10ba: 0x00c0, 0x10bb: 0x00c0, + 0x10bc: 0x00c0, 0x10bd: 0x00c0, 0x10be: 0x00c0, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x00c0, 0x10c2: 0x00c0, 0x10c3: 0x00c0, 0x10c4: 0x00c0, 0x10c5: 0x00c0, + 0x10c8: 0x00c0, 0x10c9: 0x00c0, 0x10ca: 0x00c0, 0x10cb: 0x00c0, + 0x10cc: 0x00c0, 0x10cd: 0x00c0, 0x10ce: 0x00c0, 0x10cf: 0x00c0, 0x10d0: 0x00c0, 0x10d1: 0x00c0, + 0x10d2: 0x00c0, 0x10d3: 0x00c0, 0x10d4: 0x00c0, 0x10d5: 0x00c0, 0x10d6: 0x00c0, + 0x10d8: 0x00c0, 0x10d9: 0x00c0, 0x10da: 0x00c0, 0x10db: 0x00c0, 0x10dc: 0x00c0, 0x10dd: 0x00c0, + 0x10de: 0x00c0, 0x10df: 0x00c0, 0x10e0: 0x00c0, 0x10e1: 0x00c0, 0x10e2: 0x00c0, 0x10e3: 0x00c0, + 0x10e4: 0x00c0, 0x10e5: 0x00c0, 0x10e6: 0x00c0, 0x10e7: 0x00c0, 0x10e8: 0x00c0, 0x10e9: 0x00c0, + 0x10ea: 0x00c0, 0x10eb: 0x00c0, 0x10ec: 0x00c0, 0x10ed: 0x00c0, 0x10ee: 0x00c0, 0x10ef: 0x00c0, + 0x10f0: 0x00c0, 0x10f1: 0x00c0, 0x10f2: 0x00c0, 0x10f3: 0x00c0, 0x10f4: 0x00c0, 0x10f5: 0x00c0, + 0x10f6: 0x00c0, 0x10f7: 0x00c0, 0x10f8: 0x00c0, 0x10f9: 0x00c0, 0x10fa: 0x00c0, 0x10fb: 0x00c0, + 0x10fc: 0x00c0, 0x10fd: 0x00c0, 0x10fe: 0x00c0, 0x10ff: 0x00c0, + // Block 0x44, offset 0x1100 + 0x1100: 0x00c0, 0x1101: 0x00c0, 0x1102: 0x00c0, 0x1103: 0x00c0, 0x1104: 0x00c0, 0x1105: 0x00c0, + 0x1106: 0x00c0, 0x1107: 0x00c0, 0x1108: 0x00c0, 0x1109: 0x00c0, 0x110a: 0x00c0, 0x110b: 0x00c0, + 0x110c: 0x00c0, 0x110d: 0x00c0, 0x110e: 0x00c0, 0x110f: 0x00c0, 0x1110: 0x00c0, + 0x1112: 0x00c0, 0x1113: 0x00c0, 0x1114: 0x00c0, 0x1115: 0x00c0, + 0x1118: 0x00c0, 0x1119: 0x00c0, 0x111a: 0x00c0, 0x111b: 0x00c0, 0x111c: 0x00c0, 0x111d: 0x00c0, + 0x111e: 0x00c0, 0x111f: 0x00c0, 0x1120: 0x00c0, 0x1121: 0x00c0, 0x1122: 0x00c0, 0x1123: 0x00c0, + 0x1124: 0x00c0, 0x1125: 0x00c0, 0x1126: 0x00c0, 0x1127: 0x00c0, 0x1128: 0x00c0, 0x1129: 0x00c0, + 0x112a: 0x00c0, 0x112b: 0x00c0, 0x112c: 0x00c0, 0x112d: 0x00c0, 0x112e: 0x00c0, 0x112f: 0x00c0, + 0x1130: 0x00c0, 0x1131: 0x00c0, 0x1132: 0x00c0, 0x1133: 0x00c0, 0x1134: 0x00c0, 0x1135: 0x00c0, + 0x1136: 0x00c0, 0x1137: 0x00c0, 0x1138: 0x00c0, 0x1139: 0x00c0, 0x113a: 0x00c0, 0x113b: 0x00c0, + 0x113c: 0x00c0, 0x113d: 0x00c0, 0x113e: 0x00c0, 0x113f: 0x00c0, + // Block 0x45, offset 0x1140 + 0x1140: 0x00c0, 0x1141: 0x00c0, 0x1142: 0x00c0, 0x1143: 0x00c0, 0x1144: 0x00c0, 0x1145: 0x00c0, + 0x1146: 0x00c0, 0x1147: 0x00c0, 0x1148: 0x00c0, 0x1149: 0x00c0, 0x114a: 0x00c0, 0x114b: 0x00c0, + 0x114c: 0x00c0, 0x114d: 0x00c0, 0x114e: 0x00c0, 0x114f: 0x00c0, 0x1150: 0x00c0, 0x1151: 0x00c0, + 0x1152: 0x00c0, 0x1153: 0x00c0, 0x1154: 0x00c0, 0x1155: 0x00c0, 0x1156: 0x00c0, 0x1157: 0x00c0, + 0x1158: 0x00c0, 0x1159: 0x00c0, 0x115a: 0x00c0, 0x115d: 0x00c3, + 0x115e: 0x00c3, 0x115f: 0x00c3, 0x1160: 0x0080, 0x1161: 0x0080, 0x1162: 0x0080, 0x1163: 0x0080, + 0x1164: 0x0080, 0x1165: 0x0080, 0x1166: 0x0080, 0x1167: 0x0080, 0x1168: 0x0080, 0x1169: 0x0080, + 0x116a: 0x0080, 0x116b: 0x0080, 0x116c: 0x0080, 0x116d: 0x0080, 0x116e: 0x0080, 0x116f: 0x0080, + 0x1170: 0x0080, 0x1171: 0x0080, 0x1172: 0x0080, 0x1173: 0x0080, 0x1174: 0x0080, 0x1175: 0x0080, + 0x1176: 0x0080, 0x1177: 0x0080, 0x1178: 0x0080, 0x1179: 0x0080, 0x117a: 0x0080, 0x117b: 0x0080, + 0x117c: 0x0080, + // Block 0x46, offset 0x1180 + 0x1180: 0x00c0, 0x1181: 0x00c0, 0x1182: 0x00c0, 0x1183: 0x00c0, 0x1184: 0x00c0, 0x1185: 0x00c0, + 0x1186: 0x00c0, 0x1187: 0x00c0, 0x1188: 0x00c0, 0x1189: 0x00c0, 0x118a: 0x00c0, 0x118b: 0x00c0, + 0x118c: 0x00c0, 0x118d: 0x00c0, 0x118e: 0x00c0, 0x118f: 0x00c0, 0x1190: 0x0080, 0x1191: 0x0080, + 0x1192: 0x0080, 0x1193: 0x0080, 0x1194: 0x0080, 0x1195: 0x0080, 0x1196: 0x0080, 0x1197: 0x0080, + 0x1198: 0x0080, 0x1199: 0x0080, + 0x11a0: 0x00c0, 0x11a1: 0x00c0, 0x11a2: 0x00c0, 0x11a3: 0x00c0, + 0x11a4: 0x00c0, 0x11a5: 0x00c0, 0x11a6: 0x00c0, 0x11a7: 0x00c0, 0x11a8: 0x00c0, 0x11a9: 0x00c0, + 0x11aa: 0x00c0, 0x11ab: 0x00c0, 0x11ac: 0x00c0, 0x11ad: 0x00c0, 0x11ae: 0x00c0, 0x11af: 0x00c0, + 0x11b0: 0x00c0, 0x11b1: 0x00c0, 0x11b2: 0x00c0, 0x11b3: 0x00c0, 0x11b4: 0x00c0, 0x11b5: 0x00c0, + 0x11b6: 0x00c0, 0x11b7: 0x00c0, 0x11b8: 0x00c0, 0x11b9: 0x00c0, 0x11ba: 0x00c0, 0x11bb: 0x00c0, + 0x11bc: 0x00c0, 0x11bd: 0x00c0, 0x11be: 0x00c0, 0x11bf: 0x00c0, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x00c0, 0x11c1: 0x00c0, 0x11c2: 0x00c0, 0x11c3: 0x00c0, 0x11c4: 0x00c0, 0x11c5: 0x00c0, + 0x11c6: 0x00c0, 0x11c7: 0x00c0, 0x11c8: 0x00c0, 0x11c9: 0x00c0, 0x11ca: 0x00c0, 0x11cb: 0x00c0, + 0x11cc: 0x00c0, 0x11cd: 0x00c0, 0x11ce: 0x00c0, 0x11cf: 0x00c0, 0x11d0: 0x00c0, 0x11d1: 0x00c0, + 0x11d2: 0x00c0, 0x11d3: 0x00c0, 0x11d4: 0x00c0, 0x11d5: 0x00c0, 0x11d6: 0x00c0, 0x11d7: 0x00c0, + 0x11d8: 0x00c0, 0x11d9: 0x00c0, 0x11da: 0x00c0, 0x11db: 0x00c0, 0x11dc: 0x00c0, 0x11dd: 0x00c0, + 0x11de: 0x00c0, 0x11df: 0x00c0, 0x11e0: 0x00c0, 0x11e1: 0x00c0, 0x11e2: 0x00c0, 0x11e3: 0x00c0, + 0x11e4: 0x00c0, 0x11e5: 0x00c0, 0x11e6: 0x00c0, 0x11e7: 0x00c0, 0x11e8: 0x00c0, 0x11e9: 0x00c0, + 0x11ea: 0x00c0, 0x11eb: 0x00c0, 0x11ec: 0x00c0, 0x11ed: 0x00c0, 0x11ee: 0x00c0, 0x11ef: 0x00c0, + 0x11f0: 0x00c0, 0x11f1: 0x00c0, 0x11f2: 0x00c0, 0x11f3: 0x00c0, 0x11f4: 0x00c0, 0x11f5: 0x00c0, + 0x11f8: 0x00c0, 0x11f9: 0x00c0, 0x11fa: 0x00c0, 0x11fb: 0x00c0, + 0x11fc: 0x00c0, 0x11fd: 0x00c0, + // Block 0x48, offset 0x1200 + 0x1200: 0x0080, 0x1201: 0x00c0, 0x1202: 0x00c0, 0x1203: 0x00c0, 0x1204: 0x00c0, 0x1205: 0x00c0, + 0x1206: 0x00c0, 0x1207: 0x00c0, 0x1208: 0x00c0, 0x1209: 0x00c0, 0x120a: 0x00c0, 0x120b: 0x00c0, + 0x120c: 0x00c0, 0x120d: 0x00c0, 0x120e: 0x00c0, 0x120f: 0x00c0, 0x1210: 0x00c0, 0x1211: 0x00c0, + 0x1212: 0x00c0, 0x1213: 0x00c0, 0x1214: 0x00c0, 0x1215: 0x00c0, 0x1216: 0x00c0, 0x1217: 0x00c0, + 0x1218: 0x00c0, 0x1219: 0x00c0, 0x121a: 0x00c0, 0x121b: 0x00c0, 0x121c: 0x00c0, 0x121d: 0x00c0, + 0x121e: 0x00c0, 0x121f: 0x00c0, 0x1220: 0x00c0, 0x1221: 0x00c0, 0x1222: 0x00c0, 0x1223: 0x00c0, + 0x1224: 0x00c0, 0x1225: 0x00c0, 0x1226: 0x00c0, 0x1227: 0x00c0, 0x1228: 0x00c0, 0x1229: 0x00c0, + 0x122a: 0x00c0, 0x122b: 0x00c0, 0x122c: 0x00c0, 0x122d: 0x00c0, 0x122e: 0x00c0, 0x122f: 0x00c0, + 0x1230: 0x00c0, 0x1231: 0x00c0, 0x1232: 0x00c0, 0x1233: 0x00c0, 0x1234: 0x00c0, 0x1235: 0x00c0, + 0x1236: 0x00c0, 0x1237: 0x00c0, 0x1238: 0x00c0, 0x1239: 0x00c0, 0x123a: 0x00c0, 0x123b: 0x00c0, + 0x123c: 0x00c0, 0x123d: 0x00c0, 0x123e: 0x00c0, 0x123f: 0x00c0, + // Block 0x49, offset 0x1240 + 0x1240: 0x00c0, 0x1241: 0x00c0, 0x1242: 0x00c0, 0x1243: 0x00c0, 0x1244: 0x00c0, 0x1245: 0x00c0, + 0x1246: 0x00c0, 0x1247: 0x00c0, 0x1248: 0x00c0, 0x1249: 0x00c0, 0x124a: 0x00c0, 0x124b: 0x00c0, + 0x124c: 0x00c0, 0x124d: 0x00c0, 0x124e: 0x00c0, 0x124f: 0x00c0, 0x1250: 0x00c0, 0x1251: 0x00c0, + 0x1252: 0x00c0, 0x1253: 0x00c0, 0x1254: 0x00c0, 0x1255: 0x00c0, 0x1256: 0x00c0, 0x1257: 0x00c0, + 0x1258: 0x00c0, 0x1259: 0x00c0, 0x125a: 0x00c0, 0x125b: 0x00c0, 0x125c: 0x00c0, 0x125d: 0x00c0, + 0x125e: 0x00c0, 0x125f: 0x00c0, 0x1260: 0x00c0, 0x1261: 0x00c0, 0x1262: 0x00c0, 0x1263: 0x00c0, + 0x1264: 0x00c0, 0x1265: 0x00c0, 0x1266: 0x00c0, 0x1267: 0x00c0, 0x1268: 0x00c0, 0x1269: 0x00c0, + 0x126a: 0x00c0, 0x126b: 0x00c0, 0x126c: 0x00c0, 0x126d: 0x0080, 0x126e: 0x0080, 0x126f: 0x00c0, + 0x1270: 0x00c0, 0x1271: 0x00c0, 0x1272: 0x00c0, 0x1273: 0x00c0, 0x1274: 0x00c0, 0x1275: 0x00c0, + 0x1276: 0x00c0, 0x1277: 0x00c0, 0x1278: 0x00c0, 0x1279: 0x00c0, 0x127a: 0x00c0, 0x127b: 0x00c0, + 0x127c: 0x00c0, 0x127d: 0x00c0, 0x127e: 0x00c0, 0x127f: 0x00c0, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0080, 0x1281: 0x00c0, 0x1282: 0x00c0, 0x1283: 0x00c0, 0x1284: 0x00c0, 0x1285: 0x00c0, + 0x1286: 0x00c0, 0x1287: 0x00c0, 0x1288: 0x00c0, 0x1289: 0x00c0, 0x128a: 0x00c0, 0x128b: 0x00c0, + 0x128c: 0x00c0, 0x128d: 0x00c0, 0x128e: 0x00c0, 0x128f: 0x00c0, 0x1290: 0x00c0, 0x1291: 0x00c0, + 0x1292: 0x00c0, 0x1293: 0x00c0, 0x1294: 0x00c0, 0x1295: 0x00c0, 0x1296: 0x00c0, 0x1297: 0x00c0, + 0x1298: 0x00c0, 0x1299: 0x00c0, 0x129a: 0x00c0, 0x129b: 0x0080, 0x129c: 0x0080, + 0x12a0: 0x00c0, 0x12a1: 0x00c0, 0x12a2: 0x00c0, 0x12a3: 0x00c0, + 0x12a4: 0x00c0, 0x12a5: 0x00c0, 0x12a6: 0x00c0, 0x12a7: 0x00c0, 0x12a8: 0x00c0, 0x12a9: 0x00c0, + 0x12aa: 0x00c0, 0x12ab: 0x00c0, 0x12ac: 0x00c0, 0x12ad: 0x00c0, 0x12ae: 0x00c0, 0x12af: 0x00c0, + 0x12b0: 0x00c0, 0x12b1: 0x00c0, 0x12b2: 0x00c0, 0x12b3: 0x00c0, 0x12b4: 0x00c0, 0x12b5: 0x00c0, + 0x12b6: 0x00c0, 0x12b7: 0x00c0, 0x12b8: 0x00c0, 0x12b9: 0x00c0, 0x12ba: 0x00c0, 0x12bb: 0x00c0, + 0x12bc: 0x00c0, 0x12bd: 0x00c0, 0x12be: 0x00c0, 0x12bf: 0x00c0, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x00c0, 0x12c1: 0x00c0, 0x12c2: 0x00c0, 0x12c3: 0x00c0, 0x12c4: 0x00c0, 0x12c5: 0x00c0, + 0x12c6: 0x00c0, 0x12c7: 0x00c0, 0x12c8: 0x00c0, 0x12c9: 0x00c0, 0x12ca: 0x00c0, 0x12cb: 0x00c0, + 0x12cc: 0x00c0, 0x12cd: 0x00c0, 0x12ce: 0x00c0, 0x12cf: 0x00c0, 0x12d0: 0x00c0, 0x12d1: 0x00c0, + 0x12d2: 0x00c0, 0x12d3: 0x00c0, 0x12d4: 0x00c0, 0x12d5: 0x00c0, 0x12d6: 0x00c0, 0x12d7: 0x00c0, + 0x12d8: 0x00c0, 0x12d9: 0x00c0, 0x12da: 0x00c0, 0x12db: 0x00c0, 0x12dc: 0x00c0, 0x12dd: 0x00c0, + 0x12de: 0x00c0, 0x12df: 0x00c0, 0x12e0: 0x00c0, 0x12e1: 0x00c0, 0x12e2: 0x00c0, 0x12e3: 0x00c0, + 0x12e4: 0x00c0, 0x12e5: 0x00c0, 0x12e6: 0x00c0, 0x12e7: 0x00c0, 0x12e8: 0x00c0, 0x12e9: 0x00c0, + 0x12ea: 0x00c0, 0x12eb: 0x0080, 0x12ec: 0x0080, 0x12ed: 0x0080, 0x12ee: 0x0080, 0x12ef: 0x0080, + 0x12f0: 0x0080, 0x12f1: 0x00c0, 0x12f2: 0x00c0, 0x12f3: 0x00c0, 0x12f4: 0x00c0, 0x12f5: 0x00c0, + 0x12f6: 0x00c0, 0x12f7: 0x00c0, 0x12f8: 0x00c0, + // Block 0x4c, offset 0x1300 + 0x1300: 0x00c0, 0x1301: 0x00c0, 0x1302: 0x00c0, 0x1303: 0x00c0, 0x1304: 0x00c0, 0x1305: 0x00c0, + 0x1306: 0x00c0, 0x1307: 0x00c0, 0x1308: 0x00c0, 0x1309: 0x00c0, 0x130a: 0x00c0, 0x130b: 0x00c0, + 0x130c: 0x00c0, 0x130e: 0x00c0, 0x130f: 0x00c0, 0x1310: 0x00c0, 0x1311: 0x00c0, + 0x1312: 0x00c3, 0x1313: 0x00c3, 0x1314: 0x00c6, + 0x1320: 0x00c0, 0x1321: 0x00c0, 0x1322: 0x00c0, 0x1323: 0x00c0, + 0x1324: 0x00c0, 0x1325: 0x00c0, 0x1326: 0x00c0, 0x1327: 0x00c0, 0x1328: 0x00c0, 0x1329: 0x00c0, + 0x132a: 0x00c0, 0x132b: 0x00c0, 0x132c: 0x00c0, 0x132d: 0x00c0, 0x132e: 0x00c0, 0x132f: 0x00c0, + 0x1330: 0x00c0, 0x1331: 0x00c0, 0x1332: 0x00c3, 0x1333: 0x00c3, 0x1334: 0x00c6, 0x1335: 0x0080, + 0x1336: 0x0080, + // Block 0x4d, offset 0x1340 + 0x1340: 0x00c0, 0x1341: 0x00c0, 0x1342: 0x00c0, 0x1343: 0x00c0, 0x1344: 0x00c0, 0x1345: 0x00c0, + 0x1346: 0x00c0, 0x1347: 0x00c0, 0x1348: 0x00c0, 0x1349: 0x00c0, 0x134a: 0x00c0, 0x134b: 0x00c0, + 0x134c: 0x00c0, 0x134d: 0x00c0, 0x134e: 0x00c0, 0x134f: 0x00c0, 0x1350: 0x00c0, 0x1351: 0x00c0, + 0x1352: 0x00c3, 0x1353: 0x00c3, + 0x1360: 0x00c0, 0x1361: 0x00c0, 0x1362: 0x00c0, 0x1363: 0x00c0, + 0x1364: 0x00c0, 0x1365: 0x00c0, 0x1366: 0x00c0, 0x1367: 0x00c0, 0x1368: 0x00c0, 0x1369: 0x00c0, + 0x136a: 0x00c0, 0x136b: 0x00c0, 0x136c: 0x00c0, 0x136e: 0x00c0, 0x136f: 0x00c0, + 0x1370: 0x00c0, 0x1372: 0x00c3, 0x1373: 0x00c3, + // Block 0x4e, offset 0x1380 + 0x1380: 0x00c0, 0x1381: 0x00c0, 0x1382: 0x00c0, 0x1383: 0x00c0, 0x1384: 0x00c0, 0x1385: 0x00c0, + 0x1386: 0x00c0, 0x1387: 0x00c0, 0x1388: 0x00c0, 0x1389: 0x00c0, 0x138a: 0x00c0, 0x138b: 0x00c0, + 0x138c: 0x00c0, 0x138d: 0x00c0, 0x138e: 0x00c0, 0x138f: 0x00c0, 0x1390: 0x00c0, 0x1391: 0x00c0, + 0x1392: 0x00c0, 0x1393: 0x00c0, 0x1394: 0x00c0, 0x1395: 0x00c0, 0x1396: 0x00c0, 0x1397: 0x00c0, + 0x1398: 0x00c0, 0x1399: 0x00c0, 0x139a: 0x00c0, 0x139b: 0x00c0, 0x139c: 0x00c0, 0x139d: 0x00c0, + 0x139e: 0x00c0, 0x139f: 0x00c0, 0x13a0: 0x00c0, 0x13a1: 0x00c0, 0x13a2: 0x00c0, 0x13a3: 0x00c0, + 0x13a4: 0x00c0, 0x13a5: 0x00c0, 0x13a6: 0x00c0, 0x13a7: 0x00c0, 0x13a8: 0x00c0, 0x13a9: 0x00c0, + 0x13aa: 0x00c0, 0x13ab: 0x00c0, 0x13ac: 0x00c0, 0x13ad: 0x00c0, 0x13ae: 0x00c0, 0x13af: 0x00c0, + 0x13b0: 0x00c0, 0x13b1: 0x00c0, 0x13b2: 0x00c0, 0x13b3: 0x00c0, 0x13b4: 0x0040, 0x13b5: 0x0040, + 0x13b6: 0x00c0, 0x13b7: 0x00c3, 0x13b8: 0x00c3, 0x13b9: 0x00c3, 0x13ba: 0x00c3, 0x13bb: 0x00c3, + 0x13bc: 0x00c3, 0x13bd: 0x00c3, 0x13be: 0x00c0, 0x13bf: 0x00c0, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x00c0, 0x13c1: 0x00c0, 0x13c2: 0x00c0, 0x13c3: 0x00c0, 0x13c4: 0x00c0, 0x13c5: 0x00c0, + 0x13c6: 0x00c3, 0x13c7: 0x00c0, 0x13c8: 0x00c0, 0x13c9: 0x00c3, 0x13ca: 0x00c3, 0x13cb: 0x00c3, + 0x13cc: 0x00c3, 0x13cd: 0x00c3, 0x13ce: 0x00c3, 0x13cf: 0x00c3, 0x13d0: 0x00c3, 0x13d1: 0x00c3, + 0x13d2: 0x00c6, 0x13d3: 0x00c3, 0x13d4: 0x0080, 0x13d5: 0x0080, 0x13d6: 0x0080, 0x13d7: 0x00c0, + 0x13d8: 0x0080, 0x13d9: 0x0080, 0x13da: 0x0080, 0x13db: 0x0080, 0x13dc: 0x00c0, 0x13dd: 0x00c3, + 0x13e0: 0x00c0, 0x13e1: 0x00c0, 0x13e2: 0x00c0, 0x13e3: 0x00c0, + 0x13e4: 0x00c0, 0x13e5: 0x00c0, 0x13e6: 0x00c0, 0x13e7: 0x00c0, 0x13e8: 0x00c0, 0x13e9: 0x00c0, + 0x13f0: 0x0080, 0x13f1: 0x0080, 0x13f2: 0x0080, 0x13f3: 0x0080, 0x13f4: 0x0080, 0x13f5: 0x0080, + 0x13f6: 0x0080, 0x13f7: 0x0080, 0x13f8: 0x0080, 0x13f9: 0x0080, + // Block 0x50, offset 0x1400 + 0x1400: 0x0080, 0x1401: 0x0080, 0x1402: 0x0080, 0x1403: 0x0080, 0x1404: 0x0080, 0x1405: 0x0080, + 0x1406: 0x0080, 0x1407: 0x0082, 0x1408: 0x0080, 0x1409: 0x0080, 0x140a: 0x0080, 0x140b: 0x0040, + 0x140c: 0x0040, 0x140d: 0x0040, 0x140e: 0x0040, 0x1410: 0x00c0, 0x1411: 0x00c0, + 0x1412: 0x00c0, 0x1413: 0x00c0, 0x1414: 0x00c0, 0x1415: 0x00c0, 0x1416: 0x00c0, 0x1417: 0x00c0, + 0x1418: 0x00c0, 0x1419: 0x00c0, + 0x1420: 0x00c2, 0x1421: 0x00c2, 0x1422: 0x00c2, 0x1423: 0x00c2, + 0x1424: 0x00c2, 0x1425: 0x00c2, 0x1426: 0x00c2, 0x1427: 0x00c2, 0x1428: 0x00c2, 0x1429: 0x00c2, + 0x142a: 0x00c2, 0x142b: 0x00c2, 0x142c: 0x00c2, 0x142d: 0x00c2, 0x142e: 0x00c2, 0x142f: 0x00c2, + 0x1430: 0x00c2, 0x1431: 0x00c2, 0x1432: 0x00c2, 0x1433: 0x00c2, 0x1434: 0x00c2, 0x1435: 0x00c2, + 0x1436: 0x00c2, 0x1437: 0x00c2, 0x1438: 0x00c2, 0x1439: 0x00c2, 0x143a: 0x00c2, 0x143b: 0x00c2, + 0x143c: 0x00c2, 0x143d: 0x00c2, 0x143e: 0x00c2, 0x143f: 0x00c2, + // Block 0x51, offset 0x1440 + 0x1440: 0x00c2, 0x1441: 0x00c2, 0x1442: 0x00c2, 0x1443: 0x00c2, 0x1444: 0x00c2, 0x1445: 0x00c2, + 0x1446: 0x00c2, 0x1447: 0x00c2, 0x1448: 0x00c2, 0x1449: 0x00c2, 0x144a: 0x00c2, 0x144b: 0x00c2, + 0x144c: 0x00c2, 0x144d: 0x00c2, 0x144e: 0x00c2, 0x144f: 0x00c2, 0x1450: 0x00c2, 0x1451: 0x00c2, + 0x1452: 0x00c2, 0x1453: 0x00c2, 0x1454: 0x00c2, 0x1455: 0x00c2, 0x1456: 0x00c2, 0x1457: 0x00c2, + 0x1458: 0x00c2, 0x1459: 0x00c2, 0x145a: 0x00c2, 0x145b: 0x00c2, 0x145c: 0x00c2, 0x145d: 0x00c2, + 0x145e: 0x00c2, 0x145f: 0x00c2, 0x1460: 0x00c2, 0x1461: 0x00c2, 0x1462: 0x00c2, 0x1463: 0x00c2, + 0x1464: 0x00c2, 0x1465: 0x00c2, 0x1466: 0x00c2, 0x1467: 0x00c2, 0x1468: 0x00c2, 0x1469: 0x00c2, + 0x146a: 0x00c2, 0x146b: 0x00c2, 0x146c: 0x00c2, 0x146d: 0x00c2, 0x146e: 0x00c2, 0x146f: 0x00c2, + 0x1470: 0x00c2, 0x1471: 0x00c2, 0x1472: 0x00c2, 0x1473: 0x00c2, 0x1474: 0x00c2, 0x1475: 0x00c2, + 0x1476: 0x00c2, 0x1477: 0x00c2, + // Block 0x52, offset 0x1480 + 0x1480: 0x00c0, 0x1481: 0x00c0, 0x1482: 0x00c0, 0x1483: 0x00c0, 0x1484: 0x00c0, 0x1485: 0x00c3, + 0x1486: 0x00c3, 0x1487: 0x00c2, 0x1488: 0x00c2, 0x1489: 0x00c2, 0x148a: 0x00c2, 0x148b: 0x00c2, + 0x148c: 0x00c2, 0x148d: 0x00c2, 0x148e: 0x00c2, 0x148f: 0x00c2, 0x1490: 0x00c2, 0x1491: 0x00c2, + 0x1492: 0x00c2, 0x1493: 0x00c2, 0x1494: 0x00c2, 0x1495: 0x00c2, 0x1496: 0x00c2, 0x1497: 0x00c2, + 0x1498: 0x00c2, 0x1499: 0x00c2, 0x149a: 0x00c2, 0x149b: 0x00c2, 0x149c: 0x00c2, 0x149d: 0x00c2, + 0x149e: 0x00c2, 0x149f: 0x00c2, 0x14a0: 0x00c2, 0x14a1: 0x00c2, 0x14a2: 0x00c2, 0x14a3: 0x00c2, + 0x14a4: 0x00c2, 0x14a5: 0x00c2, 0x14a6: 0x00c2, 0x14a7: 0x00c2, 0x14a8: 0x00c2, 0x14a9: 0x00c3, + 0x14aa: 0x00c2, + 0x14b0: 0x00c0, 0x14b1: 0x00c0, 0x14b2: 0x00c0, 0x14b3: 0x00c0, 0x14b4: 0x00c0, 0x14b5: 0x00c0, + 0x14b6: 0x00c0, 0x14b7: 0x00c0, 0x14b8: 0x00c0, 0x14b9: 0x00c0, 0x14ba: 0x00c0, 0x14bb: 0x00c0, + 0x14bc: 0x00c0, 0x14bd: 0x00c0, 0x14be: 0x00c0, 0x14bf: 0x00c0, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x00c0, 0x14c1: 0x00c0, 0x14c2: 0x00c0, 0x14c3: 0x00c0, 0x14c4: 0x00c0, 0x14c5: 0x00c0, + 0x14c6: 0x00c0, 0x14c7: 0x00c0, 0x14c8: 0x00c0, 0x14c9: 0x00c0, 0x14ca: 0x00c0, 0x14cb: 0x00c0, + 0x14cc: 0x00c0, 0x14cd: 0x00c0, 0x14ce: 0x00c0, 0x14cf: 0x00c0, 0x14d0: 0x00c0, 0x14d1: 0x00c0, + 0x14d2: 0x00c0, 0x14d3: 0x00c0, 0x14d4: 0x00c0, 0x14d5: 0x00c0, 0x14d6: 0x00c0, 0x14d7: 0x00c0, + 0x14d8: 0x00c0, 0x14d9: 0x00c0, 0x14da: 0x00c0, 0x14db: 0x00c0, 0x14dc: 0x00c0, 0x14dd: 0x00c0, + 0x14de: 0x00c0, 0x14df: 0x00c0, 0x14e0: 0x00c0, 0x14e1: 0x00c0, 0x14e2: 0x00c0, 0x14e3: 0x00c0, + 0x14e4: 0x00c0, 0x14e5: 0x00c0, 0x14e6: 0x00c0, 0x14e7: 0x00c0, 0x14e8: 0x00c0, 0x14e9: 0x00c0, + 0x14ea: 0x00c0, 0x14eb: 0x00c0, 0x14ec: 0x00c0, 0x14ed: 0x00c0, 0x14ee: 0x00c0, 0x14ef: 0x00c0, + 0x14f0: 0x00c0, 0x14f1: 0x00c0, 0x14f2: 0x00c0, 0x14f3: 0x00c0, 0x14f4: 0x00c0, 0x14f5: 0x00c0, + // Block 0x54, offset 0x1500 + 0x1500: 0x00c0, 0x1501: 0x00c0, 0x1502: 0x00c0, 0x1503: 0x00c0, 0x1504: 0x00c0, 0x1505: 0x00c0, + 0x1506: 0x00c0, 0x1507: 0x00c0, 0x1508: 0x00c0, 0x1509: 0x00c0, 0x150a: 0x00c0, 0x150b: 0x00c0, + 0x150c: 0x00c0, 0x150d: 0x00c0, 0x150e: 0x00c0, 0x150f: 0x00c0, 0x1510: 0x00c0, 0x1511: 0x00c0, + 0x1512: 0x00c0, 0x1513: 0x00c0, 0x1514: 0x00c0, 0x1515: 0x00c0, 0x1516: 0x00c0, 0x1517: 0x00c0, + 0x1518: 0x00c0, 0x1519: 0x00c0, 0x151a: 0x00c0, 0x151b: 0x00c0, 0x151c: 0x00c0, 0x151d: 0x00c0, + 0x151e: 0x00c0, 0x1520: 0x00c3, 0x1521: 0x00c3, 0x1522: 0x00c3, 0x1523: 0x00c0, + 0x1524: 0x00c0, 0x1525: 0x00c0, 0x1526: 0x00c0, 0x1527: 0x00c3, 0x1528: 0x00c3, 0x1529: 0x00c0, + 0x152a: 0x00c0, 0x152b: 0x00c0, + 0x1530: 0x00c0, 0x1531: 0x00c0, 0x1532: 0x00c3, 0x1533: 0x00c0, 0x1534: 0x00c0, 0x1535: 0x00c0, + 0x1536: 0x00c0, 0x1537: 0x00c0, 0x1538: 0x00c0, 0x1539: 0x00c3, 0x153a: 0x00c3, 0x153b: 0x00c3, + // Block 0x55, offset 0x1540 + 0x1540: 0x0080, 0x1544: 0x0080, 0x1545: 0x0080, + 0x1546: 0x00c0, 0x1547: 0x00c0, 0x1548: 0x00c0, 0x1549: 0x00c0, 0x154a: 0x00c0, 0x154b: 0x00c0, + 0x154c: 0x00c0, 0x154d: 0x00c0, 0x154e: 0x00c0, 0x154f: 0x00c0, 0x1550: 0x00c0, 0x1551: 0x00c0, + 0x1552: 0x00c0, 0x1553: 0x00c0, 0x1554: 0x00c0, 0x1555: 0x00c0, 0x1556: 0x00c0, 0x1557: 0x00c0, + 0x1558: 0x00c0, 0x1559: 0x00c0, 0x155a: 0x00c0, 0x155b: 0x00c0, 0x155c: 0x00c0, 0x155d: 0x00c0, + 0x155e: 0x00c0, 0x155f: 0x00c0, 0x1560: 0x00c0, 0x1561: 0x00c0, 0x1562: 0x00c0, 0x1563: 0x00c0, + 0x1564: 0x00c0, 0x1565: 0x00c0, 0x1566: 0x00c0, 0x1567: 0x00c0, 0x1568: 0x00c0, 0x1569: 0x00c0, + 0x156a: 0x00c0, 0x156b: 0x00c0, 0x156c: 0x00c0, 0x156d: 0x00c0, + 0x1570: 0x00c0, 0x1571: 0x00c0, 0x1572: 0x00c0, 0x1573: 0x00c0, 0x1574: 0x00c0, + // Block 0x56, offset 0x1580 + 0x1580: 0x00c0, 0x1581: 0x00c0, 0x1582: 0x00c0, 0x1583: 0x00c0, 0x1584: 0x00c0, 0x1585: 0x00c0, + 0x1586: 0x00c0, 0x1587: 0x00c0, 0x1588: 0x00c0, 0x1589: 0x00c0, 0x158a: 0x00c0, 0x158b: 0x00c0, + 0x158c: 0x00c0, 0x158d: 0x00c0, 0x158e: 0x00c0, 0x158f: 0x00c0, 0x1590: 0x00c0, 0x1591: 0x00c0, + 0x1592: 0x00c0, 0x1593: 0x00c0, 0x1594: 0x00c0, 0x1595: 0x00c0, 0x1596: 0x00c0, 0x1597: 0x00c0, + 0x1598: 0x00c0, 0x1599: 0x00c0, 0x159a: 0x00c0, 0x159b: 0x00c0, 0x159c: 0x00c0, 0x159d: 0x00c0, + 0x159e: 0x00c0, 0x159f: 0x00c0, 0x15a0: 0x00c0, 0x15a1: 0x00c0, 0x15a2: 0x00c0, 0x15a3: 0x00c0, + 0x15a4: 0x00c0, 0x15a5: 0x00c0, 0x15a6: 0x00c0, 0x15a7: 0x00c0, 0x15a8: 0x00c0, 0x15a9: 0x00c0, + 0x15aa: 0x00c0, 0x15ab: 0x00c0, + 0x15b0: 0x00c0, 0x15b1: 0x00c0, 0x15b2: 0x00c0, 0x15b3: 0x00c0, 0x15b4: 0x00c0, 0x15b5: 0x00c0, + 0x15b6: 0x00c0, 0x15b7: 0x00c0, 0x15b8: 0x00c0, 0x15b9: 0x00c0, 0x15ba: 0x00c0, 0x15bb: 0x00c0, + 0x15bc: 0x00c0, 0x15bd: 0x00c0, 0x15be: 0x00c0, 0x15bf: 0x00c0, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x00c0, 0x15c1: 0x00c0, 0x15c2: 0x00c0, 0x15c3: 0x00c0, 0x15c4: 0x00c0, 0x15c5: 0x00c0, + 0x15c6: 0x00c0, 0x15c7: 0x00c0, 0x15c8: 0x00c0, 0x15c9: 0x00c0, + 0x15d0: 0x00c0, 0x15d1: 0x00c0, + 0x15d2: 0x00c0, 0x15d3: 0x00c0, 0x15d4: 0x00c0, 0x15d5: 0x00c0, 0x15d6: 0x00c0, 0x15d7: 0x00c0, + 0x15d8: 0x00c0, 0x15d9: 0x00c0, 0x15da: 0x0080, + 0x15de: 0x0080, 0x15df: 0x0080, 0x15e0: 0x0080, 0x15e1: 0x0080, 0x15e2: 0x0080, 0x15e3: 0x0080, + 0x15e4: 0x0080, 0x15e5: 0x0080, 0x15e6: 0x0080, 0x15e7: 0x0080, 0x15e8: 0x0080, 0x15e9: 0x0080, + 0x15ea: 0x0080, 0x15eb: 0x0080, 0x15ec: 0x0080, 0x15ed: 0x0080, 0x15ee: 0x0080, 0x15ef: 0x0080, + 0x15f0: 0x0080, 0x15f1: 0x0080, 0x15f2: 0x0080, 0x15f3: 0x0080, 0x15f4: 0x0080, 0x15f5: 0x0080, + 0x15f6: 0x0080, 0x15f7: 0x0080, 0x15f8: 0x0080, 0x15f9: 0x0080, 0x15fa: 0x0080, 0x15fb: 0x0080, + 0x15fc: 0x0080, 0x15fd: 0x0080, 0x15fe: 0x0080, 0x15ff: 0x0080, + // Block 0x58, offset 0x1600 + 0x1600: 0x00c0, 0x1601: 0x00c0, 0x1602: 0x00c0, 0x1603: 0x00c0, 0x1604: 0x00c0, 0x1605: 0x00c0, + 0x1606: 0x00c0, 0x1607: 0x00c0, 0x1608: 0x00c0, 0x1609: 0x00c0, 0x160a: 0x00c0, 0x160b: 0x00c0, + 0x160c: 0x00c0, 0x160d: 0x00c0, 0x160e: 0x00c0, 0x160f: 0x00c0, 0x1610: 0x00c0, 0x1611: 0x00c0, + 0x1612: 0x00c0, 0x1613: 0x00c0, 0x1614: 0x00c0, 0x1615: 0x00c0, 0x1616: 0x00c0, 0x1617: 0x00c3, + 0x1618: 0x00c3, 0x1619: 0x00c0, 0x161a: 0x00c0, 0x161b: 0x00c3, + 0x161e: 0x0080, 0x161f: 0x0080, 0x1620: 0x00c0, 0x1621: 0x00c0, 0x1622: 0x00c0, 0x1623: 0x00c0, + 0x1624: 0x00c0, 0x1625: 0x00c0, 0x1626: 0x00c0, 0x1627: 0x00c0, 0x1628: 0x00c0, 0x1629: 0x00c0, + 0x162a: 0x00c0, 0x162b: 0x00c0, 0x162c: 0x00c0, 0x162d: 0x00c0, 0x162e: 0x00c0, 0x162f: 0x00c0, + 0x1630: 0x00c0, 0x1631: 0x00c0, 0x1632: 0x00c0, 0x1633: 0x00c0, 0x1634: 0x00c0, 0x1635: 0x00c0, + 0x1636: 0x00c0, 0x1637: 0x00c0, 0x1638: 0x00c0, 0x1639: 0x00c0, 0x163a: 0x00c0, 0x163b: 0x00c0, + 0x163c: 0x00c0, 0x163d: 0x00c0, 0x163e: 0x00c0, 0x163f: 0x00c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x00c0, 0x1641: 0x00c0, 0x1642: 0x00c0, 0x1643: 0x00c0, 0x1644: 0x00c0, 0x1645: 0x00c0, + 0x1646: 0x00c0, 0x1647: 0x00c0, 0x1648: 0x00c0, 0x1649: 0x00c0, 0x164a: 0x00c0, 0x164b: 0x00c0, + 0x164c: 0x00c0, 0x164d: 0x00c0, 0x164e: 0x00c0, 0x164f: 0x00c0, 0x1650: 0x00c0, 0x1651: 0x00c0, + 0x1652: 0x00c0, 0x1653: 0x00c0, 0x1654: 0x00c0, 0x1655: 0x00c0, 0x1656: 0x00c3, 0x1657: 0x00c0, + 0x1658: 0x00c3, 0x1659: 0x00c3, 0x165a: 0x00c3, 0x165b: 0x00c3, 0x165c: 0x00c3, 0x165d: 0x00c3, + 0x165e: 0x00c3, 0x1660: 0x00c6, 0x1661: 0x00c0, 0x1662: 0x00c3, 0x1663: 0x00c0, + 0x1664: 0x00c0, 0x1665: 0x00c3, 0x1666: 0x00c3, 0x1667: 0x00c3, 0x1668: 0x00c3, 0x1669: 0x00c3, + 0x166a: 0x00c3, 0x166b: 0x00c3, 0x166c: 0x00c3, 0x166d: 0x00c0, 0x166e: 0x00c0, 0x166f: 0x00c0, + 0x1670: 0x00c0, 0x1671: 0x00c0, 0x1672: 0x00c0, 0x1673: 0x00c3, 0x1674: 0x00c3, 0x1675: 0x00c3, + 0x1676: 0x00c3, 0x1677: 0x00c3, 0x1678: 0x00c3, 0x1679: 0x00c3, 0x167a: 0x00c3, 0x167b: 0x00c3, + 0x167c: 0x00c3, 0x167f: 0x00c3, + // Block 0x5a, offset 0x1680 + 0x1680: 0x00c0, 0x1681: 0x00c0, 0x1682: 0x00c0, 0x1683: 0x00c0, 0x1684: 0x00c0, 0x1685: 0x00c0, + 0x1686: 0x00c0, 0x1687: 0x00c0, 0x1688: 0x00c0, 0x1689: 0x00c0, + 0x1690: 0x00c0, 0x1691: 0x00c0, + 0x1692: 0x00c0, 0x1693: 0x00c0, 0x1694: 0x00c0, 0x1695: 0x00c0, 0x1696: 0x00c0, 0x1697: 0x00c0, + 0x1698: 0x00c0, 0x1699: 0x00c0, + 0x16a0: 0x0080, 0x16a1: 0x0080, 0x16a2: 0x0080, 0x16a3: 0x0080, + 0x16a4: 0x0080, 0x16a5: 0x0080, 0x16a6: 0x0080, 0x16a7: 0x00c0, 0x16a8: 0x0080, 0x16a9: 0x0080, + 0x16aa: 0x0080, 0x16ab: 0x0080, 0x16ac: 0x0080, 0x16ad: 0x0080, + 0x16b0: 0x00c3, 0x16b1: 0x00c3, 0x16b2: 0x00c3, 0x16b3: 0x00c3, 0x16b4: 0x00c3, 0x16b5: 0x00c3, + 0x16b6: 0x00c3, 0x16b7: 0x00c3, 0x16b8: 0x00c3, 0x16b9: 0x00c3, 0x16ba: 0x00c3, 0x16bb: 0x00c3, + 0x16bc: 0x00c3, 0x16bd: 0x00c3, 0x16be: 0x0083, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x00c3, 0x16c1: 0x00c3, 0x16c2: 0x00c3, 0x16c3: 0x00c3, 0x16c4: 0x00c0, 0x16c5: 0x00c0, + 0x16c6: 0x00c0, 0x16c7: 0x00c0, 0x16c8: 0x00c0, 0x16c9: 0x00c0, 0x16ca: 0x00c0, 0x16cb: 0x00c0, + 0x16cc: 0x00c0, 0x16cd: 0x00c0, 0x16ce: 0x00c0, 0x16cf: 0x00c0, 0x16d0: 0x00c0, 0x16d1: 0x00c0, + 0x16d2: 0x00c0, 0x16d3: 0x00c0, 0x16d4: 0x00c0, 0x16d5: 0x00c0, 0x16d6: 0x00c0, 0x16d7: 0x00c0, + 0x16d8: 0x00c0, 0x16d9: 0x00c0, 0x16da: 0x00c0, 0x16db: 0x00c0, 0x16dc: 0x00c0, 0x16dd: 0x00c0, + 0x16de: 0x00c0, 0x16df: 0x00c0, 0x16e0: 0x00c0, 0x16e1: 0x00c0, 0x16e2: 0x00c0, 0x16e3: 0x00c0, + 0x16e4: 0x00c0, 0x16e5: 0x00c0, 0x16e6: 0x00c0, 0x16e7: 0x00c0, 0x16e8: 0x00c0, 0x16e9: 0x00c0, + 0x16ea: 0x00c0, 0x16eb: 0x00c0, 0x16ec: 0x00c0, 0x16ed: 0x00c0, 0x16ee: 0x00c0, 0x16ef: 0x00c0, + 0x16f0: 0x00c0, 0x16f1: 0x00c0, 0x16f2: 0x00c0, 0x16f3: 0x00c0, 0x16f4: 0x00c3, 0x16f5: 0x00c0, + 0x16f6: 0x00c3, 0x16f7: 0x00c3, 0x16f8: 0x00c3, 0x16f9: 0x00c3, 0x16fa: 0x00c3, 0x16fb: 0x00c0, + 0x16fc: 0x00c3, 0x16fd: 0x00c0, 0x16fe: 0x00c0, 0x16ff: 0x00c0, + // Block 0x5c, offset 0x1700 + 0x1700: 0x00c0, 0x1701: 0x00c0, 0x1702: 0x00c3, 0x1703: 0x00c0, 0x1704: 0x00c5, 0x1705: 0x00c0, + 0x1706: 0x00c0, 0x1707: 0x00c0, 0x1708: 0x00c0, 0x1709: 0x00c0, 0x170a: 0x00c0, 0x170b: 0x00c0, + 0x1710: 0x00c0, 0x1711: 0x00c0, + 0x1712: 0x00c0, 0x1713: 0x00c0, 0x1714: 0x00c0, 0x1715: 0x00c0, 0x1716: 0x00c0, 0x1717: 0x00c0, + 0x1718: 0x00c0, 0x1719: 0x00c0, 0x171a: 0x0080, 0x171b: 0x0080, 0x171c: 0x0080, 0x171d: 0x0080, + 0x171e: 0x0080, 0x171f: 0x0080, 0x1720: 0x0080, 0x1721: 0x0080, 0x1722: 0x0080, 0x1723: 0x0080, + 0x1724: 0x0080, 0x1725: 0x0080, 0x1726: 0x0080, 0x1727: 0x0080, 0x1728: 0x0080, 0x1729: 0x0080, + 0x172a: 0x0080, 0x172b: 0x00c3, 0x172c: 0x00c3, 0x172d: 0x00c3, 0x172e: 0x00c3, 0x172f: 0x00c3, + 0x1730: 0x00c3, 0x1731: 0x00c3, 0x1732: 0x00c3, 0x1733: 0x00c3, 0x1734: 0x0080, 0x1735: 0x0080, + 0x1736: 0x0080, 0x1737: 0x0080, 0x1738: 0x0080, 0x1739: 0x0080, 0x173a: 0x0080, 0x173b: 0x0080, + 0x173c: 0x0080, + // Block 0x5d, offset 0x1740 + 0x1740: 0x00c3, 0x1741: 0x00c3, 0x1742: 0x00c0, 0x1743: 0x00c0, 0x1744: 0x00c0, 0x1745: 0x00c0, + 0x1746: 0x00c0, 0x1747: 0x00c0, 0x1748: 0x00c0, 0x1749: 0x00c0, 0x174a: 0x00c0, 0x174b: 0x00c0, + 0x174c: 0x00c0, 0x174d: 0x00c0, 0x174e: 0x00c0, 0x174f: 0x00c0, 0x1750: 0x00c0, 0x1751: 0x00c0, + 0x1752: 0x00c0, 0x1753: 0x00c0, 0x1754: 0x00c0, 0x1755: 0x00c0, 0x1756: 0x00c0, 0x1757: 0x00c0, + 0x1758: 0x00c0, 0x1759: 0x00c0, 0x175a: 0x00c0, 0x175b: 0x00c0, 0x175c: 0x00c0, 0x175d: 0x00c0, + 0x175e: 0x00c0, 0x175f: 0x00c0, 0x1760: 0x00c0, 0x1761: 0x00c0, 0x1762: 0x00c3, 0x1763: 0x00c3, + 0x1764: 0x00c3, 0x1765: 0x00c3, 0x1766: 0x00c0, 0x1767: 0x00c0, 0x1768: 0x00c3, 0x1769: 0x00c3, + 0x176a: 0x00c5, 0x176b: 0x00c6, 0x176c: 0x00c3, 0x176d: 0x00c3, 0x176e: 0x00c0, 0x176f: 0x00c0, + 0x1770: 0x00c0, 0x1771: 0x00c0, 0x1772: 0x00c0, 0x1773: 0x00c0, 0x1774: 0x00c0, 0x1775: 0x00c0, + 0x1776: 0x00c0, 0x1777: 0x00c0, 0x1778: 0x00c0, 0x1779: 0x00c0, 0x177a: 0x00c0, 0x177b: 0x00c0, + 0x177c: 0x00c0, 0x177d: 0x00c0, 0x177e: 0x00c0, 0x177f: 0x00c0, + // Block 0x5e, offset 0x1780 + 0x1780: 0x00c0, 0x1781: 0x00c0, 0x1782: 0x00c0, 0x1783: 0x00c0, 0x1784: 0x00c0, 0x1785: 0x00c0, + 0x1786: 0x00c0, 0x1787: 0x00c0, 0x1788: 0x00c0, 0x1789: 0x00c0, 0x178a: 0x00c0, 0x178b: 0x00c0, + 0x178c: 0x00c0, 0x178d: 0x00c0, 0x178e: 0x00c0, 0x178f: 0x00c0, 0x1790: 0x00c0, 0x1791: 0x00c0, + 0x1792: 0x00c0, 0x1793: 0x00c0, 0x1794: 0x00c0, 0x1795: 0x00c0, 0x1796: 0x00c0, 0x1797: 0x00c0, + 0x1798: 0x00c0, 0x1799: 0x00c0, 0x179a: 0x00c0, 0x179b: 0x00c0, 0x179c: 0x00c0, 0x179d: 0x00c0, + 0x179e: 0x00c0, 0x179f: 0x00c0, 0x17a0: 0x00c0, 0x17a1: 0x00c0, 0x17a2: 0x00c0, 0x17a3: 0x00c0, + 0x17a4: 0x00c0, 0x17a5: 0x00c0, 0x17a6: 0x00c3, 0x17a7: 0x00c0, 0x17a8: 0x00c3, 0x17a9: 0x00c3, + 0x17aa: 0x00c0, 0x17ab: 0x00c0, 0x17ac: 0x00c0, 0x17ad: 0x00c3, 0x17ae: 0x00c0, 0x17af: 0x00c3, + 0x17b0: 0x00c3, 0x17b1: 0x00c3, 0x17b2: 0x00c5, 0x17b3: 0x00c5, + 0x17bc: 0x0080, 0x17bd: 0x0080, 0x17be: 0x0080, 0x17bf: 0x0080, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x00c0, 0x17c1: 0x00c0, 0x17c2: 0x00c0, 0x17c3: 0x00c0, 0x17c4: 0x00c0, 0x17c5: 0x00c0, + 0x17c6: 0x00c0, 0x17c7: 0x00c0, 0x17c8: 0x00c0, 0x17c9: 0x00c0, 0x17ca: 0x00c0, 0x17cb: 0x00c0, + 0x17cc: 0x00c0, 0x17cd: 0x00c0, 0x17ce: 0x00c0, 0x17cf: 0x00c0, 0x17d0: 0x00c0, 0x17d1: 0x00c0, + 0x17d2: 0x00c0, 0x17d3: 0x00c0, 0x17d4: 0x00c0, 0x17d5: 0x00c0, 0x17d6: 0x00c0, 0x17d7: 0x00c0, + 0x17d8: 0x00c0, 0x17d9: 0x00c0, 0x17da: 0x00c0, 0x17db: 0x00c0, 0x17dc: 0x00c0, 0x17dd: 0x00c0, + 0x17de: 0x00c0, 0x17df: 0x00c0, 0x17e0: 0x00c0, 0x17e1: 0x00c0, 0x17e2: 0x00c0, 0x17e3: 0x00c0, + 0x17e4: 0x00c0, 0x17e5: 0x00c0, 0x17e6: 0x00c0, 0x17e7: 0x00c0, 0x17e8: 0x00c0, 0x17e9: 0x00c0, + 0x17ea: 0x00c0, 0x17eb: 0x00c0, 0x17ec: 0x00c3, 0x17ed: 0x00c3, 0x17ee: 0x00c3, 0x17ef: 0x00c3, + 0x17f0: 0x00c3, 0x17f1: 0x00c3, 0x17f2: 0x00c3, 0x17f3: 0x00c3, 0x17f4: 0x00c0, 0x17f5: 0x00c0, + 0x17f6: 0x00c3, 0x17f7: 0x00c3, 0x17fb: 0x0080, + 0x17fc: 0x0080, 0x17fd: 0x0080, 0x17fe: 0x0080, 0x17ff: 0x0080, + // Block 0x60, offset 0x1800 + 0x1800: 0x00c0, 0x1801: 0x00c0, 0x1802: 0x00c0, 0x1803: 0x00c0, 0x1804: 0x00c0, 0x1805: 0x00c0, + 0x1806: 0x00c0, 0x1807: 0x00c0, 0x1808: 0x00c0, 0x1809: 0x00c0, + 0x180d: 0x00c0, 0x180e: 0x00c0, 0x180f: 0x00c0, 0x1810: 0x00c0, 0x1811: 0x00c0, + 0x1812: 0x00c0, 0x1813: 0x00c0, 0x1814: 0x00c0, 0x1815: 0x00c0, 0x1816: 0x00c0, 0x1817: 0x00c0, + 0x1818: 0x00c0, 0x1819: 0x00c0, 0x181a: 0x00c0, 0x181b: 0x00c0, 0x181c: 0x00c0, 0x181d: 0x00c0, + 0x181e: 0x00c0, 0x181f: 0x00c0, 0x1820: 0x00c0, 0x1821: 0x00c0, 0x1822: 0x00c0, 0x1823: 0x00c0, + 0x1824: 0x00c0, 0x1825: 0x00c0, 0x1826: 0x00c0, 0x1827: 0x00c0, 0x1828: 0x00c0, 0x1829: 0x00c0, + 0x182a: 0x00c0, 0x182b: 0x00c0, 0x182c: 0x00c0, 0x182d: 0x00c0, 0x182e: 0x00c0, 0x182f: 0x00c0, + 0x1830: 0x00c0, 0x1831: 0x00c0, 0x1832: 0x00c0, 0x1833: 0x00c0, 0x1834: 0x00c0, 0x1835: 0x00c0, + 0x1836: 0x00c0, 0x1837: 0x00c0, 0x1838: 0x00c0, 0x1839: 0x00c0, 0x183a: 0x00c0, 0x183b: 0x00c0, + 0x183c: 0x00c0, 0x183d: 0x00c0, 0x183e: 0x0080, 0x183f: 0x0080, + // Block 0x61, offset 0x1840 + 0x1840: 0x00c0, 0x1841: 0x00c0, 0x1842: 0x00c0, 0x1843: 0x00c0, 0x1844: 0x00c0, 0x1845: 0x00c0, + 0x1846: 0x00c0, 0x1847: 0x00c0, 0x1848: 0x00c0, + // Block 0x62, offset 0x1880 + 0x1880: 0x0080, 0x1881: 0x0080, 0x1882: 0x0080, 0x1883: 0x0080, 0x1884: 0x0080, 0x1885: 0x0080, + 0x1886: 0x0080, 0x1887: 0x0080, + 0x1890: 0x00c3, 0x1891: 0x00c3, + 0x1892: 0x00c3, 0x1893: 0x0080, 0x1894: 0x00c3, 0x1895: 0x00c3, 0x1896: 0x00c3, 0x1897: 0x00c3, + 0x1898: 0x00c3, 0x1899: 0x00c3, 0x189a: 0x00c3, 0x189b: 0x00c3, 0x189c: 0x00c3, 0x189d: 0x00c3, + 0x189e: 0x00c3, 0x189f: 0x00c3, 0x18a0: 0x00c3, 0x18a1: 0x00c0, 0x18a2: 0x00c3, 0x18a3: 0x00c3, + 0x18a4: 0x00c3, 0x18a5: 0x00c3, 0x18a6: 0x00c3, 0x18a7: 0x00c3, 0x18a8: 0x00c3, 0x18a9: 0x00c0, + 0x18aa: 0x00c0, 0x18ab: 0x00c0, 0x18ac: 0x00c0, 0x18ad: 0x00c3, 0x18ae: 0x00c0, 0x18af: 0x00c0, + 0x18b0: 0x00c0, 0x18b1: 0x00c0, 0x18b2: 0x00c0, 0x18b3: 0x00c0, 0x18b4: 0x00c3, 0x18b5: 0x00c0, + 0x18b6: 0x00c0, 0x18b7: 0x00c0, 0x18b8: 0x00c3, 0x18b9: 0x00c3, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x00c0, 0x18c1: 0x00c0, 0x18c2: 0x00c0, 0x18c3: 0x00c0, 0x18c4: 0x00c0, 0x18c5: 0x00c0, + 0x18c6: 0x00c0, 0x18c7: 0x00c0, 0x18c8: 0x00c0, 0x18c9: 0x00c0, 0x18ca: 0x00c0, 0x18cb: 0x00c0, + 0x18cc: 0x00c0, 0x18cd: 0x00c0, 0x18ce: 0x00c0, 0x18cf: 0x00c0, 0x18d0: 0x00c0, 0x18d1: 0x00c0, + 0x18d2: 0x00c0, 0x18d3: 0x00c0, 0x18d4: 0x00c0, 0x18d5: 0x00c0, 0x18d6: 0x00c0, 0x18d7: 0x00c0, + 0x18d8: 0x00c0, 0x18d9: 0x00c0, 0x18da: 0x00c0, 0x18db: 0x00c0, 0x18dc: 0x00c0, 0x18dd: 0x00c0, + 0x18de: 0x00c0, 0x18df: 0x00c0, 0x18e0: 0x00c0, 0x18e1: 0x00c0, 0x18e2: 0x00c0, 0x18e3: 0x00c0, + 0x18e4: 0x00c0, 0x18e5: 0x00c0, 0x18e6: 0x00c8, 0x18e7: 0x00c8, 0x18e8: 0x00c8, 0x18e9: 0x00c8, + 0x18ea: 0x00c8, 0x18eb: 0x00c0, 0x18ec: 0x0080, 0x18ed: 0x0080, 0x18ee: 0x0080, 0x18ef: 0x00c0, + 0x18f0: 0x0080, 0x18f1: 0x0080, 0x18f2: 0x0080, 0x18f3: 0x0080, 0x18f4: 0x0080, 0x18f5: 0x0080, + 0x18f6: 0x0080, 0x18f7: 0x0080, 0x18f8: 0x0080, 0x18f9: 0x0080, 0x18fa: 0x0080, 0x18fb: 0x00c0, + 0x18fc: 0x0080, 0x18fd: 0x0080, 0x18fe: 0x0080, 0x18ff: 0x0080, + // Block 0x64, offset 0x1900 + 0x1900: 0x0080, 0x1901: 0x0080, 0x1902: 0x0080, 0x1903: 0x0080, 0x1904: 0x0080, 0x1905: 0x0080, + 0x1906: 0x0080, 0x1907: 0x0080, 0x1908: 0x0080, 0x1909: 0x0080, 0x190a: 0x0080, 0x190b: 0x0080, + 0x190c: 0x0080, 0x190d: 0x0080, 0x190e: 0x00c0, 0x190f: 0x0080, 0x1910: 0x0080, 0x1911: 0x0080, + 0x1912: 0x0080, 0x1913: 0x0080, 0x1914: 0x0080, 0x1915: 0x0080, 0x1916: 0x0080, 0x1917: 0x0080, + 0x1918: 0x0080, 0x1919: 0x0080, 0x191a: 0x0080, 0x191b: 0x0080, 0x191c: 0x0080, 0x191d: 0x0088, + 0x191e: 0x0088, 0x191f: 0x0088, 0x1920: 0x0088, 0x1921: 0x0088, 0x1922: 0x0080, 0x1923: 0x0080, + 0x1924: 0x0080, 0x1925: 0x0080, 0x1926: 0x0088, 0x1927: 0x0088, 0x1928: 0x0088, 0x1929: 0x0088, + 0x192a: 0x0088, 0x192b: 0x00c0, 0x192c: 0x00c0, 0x192d: 0x00c0, 0x192e: 0x00c0, 0x192f: 0x00c0, + 0x1930: 0x00c0, 0x1931: 0x00c0, 0x1932: 0x00c0, 0x1933: 0x00c0, 0x1934: 0x00c0, 0x1935: 0x00c0, + 0x1936: 0x00c0, 0x1937: 0x00c0, 0x1938: 0x0080, 0x1939: 0x00c0, 0x193a: 0x00c0, 0x193b: 0x00c0, + 0x193c: 0x00c0, 0x193d: 0x00c0, 0x193e: 0x00c0, 0x193f: 0x00c0, + // Block 0x65, offset 0x1940 + 0x1940: 0x00c0, 0x1941: 0x00c0, 0x1942: 0x00c0, 0x1943: 0x00c0, 0x1944: 0x00c0, 0x1945: 0x00c0, + 0x1946: 0x00c0, 0x1947: 0x00c0, 0x1948: 0x00c0, 0x1949: 0x00c0, 0x194a: 0x00c0, 0x194b: 0x00c0, + 0x194c: 0x00c0, 0x194d: 0x00c0, 0x194e: 0x00c0, 0x194f: 0x00c0, 0x1950: 0x00c0, 0x1951: 0x00c0, + 0x1952: 0x00c0, 0x1953: 0x00c0, 0x1954: 0x00c0, 0x1955: 0x00c0, 0x1956: 0x00c0, 0x1957: 0x00c0, + 0x1958: 0x00c0, 0x1959: 0x00c0, 0x195a: 0x00c0, 0x195b: 0x0080, 0x195c: 0x0080, 0x195d: 0x0080, + 0x195e: 0x0080, 0x195f: 0x0080, 0x1960: 0x0080, 0x1961: 0x0080, 0x1962: 0x0080, 0x1963: 0x0080, + 0x1964: 0x0080, 0x1965: 0x0080, 0x1966: 0x0080, 0x1967: 0x0080, 0x1968: 0x0080, 0x1969: 0x0080, + 0x196a: 0x0080, 0x196b: 0x0080, 0x196c: 0x0080, 0x196d: 0x0080, 0x196e: 0x0080, 0x196f: 0x0080, + 0x1970: 0x0080, 0x1971: 0x0080, 0x1972: 0x0080, 0x1973: 0x0080, 0x1974: 0x0080, 0x1975: 0x0080, + 0x1976: 0x0080, 0x1977: 0x0080, 0x1978: 0x0080, 0x1979: 0x0080, 0x197a: 0x0080, 0x197b: 0x0080, + 0x197c: 0x0080, 0x197d: 0x0080, 0x197e: 0x0080, 0x197f: 0x0088, + // Block 0x66, offset 0x1980 + 0x1980: 0x00c3, 0x1981: 0x00c3, 0x1982: 0x00c3, 0x1983: 0x00c3, 0x1984: 0x00c3, 0x1985: 0x00c3, + 0x1986: 0x00c3, 0x1987: 0x00c3, 0x1988: 0x00c3, 0x1989: 0x00c3, 0x198a: 0x00c3, 0x198b: 0x00c3, + 0x198c: 0x00c3, 0x198d: 0x00c3, 0x198e: 0x00c3, 0x198f: 0x00c3, 0x1990: 0x00c3, 0x1991: 0x00c3, + 0x1992: 0x00c3, 0x1993: 0x00c3, 0x1994: 0x00c3, 0x1995: 0x00c3, 0x1996: 0x00c3, 0x1997: 0x00c3, + 0x1998: 0x00c3, 0x1999: 0x00c3, 0x199a: 0x00c3, 0x199b: 0x00c3, 0x199c: 0x00c3, 0x199d: 0x00c3, + 0x199e: 0x00c3, 0x199f: 0x00c3, 0x19a0: 0x00c3, 0x19a1: 0x00c3, 0x19a2: 0x00c3, 0x19a3: 0x00c3, + 0x19a4: 0x00c3, 0x19a5: 0x00c3, 0x19a6: 0x00c3, 0x19a7: 0x00c3, 0x19a8: 0x00c3, 0x19a9: 0x00c3, + 0x19aa: 0x00c3, 0x19ab: 0x00c3, 0x19ac: 0x00c3, 0x19ad: 0x00c3, 0x19ae: 0x00c3, 0x19af: 0x00c3, + 0x19b0: 0x00c3, 0x19b1: 0x00c3, 0x19b2: 0x00c3, 0x19b3: 0x00c3, 0x19b4: 0x00c3, 0x19b5: 0x00c3, + 0x19b6: 0x00c3, 0x19b7: 0x00c3, 0x19b8: 0x00c3, 0x19b9: 0x00c3, 0x19bb: 0x00c3, + 0x19bc: 0x00c3, 0x19bd: 0x00c3, 0x19be: 0x00c3, 0x19bf: 0x00c3, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x00c0, 0x19c1: 0x00c0, 0x19c2: 0x00c0, 0x19c3: 0x00c0, 0x19c4: 0x00c0, 0x19c5: 0x00c0, + 0x19c6: 0x00c0, 0x19c7: 0x00c0, 0x19c8: 0x00c0, 0x19c9: 0x00c0, 0x19ca: 0x00c0, 0x19cb: 0x00c0, + 0x19cc: 0x00c0, 0x19cd: 0x00c0, 0x19ce: 0x00c0, 0x19cf: 0x00c0, 0x19d0: 0x00c0, 0x19d1: 0x00c0, + 0x19d2: 0x00c0, 0x19d3: 0x00c0, 0x19d4: 0x00c0, 0x19d5: 0x00c0, 0x19d6: 0x00c0, 0x19d7: 0x00c0, + 0x19d8: 0x00c0, 0x19d9: 0x00c0, 0x19da: 0x0080, 0x19db: 0x0080, 0x19dc: 0x00c0, 0x19dd: 0x00c0, + 0x19de: 0x00c0, 0x19df: 0x00c0, 0x19e0: 0x00c0, 0x19e1: 0x00c0, 0x19e2: 0x00c0, 0x19e3: 0x00c0, + 0x19e4: 0x00c0, 0x19e5: 0x00c0, 0x19e6: 0x00c0, 0x19e7: 0x00c0, 0x19e8: 0x00c0, 0x19e9: 0x00c0, + 0x19ea: 0x00c0, 0x19eb: 0x00c0, 0x19ec: 0x00c0, 0x19ed: 0x00c0, 0x19ee: 0x00c0, 0x19ef: 0x00c0, + 0x19f0: 0x00c0, 0x19f1: 0x00c0, 0x19f2: 0x00c0, 0x19f3: 0x00c0, 0x19f4: 0x00c0, 0x19f5: 0x00c0, + 0x19f6: 0x00c0, 0x19f7: 0x00c0, 0x19f8: 0x00c0, 0x19f9: 0x00c0, 0x19fa: 0x00c0, 0x19fb: 0x00c0, + 0x19fc: 0x00c0, 0x19fd: 0x00c0, 0x19fe: 0x00c0, 0x19ff: 0x00c0, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x00c8, 0x1a01: 0x00c8, 0x1a02: 0x00c8, 0x1a03: 0x00c8, 0x1a04: 0x00c8, 0x1a05: 0x00c8, + 0x1a06: 0x00c8, 0x1a07: 0x00c8, 0x1a08: 0x00c8, 0x1a09: 0x00c8, 0x1a0a: 0x00c8, 0x1a0b: 0x00c8, + 0x1a0c: 0x00c8, 0x1a0d: 0x00c8, 0x1a0e: 0x00c8, 0x1a0f: 0x00c8, 0x1a10: 0x00c8, 0x1a11: 0x00c8, + 0x1a12: 0x00c8, 0x1a13: 0x00c8, 0x1a14: 0x00c8, 0x1a15: 0x00c8, + 0x1a18: 0x00c8, 0x1a19: 0x00c8, 0x1a1a: 0x00c8, 0x1a1b: 0x00c8, 0x1a1c: 0x00c8, 0x1a1d: 0x00c8, + 0x1a20: 0x00c8, 0x1a21: 0x00c8, 0x1a22: 0x00c8, 0x1a23: 0x00c8, + 0x1a24: 0x00c8, 0x1a25: 0x00c8, 0x1a26: 0x00c8, 0x1a27: 0x00c8, 0x1a28: 0x00c8, 0x1a29: 0x00c8, + 0x1a2a: 0x00c8, 0x1a2b: 0x00c8, 0x1a2c: 0x00c8, 0x1a2d: 0x00c8, 0x1a2e: 0x00c8, 0x1a2f: 0x00c8, + 0x1a30: 0x00c8, 0x1a31: 0x00c8, 0x1a32: 0x00c8, 0x1a33: 0x00c8, 0x1a34: 0x00c8, 0x1a35: 0x00c8, + 0x1a36: 0x00c8, 0x1a37: 0x00c8, 0x1a38: 0x00c8, 0x1a39: 0x00c8, 0x1a3a: 0x00c8, 0x1a3b: 0x00c8, + 0x1a3c: 0x00c8, 0x1a3d: 0x00c8, 0x1a3e: 0x00c8, 0x1a3f: 0x00c8, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x00c8, 0x1a41: 0x00c8, 0x1a42: 0x00c8, 0x1a43: 0x00c8, 0x1a44: 0x00c8, 0x1a45: 0x00c8, + 0x1a48: 0x00c8, 0x1a49: 0x00c8, 0x1a4a: 0x00c8, 0x1a4b: 0x00c8, + 0x1a4c: 0x00c8, 0x1a4d: 0x00c8, 0x1a50: 0x00c8, 0x1a51: 0x00c8, + 0x1a52: 0x00c8, 0x1a53: 0x00c8, 0x1a54: 0x00c8, 0x1a55: 0x00c8, 0x1a56: 0x00c8, 0x1a57: 0x00c8, + 0x1a59: 0x00c8, 0x1a5b: 0x00c8, 0x1a5d: 0x00c8, + 0x1a5f: 0x00c8, 0x1a60: 0x00c8, 0x1a61: 0x00c8, 0x1a62: 0x00c8, 0x1a63: 0x00c8, + 0x1a64: 0x00c8, 0x1a65: 0x00c8, 0x1a66: 0x00c8, 0x1a67: 0x00c8, 0x1a68: 0x00c8, 0x1a69: 0x00c8, + 0x1a6a: 0x00c8, 0x1a6b: 0x00c8, 0x1a6c: 0x00c8, 0x1a6d: 0x00c8, 0x1a6e: 0x00c8, 0x1a6f: 0x00c8, + 0x1a70: 0x00c8, 0x1a71: 0x0088, 0x1a72: 0x00c8, 0x1a73: 0x0088, 0x1a74: 0x00c8, 0x1a75: 0x0088, + 0x1a76: 0x00c8, 0x1a77: 0x0088, 0x1a78: 0x00c8, 0x1a79: 0x0088, 0x1a7a: 0x00c8, 0x1a7b: 0x0088, + 0x1a7c: 0x00c8, 0x1a7d: 0x0088, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x00c8, 0x1a81: 0x00c8, 0x1a82: 0x00c8, 0x1a83: 0x00c8, 0x1a84: 0x00c8, 0x1a85: 0x00c8, + 0x1a86: 0x00c8, 0x1a87: 0x00c8, 0x1a88: 0x0088, 0x1a89: 0x0088, 0x1a8a: 0x0088, 0x1a8b: 0x0088, + 0x1a8c: 0x0088, 0x1a8d: 0x0088, 0x1a8e: 0x0088, 0x1a8f: 0x0088, 0x1a90: 0x00c8, 0x1a91: 0x00c8, + 0x1a92: 0x00c8, 0x1a93: 0x00c8, 0x1a94: 0x00c8, 0x1a95: 0x00c8, 0x1a96: 0x00c8, 0x1a97: 0x00c8, + 0x1a98: 0x0088, 0x1a99: 0x0088, 0x1a9a: 0x0088, 0x1a9b: 0x0088, 0x1a9c: 0x0088, 0x1a9d: 0x0088, + 0x1a9e: 0x0088, 0x1a9f: 0x0088, 0x1aa0: 0x00c8, 0x1aa1: 0x00c8, 0x1aa2: 0x00c8, 0x1aa3: 0x00c8, + 0x1aa4: 0x00c8, 0x1aa5: 0x00c8, 0x1aa6: 0x00c8, 0x1aa7: 0x00c8, 0x1aa8: 0x0088, 0x1aa9: 0x0088, + 0x1aaa: 0x0088, 0x1aab: 0x0088, 0x1aac: 0x0088, 0x1aad: 0x0088, 0x1aae: 0x0088, 0x1aaf: 0x0088, + 0x1ab0: 0x00c8, 0x1ab1: 0x00c8, 0x1ab2: 0x00c8, 0x1ab3: 0x00c8, 0x1ab4: 0x00c8, + 0x1ab6: 0x00c8, 0x1ab7: 0x00c8, 0x1ab8: 0x00c8, 0x1ab9: 0x00c8, 0x1aba: 0x00c8, 0x1abb: 0x0088, + 0x1abc: 0x0088, 0x1abd: 0x0088, 0x1abe: 0x0088, 0x1abf: 0x0088, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x0088, 0x1ac1: 0x0088, 0x1ac2: 0x00c8, 0x1ac3: 0x00c8, 0x1ac4: 0x00c8, + 0x1ac6: 0x00c8, 0x1ac7: 0x00c8, 0x1ac8: 0x00c8, 0x1ac9: 0x0088, 0x1aca: 0x00c8, 0x1acb: 0x0088, + 0x1acc: 0x0088, 0x1acd: 0x0088, 0x1ace: 0x0088, 0x1acf: 0x0088, 0x1ad0: 0x00c8, 0x1ad1: 0x00c8, + 0x1ad2: 0x00c8, 0x1ad3: 0x0088, 0x1ad6: 0x00c8, 0x1ad7: 0x00c8, + 0x1ad8: 0x00c8, 0x1ad9: 0x00c8, 0x1ada: 0x00c8, 0x1adb: 0x0088, 0x1add: 0x0088, + 0x1ade: 0x0088, 0x1adf: 0x0088, 0x1ae0: 0x00c8, 0x1ae1: 0x00c8, 0x1ae2: 0x00c8, 0x1ae3: 0x0088, + 0x1ae4: 0x00c8, 0x1ae5: 0x00c8, 0x1ae6: 0x00c8, 0x1ae7: 0x00c8, 0x1ae8: 0x00c8, 0x1ae9: 0x00c8, + 0x1aea: 0x00c8, 0x1aeb: 0x0088, 0x1aec: 0x00c8, 0x1aed: 0x0088, 0x1aee: 0x0088, 0x1aef: 0x0088, + 0x1af2: 0x00c8, 0x1af3: 0x00c8, 0x1af4: 0x00c8, + 0x1af6: 0x00c8, 0x1af7: 0x00c8, 0x1af8: 0x00c8, 0x1af9: 0x0088, 0x1afa: 0x00c8, 0x1afb: 0x0088, + 0x1afc: 0x0088, 0x1afd: 0x0088, 0x1afe: 0x0088, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x0080, 0x1b01: 0x0080, 0x1b02: 0x0080, 0x1b03: 0x0080, 0x1b04: 0x0080, 0x1b05: 0x0080, + 0x1b06: 0x0080, 0x1b07: 0x0080, 0x1b08: 0x0080, 0x1b09: 0x0080, 0x1b0a: 0x0080, 0x1b0b: 0x0040, + 0x1b0c: 0x004d, 0x1b0d: 0x004e, 0x1b0e: 0x0040, 0x1b0f: 0x0040, 0x1b10: 0x0080, 0x1b11: 0x0080, + 0x1b12: 0x0080, 0x1b13: 0x0080, 0x1b14: 0x0080, 0x1b15: 0x0080, 0x1b16: 0x0080, 0x1b17: 0x0080, + 0x1b18: 0x0080, 0x1b19: 0x0080, 0x1b1a: 0x0080, 0x1b1b: 0x0080, 0x1b1c: 0x0080, 0x1b1d: 0x0080, + 0x1b1e: 0x0080, 0x1b1f: 0x0080, 0x1b20: 0x0080, 0x1b21: 0x0080, 0x1b22: 0x0080, 0x1b23: 0x0080, + 0x1b24: 0x0080, 0x1b25: 0x0080, 0x1b26: 0x0080, 0x1b27: 0x0080, 0x1b28: 0x0040, 0x1b29: 0x0040, + 0x1b2a: 0x0040, 0x1b2b: 0x0040, 0x1b2c: 0x0040, 0x1b2d: 0x0040, 0x1b2e: 0x0040, 0x1b2f: 0x0080, + 0x1b30: 0x0080, 0x1b31: 0x0080, 0x1b32: 0x0080, 0x1b33: 0x0080, 0x1b34: 0x0080, 0x1b35: 0x0080, + 0x1b36: 0x0080, 0x1b37: 0x0080, 0x1b38: 0x0080, 0x1b39: 0x0080, 0x1b3a: 0x0080, 0x1b3b: 0x0080, + 0x1b3c: 0x0080, 0x1b3d: 0x0080, 0x1b3e: 0x0080, 0x1b3f: 0x0080, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x0080, 0x1b41: 0x0080, 0x1b42: 0x0080, 0x1b43: 0x0080, 0x1b44: 0x0080, 0x1b45: 0x0080, + 0x1b46: 0x0080, 0x1b47: 0x0080, 0x1b48: 0x0080, 0x1b49: 0x0080, 0x1b4a: 0x0080, 0x1b4b: 0x0080, + 0x1b4c: 0x0080, 0x1b4d: 0x0080, 0x1b4e: 0x0080, 0x1b4f: 0x0080, 0x1b50: 0x0080, 0x1b51: 0x0080, + 0x1b52: 0x0080, 0x1b53: 0x0080, 0x1b54: 0x0080, 0x1b55: 0x0080, 0x1b56: 0x0080, 0x1b57: 0x0080, + 0x1b58: 0x0080, 0x1b59: 0x0080, 0x1b5a: 0x0080, 0x1b5b: 0x0080, 0x1b5c: 0x0080, 0x1b5d: 0x0080, + 0x1b5e: 0x0080, 0x1b5f: 0x0080, 0x1b60: 0x0040, 0x1b61: 0x0040, 0x1b62: 0x0040, 0x1b63: 0x0040, + 0x1b64: 0x0040, 0x1b66: 0x0040, 0x1b67: 0x0040, 0x1b68: 0x0040, 0x1b69: 0x0040, + 0x1b6a: 0x0040, 0x1b6b: 0x0040, 0x1b6c: 0x0040, 0x1b6d: 0x0040, 0x1b6e: 0x0040, 0x1b6f: 0x0040, + 0x1b70: 0x0080, 0x1b71: 0x0080, 0x1b74: 0x0080, 0x1b75: 0x0080, + 0x1b76: 0x0080, 0x1b77: 0x0080, 0x1b78: 0x0080, 0x1b79: 0x0080, 0x1b7a: 0x0080, 0x1b7b: 0x0080, + 0x1b7c: 0x0080, 0x1b7d: 0x0080, 0x1b7e: 0x0080, 0x1b7f: 0x0080, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x0080, 0x1b81: 0x0080, 0x1b82: 0x0080, 0x1b83: 0x0080, 0x1b84: 0x0080, 0x1b85: 0x0080, + 0x1b86: 0x0080, 0x1b87: 0x0080, 0x1b88: 0x0080, 0x1b89: 0x0080, 0x1b8a: 0x0080, 0x1b8b: 0x0080, + 0x1b8c: 0x0080, 0x1b8d: 0x0080, 0x1b8e: 0x0080, 0x1b90: 0x0080, 0x1b91: 0x0080, + 0x1b92: 0x0080, 0x1b93: 0x0080, 0x1b94: 0x0080, 0x1b95: 0x0080, 0x1b96: 0x0080, 0x1b97: 0x0080, + 0x1b98: 0x0080, 0x1b99: 0x0080, 0x1b9a: 0x0080, 0x1b9b: 0x0080, 0x1b9c: 0x0080, + 0x1ba0: 0x0080, 0x1ba1: 0x0080, 0x1ba2: 0x0080, 0x1ba3: 0x0080, + 0x1ba4: 0x0080, 0x1ba5: 0x0080, 0x1ba6: 0x0080, 0x1ba7: 0x0080, 0x1ba8: 0x0080, 0x1ba9: 0x0080, + 0x1baa: 0x0080, 0x1bab: 0x0080, 0x1bac: 0x0080, 0x1bad: 0x0080, 0x1bae: 0x0080, 0x1baf: 0x0080, + 0x1bb0: 0x0080, 0x1bb1: 0x0080, 0x1bb2: 0x0080, 0x1bb3: 0x0080, 0x1bb4: 0x0080, 0x1bb5: 0x0080, + 0x1bb6: 0x0080, 0x1bb7: 0x0080, 0x1bb8: 0x0080, 0x1bb9: 0x0080, 0x1bba: 0x0080, 0x1bbb: 0x0080, + 0x1bbc: 0x0080, 0x1bbd: 0x0080, 0x1bbe: 0x0080, 0x1bbf: 0x0080, + // Block 0x6f, offset 0x1bc0 + 0x1bd0: 0x00c3, 0x1bd1: 0x00c3, + 0x1bd2: 0x00c3, 0x1bd3: 0x00c3, 0x1bd4: 0x00c3, 0x1bd5: 0x00c3, 0x1bd6: 0x00c3, 0x1bd7: 0x00c3, + 0x1bd8: 0x00c3, 0x1bd9: 0x00c3, 0x1bda: 0x00c3, 0x1bdb: 0x00c3, 0x1bdc: 0x00c3, 0x1bdd: 0x0083, + 0x1bde: 0x0083, 0x1bdf: 0x0083, 0x1be0: 0x0083, 0x1be1: 0x00c3, 0x1be2: 0x0083, 0x1be3: 0x0083, + 0x1be4: 0x0083, 0x1be5: 0x00c3, 0x1be6: 0x00c3, 0x1be7: 0x00c3, 0x1be8: 0x00c3, 0x1be9: 0x00c3, + 0x1bea: 0x00c3, 0x1beb: 0x00c3, 0x1bec: 0x00c3, 0x1bed: 0x00c3, 0x1bee: 0x00c3, 0x1bef: 0x00c3, + 0x1bf0: 0x00c3, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x0080, 0x1c01: 0x0080, 0x1c02: 0x0080, 0x1c03: 0x0080, 0x1c04: 0x0080, 0x1c05: 0x0080, + 0x1c06: 0x0080, 0x1c07: 0x0080, 0x1c08: 0x0080, 0x1c09: 0x0080, 0x1c0a: 0x0080, 0x1c0b: 0x0080, + 0x1c0c: 0x0080, 0x1c0d: 0x0080, 0x1c0e: 0x0080, 0x1c0f: 0x0080, 0x1c10: 0x0080, 0x1c11: 0x0080, + 0x1c12: 0x0080, 0x1c13: 0x0080, 0x1c14: 0x0080, 0x1c15: 0x0080, 0x1c16: 0x0080, 0x1c17: 0x0080, + 0x1c18: 0x0080, 0x1c19: 0x0080, 0x1c1a: 0x0080, 0x1c1b: 0x0080, 0x1c1c: 0x0080, 0x1c1d: 0x0080, + 0x1c1e: 0x0080, 0x1c1f: 0x0080, 0x1c20: 0x0080, 0x1c21: 0x0080, 0x1c22: 0x0080, 0x1c23: 0x0080, + 0x1c24: 0x0080, 0x1c25: 0x0080, 0x1c26: 0x0088, 0x1c27: 0x0080, 0x1c28: 0x0080, 0x1c29: 0x0080, + 0x1c2a: 0x0080, 0x1c2b: 0x0080, 0x1c2c: 0x0080, 0x1c2d: 0x0080, 0x1c2e: 0x0080, 0x1c2f: 0x0080, + 0x1c30: 0x0080, 0x1c31: 0x0080, 0x1c32: 0x00c0, 0x1c33: 0x0080, 0x1c34: 0x0080, 0x1c35: 0x0080, + 0x1c36: 0x0080, 0x1c37: 0x0080, 0x1c38: 0x0080, 0x1c39: 0x0080, 0x1c3a: 0x0080, 0x1c3b: 0x0080, + 0x1c3c: 0x0080, 0x1c3d: 0x0080, 0x1c3e: 0x0080, 0x1c3f: 0x0080, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x0080, 0x1c41: 0x0080, 0x1c42: 0x0080, 0x1c43: 0x0080, 0x1c44: 0x0080, 0x1c45: 0x0080, + 0x1c46: 0x0080, 0x1c47: 0x0080, 0x1c48: 0x0080, 0x1c49: 0x0080, 0x1c4a: 0x0080, 0x1c4b: 0x0080, + 0x1c4c: 0x0080, 0x1c4d: 0x0080, 0x1c4e: 0x00c0, 0x1c4f: 0x0080, 0x1c50: 0x0080, 0x1c51: 0x0080, + 0x1c52: 0x0080, 0x1c53: 0x0080, 0x1c54: 0x0080, 0x1c55: 0x0080, 0x1c56: 0x0080, 0x1c57: 0x0080, + 0x1c58: 0x0080, 0x1c59: 0x0080, 0x1c5a: 0x0080, 0x1c5b: 0x0080, 0x1c5c: 0x0080, 0x1c5d: 0x0080, + 0x1c5e: 0x0080, 0x1c5f: 0x0080, 0x1c60: 0x0080, 0x1c61: 0x0080, 0x1c62: 0x0080, 0x1c63: 0x0080, + 0x1c64: 0x0080, 0x1c65: 0x0080, 0x1c66: 0x0080, 0x1c67: 0x0080, 0x1c68: 0x0080, 0x1c69: 0x0080, + 0x1c6a: 0x0080, 0x1c6b: 0x0080, 0x1c6c: 0x0080, 0x1c6d: 0x0080, 0x1c6e: 0x0080, 0x1c6f: 0x0080, + 0x1c70: 0x0080, 0x1c71: 0x0080, 0x1c72: 0x0080, 0x1c73: 0x0080, 0x1c74: 0x0080, 0x1c75: 0x0080, + 0x1c76: 0x0080, 0x1c77: 0x0080, 0x1c78: 0x0080, 0x1c79: 0x0080, 0x1c7a: 0x0080, 0x1c7b: 0x0080, + 0x1c7c: 0x0080, 0x1c7d: 0x0080, 0x1c7e: 0x0080, 0x1c7f: 0x0080, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x0080, 0x1c81: 0x0080, 0x1c82: 0x0080, 0x1c83: 0x00c0, 0x1c84: 0x00c0, 0x1c85: 0x0080, + 0x1c86: 0x0080, 0x1c87: 0x0080, 0x1c88: 0x0080, 0x1c89: 0x0080, 0x1c8a: 0x0080, 0x1c8b: 0x0080, + 0x1c90: 0x0080, 0x1c91: 0x0080, + 0x1c92: 0x0080, 0x1c93: 0x0080, 0x1c94: 0x0080, 0x1c95: 0x0080, 0x1c96: 0x0080, 0x1c97: 0x0080, + 0x1c98: 0x0080, 0x1c99: 0x0080, 0x1c9a: 0x0080, 0x1c9b: 0x0080, 0x1c9c: 0x0080, 0x1c9d: 0x0080, + 0x1c9e: 0x0080, 0x1c9f: 0x0080, 0x1ca0: 0x0080, 0x1ca1: 0x0080, 0x1ca2: 0x0080, 0x1ca3: 0x0080, + 0x1ca4: 0x0080, 0x1ca5: 0x0080, 0x1ca6: 0x0080, 0x1ca7: 0x0080, 0x1ca8: 0x0080, 0x1ca9: 0x0080, + 0x1caa: 0x0080, 0x1cab: 0x0080, 0x1cac: 0x0080, 0x1cad: 0x0080, 0x1cae: 0x0080, 0x1caf: 0x0080, + 0x1cb0: 0x0080, 0x1cb1: 0x0080, 0x1cb2: 0x0080, 0x1cb3: 0x0080, 0x1cb4: 0x0080, 0x1cb5: 0x0080, + 0x1cb6: 0x0080, 0x1cb7: 0x0080, 0x1cb8: 0x0080, 0x1cb9: 0x0080, 0x1cba: 0x0080, 0x1cbb: 0x0080, + 0x1cbc: 0x0080, 0x1cbd: 0x0080, 0x1cbe: 0x0080, 0x1cbf: 0x0080, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0080, 0x1cc1: 0x0080, 0x1cc2: 0x0080, 0x1cc3: 0x0080, 0x1cc4: 0x0080, 0x1cc5: 0x0080, + 0x1cc6: 0x0080, 0x1cc7: 0x0080, 0x1cc8: 0x0080, 0x1cc9: 0x0080, 0x1cca: 0x0080, 0x1ccb: 0x0080, + 0x1ccc: 0x0080, 0x1ccd: 0x0080, 0x1cce: 0x0080, 0x1ccf: 0x0080, 0x1cd0: 0x0080, 0x1cd1: 0x0080, + 0x1cd2: 0x0080, 0x1cd3: 0x0080, 0x1cd4: 0x0080, 0x1cd5: 0x0080, 0x1cd6: 0x0080, 0x1cd7: 0x0080, + 0x1cd8: 0x0080, 0x1cd9: 0x0080, 0x1cda: 0x0080, 0x1cdb: 0x0080, 0x1cdc: 0x0080, 0x1cdd: 0x0080, + 0x1cde: 0x0080, 0x1cdf: 0x0080, 0x1ce0: 0x0080, 0x1ce1: 0x0080, 0x1ce2: 0x0080, 0x1ce3: 0x0080, + 0x1ce4: 0x0080, 0x1ce5: 0x0080, 0x1ce6: 0x0080, 0x1ce7: 0x0080, 0x1ce8: 0x0080, 0x1ce9: 0x0080, + 0x1cea: 0x0080, 0x1ceb: 0x0080, 0x1cec: 0x0080, 0x1ced: 0x0080, 0x1cee: 0x0080, 0x1cef: 0x0080, + 0x1cf0: 0x0080, 0x1cf1: 0x0080, 0x1cf2: 0x0080, 0x1cf3: 0x0080, 0x1cf4: 0x0080, 0x1cf5: 0x0080, + 0x1cf6: 0x0080, 0x1cf7: 0x0080, 0x1cf8: 0x0080, 0x1cf9: 0x0080, 0x1cfa: 0x0080, 0x1cfb: 0x0080, + 0x1cfc: 0x0080, 0x1cfd: 0x0080, 0x1cfe: 0x0080, 0x1cff: 0x0080, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0080, 0x1d01: 0x0080, 0x1d02: 0x0080, 0x1d03: 0x0080, 0x1d04: 0x0080, 0x1d05: 0x0080, + 0x1d06: 0x0080, 0x1d07: 0x0080, 0x1d08: 0x0080, 0x1d09: 0x0080, 0x1d0a: 0x0080, 0x1d0b: 0x0080, + 0x1d0c: 0x0080, 0x1d0d: 0x0080, 0x1d0e: 0x0080, 0x1d0f: 0x0080, 0x1d10: 0x0080, 0x1d11: 0x0080, + 0x1d12: 0x0080, 0x1d13: 0x0080, 0x1d14: 0x0080, 0x1d15: 0x0080, 0x1d16: 0x0080, 0x1d17: 0x0080, + 0x1d18: 0x0080, 0x1d19: 0x0080, 0x1d1a: 0x0080, 0x1d1b: 0x0080, 0x1d1c: 0x0080, 0x1d1d: 0x0080, + 0x1d1e: 0x0080, 0x1d1f: 0x0080, 0x1d20: 0x0080, 0x1d21: 0x0080, 0x1d22: 0x0080, 0x1d23: 0x0080, + 0x1d24: 0x0080, 0x1d25: 0x0080, 0x1d26: 0x0080, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0080, 0x1d41: 0x0080, 0x1d42: 0x0080, 0x1d43: 0x0080, 0x1d44: 0x0080, 0x1d45: 0x0080, + 0x1d46: 0x0080, 0x1d47: 0x0080, 0x1d48: 0x0080, 0x1d49: 0x0080, 0x1d4a: 0x0080, + 0x1d60: 0x0080, 0x1d61: 0x0080, 0x1d62: 0x0080, 0x1d63: 0x0080, + 0x1d64: 0x0080, 0x1d65: 0x0080, 0x1d66: 0x0080, 0x1d67: 0x0080, 0x1d68: 0x0080, 0x1d69: 0x0080, + 0x1d6a: 0x0080, 0x1d6b: 0x0080, 0x1d6c: 0x0080, 0x1d6d: 0x0080, 0x1d6e: 0x0080, 0x1d6f: 0x0080, + 0x1d70: 0x0080, 0x1d71: 0x0080, 0x1d72: 0x0080, 0x1d73: 0x0080, 0x1d74: 0x0080, 0x1d75: 0x0080, + 0x1d76: 0x0080, 0x1d77: 0x0080, 0x1d78: 0x0080, 0x1d79: 0x0080, 0x1d7a: 0x0080, 0x1d7b: 0x0080, + 0x1d7c: 0x0080, 0x1d7d: 0x0080, 0x1d7e: 0x0080, 0x1d7f: 0x0080, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x0080, 0x1d81: 0x0080, 0x1d82: 0x0080, 0x1d83: 0x0080, 0x1d84: 0x0080, 0x1d85: 0x0080, + 0x1d86: 0x0080, 0x1d87: 0x0080, 0x1d88: 0x0080, 0x1d89: 0x0080, 0x1d8a: 0x0080, 0x1d8b: 0x0080, + 0x1d8c: 0x0080, 0x1d8d: 0x0080, 0x1d8e: 0x0080, 0x1d8f: 0x0080, 0x1d90: 0x0080, 0x1d91: 0x0080, + 0x1d92: 0x0080, 0x1d93: 0x0080, 0x1d94: 0x0080, 0x1d95: 0x0080, 0x1d96: 0x0080, 0x1d97: 0x0080, + 0x1d98: 0x0080, 0x1d99: 0x0080, 0x1d9a: 0x0080, 0x1d9b: 0x0080, 0x1d9c: 0x0080, 0x1d9d: 0x0080, + 0x1d9e: 0x0080, 0x1d9f: 0x0080, 0x1da0: 0x0080, 0x1da1: 0x0080, 0x1da2: 0x0080, 0x1da3: 0x0080, + 0x1da4: 0x0080, 0x1da5: 0x0080, 0x1da6: 0x0080, 0x1da7: 0x0080, 0x1da8: 0x0080, 0x1da9: 0x0080, + 0x1daa: 0x0080, 0x1dab: 0x0080, 0x1dac: 0x0080, 0x1dad: 0x0080, 0x1dae: 0x0080, 0x1daf: 0x0080, + 0x1db0: 0x0080, 0x1db1: 0x0080, 0x1db2: 0x0080, 0x1db3: 0x0080, + 0x1db6: 0x0080, 0x1db7: 0x0080, 0x1db8: 0x0080, 0x1db9: 0x0080, 0x1dba: 0x0080, 0x1dbb: 0x0080, + 0x1dbc: 0x0080, 0x1dbd: 0x0080, 0x1dbe: 0x0080, 0x1dbf: 0x0080, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x0080, 0x1dc1: 0x0080, 0x1dc2: 0x0080, 0x1dc3: 0x0080, 0x1dc4: 0x0080, 0x1dc5: 0x0080, + 0x1dc6: 0x0080, 0x1dc7: 0x0080, 0x1dc8: 0x0080, 0x1dc9: 0x0080, 0x1dca: 0x0080, 0x1dcb: 0x0080, + 0x1dcc: 0x0080, 0x1dcd: 0x0080, 0x1dce: 0x0080, 0x1dcf: 0x0080, 0x1dd0: 0x0080, 0x1dd1: 0x0080, + 0x1dd2: 0x0080, 0x1dd3: 0x0080, 0x1dd4: 0x0080, 0x1dd5: 0x0080, + 0x1dd8: 0x0080, 0x1dd9: 0x0080, 0x1dda: 0x0080, 0x1ddb: 0x0080, 0x1ddc: 0x0080, 0x1ddd: 0x0080, + 0x1dde: 0x0080, 0x1ddf: 0x0080, 0x1de0: 0x0080, 0x1de1: 0x0080, 0x1de2: 0x0080, 0x1de3: 0x0080, + 0x1de4: 0x0080, 0x1de5: 0x0080, 0x1de6: 0x0080, 0x1de7: 0x0080, 0x1de8: 0x0080, 0x1de9: 0x0080, + 0x1dea: 0x0080, 0x1deb: 0x0080, 0x1dec: 0x0080, 0x1ded: 0x0080, 0x1dee: 0x0080, 0x1def: 0x0080, + 0x1df0: 0x0080, 0x1df1: 0x0080, 0x1df2: 0x0080, 0x1df3: 0x0080, 0x1df4: 0x0080, 0x1df5: 0x0080, + 0x1df6: 0x0080, 0x1df7: 0x0080, 0x1df8: 0x0080, 0x1df9: 0x0080, + 0x1dfd: 0x0080, 0x1dfe: 0x0080, 0x1dff: 0x0080, + // Block 0x78, offset 0x1e00 + 0x1e00: 0x0080, 0x1e01: 0x0080, 0x1e02: 0x0080, 0x1e03: 0x0080, 0x1e04: 0x0080, 0x1e05: 0x0080, + 0x1e06: 0x0080, 0x1e07: 0x0080, 0x1e08: 0x0080, 0x1e0a: 0x0080, 0x1e0b: 0x0080, + 0x1e0c: 0x0080, 0x1e0d: 0x0080, 0x1e0e: 0x0080, 0x1e0f: 0x0080, 0x1e10: 0x0080, 0x1e11: 0x0080, + 0x1e12: 0x0080, + 0x1e2c: 0x0080, 0x1e2d: 0x0080, 0x1e2e: 0x0080, 0x1e2f: 0x0080, + // Block 0x79, offset 0x1e40 + 0x1e40: 0x00c0, 0x1e41: 0x00c0, 0x1e42: 0x00c0, 0x1e43: 0x00c0, 0x1e44: 0x00c0, 0x1e45: 0x00c0, + 0x1e46: 0x00c0, 0x1e47: 0x00c0, 0x1e48: 0x00c0, 0x1e49: 0x00c0, 0x1e4a: 0x00c0, 0x1e4b: 0x00c0, + 0x1e4c: 0x00c0, 0x1e4d: 0x00c0, 0x1e4e: 0x00c0, 0x1e4f: 0x00c0, 0x1e50: 0x00c0, 0x1e51: 0x00c0, + 0x1e52: 0x00c0, 0x1e53: 0x00c0, 0x1e54: 0x00c0, 0x1e55: 0x00c0, 0x1e56: 0x00c0, 0x1e57: 0x00c0, + 0x1e58: 0x00c0, 0x1e59: 0x00c0, 0x1e5a: 0x00c0, 0x1e5b: 0x00c0, 0x1e5c: 0x00c0, 0x1e5d: 0x00c0, + 0x1e5e: 0x00c0, 0x1e5f: 0x00c0, 0x1e60: 0x00c0, 0x1e61: 0x00c0, 0x1e62: 0x00c0, 0x1e63: 0x00c0, + 0x1e64: 0x00c0, 0x1e65: 0x00c0, 0x1e66: 0x00c0, 0x1e67: 0x00c0, 0x1e68: 0x00c0, 0x1e69: 0x00c0, + 0x1e6a: 0x00c0, 0x1e6b: 0x00c0, 0x1e6c: 0x00c0, 0x1e6d: 0x00c0, 0x1e6e: 0x00c0, + 0x1e70: 0x00c0, 0x1e71: 0x00c0, 0x1e72: 0x00c0, 0x1e73: 0x00c0, 0x1e74: 0x00c0, 0x1e75: 0x00c0, + 0x1e76: 0x00c0, 0x1e77: 0x00c0, 0x1e78: 0x00c0, 0x1e79: 0x00c0, 0x1e7a: 0x00c0, 0x1e7b: 0x00c0, + 0x1e7c: 0x00c0, 0x1e7d: 0x00c0, 0x1e7e: 0x00c0, 0x1e7f: 0x00c0, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x00c0, 0x1e81: 0x00c0, 0x1e82: 0x00c0, 0x1e83: 0x00c0, 0x1e84: 0x00c0, 0x1e85: 0x00c0, + 0x1e86: 0x00c0, 0x1e87: 0x00c0, 0x1e88: 0x00c0, 0x1e89: 0x00c0, 0x1e8a: 0x00c0, 0x1e8b: 0x00c0, + 0x1e8c: 0x00c0, 0x1e8d: 0x00c0, 0x1e8e: 0x00c0, 0x1e8f: 0x00c0, 0x1e90: 0x00c0, 0x1e91: 0x00c0, + 0x1e92: 0x00c0, 0x1e93: 0x00c0, 0x1e94: 0x00c0, 0x1e95: 0x00c0, 0x1e96: 0x00c0, 0x1e97: 0x00c0, + 0x1e98: 0x00c0, 0x1e99: 0x00c0, 0x1e9a: 0x00c0, 0x1e9b: 0x00c0, 0x1e9c: 0x00c0, 0x1e9d: 0x00c0, + 0x1e9e: 0x00c0, 0x1ea0: 0x00c0, 0x1ea1: 0x00c0, 0x1ea2: 0x00c0, 0x1ea3: 0x00c0, + 0x1ea4: 0x00c0, 0x1ea5: 0x00c0, 0x1ea6: 0x00c0, 0x1ea7: 0x00c0, 0x1ea8: 0x00c0, 0x1ea9: 0x00c0, + 0x1eaa: 0x00c0, 0x1eab: 0x00c0, 0x1eac: 0x00c0, 0x1ead: 0x00c0, 0x1eae: 0x00c0, 0x1eaf: 0x00c0, + 0x1eb0: 0x00c0, 0x1eb1: 0x00c0, 0x1eb2: 0x00c0, 0x1eb3: 0x00c0, 0x1eb4: 0x00c0, 0x1eb5: 0x00c0, + 0x1eb6: 0x00c0, 0x1eb7: 0x00c0, 0x1eb8: 0x00c0, 0x1eb9: 0x00c0, 0x1eba: 0x00c0, 0x1ebb: 0x00c0, + 0x1ebc: 0x0080, 0x1ebd: 0x0080, 0x1ebe: 0x00c0, 0x1ebf: 0x00c0, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x00c0, 0x1ec1: 0x00c0, 0x1ec2: 0x00c0, 0x1ec3: 0x00c0, 0x1ec4: 0x00c0, 0x1ec5: 0x00c0, + 0x1ec6: 0x00c0, 0x1ec7: 0x00c0, 0x1ec8: 0x00c0, 0x1ec9: 0x00c0, 0x1eca: 0x00c0, 0x1ecb: 0x00c0, + 0x1ecc: 0x00c0, 0x1ecd: 0x00c0, 0x1ece: 0x00c0, 0x1ecf: 0x00c0, 0x1ed0: 0x00c0, 0x1ed1: 0x00c0, + 0x1ed2: 0x00c0, 0x1ed3: 0x00c0, 0x1ed4: 0x00c0, 0x1ed5: 0x00c0, 0x1ed6: 0x00c0, 0x1ed7: 0x00c0, + 0x1ed8: 0x00c0, 0x1ed9: 0x00c0, 0x1eda: 0x00c0, 0x1edb: 0x00c0, 0x1edc: 0x00c0, 0x1edd: 0x00c0, + 0x1ede: 0x00c0, 0x1edf: 0x00c0, 0x1ee0: 0x00c0, 0x1ee1: 0x00c0, 0x1ee2: 0x00c0, 0x1ee3: 0x00c0, + 0x1ee4: 0x00c0, 0x1ee5: 0x0080, 0x1ee6: 0x0080, 0x1ee7: 0x0080, 0x1ee8: 0x0080, 0x1ee9: 0x0080, + 0x1eea: 0x0080, 0x1eeb: 0x00c0, 0x1eec: 0x00c0, 0x1eed: 0x00c0, 0x1eee: 0x00c0, 0x1eef: 0x00c3, + 0x1ef0: 0x00c3, 0x1ef1: 0x00c3, 0x1ef2: 0x00c0, 0x1ef3: 0x00c0, + 0x1ef9: 0x0080, 0x1efa: 0x0080, 0x1efb: 0x0080, + 0x1efc: 0x0080, 0x1efd: 0x0080, 0x1efe: 0x0080, 0x1eff: 0x0080, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0x00c0, 0x1f01: 0x00c0, 0x1f02: 0x00c0, 0x1f03: 0x00c0, 0x1f04: 0x00c0, 0x1f05: 0x00c0, + 0x1f06: 0x00c0, 0x1f07: 0x00c0, 0x1f08: 0x00c0, 0x1f09: 0x00c0, 0x1f0a: 0x00c0, 0x1f0b: 0x00c0, + 0x1f0c: 0x00c0, 0x1f0d: 0x00c0, 0x1f0e: 0x00c0, 0x1f0f: 0x00c0, 0x1f10: 0x00c0, 0x1f11: 0x00c0, + 0x1f12: 0x00c0, 0x1f13: 0x00c0, 0x1f14: 0x00c0, 0x1f15: 0x00c0, 0x1f16: 0x00c0, 0x1f17: 0x00c0, + 0x1f18: 0x00c0, 0x1f19: 0x00c0, 0x1f1a: 0x00c0, 0x1f1b: 0x00c0, 0x1f1c: 0x00c0, 0x1f1d: 0x00c0, + 0x1f1e: 0x00c0, 0x1f1f: 0x00c0, 0x1f20: 0x00c0, 0x1f21: 0x00c0, 0x1f22: 0x00c0, 0x1f23: 0x00c0, + 0x1f24: 0x00c0, 0x1f25: 0x00c0, 0x1f27: 0x00c0, + 0x1f2d: 0x00c0, + 0x1f30: 0x00c0, 0x1f31: 0x00c0, 0x1f32: 0x00c0, 0x1f33: 0x00c0, 0x1f34: 0x00c0, 0x1f35: 0x00c0, + 0x1f36: 0x00c0, 0x1f37: 0x00c0, 0x1f38: 0x00c0, 0x1f39: 0x00c0, 0x1f3a: 0x00c0, 0x1f3b: 0x00c0, + 0x1f3c: 0x00c0, 0x1f3d: 0x00c0, 0x1f3e: 0x00c0, 0x1f3f: 0x00c0, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0x00c0, 0x1f41: 0x00c0, 0x1f42: 0x00c0, 0x1f43: 0x00c0, 0x1f44: 0x00c0, 0x1f45: 0x00c0, + 0x1f46: 0x00c0, 0x1f47: 0x00c0, 0x1f48: 0x00c0, 0x1f49: 0x00c0, 0x1f4a: 0x00c0, 0x1f4b: 0x00c0, + 0x1f4c: 0x00c0, 0x1f4d: 0x00c0, 0x1f4e: 0x00c0, 0x1f4f: 0x00c0, 0x1f50: 0x00c0, 0x1f51: 0x00c0, + 0x1f52: 0x00c0, 0x1f53: 0x00c0, 0x1f54: 0x00c0, 0x1f55: 0x00c0, 0x1f56: 0x00c0, 0x1f57: 0x00c0, + 0x1f58: 0x00c0, 0x1f59: 0x00c0, 0x1f5a: 0x00c0, 0x1f5b: 0x00c0, 0x1f5c: 0x00c0, 0x1f5d: 0x00c0, + 0x1f5e: 0x00c0, 0x1f5f: 0x00c0, 0x1f60: 0x00c0, 0x1f61: 0x00c0, 0x1f62: 0x00c0, 0x1f63: 0x00c0, + 0x1f64: 0x00c0, 0x1f65: 0x00c0, 0x1f66: 0x00c0, 0x1f67: 0x00c0, + 0x1f6f: 0x0080, + 0x1f70: 0x0080, + 0x1f7f: 0x00c6, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0x00c0, 0x1f81: 0x00c0, 0x1f82: 0x00c0, 0x1f83: 0x00c0, 0x1f84: 0x00c0, 0x1f85: 0x00c0, + 0x1f86: 0x00c0, 0x1f87: 0x00c0, 0x1f88: 0x00c0, 0x1f89: 0x00c0, 0x1f8a: 0x00c0, 0x1f8b: 0x00c0, + 0x1f8c: 0x00c0, 0x1f8d: 0x00c0, 0x1f8e: 0x00c0, 0x1f8f: 0x00c0, 0x1f90: 0x00c0, 0x1f91: 0x00c0, + 0x1f92: 0x00c0, 0x1f93: 0x00c0, 0x1f94: 0x00c0, 0x1f95: 0x00c0, 0x1f96: 0x00c0, + 0x1fa0: 0x00c0, 0x1fa1: 0x00c0, 0x1fa2: 0x00c0, 0x1fa3: 0x00c0, + 0x1fa4: 0x00c0, 0x1fa5: 0x00c0, 0x1fa6: 0x00c0, 0x1fa8: 0x00c0, 0x1fa9: 0x00c0, + 0x1faa: 0x00c0, 0x1fab: 0x00c0, 0x1fac: 0x00c0, 0x1fad: 0x00c0, 0x1fae: 0x00c0, + 0x1fb0: 0x00c0, 0x1fb1: 0x00c0, 0x1fb2: 0x00c0, 0x1fb3: 0x00c0, 0x1fb4: 0x00c0, 0x1fb5: 0x00c0, + 0x1fb6: 0x00c0, 0x1fb8: 0x00c0, 0x1fb9: 0x00c0, 0x1fba: 0x00c0, 0x1fbb: 0x00c0, + 0x1fbc: 0x00c0, 0x1fbd: 0x00c0, 0x1fbe: 0x00c0, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x00c0, 0x1fc1: 0x00c0, 0x1fc2: 0x00c0, 0x1fc3: 0x00c0, 0x1fc4: 0x00c0, 0x1fc5: 0x00c0, + 0x1fc6: 0x00c0, 0x1fc8: 0x00c0, 0x1fc9: 0x00c0, 0x1fca: 0x00c0, 0x1fcb: 0x00c0, + 0x1fcc: 0x00c0, 0x1fcd: 0x00c0, 0x1fce: 0x00c0, 0x1fd0: 0x00c0, 0x1fd1: 0x00c0, + 0x1fd2: 0x00c0, 0x1fd3: 0x00c0, 0x1fd4: 0x00c0, 0x1fd5: 0x00c0, 0x1fd6: 0x00c0, + 0x1fd8: 0x00c0, 0x1fd9: 0x00c0, 0x1fda: 0x00c0, 0x1fdb: 0x00c0, 0x1fdc: 0x00c0, 0x1fdd: 0x00c0, + 0x1fde: 0x00c0, 0x1fe0: 0x00c3, 0x1fe1: 0x00c3, 0x1fe2: 0x00c3, 0x1fe3: 0x00c3, + 0x1fe4: 0x00c3, 0x1fe5: 0x00c3, 0x1fe6: 0x00c3, 0x1fe7: 0x00c3, 0x1fe8: 0x00c3, 0x1fe9: 0x00c3, + 0x1fea: 0x00c3, 0x1feb: 0x00c3, 0x1fec: 0x00c3, 0x1fed: 0x00c3, 0x1fee: 0x00c3, 0x1fef: 0x00c3, + 0x1ff0: 0x00c3, 0x1ff1: 0x00c3, 0x1ff2: 0x00c3, 0x1ff3: 0x00c3, 0x1ff4: 0x00c3, 0x1ff5: 0x00c3, + 0x1ff6: 0x00c3, 0x1ff7: 0x00c3, 0x1ff8: 0x00c3, 0x1ff9: 0x00c3, 0x1ffa: 0x00c3, 0x1ffb: 0x00c3, + 0x1ffc: 0x00c3, 0x1ffd: 0x00c3, 0x1ffe: 0x00c3, 0x1fff: 0x00c3, + // Block 0x80, offset 0x2000 + 0x2000: 0x0080, 0x2001: 0x0080, 0x2002: 0x0080, 0x2003: 0x0080, 0x2004: 0x0080, 0x2005: 0x0080, + 0x2006: 0x0080, 0x2007: 0x0080, 0x2008: 0x0080, 0x2009: 0x0080, 0x200a: 0x0080, 0x200b: 0x0080, + 0x200c: 0x0080, 0x200d: 0x0080, 0x200e: 0x0080, 0x200f: 0x0080, 0x2010: 0x0080, 0x2011: 0x0080, + 0x2012: 0x0080, 0x2013: 0x0080, 0x2014: 0x0080, 0x2015: 0x0080, 0x2016: 0x0080, 0x2017: 0x0080, + 0x2018: 0x0080, 0x2019: 0x0080, 0x201a: 0x0080, 0x201b: 0x0080, 0x201c: 0x0080, 0x201d: 0x0080, + 0x201e: 0x0080, 0x201f: 0x0080, 0x2020: 0x0080, 0x2021: 0x0080, 0x2022: 0x0080, 0x2023: 0x0080, + 0x2024: 0x0080, 0x2025: 0x0080, 0x2026: 0x0080, 0x2027: 0x0080, 0x2028: 0x0080, 0x2029: 0x0080, + 0x202a: 0x0080, 0x202b: 0x0080, 0x202c: 0x0080, 0x202d: 0x0080, 0x202e: 0x0080, 0x202f: 0x00c0, + 0x2030: 0x0080, 0x2031: 0x0080, 0x2032: 0x0080, 0x2033: 0x0080, 0x2034: 0x0080, 0x2035: 0x0080, + 0x2036: 0x0080, 0x2037: 0x0080, 0x2038: 0x0080, 0x2039: 0x0080, 0x203a: 0x0080, 0x203b: 0x0080, + 0x203c: 0x0080, 0x203d: 0x0080, 0x203e: 0x0080, 0x203f: 0x0080, + // Block 0x81, offset 0x2040 + 0x2040: 0x0080, 0x2041: 0x0080, 0x2042: 0x0080, 0x2043: 0x0080, 0x2044: 0x0080, 0x2045: 0x0080, + 0x2046: 0x0080, 0x2047: 0x0080, 0x2048: 0x0080, 0x2049: 0x0080, + // Block 0x82, offset 0x2080 + 0x2080: 0x008c, 0x2081: 0x008c, 0x2082: 0x008c, 0x2083: 0x008c, 0x2084: 0x008c, 0x2085: 0x008c, + 0x2086: 0x008c, 0x2087: 0x008c, 0x2088: 0x008c, 0x2089: 0x008c, 0x208a: 0x008c, 0x208b: 0x008c, + 0x208c: 0x008c, 0x208d: 0x008c, 0x208e: 0x008c, 0x208f: 0x008c, 0x2090: 0x008c, 0x2091: 0x008c, + 0x2092: 0x008c, 0x2093: 0x008c, 0x2094: 0x008c, 0x2095: 0x008c, 0x2096: 0x008c, 0x2097: 0x008c, + 0x2098: 0x008c, 0x2099: 0x008c, 0x209b: 0x008c, 0x209c: 0x008c, 0x209d: 0x008c, + 0x209e: 0x008c, 0x209f: 0x008c, 0x20a0: 0x008c, 0x20a1: 0x008c, 0x20a2: 0x008c, 0x20a3: 0x008c, + 0x20a4: 0x008c, 0x20a5: 0x008c, 0x20a6: 0x008c, 0x20a7: 0x008c, 0x20a8: 0x008c, 0x20a9: 0x008c, + 0x20aa: 0x008c, 0x20ab: 0x008c, 0x20ac: 0x008c, 0x20ad: 0x008c, 0x20ae: 0x008c, 0x20af: 0x008c, + 0x20b0: 0x008c, 0x20b1: 0x008c, 0x20b2: 0x008c, 0x20b3: 0x008c, 0x20b4: 0x008c, 0x20b5: 0x008c, + 0x20b6: 0x008c, 0x20b7: 0x008c, 0x20b8: 0x008c, 0x20b9: 0x008c, 0x20ba: 0x008c, 0x20bb: 0x008c, + 0x20bc: 0x008c, 0x20bd: 0x008c, 0x20be: 0x008c, 0x20bf: 0x008c, + // Block 0x83, offset 0x20c0 + 0x20c0: 0x008c, 0x20c1: 0x008c, 0x20c2: 0x008c, 0x20c3: 0x008c, 0x20c4: 0x008c, 0x20c5: 0x008c, + 0x20c6: 0x008c, 0x20c7: 0x008c, 0x20c8: 0x008c, 0x20c9: 0x008c, 0x20ca: 0x008c, 0x20cb: 0x008c, + 0x20cc: 0x008c, 0x20cd: 0x008c, 0x20ce: 0x008c, 0x20cf: 0x008c, 0x20d0: 0x008c, 0x20d1: 0x008c, + 0x20d2: 0x008c, 0x20d3: 0x008c, 0x20d4: 0x008c, 0x20d5: 0x008c, 0x20d6: 0x008c, 0x20d7: 0x008c, + 0x20d8: 0x008c, 0x20d9: 0x008c, 0x20da: 0x008c, 0x20db: 0x008c, 0x20dc: 0x008c, 0x20dd: 0x008c, + 0x20de: 0x008c, 0x20df: 0x008c, 0x20e0: 0x008c, 0x20e1: 0x008c, 0x20e2: 0x008c, 0x20e3: 0x008c, + 0x20e4: 0x008c, 0x20e5: 0x008c, 0x20e6: 0x008c, 0x20e7: 0x008c, 0x20e8: 0x008c, 0x20e9: 0x008c, + 0x20ea: 0x008c, 0x20eb: 0x008c, 0x20ec: 0x008c, 0x20ed: 0x008c, 0x20ee: 0x008c, 0x20ef: 0x008c, + 0x20f0: 0x008c, 0x20f1: 0x008c, 0x20f2: 0x008c, 0x20f3: 0x008c, + // Block 0x84, offset 0x2100 + 0x2100: 0x008c, 0x2101: 0x008c, 0x2102: 0x008c, 0x2103: 0x008c, 0x2104: 0x008c, 0x2105: 0x008c, + 0x2106: 0x008c, 0x2107: 0x008c, 0x2108: 0x008c, 0x2109: 0x008c, 0x210a: 0x008c, 0x210b: 0x008c, + 0x210c: 0x008c, 0x210d: 0x008c, 0x210e: 0x008c, 0x210f: 0x008c, 0x2110: 0x008c, 0x2111: 0x008c, + 0x2112: 0x008c, 0x2113: 0x008c, 0x2114: 0x008c, 0x2115: 0x008c, 0x2116: 0x008c, 0x2117: 0x008c, + 0x2118: 0x008c, 0x2119: 0x008c, 0x211a: 0x008c, 0x211b: 0x008c, 0x211c: 0x008c, 0x211d: 0x008c, + 0x211e: 0x008c, 0x211f: 0x008c, 0x2120: 0x008c, 0x2121: 0x008c, 0x2122: 0x008c, 0x2123: 0x008c, + 0x2124: 0x008c, 0x2125: 0x008c, 0x2126: 0x008c, 0x2127: 0x008c, 0x2128: 0x008c, 0x2129: 0x008c, + 0x212a: 0x008c, 0x212b: 0x008c, 0x212c: 0x008c, 0x212d: 0x008c, 0x212e: 0x008c, 0x212f: 0x008c, + 0x2130: 0x008c, 0x2131: 0x008c, 0x2132: 0x008c, 0x2133: 0x008c, 0x2134: 0x008c, 0x2135: 0x008c, + 0x2136: 0x008c, 0x2137: 0x008c, 0x2138: 0x008c, 0x2139: 0x008c, 0x213a: 0x008c, 0x213b: 0x008c, + 0x213c: 0x008c, 0x213d: 0x008c, 0x213e: 0x008c, 0x213f: 0x008c, + // Block 0x85, offset 0x2140 + 0x2140: 0x008c, 0x2141: 0x008c, 0x2142: 0x008c, 0x2143: 0x008c, 0x2144: 0x008c, 0x2145: 0x008c, + 0x2146: 0x008c, 0x2147: 0x008c, 0x2148: 0x008c, 0x2149: 0x008c, 0x214a: 0x008c, 0x214b: 0x008c, + 0x214c: 0x008c, 0x214d: 0x008c, 0x214e: 0x008c, 0x214f: 0x008c, 0x2150: 0x008c, 0x2151: 0x008c, + 0x2152: 0x008c, 0x2153: 0x008c, 0x2154: 0x008c, 0x2155: 0x008c, + 0x2170: 0x0080, 0x2171: 0x0080, 0x2172: 0x0080, 0x2173: 0x0080, 0x2174: 0x0080, 0x2175: 0x0080, + 0x2176: 0x0080, 0x2177: 0x0080, 0x2178: 0x0080, 0x2179: 0x0080, 0x217a: 0x0080, 0x217b: 0x0080, + // Block 0x86, offset 0x2180 + 0x2180: 0x0080, 0x2181: 0x0080, 0x2182: 0x0080, 0x2183: 0x0080, 0x2184: 0x0080, 0x2185: 0x00cc, + 0x2186: 0x00c0, 0x2187: 0x00cc, 0x2188: 0x0080, 0x2189: 0x0080, 0x218a: 0x0080, 0x218b: 0x0080, + 0x218c: 0x0080, 0x218d: 0x0080, 0x218e: 0x0080, 0x218f: 0x0080, 0x2190: 0x0080, 0x2191: 0x0080, + 0x2192: 0x0080, 0x2193: 0x0080, 0x2194: 0x0080, 0x2195: 0x0080, 0x2196: 0x0080, 0x2197: 0x0080, + 0x2198: 0x0080, 0x2199: 0x0080, 0x219a: 0x0080, 0x219b: 0x0080, 0x219c: 0x0080, 0x219d: 0x0080, + 0x219e: 0x0080, 0x219f: 0x0080, 0x21a0: 0x0080, 0x21a1: 0x008c, 0x21a2: 0x008c, 0x21a3: 0x008c, + 0x21a4: 0x008c, 0x21a5: 0x008c, 0x21a6: 0x008c, 0x21a7: 0x008c, 0x21a8: 0x008c, 0x21a9: 0x008c, + 0x21aa: 0x00c3, 0x21ab: 0x00c3, 0x21ac: 0x00c3, 0x21ad: 0x00c3, 0x21ae: 0x0040, 0x21af: 0x0040, + 0x21b0: 0x0080, 0x21b1: 0x0040, 0x21b2: 0x0040, 0x21b3: 0x0040, 0x21b4: 0x0040, 0x21b5: 0x0040, + 0x21b6: 0x0080, 0x21b7: 0x0080, 0x21b8: 0x008c, 0x21b9: 0x008c, 0x21ba: 0x008c, 0x21bb: 0x0040, + 0x21bc: 0x00c0, 0x21bd: 0x0080, 0x21be: 0x0080, 0x21bf: 0x0080, + // Block 0x87, offset 0x21c0 + 0x21c1: 0x00cc, 0x21c2: 0x00cc, 0x21c3: 0x00cc, 0x21c4: 0x00cc, 0x21c5: 0x00cc, + 0x21c6: 0x00cc, 0x21c7: 0x00cc, 0x21c8: 0x00cc, 0x21c9: 0x00cc, 0x21ca: 0x00cc, 0x21cb: 0x00cc, + 0x21cc: 0x00cc, 0x21cd: 0x00cc, 0x21ce: 0x00cc, 0x21cf: 0x00cc, 0x21d0: 0x00cc, 0x21d1: 0x00cc, + 0x21d2: 0x00cc, 0x21d3: 0x00cc, 0x21d4: 0x00cc, 0x21d5: 0x00cc, 0x21d6: 0x00cc, 0x21d7: 0x00cc, + 0x21d8: 0x00cc, 0x21d9: 0x00cc, 0x21da: 0x00cc, 0x21db: 0x00cc, 0x21dc: 0x00cc, 0x21dd: 0x00cc, + 0x21de: 0x00cc, 0x21df: 0x00cc, 0x21e0: 0x00cc, 0x21e1: 0x00cc, 0x21e2: 0x00cc, 0x21e3: 0x00cc, + 0x21e4: 0x00cc, 0x21e5: 0x00cc, 0x21e6: 0x00cc, 0x21e7: 0x00cc, 0x21e8: 0x00cc, 0x21e9: 0x00cc, + 0x21ea: 0x00cc, 0x21eb: 0x00cc, 0x21ec: 0x00cc, 0x21ed: 0x00cc, 0x21ee: 0x00cc, 0x21ef: 0x00cc, + 0x21f0: 0x00cc, 0x21f1: 0x00cc, 0x21f2: 0x00cc, 0x21f3: 0x00cc, 0x21f4: 0x00cc, 0x21f5: 0x00cc, + 0x21f6: 0x00cc, 0x21f7: 0x00cc, 0x21f8: 0x00cc, 0x21f9: 0x00cc, 0x21fa: 0x00cc, 0x21fb: 0x00cc, + 0x21fc: 0x00cc, 0x21fd: 0x00cc, 0x21fe: 0x00cc, 0x21ff: 0x00cc, + // Block 0x88, offset 0x2200 + 0x2200: 0x00cc, 0x2201: 0x00cc, 0x2202: 0x00cc, 0x2203: 0x00cc, 0x2204: 0x00cc, 0x2205: 0x00cc, + 0x2206: 0x00cc, 0x2207: 0x00cc, 0x2208: 0x00cc, 0x2209: 0x00cc, 0x220a: 0x00cc, 0x220b: 0x00cc, + 0x220c: 0x00cc, 0x220d: 0x00cc, 0x220e: 0x00cc, 0x220f: 0x00cc, 0x2210: 0x00cc, 0x2211: 0x00cc, + 0x2212: 0x00cc, 0x2213: 0x00cc, 0x2214: 0x00cc, 0x2215: 0x00cc, 0x2216: 0x00cc, + 0x2219: 0x00c3, 0x221a: 0x00c3, 0x221b: 0x0080, 0x221c: 0x0080, 0x221d: 0x00cc, + 0x221e: 0x00cc, 0x221f: 0x008c, 0x2220: 0x0080, 0x2221: 0x00cc, 0x2222: 0x00cc, 0x2223: 0x00cc, + 0x2224: 0x00cc, 0x2225: 0x00cc, 0x2226: 0x00cc, 0x2227: 0x00cc, 0x2228: 0x00cc, 0x2229: 0x00cc, + 0x222a: 0x00cc, 0x222b: 0x00cc, 0x222c: 0x00cc, 0x222d: 0x00cc, 0x222e: 0x00cc, 0x222f: 0x00cc, + 0x2230: 0x00cc, 0x2231: 0x00cc, 0x2232: 0x00cc, 0x2233: 0x00cc, 0x2234: 0x00cc, 0x2235: 0x00cc, + 0x2236: 0x00cc, 0x2237: 0x00cc, 0x2238: 0x00cc, 0x2239: 0x00cc, 0x223a: 0x00cc, 0x223b: 0x00cc, + 0x223c: 0x00cc, 0x223d: 0x00cc, 0x223e: 0x00cc, 0x223f: 0x00cc, + // Block 0x89, offset 0x2240 + 0x2240: 0x00cc, 0x2241: 0x00cc, 0x2242: 0x00cc, 0x2243: 0x00cc, 0x2244: 0x00cc, 0x2245: 0x00cc, + 0x2246: 0x00cc, 0x2247: 0x00cc, 0x2248: 0x00cc, 0x2249: 0x00cc, 0x224a: 0x00cc, 0x224b: 0x00cc, + 0x224c: 0x00cc, 0x224d: 0x00cc, 0x224e: 0x00cc, 0x224f: 0x00cc, 0x2250: 0x00cc, 0x2251: 0x00cc, + 0x2252: 0x00cc, 0x2253: 0x00cc, 0x2254: 0x00cc, 0x2255: 0x00cc, 0x2256: 0x00cc, 0x2257: 0x00cc, + 0x2258: 0x00cc, 0x2259: 0x00cc, 0x225a: 0x00cc, 0x225b: 0x00cc, 0x225c: 0x00cc, 0x225d: 0x00cc, + 0x225e: 0x00cc, 0x225f: 0x00cc, 0x2260: 0x00cc, 0x2261: 0x00cc, 0x2262: 0x00cc, 0x2263: 0x00cc, + 0x2264: 0x00cc, 0x2265: 0x00cc, 0x2266: 0x00cc, 0x2267: 0x00cc, 0x2268: 0x00cc, 0x2269: 0x00cc, + 0x226a: 0x00cc, 0x226b: 0x00cc, 0x226c: 0x00cc, 0x226d: 0x00cc, 0x226e: 0x00cc, 0x226f: 0x00cc, + 0x2270: 0x00cc, 0x2271: 0x00cc, 0x2272: 0x00cc, 0x2273: 0x00cc, 0x2274: 0x00cc, 0x2275: 0x00cc, + 0x2276: 0x00cc, 0x2277: 0x00cc, 0x2278: 0x00cc, 0x2279: 0x00cc, 0x227a: 0x00cc, 0x227b: 0x00d2, + 0x227c: 0x00c0, 0x227d: 0x00cc, 0x227e: 0x00cc, 0x227f: 0x008c, + // Block 0x8a, offset 0x2280 + 0x2285: 0x00c0, + 0x2286: 0x00c0, 0x2287: 0x00c0, 0x2288: 0x00c0, 0x2289: 0x00c0, 0x228a: 0x00c0, 0x228b: 0x00c0, + 0x228c: 0x00c0, 0x228d: 0x00c0, 0x228e: 0x00c0, 0x228f: 0x00c0, 0x2290: 0x00c0, 0x2291: 0x00c0, + 0x2292: 0x00c0, 0x2293: 0x00c0, 0x2294: 0x00c0, 0x2295: 0x00c0, 0x2296: 0x00c0, 0x2297: 0x00c0, + 0x2298: 0x00c0, 0x2299: 0x00c0, 0x229a: 0x00c0, 0x229b: 0x00c0, 0x229c: 0x00c0, 0x229d: 0x00c0, + 0x229e: 0x00c0, 0x229f: 0x00c0, 0x22a0: 0x00c0, 0x22a1: 0x00c0, 0x22a2: 0x00c0, 0x22a3: 0x00c0, + 0x22a4: 0x00c0, 0x22a5: 0x00c0, 0x22a6: 0x00c0, 0x22a7: 0x00c0, 0x22a8: 0x00c0, 0x22a9: 0x00c0, + 0x22aa: 0x00c0, 0x22ab: 0x00c0, 0x22ac: 0x00c0, 0x22ad: 0x00c0, 0x22ae: 0x00c0, + 0x22b1: 0x0080, 0x22b2: 0x0080, 0x22b3: 0x0080, 0x22b4: 0x0080, 0x22b5: 0x0080, + 0x22b6: 0x0080, 0x22b7: 0x0080, 0x22b8: 0x0080, 0x22b9: 0x0080, 0x22ba: 0x0080, 0x22bb: 0x0080, + 0x22bc: 0x0080, 0x22bd: 0x0080, 0x22be: 0x0080, 0x22bf: 0x0080, + // Block 0x8b, offset 0x22c0 + 0x22c0: 0x0080, 0x22c1: 0x0080, 0x22c2: 0x0080, 0x22c3: 0x0080, 0x22c4: 0x0080, 0x22c5: 0x0080, + 0x22c6: 0x0080, 0x22c7: 0x0080, 0x22c8: 0x0080, 0x22c9: 0x0080, 0x22ca: 0x0080, 0x22cb: 0x0080, + 0x22cc: 0x0080, 0x22cd: 0x0080, 0x22ce: 0x0080, 0x22cf: 0x0080, 0x22d0: 0x0080, 0x22d1: 0x0080, + 0x22d2: 0x0080, 0x22d3: 0x0080, 0x22d4: 0x0080, 0x22d5: 0x0080, 0x22d6: 0x0080, 0x22d7: 0x0080, + 0x22d8: 0x0080, 0x22d9: 0x0080, 0x22da: 0x0080, 0x22db: 0x0080, 0x22dc: 0x0080, 0x22dd: 0x0080, + 0x22de: 0x0080, 0x22df: 0x0080, 0x22e0: 0x0080, 0x22e1: 0x0080, 0x22e2: 0x0080, 0x22e3: 0x0080, + 0x22e4: 0x0040, 0x22e5: 0x0080, 0x22e6: 0x0080, 0x22e7: 0x0080, 0x22e8: 0x0080, 0x22e9: 0x0080, + 0x22ea: 0x0080, 0x22eb: 0x0080, 0x22ec: 0x0080, 0x22ed: 0x0080, 0x22ee: 0x0080, 0x22ef: 0x0080, + 0x22f0: 0x0080, 0x22f1: 0x0080, 0x22f2: 0x0080, 0x22f3: 0x0080, 0x22f4: 0x0080, 0x22f5: 0x0080, + 0x22f6: 0x0080, 0x22f7: 0x0080, 0x22f8: 0x0080, 0x22f9: 0x0080, 0x22fa: 0x0080, 0x22fb: 0x0080, + 0x22fc: 0x0080, 0x22fd: 0x0080, 0x22fe: 0x0080, 0x22ff: 0x0080, + // Block 0x8c, offset 0x2300 + 0x2300: 0x0080, 0x2301: 0x0080, 0x2302: 0x0080, 0x2303: 0x0080, 0x2304: 0x0080, 0x2305: 0x0080, + 0x2306: 0x0080, 0x2307: 0x0080, 0x2308: 0x0080, 0x2309: 0x0080, 0x230a: 0x0080, 0x230b: 0x0080, + 0x230c: 0x0080, 0x230d: 0x0080, 0x230e: 0x0080, 0x2310: 0x0080, 0x2311: 0x0080, + 0x2312: 0x0080, 0x2313: 0x0080, 0x2314: 0x0080, 0x2315: 0x0080, 0x2316: 0x0080, 0x2317: 0x0080, + 0x2318: 0x0080, 0x2319: 0x0080, 0x231a: 0x0080, 0x231b: 0x0080, 0x231c: 0x0080, 0x231d: 0x0080, + 0x231e: 0x0080, 0x231f: 0x0080, 0x2320: 0x00c0, 0x2321: 0x00c0, 0x2322: 0x00c0, 0x2323: 0x00c0, + 0x2324: 0x00c0, 0x2325: 0x00c0, 0x2326: 0x00c0, 0x2327: 0x00c0, 0x2328: 0x00c0, 0x2329: 0x00c0, + 0x232a: 0x00c0, 0x232b: 0x00c0, 0x232c: 0x00c0, 0x232d: 0x00c0, 0x232e: 0x00c0, 0x232f: 0x00c0, + 0x2330: 0x00c0, 0x2331: 0x00c0, 0x2332: 0x00c0, 0x2333: 0x00c0, 0x2334: 0x00c0, 0x2335: 0x00c0, + 0x2336: 0x00c0, 0x2337: 0x00c0, 0x2338: 0x00c0, 0x2339: 0x00c0, 0x233a: 0x00c0, + // Block 0x8d, offset 0x2340 + 0x2340: 0x0080, 0x2341: 0x0080, 0x2342: 0x0080, 0x2343: 0x0080, 0x2344: 0x0080, 0x2345: 0x0080, + 0x2346: 0x0080, 0x2347: 0x0080, 0x2348: 0x0080, 0x2349: 0x0080, 0x234a: 0x0080, 0x234b: 0x0080, + 0x234c: 0x0080, 0x234d: 0x0080, 0x234e: 0x0080, 0x234f: 0x0080, 0x2350: 0x0080, 0x2351: 0x0080, + 0x2352: 0x0080, 0x2353: 0x0080, 0x2354: 0x0080, 0x2355: 0x0080, 0x2356: 0x0080, 0x2357: 0x0080, + 0x2358: 0x0080, 0x2359: 0x0080, 0x235a: 0x0080, 0x235b: 0x0080, 0x235c: 0x0080, 0x235d: 0x0080, + 0x235e: 0x0080, 0x235f: 0x0080, 0x2360: 0x0080, 0x2361: 0x0080, 0x2362: 0x0080, 0x2363: 0x0080, + 0x2370: 0x00cc, 0x2371: 0x00cc, 0x2372: 0x00cc, 0x2373: 0x00cc, 0x2374: 0x00cc, 0x2375: 0x00cc, + 0x2376: 0x00cc, 0x2377: 0x00cc, 0x2378: 0x00cc, 0x2379: 0x00cc, 0x237a: 0x00cc, 0x237b: 0x00cc, + 0x237c: 0x00cc, 0x237d: 0x00cc, 0x237e: 0x00cc, 0x237f: 0x00cc, + // Block 0x8e, offset 0x2380 + 0x2380: 0x0080, 0x2381: 0x0080, 0x2382: 0x0080, 0x2383: 0x0080, 0x2384: 0x0080, 0x2385: 0x0080, + 0x2386: 0x0080, 0x2387: 0x0080, 0x2388: 0x0080, 0x2389: 0x0080, 0x238a: 0x0080, 0x238b: 0x0080, + 0x238c: 0x0080, 0x238d: 0x0080, 0x238e: 0x0080, 0x238f: 0x0080, 0x2390: 0x0080, 0x2391: 0x0080, + 0x2392: 0x0080, 0x2393: 0x0080, 0x2394: 0x0080, 0x2395: 0x0080, 0x2396: 0x0080, 0x2397: 0x0080, + 0x2398: 0x0080, 0x2399: 0x0080, 0x239a: 0x0080, 0x239b: 0x0080, 0x239c: 0x0080, 0x239d: 0x0080, + 0x239e: 0x0080, 0x23a0: 0x0080, 0x23a1: 0x0080, 0x23a2: 0x0080, 0x23a3: 0x0080, + 0x23a4: 0x0080, 0x23a5: 0x0080, 0x23a6: 0x0080, 0x23a7: 0x0080, 0x23a8: 0x0080, 0x23a9: 0x0080, + 0x23aa: 0x0080, 0x23ab: 0x0080, 0x23ac: 0x0080, 0x23ad: 0x0080, 0x23ae: 0x0080, 0x23af: 0x0080, + 0x23b0: 0x0080, 0x23b1: 0x0080, 0x23b2: 0x0080, 0x23b3: 0x0080, 0x23b4: 0x0080, 0x23b5: 0x0080, + 0x23b6: 0x0080, 0x23b7: 0x0080, 0x23b8: 0x0080, 0x23b9: 0x0080, 0x23ba: 0x0080, 0x23bb: 0x0080, + 0x23bc: 0x0080, 0x23bd: 0x0080, 0x23be: 0x0080, 0x23bf: 0x0080, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x0080, 0x23c1: 0x0080, 0x23c2: 0x0080, 0x23c3: 0x0080, 0x23c4: 0x0080, 0x23c5: 0x0080, + 0x23c6: 0x0080, 0x23c7: 0x0080, 0x23c8: 0x0080, 0x23c9: 0x0080, 0x23ca: 0x0080, 0x23cb: 0x0080, + 0x23cc: 0x0080, 0x23cd: 0x0080, 0x23ce: 0x0080, 0x23cf: 0x0080, 0x23d0: 0x008c, 0x23d1: 0x008c, + 0x23d2: 0x008c, 0x23d3: 0x008c, 0x23d4: 0x008c, 0x23d5: 0x008c, 0x23d6: 0x008c, 0x23d7: 0x008c, + 0x23d8: 0x008c, 0x23d9: 0x008c, 0x23da: 0x008c, 0x23db: 0x008c, 0x23dc: 0x008c, 0x23dd: 0x008c, + 0x23de: 0x008c, 0x23df: 0x008c, 0x23e0: 0x008c, 0x23e1: 0x008c, 0x23e2: 0x008c, 0x23e3: 0x008c, + 0x23e4: 0x008c, 0x23e5: 0x008c, 0x23e6: 0x008c, 0x23e7: 0x008c, 0x23e8: 0x008c, 0x23e9: 0x008c, + 0x23ea: 0x008c, 0x23eb: 0x008c, 0x23ec: 0x008c, 0x23ed: 0x008c, 0x23ee: 0x008c, 0x23ef: 0x008c, + 0x23f0: 0x008c, 0x23f1: 0x008c, 0x23f2: 0x008c, 0x23f3: 0x008c, 0x23f4: 0x008c, 0x23f5: 0x008c, + 0x23f6: 0x008c, 0x23f7: 0x008c, 0x23f8: 0x008c, 0x23f9: 0x008c, 0x23fa: 0x008c, 0x23fb: 0x008c, + 0x23fc: 0x008c, 0x23fd: 0x008c, 0x23fe: 0x008c, + // Block 0x90, offset 0x2400 + 0x2400: 0x008c, 0x2401: 0x008c, 0x2402: 0x008c, 0x2403: 0x008c, 0x2404: 0x008c, 0x2405: 0x008c, + 0x2406: 0x008c, 0x2407: 0x008c, 0x2408: 0x008c, 0x2409: 0x008c, 0x240a: 0x008c, 0x240b: 0x008c, + 0x240c: 0x008c, 0x240d: 0x008c, 0x240e: 0x008c, 0x240f: 0x008c, 0x2410: 0x008c, 0x2411: 0x008c, + 0x2412: 0x008c, 0x2413: 0x008c, 0x2414: 0x008c, 0x2415: 0x008c, 0x2416: 0x008c, 0x2417: 0x008c, + 0x2418: 0x0080, 0x2419: 0x0080, 0x241a: 0x0080, 0x241b: 0x0080, 0x241c: 0x0080, 0x241d: 0x0080, + 0x241e: 0x0080, 0x241f: 0x0080, 0x2420: 0x0080, 0x2421: 0x0080, 0x2422: 0x0080, 0x2423: 0x0080, + 0x2424: 0x0080, 0x2425: 0x0080, 0x2426: 0x0080, 0x2427: 0x0080, 0x2428: 0x0080, 0x2429: 0x0080, + 0x242a: 0x0080, 0x242b: 0x0080, 0x242c: 0x0080, 0x242d: 0x0080, 0x242e: 0x0080, 0x242f: 0x0080, + 0x2430: 0x0080, 0x2431: 0x0080, 0x2432: 0x0080, 0x2433: 0x0080, 0x2434: 0x0080, 0x2435: 0x0080, + 0x2436: 0x0080, 0x2437: 0x0080, 0x2438: 0x0080, 0x2439: 0x0080, 0x243a: 0x0080, 0x243b: 0x0080, + 0x243c: 0x0080, 0x243d: 0x0080, 0x243e: 0x0080, 0x243f: 0x0080, + // Block 0x91, offset 0x2440 + 0x2440: 0x00cc, 0x2441: 0x00cc, 0x2442: 0x00cc, 0x2443: 0x00cc, 0x2444: 0x00cc, 0x2445: 0x00cc, + 0x2446: 0x00cc, 0x2447: 0x00cc, 0x2448: 0x00cc, 0x2449: 0x00cc, 0x244a: 0x00cc, 0x244b: 0x00cc, + 0x244c: 0x00cc, 0x244d: 0x00cc, 0x244e: 0x00cc, 0x244f: 0x00cc, 0x2450: 0x00cc, 0x2451: 0x00cc, + 0x2452: 0x00cc, 0x2453: 0x00cc, 0x2454: 0x00cc, 0x2455: 0x00cc, 0x2456: 0x00cc, 0x2457: 0x00cc, + 0x2458: 0x00cc, 0x2459: 0x00cc, 0x245a: 0x00cc, 0x245b: 0x00cc, 0x245c: 0x00cc, 0x245d: 0x00cc, + 0x245e: 0x00cc, 0x245f: 0x00cc, 0x2460: 0x00cc, 0x2461: 0x00cc, 0x2462: 0x00cc, 0x2463: 0x00cc, + 0x2464: 0x00cc, 0x2465: 0x00cc, 0x2466: 0x00cc, 0x2467: 0x00cc, 0x2468: 0x00cc, 0x2469: 0x00cc, + 0x246a: 0x00cc, 0x246b: 0x00cc, 0x246c: 0x00cc, 0x246d: 0x00cc, 0x246e: 0x00cc, 0x246f: 0x00cc, + 0x2470: 0x00cc, 0x2471: 0x00cc, 0x2472: 0x00cc, 0x2473: 0x00cc, 0x2474: 0x00cc, 0x2475: 0x00cc, + 0x2476: 0x00cc, 0x2477: 0x00cc, 0x2478: 0x00cc, 0x2479: 0x00cc, 0x247a: 0x00cc, 0x247b: 0x00cc, + 0x247c: 0x00cc, 0x247d: 0x00cc, 0x247e: 0x00cc, 0x247f: 0x00cc, + // Block 0x92, offset 0x2480 + 0x2480: 0x00cc, 0x2481: 0x00cc, 0x2482: 0x00cc, 0x2483: 0x00cc, 0x2484: 0x00cc, 0x2485: 0x00cc, + 0x2486: 0x00cc, 0x2487: 0x00cc, 0x2488: 0x00cc, 0x2489: 0x00cc, 0x248a: 0x00cc, 0x248b: 0x00cc, + 0x248c: 0x00cc, 0x248d: 0x00cc, 0x248e: 0x00cc, 0x248f: 0x00cc, 0x2490: 0x00cc, 0x2491: 0x00cc, + 0x2492: 0x00cc, 0x2493: 0x00cc, 0x2494: 0x00cc, 0x2495: 0x00cc, 0x2496: 0x00cc, 0x2497: 0x00cc, + 0x2498: 0x00cc, 0x2499: 0x00cc, 0x249a: 0x00cc, 0x249b: 0x00cc, 0x249c: 0x00cc, 0x249d: 0x00cc, + 0x249e: 0x00cc, 0x249f: 0x00cc, 0x24a0: 0x00cc, 0x24a1: 0x00cc, 0x24a2: 0x00cc, 0x24a3: 0x00cc, + 0x24a4: 0x00cc, 0x24a5: 0x00cc, 0x24a6: 0x00cc, 0x24a7: 0x00cc, 0x24a8: 0x00cc, 0x24a9: 0x00cc, + 0x24aa: 0x00cc, 0x24ab: 0x00cc, 0x24ac: 0x00cc, 0x24ad: 0x00cc, 0x24ae: 0x00cc, 0x24af: 0x00cc, + 0x24b0: 0x00cc, 0x24b1: 0x00cc, 0x24b2: 0x00cc, 0x24b3: 0x00cc, 0x24b4: 0x00cc, 0x24b5: 0x00cc, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x00cc, 0x24c1: 0x00cc, 0x24c2: 0x00cc, 0x24c3: 0x00cc, 0x24c4: 0x00cc, 0x24c5: 0x00cc, + 0x24c6: 0x00cc, 0x24c7: 0x00cc, 0x24c8: 0x00cc, 0x24c9: 0x00cc, 0x24ca: 0x00cc, 0x24cb: 0x00cc, + 0x24cc: 0x00cc, 0x24cd: 0x00cc, 0x24ce: 0x00cc, 0x24cf: 0x00cc, 0x24d0: 0x00cc, 0x24d1: 0x00cc, + 0x24d2: 0x00cc, 0x24d3: 0x00cc, 0x24d4: 0x00cc, 0x24d5: 0x00cc, 0x24d6: 0x00cc, 0x24d7: 0x00cc, + 0x24d8: 0x00cc, 0x24d9: 0x00cc, 0x24da: 0x00cc, 0x24db: 0x00cc, 0x24dc: 0x00cc, 0x24dd: 0x00cc, + 0x24de: 0x00cc, 0x24df: 0x00cc, 0x24e0: 0x00cc, 0x24e1: 0x00cc, 0x24e2: 0x00cc, 0x24e3: 0x00cc, + 0x24e4: 0x00cc, 0x24e5: 0x00cc, 0x24e6: 0x00cc, 0x24e7: 0x00cc, 0x24e8: 0x00cc, 0x24e9: 0x00cc, + 0x24ea: 0x00cc, + // Block 0x94, offset 0x2500 + 0x2500: 0x00c0, 0x2501: 0x00c0, 0x2502: 0x00c0, 0x2503: 0x00c0, 0x2504: 0x00c0, 0x2505: 0x00c0, + 0x2506: 0x00c0, 0x2507: 0x00c0, 0x2508: 0x00c0, 0x2509: 0x00c0, 0x250a: 0x00c0, 0x250b: 0x00c0, + 0x250c: 0x00c0, 0x2510: 0x0080, 0x2511: 0x0080, + 0x2512: 0x0080, 0x2513: 0x0080, 0x2514: 0x0080, 0x2515: 0x0080, 0x2516: 0x0080, 0x2517: 0x0080, + 0x2518: 0x0080, 0x2519: 0x0080, 0x251a: 0x0080, 0x251b: 0x0080, 0x251c: 0x0080, 0x251d: 0x0080, + 0x251e: 0x0080, 0x251f: 0x0080, 0x2520: 0x0080, 0x2521: 0x0080, 0x2522: 0x0080, 0x2523: 0x0080, + 0x2524: 0x0080, 0x2525: 0x0080, 0x2526: 0x0080, 0x2527: 0x0080, 0x2528: 0x0080, 0x2529: 0x0080, + 0x252a: 0x0080, 0x252b: 0x0080, 0x252c: 0x0080, 0x252d: 0x0080, 0x252e: 0x0080, 0x252f: 0x0080, + 0x2530: 0x0080, 0x2531: 0x0080, 0x2532: 0x0080, 0x2533: 0x0080, 0x2534: 0x0080, 0x2535: 0x0080, + 0x2536: 0x0080, 0x2537: 0x0080, 0x2538: 0x0080, 0x2539: 0x0080, 0x253a: 0x0080, 0x253b: 0x0080, + 0x253c: 0x0080, 0x253d: 0x0080, 0x253e: 0x0080, 0x253f: 0x0080, + // Block 0x95, offset 0x2540 + 0x2540: 0x0080, 0x2541: 0x0080, 0x2542: 0x0080, 0x2543: 0x0080, 0x2544: 0x0080, 0x2545: 0x0080, + 0x2546: 0x0080, + 0x2550: 0x00c0, 0x2551: 0x00c0, + 0x2552: 0x00c0, 0x2553: 0x00c0, 0x2554: 0x00c0, 0x2555: 0x00c0, 0x2556: 0x00c0, 0x2557: 0x00c0, + 0x2558: 0x00c0, 0x2559: 0x00c0, 0x255a: 0x00c0, 0x255b: 0x00c0, 0x255c: 0x00c0, 0x255d: 0x00c0, + 0x255e: 0x00c0, 0x255f: 0x00c0, 0x2560: 0x00c0, 0x2561: 0x00c0, 0x2562: 0x00c0, 0x2563: 0x00c0, + 0x2564: 0x00c0, 0x2565: 0x00c0, 0x2566: 0x00c0, 0x2567: 0x00c0, 0x2568: 0x00c0, 0x2569: 0x00c0, + 0x256a: 0x00c0, 0x256b: 0x00c0, 0x256c: 0x00c0, 0x256d: 0x00c0, 0x256e: 0x00c0, 0x256f: 0x00c0, + 0x2570: 0x00c0, 0x2571: 0x00c0, 0x2572: 0x00c0, 0x2573: 0x00c0, 0x2574: 0x00c0, 0x2575: 0x00c0, + 0x2576: 0x00c0, 0x2577: 0x00c0, 0x2578: 0x00c0, 0x2579: 0x00c0, 0x257a: 0x00c0, 0x257b: 0x00c0, + 0x257c: 0x00c0, 0x257d: 0x00c0, 0x257e: 0x0080, 0x257f: 0x0080, + // Block 0x96, offset 0x2580 + 0x2580: 0x00c0, 0x2581: 0x00c0, 0x2582: 0x00c0, 0x2583: 0x00c0, 0x2584: 0x00c0, 0x2585: 0x00c0, + 0x2586: 0x00c0, 0x2587: 0x00c0, 0x2588: 0x00c0, 0x2589: 0x00c0, 0x258a: 0x00c0, 0x258b: 0x00c0, + 0x258c: 0x00c0, 0x258d: 0x0080, 0x258e: 0x0080, 0x258f: 0x0080, 0x2590: 0x00c0, 0x2591: 0x00c0, + 0x2592: 0x00c0, 0x2593: 0x00c0, 0x2594: 0x00c0, 0x2595: 0x00c0, 0x2596: 0x00c0, 0x2597: 0x00c0, + 0x2598: 0x00c0, 0x2599: 0x00c0, 0x259a: 0x00c0, 0x259b: 0x00c0, 0x259c: 0x00c0, 0x259d: 0x00c0, + 0x259e: 0x00c0, 0x259f: 0x00c0, 0x25a0: 0x00c0, 0x25a1: 0x00c0, 0x25a2: 0x00c0, 0x25a3: 0x00c0, + 0x25a4: 0x00c0, 0x25a5: 0x00c0, 0x25a6: 0x00c0, 0x25a7: 0x00c0, 0x25a8: 0x00c0, 0x25a9: 0x00c0, + 0x25aa: 0x00c0, 0x25ab: 0x00c0, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x00c0, 0x25c1: 0x00c0, 0x25c2: 0x00c0, 0x25c3: 0x00c0, 0x25c4: 0x00c0, 0x25c5: 0x00c0, + 0x25c6: 0x00c0, 0x25c7: 0x00c0, 0x25c8: 0x00c0, 0x25c9: 0x00c0, 0x25ca: 0x00c0, 0x25cb: 0x00c0, + 0x25cc: 0x00c0, 0x25cd: 0x00c0, 0x25ce: 0x00c0, 0x25cf: 0x00c0, 0x25d0: 0x00c0, 0x25d1: 0x00c0, + 0x25d2: 0x00c0, 0x25d3: 0x00c0, 0x25d4: 0x00c0, 0x25d5: 0x00c0, 0x25d6: 0x00c0, 0x25d7: 0x00c0, + 0x25d8: 0x00c0, 0x25d9: 0x00c0, 0x25da: 0x00c0, 0x25db: 0x00c0, 0x25dc: 0x00c0, 0x25dd: 0x00c0, + 0x25de: 0x00c0, 0x25df: 0x00c0, 0x25e0: 0x00c0, 0x25e1: 0x00c0, 0x25e2: 0x00c0, 0x25e3: 0x00c0, + 0x25e4: 0x00c0, 0x25e5: 0x00c0, 0x25e6: 0x00c0, 0x25e7: 0x00c0, 0x25e8: 0x00c0, 0x25e9: 0x00c0, + 0x25ea: 0x00c0, 0x25eb: 0x00c0, 0x25ec: 0x00c0, 0x25ed: 0x00c0, 0x25ee: 0x00c0, 0x25ef: 0x00c3, + 0x25f0: 0x0083, 0x25f1: 0x0083, 0x25f2: 0x0083, 0x25f3: 0x0080, 0x25f4: 0x00c3, 0x25f5: 0x00c3, + 0x25f6: 0x00c3, 0x25f7: 0x00c3, 0x25f8: 0x00c3, 0x25f9: 0x00c3, 0x25fa: 0x00c3, 0x25fb: 0x00c3, + 0x25fc: 0x00c3, 0x25fd: 0x00c3, 0x25fe: 0x0080, 0x25ff: 0x00c0, + // Block 0x98, offset 0x2600 + 0x2600: 0x00c0, 0x2601: 0x00c0, 0x2602: 0x00c0, 0x2603: 0x00c0, 0x2604: 0x00c0, 0x2605: 0x00c0, + 0x2606: 0x00c0, 0x2607: 0x00c0, 0x2608: 0x00c0, 0x2609: 0x00c0, 0x260a: 0x00c0, 0x260b: 0x00c0, + 0x260c: 0x00c0, 0x260d: 0x00c0, 0x260e: 0x00c0, 0x260f: 0x00c0, 0x2610: 0x00c0, 0x2611: 0x00c0, + 0x2612: 0x00c0, 0x2613: 0x00c0, 0x2614: 0x00c0, 0x2615: 0x00c0, 0x2616: 0x00c0, 0x2617: 0x00c0, + 0x2618: 0x00c0, 0x2619: 0x00c0, 0x261a: 0x00c0, 0x261b: 0x00c0, 0x261c: 0x0080, 0x261d: 0x0080, + 0x261e: 0x00c3, 0x261f: 0x00c3, 0x2620: 0x00c0, 0x2621: 0x00c0, 0x2622: 0x00c0, 0x2623: 0x00c0, + 0x2624: 0x00c0, 0x2625: 0x00c0, 0x2626: 0x00c0, 0x2627: 0x00c0, 0x2628: 0x00c0, 0x2629: 0x00c0, + 0x262a: 0x00c0, 0x262b: 0x00c0, 0x262c: 0x00c0, 0x262d: 0x00c0, 0x262e: 0x00c0, 0x262f: 0x00c0, + 0x2630: 0x00c0, 0x2631: 0x00c0, 0x2632: 0x00c0, 0x2633: 0x00c0, 0x2634: 0x00c0, 0x2635: 0x00c0, + 0x2636: 0x00c0, 0x2637: 0x00c0, 0x2638: 0x00c0, 0x2639: 0x00c0, 0x263a: 0x00c0, 0x263b: 0x00c0, + 0x263c: 0x00c0, 0x263d: 0x00c0, 0x263e: 0x00c0, 0x263f: 0x00c0, + // Block 0x99, offset 0x2640 + 0x2640: 0x00c0, 0x2641: 0x00c0, 0x2642: 0x00c0, 0x2643: 0x00c0, 0x2644: 0x00c0, 0x2645: 0x00c0, + 0x2646: 0x00c0, 0x2647: 0x00c0, 0x2648: 0x00c0, 0x2649: 0x00c0, 0x264a: 0x00c0, 0x264b: 0x00c0, + 0x264c: 0x00c0, 0x264d: 0x00c0, 0x264e: 0x00c0, 0x264f: 0x00c0, 0x2650: 0x00c0, 0x2651: 0x00c0, + 0x2652: 0x00c0, 0x2653: 0x00c0, 0x2654: 0x00c0, 0x2655: 0x00c0, 0x2656: 0x00c0, 0x2657: 0x00c0, + 0x2658: 0x00c0, 0x2659: 0x00c0, 0x265a: 0x00c0, 0x265b: 0x00c0, 0x265c: 0x00c0, 0x265d: 0x00c0, + 0x265e: 0x00c0, 0x265f: 0x00c0, 0x2660: 0x00c0, 0x2661: 0x00c0, 0x2662: 0x00c0, 0x2663: 0x00c0, + 0x2664: 0x00c0, 0x2665: 0x00c0, 0x2666: 0x0080, 0x2667: 0x0080, 0x2668: 0x0080, 0x2669: 0x0080, + 0x266a: 0x0080, 0x266b: 0x0080, 0x266c: 0x0080, 0x266d: 0x0080, 0x266e: 0x0080, 0x266f: 0x0080, + 0x2670: 0x00c3, 0x2671: 0x00c3, 0x2672: 0x0080, 0x2673: 0x0080, 0x2674: 0x0080, 0x2675: 0x0080, + 0x2676: 0x0080, 0x2677: 0x0080, + // Block 0x9a, offset 0x2680 + 0x2680: 0x0080, 0x2681: 0x0080, 0x2682: 0x0080, 0x2683: 0x0080, 0x2684: 0x0080, 0x2685: 0x0080, + 0x2686: 0x0080, 0x2687: 0x0080, 0x2688: 0x0080, 0x2689: 0x0080, 0x268a: 0x0080, 0x268b: 0x0080, + 0x268c: 0x0080, 0x268d: 0x0080, 0x268e: 0x0080, 0x268f: 0x0080, 0x2690: 0x0080, 0x2691: 0x0080, + 0x2692: 0x0080, 0x2693: 0x0080, 0x2694: 0x0080, 0x2695: 0x0080, 0x2696: 0x0080, 0x2697: 0x00c0, + 0x2698: 0x00c0, 0x2699: 0x00c0, 0x269a: 0x00c0, 0x269b: 0x00c0, 0x269c: 0x00c0, 0x269d: 0x00c0, + 0x269e: 0x00c0, 0x269f: 0x00c0, 0x26a0: 0x0080, 0x26a1: 0x0080, 0x26a2: 0x00c0, 0x26a3: 0x00c0, + 0x26a4: 0x00c0, 0x26a5: 0x00c0, 0x26a6: 0x00c0, 0x26a7: 0x00c0, 0x26a8: 0x00c0, 0x26a9: 0x00c0, + 0x26aa: 0x00c0, 0x26ab: 0x00c0, 0x26ac: 0x00c0, 0x26ad: 0x00c0, 0x26ae: 0x00c0, 0x26af: 0x00c0, + 0x26b0: 0x00c0, 0x26b1: 0x00c0, 0x26b2: 0x00c0, 0x26b3: 0x00c0, 0x26b4: 0x00c0, 0x26b5: 0x00c0, + 0x26b6: 0x00c0, 0x26b7: 0x00c0, 0x26b8: 0x00c0, 0x26b9: 0x00c0, 0x26ba: 0x00c0, 0x26bb: 0x00c0, + 0x26bc: 0x00c0, 0x26bd: 0x00c0, 0x26be: 0x00c0, 0x26bf: 0x00c0, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x00c0, 0x26c1: 0x00c0, 0x26c2: 0x00c0, 0x26c3: 0x00c0, 0x26c4: 0x00c0, 0x26c5: 0x00c0, + 0x26c6: 0x00c0, 0x26c7: 0x00c0, 0x26c8: 0x00c0, 0x26c9: 0x00c0, 0x26ca: 0x00c0, 0x26cb: 0x00c0, + 0x26cc: 0x00c0, 0x26cd: 0x00c0, 0x26ce: 0x00c0, 0x26cf: 0x00c0, 0x26d0: 0x00c0, 0x26d1: 0x00c0, + 0x26d2: 0x00c0, 0x26d3: 0x00c0, 0x26d4: 0x00c0, 0x26d5: 0x00c0, 0x26d6: 0x00c0, 0x26d7: 0x00c0, + 0x26d8: 0x00c0, 0x26d9: 0x00c0, 0x26da: 0x00c0, 0x26db: 0x00c0, 0x26dc: 0x00c0, 0x26dd: 0x00c0, + 0x26de: 0x00c0, 0x26df: 0x00c0, 0x26e0: 0x00c0, 0x26e1: 0x00c0, 0x26e2: 0x00c0, 0x26e3: 0x00c0, + 0x26e4: 0x00c0, 0x26e5: 0x00c0, 0x26e6: 0x00c0, 0x26e7: 0x00c0, 0x26e8: 0x00c0, 0x26e9: 0x00c0, + 0x26ea: 0x00c0, 0x26eb: 0x00c0, 0x26ec: 0x00c0, 0x26ed: 0x00c0, 0x26ee: 0x00c0, 0x26ef: 0x00c0, + 0x26f0: 0x0080, 0x26f1: 0x00c0, 0x26f2: 0x00c0, 0x26f3: 0x00c0, 0x26f4: 0x00c0, 0x26f5: 0x00c0, + 0x26f6: 0x00c0, 0x26f7: 0x00c0, 0x26f8: 0x00c0, 0x26f9: 0x00c0, 0x26fa: 0x00c0, 0x26fb: 0x00c0, + 0x26fc: 0x00c0, 0x26fd: 0x00c0, 0x26fe: 0x00c0, 0x26ff: 0x00c0, + // Block 0x9c, offset 0x2700 + 0x2700: 0x00c0, 0x2701: 0x00c0, 0x2702: 0x00c0, 0x2703: 0x00c0, 0x2704: 0x00c0, 0x2705: 0x00c0, + 0x2706: 0x00c0, 0x2707: 0x00c0, 0x2708: 0x00c0, 0x2709: 0x0080, 0x270a: 0x0080, 0x270b: 0x00c0, + 0x270c: 0x00c0, 0x270d: 0x00c0, 0x270e: 0x00c0, 0x270f: 0x00c0, 0x2710: 0x00c0, 0x2711: 0x00c0, + 0x2712: 0x00c0, 0x2713: 0x00c0, 0x2714: 0x00c0, 0x2715: 0x00c0, 0x2716: 0x00c0, 0x2717: 0x00c0, + 0x2718: 0x00c0, 0x2719: 0x00c0, 0x271a: 0x00c0, 0x271b: 0x00c0, 0x271c: 0x00c0, 0x271d: 0x00c0, + 0x271e: 0x00c0, 0x271f: 0x00c0, 0x2720: 0x00c0, 0x2721: 0x00c0, 0x2722: 0x00c0, 0x2723: 0x00c0, + 0x2724: 0x00c0, 0x2725: 0x00c0, 0x2726: 0x00c0, 0x2727: 0x00c0, 0x2728: 0x00c0, 0x2729: 0x00c0, + 0x272a: 0x00c0, 0x272b: 0x00c0, 0x272c: 0x00c0, 0x272d: 0x00c0, 0x272e: 0x00c0, + 0x2730: 0x00c0, 0x2731: 0x00c0, 0x2732: 0x00c0, 0x2733: 0x00c0, 0x2734: 0x00c0, 0x2735: 0x00c0, + 0x2736: 0x00c0, 0x2737: 0x00c0, + // Block 0x9d, offset 0x2740 + 0x2777: 0x00c0, 0x2778: 0x0080, 0x2779: 0x0080, 0x277a: 0x00c0, 0x277b: 0x00c0, + 0x277c: 0x00c0, 0x277d: 0x00c0, 0x277e: 0x00c0, 0x277f: 0x00c0, + // Block 0x9e, offset 0x2780 + 0x2780: 0x00c0, 0x2781: 0x00c0, 0x2782: 0x00c3, 0x2783: 0x00c0, 0x2784: 0x00c0, 0x2785: 0x00c0, + 0x2786: 0x00c6, 0x2787: 0x00c0, 0x2788: 0x00c0, 0x2789: 0x00c0, 0x278a: 0x00c0, 0x278b: 0x00c3, + 0x278c: 0x00c0, 0x278d: 0x00c0, 0x278e: 0x00c0, 0x278f: 0x00c0, 0x2790: 0x00c0, 0x2791: 0x00c0, + 0x2792: 0x00c0, 0x2793: 0x00c0, 0x2794: 0x00c0, 0x2795: 0x00c0, 0x2796: 0x00c0, 0x2797: 0x00c0, + 0x2798: 0x00c0, 0x2799: 0x00c0, 0x279a: 0x00c0, 0x279b: 0x00c0, 0x279c: 0x00c0, 0x279d: 0x00c0, + 0x279e: 0x00c0, 0x279f: 0x00c0, 0x27a0: 0x00c0, 0x27a1: 0x00c0, 0x27a2: 0x00c0, 0x27a3: 0x00c0, + 0x27a4: 0x00c0, 0x27a5: 0x00c3, 0x27a6: 0x00c3, 0x27a7: 0x00c0, 0x27a8: 0x0080, 0x27a9: 0x0080, + 0x27aa: 0x0080, 0x27ab: 0x0080, + 0x27b0: 0x0080, 0x27b1: 0x0080, 0x27b2: 0x0080, 0x27b3: 0x0080, 0x27b4: 0x0080, 0x27b5: 0x0080, + 0x27b6: 0x0080, 0x27b7: 0x0080, 0x27b8: 0x0080, 0x27b9: 0x0080, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x00c2, 0x27c1: 0x00c2, 0x27c2: 0x00c2, 0x27c3: 0x00c2, 0x27c4: 0x00c2, 0x27c5: 0x00c2, + 0x27c6: 0x00c2, 0x27c7: 0x00c2, 0x27c8: 0x00c2, 0x27c9: 0x00c2, 0x27ca: 0x00c2, 0x27cb: 0x00c2, + 0x27cc: 0x00c2, 0x27cd: 0x00c2, 0x27ce: 0x00c2, 0x27cf: 0x00c2, 0x27d0: 0x00c2, 0x27d1: 0x00c2, + 0x27d2: 0x00c2, 0x27d3: 0x00c2, 0x27d4: 0x00c2, 0x27d5: 0x00c2, 0x27d6: 0x00c2, 0x27d7: 0x00c2, + 0x27d8: 0x00c2, 0x27d9: 0x00c2, 0x27da: 0x00c2, 0x27db: 0x00c2, 0x27dc: 0x00c2, 0x27dd: 0x00c2, + 0x27de: 0x00c2, 0x27df: 0x00c2, 0x27e0: 0x00c2, 0x27e1: 0x00c2, 0x27e2: 0x00c2, 0x27e3: 0x00c2, + 0x27e4: 0x00c2, 0x27e5: 0x00c2, 0x27e6: 0x00c2, 0x27e7: 0x00c2, 0x27e8: 0x00c2, 0x27e9: 0x00c2, + 0x27ea: 0x00c2, 0x27eb: 0x00c2, 0x27ec: 0x00c2, 0x27ed: 0x00c2, 0x27ee: 0x00c2, 0x27ef: 0x00c2, + 0x27f0: 0x00c2, 0x27f1: 0x00c2, 0x27f2: 0x00c1, 0x27f3: 0x00c0, 0x27f4: 0x0080, 0x27f5: 0x0080, + 0x27f6: 0x0080, 0x27f7: 0x0080, + // Block 0xa0, offset 0x2800 + 0x2800: 0x00c0, 0x2801: 0x00c0, 0x2802: 0x00c0, 0x2803: 0x00c0, 0x2804: 0x00c6, 0x2805: 0x00c3, + 0x280e: 0x0080, 0x280f: 0x0080, 0x2810: 0x00c0, 0x2811: 0x00c0, + 0x2812: 0x00c0, 0x2813: 0x00c0, 0x2814: 0x00c0, 0x2815: 0x00c0, 0x2816: 0x00c0, 0x2817: 0x00c0, + 0x2818: 0x00c0, 0x2819: 0x00c0, + 0x2820: 0x00c3, 0x2821: 0x00c3, 0x2822: 0x00c3, 0x2823: 0x00c3, + 0x2824: 0x00c3, 0x2825: 0x00c3, 0x2826: 0x00c3, 0x2827: 0x00c3, 0x2828: 0x00c3, 0x2829: 0x00c3, + 0x282a: 0x00c3, 0x282b: 0x00c3, 0x282c: 0x00c3, 0x282d: 0x00c3, 0x282e: 0x00c3, 0x282f: 0x00c3, + 0x2830: 0x00c3, 0x2831: 0x00c3, 0x2832: 0x00c0, 0x2833: 0x00c0, 0x2834: 0x00c0, 0x2835: 0x00c0, + 0x2836: 0x00c0, 0x2837: 0x00c0, 0x2838: 0x0080, 0x2839: 0x0080, 0x283a: 0x0080, 0x283b: 0x00c0, + 0x283c: 0x0080, 0x283d: 0x00c0, + // Block 0xa1, offset 0x2840 + 0x2840: 0x00c0, 0x2841: 0x00c0, 0x2842: 0x00c0, 0x2843: 0x00c0, 0x2844: 0x00c0, 0x2845: 0x00c0, + 0x2846: 0x00c0, 0x2847: 0x00c0, 0x2848: 0x00c0, 0x2849: 0x00c0, 0x284a: 0x00c0, 0x284b: 0x00c0, + 0x284c: 0x00c0, 0x284d: 0x00c0, 0x284e: 0x00c0, 0x284f: 0x00c0, 0x2850: 0x00c0, 0x2851: 0x00c0, + 0x2852: 0x00c0, 0x2853: 0x00c0, 0x2854: 0x00c0, 0x2855: 0x00c0, 0x2856: 0x00c0, 0x2857: 0x00c0, + 0x2858: 0x00c0, 0x2859: 0x00c0, 0x285a: 0x00c0, 0x285b: 0x00c0, 0x285c: 0x00c0, 0x285d: 0x00c0, + 0x285e: 0x00c0, 0x285f: 0x00c0, 0x2860: 0x00c0, 0x2861: 0x00c0, 0x2862: 0x00c0, 0x2863: 0x00c0, + 0x2864: 0x00c0, 0x2865: 0x00c0, 0x2866: 0x00c3, 0x2867: 0x00c3, 0x2868: 0x00c3, 0x2869: 0x00c3, + 0x286a: 0x00c3, 0x286b: 0x00c3, 0x286c: 0x00c3, 0x286d: 0x00c3, 0x286e: 0x0080, 0x286f: 0x0080, + 0x2870: 0x00c0, 0x2871: 0x00c0, 0x2872: 0x00c0, 0x2873: 0x00c0, 0x2874: 0x00c0, 0x2875: 0x00c0, + 0x2876: 0x00c0, 0x2877: 0x00c0, 0x2878: 0x00c0, 0x2879: 0x00c0, 0x287a: 0x00c0, 0x287b: 0x00c0, + 0x287c: 0x00c0, 0x287d: 0x00c0, 0x287e: 0x00c0, 0x287f: 0x00c0, + // Block 0xa2, offset 0x2880 + 0x2880: 0x00c0, 0x2881: 0x00c0, 0x2882: 0x00c0, 0x2883: 0x00c0, 0x2884: 0x00c0, 0x2885: 0x00c0, + 0x2886: 0x00c0, 0x2887: 0x00c3, 0x2888: 0x00c3, 0x2889: 0x00c3, 0x288a: 0x00c3, 0x288b: 0x00c3, + 0x288c: 0x00c3, 0x288d: 0x00c3, 0x288e: 0x00c3, 0x288f: 0x00c3, 0x2890: 0x00c3, 0x2891: 0x00c3, + 0x2892: 0x00c0, 0x2893: 0x00c5, + 0x289f: 0x0080, 0x28a0: 0x0040, 0x28a1: 0x0040, 0x28a2: 0x0040, 0x28a3: 0x0040, + 0x28a4: 0x0040, 0x28a5: 0x0040, 0x28a6: 0x0040, 0x28a7: 0x0040, 0x28a8: 0x0040, 0x28a9: 0x0040, + 0x28aa: 0x0040, 0x28ab: 0x0040, 0x28ac: 0x0040, 0x28ad: 0x0040, 0x28ae: 0x0040, 0x28af: 0x0040, + 0x28b0: 0x0040, 0x28b1: 0x0040, 0x28b2: 0x0040, 0x28b3: 0x0040, 0x28b4: 0x0040, 0x28b5: 0x0040, + 0x28b6: 0x0040, 0x28b7: 0x0040, 0x28b8: 0x0040, 0x28b9: 0x0040, 0x28ba: 0x0040, 0x28bb: 0x0040, + 0x28bc: 0x0040, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x00c3, 0x28c1: 0x00c3, 0x28c2: 0x00c3, 0x28c3: 0x00c0, 0x28c4: 0x00c0, 0x28c5: 0x00c0, + 0x28c6: 0x00c0, 0x28c7: 0x00c0, 0x28c8: 0x00c0, 0x28c9: 0x00c0, 0x28ca: 0x00c0, 0x28cb: 0x00c0, + 0x28cc: 0x00c0, 0x28cd: 0x00c0, 0x28ce: 0x00c0, 0x28cf: 0x00c0, 0x28d0: 0x00c0, 0x28d1: 0x00c0, + 0x28d2: 0x00c0, 0x28d3: 0x00c0, 0x28d4: 0x00c0, 0x28d5: 0x00c0, 0x28d6: 0x00c0, 0x28d7: 0x00c0, + 0x28d8: 0x00c0, 0x28d9: 0x00c0, 0x28da: 0x00c0, 0x28db: 0x00c0, 0x28dc: 0x00c0, 0x28dd: 0x00c0, + 0x28de: 0x00c0, 0x28df: 0x00c0, 0x28e0: 0x00c0, 0x28e1: 0x00c0, 0x28e2: 0x00c0, 0x28e3: 0x00c0, + 0x28e4: 0x00c0, 0x28e5: 0x00c0, 0x28e6: 0x00c0, 0x28e7: 0x00c0, 0x28e8: 0x00c0, 0x28e9: 0x00c0, + 0x28ea: 0x00c0, 0x28eb: 0x00c0, 0x28ec: 0x00c0, 0x28ed: 0x00c0, 0x28ee: 0x00c0, 0x28ef: 0x00c0, + 0x28f0: 0x00c0, 0x28f1: 0x00c0, 0x28f2: 0x00c0, 0x28f3: 0x00c3, 0x28f4: 0x00c0, 0x28f5: 0x00c0, + 0x28f6: 0x00c3, 0x28f7: 0x00c3, 0x28f8: 0x00c3, 0x28f9: 0x00c3, 0x28fa: 0x00c0, 0x28fb: 0x00c0, + 0x28fc: 0x00c3, 0x28fd: 0x00c0, 0x28fe: 0x00c0, 0x28ff: 0x00c0, + // Block 0xa4, offset 0x2900 + 0x2900: 0x00c5, 0x2901: 0x0080, 0x2902: 0x0080, 0x2903: 0x0080, 0x2904: 0x0080, 0x2905: 0x0080, + 0x2906: 0x0080, 0x2907: 0x0080, 0x2908: 0x0080, 0x2909: 0x0080, 0x290a: 0x0080, 0x290b: 0x0080, + 0x290c: 0x0080, 0x290d: 0x0080, 0x290f: 0x00c0, 0x2910: 0x00c0, 0x2911: 0x00c0, + 0x2912: 0x00c0, 0x2913: 0x00c0, 0x2914: 0x00c0, 0x2915: 0x00c0, 0x2916: 0x00c0, 0x2917: 0x00c0, + 0x2918: 0x00c0, 0x2919: 0x00c0, + 0x291e: 0x0080, 0x291f: 0x0080, 0x2920: 0x00c0, 0x2921: 0x00c0, 0x2922: 0x00c0, 0x2923: 0x00c0, + 0x2924: 0x00c0, 0x2925: 0x00c3, 0x2926: 0x00c0, 0x2927: 0x00c0, 0x2928: 0x00c0, 0x2929: 0x00c0, + 0x292a: 0x00c0, 0x292b: 0x00c0, 0x292c: 0x00c0, 0x292d: 0x00c0, 0x292e: 0x00c0, 0x292f: 0x00c0, + 0x2930: 0x00c0, 0x2931: 0x00c0, 0x2932: 0x00c0, 0x2933: 0x00c0, 0x2934: 0x00c0, 0x2935: 0x00c0, + 0x2936: 0x00c0, 0x2937: 0x00c0, 0x2938: 0x00c0, 0x2939: 0x00c0, 0x293a: 0x00c0, 0x293b: 0x00c0, + 0x293c: 0x00c0, 0x293d: 0x00c0, 0x293e: 0x00c0, + // Block 0xa5, offset 0x2940 + 0x2940: 0x00c0, 0x2941: 0x00c0, 0x2942: 0x00c0, 0x2943: 0x00c0, 0x2944: 0x00c0, 0x2945: 0x00c0, + 0x2946: 0x00c0, 0x2947: 0x00c0, 0x2948: 0x00c0, 0x2949: 0x00c0, 0x294a: 0x00c0, 0x294b: 0x00c0, + 0x294c: 0x00c0, 0x294d: 0x00c0, 0x294e: 0x00c0, 0x294f: 0x00c0, 0x2950: 0x00c0, 0x2951: 0x00c0, + 0x2952: 0x00c0, 0x2953: 0x00c0, 0x2954: 0x00c0, 0x2955: 0x00c0, 0x2956: 0x00c0, 0x2957: 0x00c0, + 0x2958: 0x00c0, 0x2959: 0x00c0, 0x295a: 0x00c0, 0x295b: 0x00c0, 0x295c: 0x00c0, 0x295d: 0x00c0, + 0x295e: 0x00c0, 0x295f: 0x00c0, 0x2960: 0x00c0, 0x2961: 0x00c0, 0x2962: 0x00c0, 0x2963: 0x00c0, + 0x2964: 0x00c0, 0x2965: 0x00c0, 0x2966: 0x00c0, 0x2967: 0x00c0, 0x2968: 0x00c0, 0x2969: 0x00c3, + 0x296a: 0x00c3, 0x296b: 0x00c3, 0x296c: 0x00c3, 0x296d: 0x00c3, 0x296e: 0x00c3, 0x296f: 0x00c0, + 0x2970: 0x00c0, 0x2971: 0x00c3, 0x2972: 0x00c3, 0x2973: 0x00c0, 0x2974: 0x00c0, 0x2975: 0x00c3, + 0x2976: 0x00c3, + // Block 0xa6, offset 0x2980 + 0x2980: 0x00c0, 0x2981: 0x00c0, 0x2982: 0x00c0, 0x2983: 0x00c3, 0x2984: 0x00c0, 0x2985: 0x00c0, + 0x2986: 0x00c0, 0x2987: 0x00c0, 0x2988: 0x00c0, 0x2989: 0x00c0, 0x298a: 0x00c0, 0x298b: 0x00c0, + 0x298c: 0x00c3, 0x298d: 0x00c0, 0x2990: 0x00c0, 0x2991: 0x00c0, + 0x2992: 0x00c0, 0x2993: 0x00c0, 0x2994: 0x00c0, 0x2995: 0x00c0, 0x2996: 0x00c0, 0x2997: 0x00c0, + 0x2998: 0x00c0, 0x2999: 0x00c0, 0x299c: 0x0080, 0x299d: 0x0080, + 0x299e: 0x0080, 0x299f: 0x0080, 0x29a0: 0x00c0, 0x29a1: 0x00c0, 0x29a2: 0x00c0, 0x29a3: 0x00c0, + 0x29a4: 0x00c0, 0x29a5: 0x00c0, 0x29a6: 0x00c0, 0x29a7: 0x00c0, 0x29a8: 0x00c0, 0x29a9: 0x00c0, + 0x29aa: 0x00c0, 0x29ab: 0x00c0, 0x29ac: 0x00c0, 0x29ad: 0x00c0, 0x29ae: 0x00c0, 0x29af: 0x00c0, + 0x29b0: 0x00c0, 0x29b1: 0x00c0, 0x29b2: 0x00c0, 0x29b3: 0x00c0, 0x29b4: 0x00c0, 0x29b5: 0x00c0, + 0x29b6: 0x00c0, 0x29b7: 0x0080, 0x29b8: 0x0080, 0x29b9: 0x0080, 0x29ba: 0x00c0, 0x29bb: 0x00c0, + 0x29bc: 0x00c3, 0x29bd: 0x00c0, 0x29be: 0x00c0, 0x29bf: 0x00c0, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x00c0, 0x29c1: 0x00c0, 0x29c2: 0x00c0, 0x29c3: 0x00c0, 0x29c4: 0x00c0, 0x29c5: 0x00c0, + 0x29c6: 0x00c0, 0x29c7: 0x00c0, 0x29c8: 0x00c0, 0x29c9: 0x00c0, 0x29ca: 0x00c0, 0x29cb: 0x00c0, + 0x29cc: 0x00c0, 0x29cd: 0x00c0, 0x29ce: 0x00c0, 0x29cf: 0x00c0, 0x29d0: 0x00c0, 0x29d1: 0x00c0, + 0x29d2: 0x00c0, 0x29d3: 0x00c0, 0x29d4: 0x00c0, 0x29d5: 0x00c0, 0x29d6: 0x00c0, 0x29d7: 0x00c0, + 0x29d8: 0x00c0, 0x29d9: 0x00c0, 0x29da: 0x00c0, 0x29db: 0x00c0, 0x29dc: 0x00c0, 0x29dd: 0x00c0, + 0x29de: 0x00c0, 0x29df: 0x00c0, 0x29e0: 0x00c0, 0x29e1: 0x00c0, 0x29e2: 0x00c0, 0x29e3: 0x00c0, + 0x29e4: 0x00c0, 0x29e5: 0x00c0, 0x29e6: 0x00c0, 0x29e7: 0x00c0, 0x29e8: 0x00c0, 0x29e9: 0x00c0, + 0x29ea: 0x00c0, 0x29eb: 0x00c0, 0x29ec: 0x00c0, 0x29ed: 0x00c0, 0x29ee: 0x00c0, 0x29ef: 0x00c0, + 0x29f0: 0x00c3, 0x29f1: 0x00c0, 0x29f2: 0x00c3, 0x29f3: 0x00c3, 0x29f4: 0x00c3, 0x29f5: 0x00c0, + 0x29f6: 0x00c0, 0x29f7: 0x00c3, 0x29f8: 0x00c3, 0x29f9: 0x00c0, 0x29fa: 0x00c0, 0x29fb: 0x00c0, + 0x29fc: 0x00c0, 0x29fd: 0x00c0, 0x29fe: 0x00c3, 0x29ff: 0x00c3, + // Block 0xa8, offset 0x2a00 + 0x2a00: 0x00c0, 0x2a01: 0x00c3, 0x2a02: 0x00c0, + 0x2a1b: 0x00c0, 0x2a1c: 0x00c0, 0x2a1d: 0x00c0, + 0x2a1e: 0x0080, 0x2a1f: 0x0080, 0x2a20: 0x00c0, 0x2a21: 0x00c0, 0x2a22: 0x00c0, 0x2a23: 0x00c0, + 0x2a24: 0x00c0, 0x2a25: 0x00c0, 0x2a26: 0x00c0, 0x2a27: 0x00c0, 0x2a28: 0x00c0, 0x2a29: 0x00c0, + 0x2a2a: 0x00c0, 0x2a2b: 0x00c0, 0x2a2c: 0x00c3, 0x2a2d: 0x00c3, 0x2a2e: 0x00c0, 0x2a2f: 0x00c0, + 0x2a30: 0x0080, 0x2a31: 0x0080, 0x2a32: 0x00c0, 0x2a33: 0x00c0, 0x2a34: 0x00c0, 0x2a35: 0x00c0, + 0x2a36: 0x00c6, + // Block 0xa9, offset 0x2a40 + 0x2a41: 0x00c0, 0x2a42: 0x00c0, 0x2a43: 0x00c0, 0x2a44: 0x00c0, 0x2a45: 0x00c0, + 0x2a46: 0x00c0, 0x2a49: 0x00c0, 0x2a4a: 0x00c0, 0x2a4b: 0x00c0, + 0x2a4c: 0x00c0, 0x2a4d: 0x00c0, 0x2a4e: 0x00c0, 0x2a51: 0x00c0, + 0x2a52: 0x00c0, 0x2a53: 0x00c0, 0x2a54: 0x00c0, 0x2a55: 0x00c0, 0x2a56: 0x00c0, + 0x2a60: 0x00c0, 0x2a61: 0x00c0, 0x2a62: 0x00c0, 0x2a63: 0x00c0, + 0x2a64: 0x00c0, 0x2a65: 0x00c0, 0x2a66: 0x00c0, 0x2a68: 0x00c0, 0x2a69: 0x00c0, + 0x2a6a: 0x00c0, 0x2a6b: 0x00c0, 0x2a6c: 0x00c0, 0x2a6d: 0x00c0, 0x2a6e: 0x00c0, + 0x2a70: 0x00c0, 0x2a71: 0x00c0, 0x2a72: 0x00c0, 0x2a73: 0x00c0, 0x2a74: 0x00c0, 0x2a75: 0x00c0, + 0x2a76: 0x00c0, 0x2a77: 0x00c0, 0x2a78: 0x00c0, 0x2a79: 0x00c0, 0x2a7a: 0x00c0, 0x2a7b: 0x00c0, + 0x2a7c: 0x00c0, 0x2a7d: 0x00c0, 0x2a7e: 0x00c0, 0x2a7f: 0x00c0, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x00c0, 0x2a81: 0x00c0, 0x2a82: 0x00c0, 0x2a83: 0x00c0, 0x2a84: 0x00c0, 0x2a85: 0x00c0, + 0x2a86: 0x00c0, 0x2a87: 0x00c0, 0x2a88: 0x00c0, 0x2a89: 0x00c0, 0x2a8a: 0x00c0, 0x2a8b: 0x00c0, + 0x2a8c: 0x00c0, 0x2a8d: 0x00c0, 0x2a8e: 0x00c0, 0x2a8f: 0x00c0, 0x2a90: 0x00c0, 0x2a91: 0x00c0, + 0x2a92: 0x00c0, 0x2a93: 0x00c0, 0x2a94: 0x00c0, 0x2a95: 0x00c0, 0x2a96: 0x00c0, 0x2a97: 0x00c0, + 0x2a98: 0x00c0, 0x2a99: 0x00c0, 0x2a9a: 0x00c0, 0x2a9b: 0x0080, 0x2a9c: 0x0080, 0x2a9d: 0x0080, + 0x2a9e: 0x0080, 0x2a9f: 0x0080, 0x2aa0: 0x00c0, 0x2aa1: 0x00c0, 0x2aa2: 0x00c0, 0x2aa3: 0x00c0, + 0x2aa4: 0x00c0, 0x2aa5: 0x00c8, + 0x2ab0: 0x00c0, 0x2ab1: 0x00c0, 0x2ab2: 0x00c0, 0x2ab3: 0x00c0, 0x2ab4: 0x00c0, 0x2ab5: 0x00c0, + 0x2ab6: 0x00c0, 0x2ab7: 0x00c0, 0x2ab8: 0x00c0, 0x2ab9: 0x00c0, 0x2aba: 0x00c0, 0x2abb: 0x00c0, + 0x2abc: 0x00c0, 0x2abd: 0x00c0, 0x2abe: 0x00c0, 0x2abf: 0x00c0, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x00c0, 0x2ac1: 0x00c0, 0x2ac2: 0x00c0, 0x2ac3: 0x00c0, 0x2ac4: 0x00c0, 0x2ac5: 0x00c0, + 0x2ac6: 0x00c0, 0x2ac7: 0x00c0, 0x2ac8: 0x00c0, 0x2ac9: 0x00c0, 0x2aca: 0x00c0, 0x2acb: 0x00c0, + 0x2acc: 0x00c0, 0x2acd: 0x00c0, 0x2ace: 0x00c0, 0x2acf: 0x00c0, 0x2ad0: 0x00c0, 0x2ad1: 0x00c0, + 0x2ad2: 0x00c0, 0x2ad3: 0x00c0, 0x2ad4: 0x00c0, 0x2ad5: 0x00c0, 0x2ad6: 0x00c0, 0x2ad7: 0x00c0, + 0x2ad8: 0x00c0, 0x2ad9: 0x00c0, 0x2ada: 0x00c0, 0x2adb: 0x00c0, 0x2adc: 0x00c0, 0x2add: 0x00c0, + 0x2ade: 0x00c0, 0x2adf: 0x00c0, 0x2ae0: 0x00c0, 0x2ae1: 0x00c0, 0x2ae2: 0x00c0, 0x2ae3: 0x00c0, + 0x2ae4: 0x00c0, 0x2ae5: 0x00c3, 0x2ae6: 0x00c0, 0x2ae7: 0x00c0, 0x2ae8: 0x00c3, 0x2ae9: 0x00c0, + 0x2aea: 0x00c0, 0x2aeb: 0x0080, 0x2aec: 0x00c0, 0x2aed: 0x00c6, + 0x2af0: 0x00c0, 0x2af1: 0x00c0, 0x2af2: 0x00c0, 0x2af3: 0x00c0, 0x2af4: 0x00c0, 0x2af5: 0x00c0, + 0x2af6: 0x00c0, 0x2af7: 0x00c0, 0x2af8: 0x00c0, 0x2af9: 0x00c0, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x00c0, 0x2b01: 0x00c0, 0x2b02: 0x00c0, 0x2b03: 0x00c0, 0x2b04: 0x00c0, 0x2b05: 0x00c0, + 0x2b06: 0x00c0, 0x2b07: 0x00c0, 0x2b08: 0x00c0, 0x2b09: 0x00c0, 0x2b0a: 0x00c0, 0x2b0b: 0x00c0, + 0x2b0c: 0x00c0, 0x2b0d: 0x00c0, 0x2b0e: 0x00c0, 0x2b0f: 0x00c0, 0x2b10: 0x00c0, 0x2b11: 0x00c0, + 0x2b12: 0x00c0, 0x2b13: 0x00c0, 0x2b14: 0x00c0, 0x2b15: 0x00c0, 0x2b16: 0x00c0, 0x2b17: 0x00c0, + 0x2b18: 0x00c0, 0x2b19: 0x00c0, 0x2b1a: 0x00c0, 0x2b1b: 0x00c0, 0x2b1c: 0x00c0, 0x2b1d: 0x00c0, + 0x2b1e: 0x00c0, 0x2b1f: 0x00c0, 0x2b20: 0x00c0, 0x2b21: 0x00c0, 0x2b22: 0x00c0, 0x2b23: 0x00c0, + 0x2b30: 0x0040, 0x2b31: 0x0040, 0x2b32: 0x0040, 0x2b33: 0x0040, 0x2b34: 0x0040, 0x2b35: 0x0040, + 0x2b36: 0x0040, 0x2b37: 0x0040, 0x2b38: 0x0040, 0x2b39: 0x0040, 0x2b3a: 0x0040, 0x2b3b: 0x0040, + 0x2b3c: 0x0040, 0x2b3d: 0x0040, 0x2b3e: 0x0040, 0x2b3f: 0x0040, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x0040, 0x2b41: 0x0040, 0x2b42: 0x0040, 0x2b43: 0x0040, 0x2b44: 0x0040, 0x2b45: 0x0040, + 0x2b46: 0x0040, 0x2b4b: 0x0040, + 0x2b4c: 0x0040, 0x2b4d: 0x0040, 0x2b4e: 0x0040, 0x2b4f: 0x0040, 0x2b50: 0x0040, 0x2b51: 0x0040, + 0x2b52: 0x0040, 0x2b53: 0x0040, 0x2b54: 0x0040, 0x2b55: 0x0040, 0x2b56: 0x0040, 0x2b57: 0x0040, + 0x2b58: 0x0040, 0x2b59: 0x0040, 0x2b5a: 0x0040, 0x2b5b: 0x0040, 0x2b5c: 0x0040, 0x2b5d: 0x0040, + 0x2b5e: 0x0040, 0x2b5f: 0x0040, 0x2b60: 0x0040, 0x2b61: 0x0040, 0x2b62: 0x0040, 0x2b63: 0x0040, + 0x2b64: 0x0040, 0x2b65: 0x0040, 0x2b66: 0x0040, 0x2b67: 0x0040, 0x2b68: 0x0040, 0x2b69: 0x0040, + 0x2b6a: 0x0040, 0x2b6b: 0x0040, 0x2b6c: 0x0040, 0x2b6d: 0x0040, 0x2b6e: 0x0040, 0x2b6f: 0x0040, + 0x2b70: 0x0040, 0x2b71: 0x0040, 0x2b72: 0x0040, 0x2b73: 0x0040, 0x2b74: 0x0040, 0x2b75: 0x0040, + 0x2b76: 0x0040, 0x2b77: 0x0040, 0x2b78: 0x0040, 0x2b79: 0x0040, 0x2b7a: 0x0040, 0x2b7b: 0x0040, + // Block 0xae, offset 0x2b80 + 0x2b80: 0x008c, 0x2b81: 0x008c, 0x2b82: 0x008c, 0x2b83: 0x008c, 0x2b84: 0x008c, 0x2b85: 0x008c, + 0x2b86: 0x008c, 0x2b87: 0x008c, 0x2b88: 0x008c, 0x2b89: 0x008c, 0x2b8a: 0x008c, 0x2b8b: 0x008c, + 0x2b8c: 0x008c, 0x2b8d: 0x008c, 0x2b8e: 0x00cc, 0x2b8f: 0x00cc, 0x2b90: 0x008c, 0x2b91: 0x00cc, + 0x2b92: 0x008c, 0x2b93: 0x00cc, 0x2b94: 0x00cc, 0x2b95: 0x008c, 0x2b96: 0x008c, 0x2b97: 0x008c, + 0x2b98: 0x008c, 0x2b99: 0x008c, 0x2b9a: 0x008c, 0x2b9b: 0x008c, 0x2b9c: 0x008c, 0x2b9d: 0x008c, + 0x2b9e: 0x008c, 0x2b9f: 0x00cc, 0x2ba0: 0x008c, 0x2ba1: 0x00cc, 0x2ba2: 0x008c, 0x2ba3: 0x00cc, + 0x2ba4: 0x00cc, 0x2ba5: 0x008c, 0x2ba6: 0x008c, 0x2ba7: 0x00cc, 0x2ba8: 0x00cc, 0x2ba9: 0x00cc, + 0x2baa: 0x008c, 0x2bab: 0x008c, 0x2bac: 0x008c, 0x2bad: 0x008c, 0x2bae: 0x008c, 0x2baf: 0x008c, + 0x2bb0: 0x008c, 0x2bb1: 0x008c, 0x2bb2: 0x008c, 0x2bb3: 0x008c, 0x2bb4: 0x008c, 0x2bb5: 0x008c, + 0x2bb6: 0x008c, 0x2bb7: 0x008c, 0x2bb8: 0x008c, 0x2bb9: 0x008c, 0x2bba: 0x008c, 0x2bbb: 0x008c, + 0x2bbc: 0x008c, 0x2bbd: 0x008c, 0x2bbe: 0x008c, 0x2bbf: 0x008c, + // Block 0xaf, offset 0x2bc0 + 0x2bc0: 0x008c, 0x2bc1: 0x008c, 0x2bc2: 0x008c, 0x2bc3: 0x008c, 0x2bc4: 0x008c, 0x2bc5: 0x008c, + 0x2bc6: 0x008c, 0x2bc7: 0x008c, 0x2bc8: 0x008c, 0x2bc9: 0x008c, 0x2bca: 0x008c, 0x2bcb: 0x008c, + 0x2bcc: 0x008c, 0x2bcd: 0x008c, 0x2bce: 0x008c, 0x2bcf: 0x008c, 0x2bd0: 0x008c, 0x2bd1: 0x008c, + 0x2bd2: 0x008c, 0x2bd3: 0x008c, 0x2bd4: 0x008c, 0x2bd5: 0x008c, 0x2bd6: 0x008c, 0x2bd7: 0x008c, + 0x2bd8: 0x008c, 0x2bd9: 0x008c, 0x2bda: 0x008c, 0x2bdb: 0x008c, 0x2bdc: 0x008c, 0x2bdd: 0x008c, + 0x2bde: 0x008c, 0x2bdf: 0x008c, 0x2be0: 0x008c, 0x2be1: 0x008c, 0x2be2: 0x008c, 0x2be3: 0x008c, + 0x2be4: 0x008c, 0x2be5: 0x008c, 0x2be6: 0x008c, 0x2be7: 0x008c, 0x2be8: 0x008c, 0x2be9: 0x008c, + 0x2bea: 0x008c, 0x2beb: 0x008c, 0x2bec: 0x008c, 0x2bed: 0x008c, + 0x2bf0: 0x008c, 0x2bf1: 0x008c, 0x2bf2: 0x008c, 0x2bf3: 0x008c, 0x2bf4: 0x008c, 0x2bf5: 0x008c, + 0x2bf6: 0x008c, 0x2bf7: 0x008c, 0x2bf8: 0x008c, 0x2bf9: 0x008c, 0x2bfa: 0x008c, 0x2bfb: 0x008c, + 0x2bfc: 0x008c, 0x2bfd: 0x008c, 0x2bfe: 0x008c, 0x2bff: 0x008c, + // Block 0xb0, offset 0x2c00 + 0x2c00: 0x008c, 0x2c01: 0x008c, 0x2c02: 0x008c, 0x2c03: 0x008c, 0x2c04: 0x008c, 0x2c05: 0x008c, + 0x2c06: 0x008c, 0x2c07: 0x008c, 0x2c08: 0x008c, 0x2c09: 0x008c, 0x2c0a: 0x008c, 0x2c0b: 0x008c, + 0x2c0c: 0x008c, 0x2c0d: 0x008c, 0x2c0e: 0x008c, 0x2c0f: 0x008c, 0x2c10: 0x008c, 0x2c11: 0x008c, + 0x2c12: 0x008c, 0x2c13: 0x008c, 0x2c14: 0x008c, 0x2c15: 0x008c, 0x2c16: 0x008c, 0x2c17: 0x008c, + 0x2c18: 0x008c, 0x2c19: 0x008c, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x0080, 0x2c41: 0x0080, 0x2c42: 0x0080, 0x2c43: 0x0080, 0x2c44: 0x0080, 0x2c45: 0x0080, + 0x2c46: 0x0080, + 0x2c53: 0x0080, 0x2c54: 0x0080, 0x2c55: 0x0080, 0x2c56: 0x0080, 0x2c57: 0x0080, + 0x2c5d: 0x008a, + 0x2c5e: 0x00cb, 0x2c5f: 0x008a, 0x2c60: 0x008a, 0x2c61: 0x008a, 0x2c62: 0x008a, 0x2c63: 0x008a, + 0x2c64: 0x008a, 0x2c65: 0x008a, 0x2c66: 0x008a, 0x2c67: 0x008a, 0x2c68: 0x008a, 0x2c69: 0x008a, + 0x2c6a: 0x008a, 0x2c6b: 0x008a, 0x2c6c: 0x008a, 0x2c6d: 0x008a, 0x2c6e: 0x008a, 0x2c6f: 0x008a, + 0x2c70: 0x008a, 0x2c71: 0x008a, 0x2c72: 0x008a, 0x2c73: 0x008a, 0x2c74: 0x008a, 0x2c75: 0x008a, + 0x2c76: 0x008a, 0x2c78: 0x008a, 0x2c79: 0x008a, 0x2c7a: 0x008a, 0x2c7b: 0x008a, + 0x2c7c: 0x008a, 0x2c7e: 0x008a, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0x008a, 0x2c81: 0x008a, 0x2c83: 0x008a, 0x2c84: 0x008a, + 0x2c86: 0x008a, 0x2c87: 0x008a, 0x2c88: 0x008a, 0x2c89: 0x008a, 0x2c8a: 0x008a, 0x2c8b: 0x008a, + 0x2c8c: 0x008a, 0x2c8d: 0x008a, 0x2c8e: 0x008a, 0x2c8f: 0x008a, 0x2c90: 0x0080, 0x2c91: 0x0080, + 0x2c92: 0x0080, 0x2c93: 0x0080, 0x2c94: 0x0080, 0x2c95: 0x0080, 0x2c96: 0x0080, 0x2c97: 0x0080, + 0x2c98: 0x0080, 0x2c99: 0x0080, 0x2c9a: 0x0080, 0x2c9b: 0x0080, 0x2c9c: 0x0080, 0x2c9d: 0x0080, + 0x2c9e: 0x0080, 0x2c9f: 0x0080, 0x2ca0: 0x0080, 0x2ca1: 0x0080, 0x2ca2: 0x0080, 0x2ca3: 0x0080, + 0x2ca4: 0x0080, 0x2ca5: 0x0080, 0x2ca6: 0x0080, 0x2ca7: 0x0080, 0x2ca8: 0x0080, 0x2ca9: 0x0080, + 0x2caa: 0x0080, 0x2cab: 0x0080, 0x2cac: 0x0080, 0x2cad: 0x0080, 0x2cae: 0x0080, 0x2caf: 0x0080, + 0x2cb0: 0x0080, 0x2cb1: 0x0080, 0x2cb2: 0x0080, 0x2cb3: 0x0080, 0x2cb4: 0x0080, 0x2cb5: 0x0080, + 0x2cb6: 0x0080, 0x2cb7: 0x0080, 0x2cb8: 0x0080, 0x2cb9: 0x0080, 0x2cba: 0x0080, 0x2cbb: 0x0080, + 0x2cbc: 0x0080, 0x2cbd: 0x0080, 0x2cbe: 0x0080, 0x2cbf: 0x0080, + // Block 0xb3, offset 0x2cc0 + 0x2cc0: 0x0080, 0x2cc1: 0x0080, + 0x2cd3: 0x0080, 0x2cd4: 0x0080, 0x2cd5: 0x0080, 0x2cd6: 0x0080, 0x2cd7: 0x0080, + 0x2cd8: 0x0080, 0x2cd9: 0x0080, 0x2cda: 0x0080, 0x2cdb: 0x0080, 0x2cdc: 0x0080, 0x2cdd: 0x0080, + 0x2cde: 0x0080, 0x2cdf: 0x0080, 0x2ce0: 0x0080, 0x2ce1: 0x0080, 0x2ce2: 0x0080, 0x2ce3: 0x0080, + 0x2ce4: 0x0080, 0x2ce5: 0x0080, 0x2ce6: 0x0080, 0x2ce7: 0x0080, 0x2ce8: 0x0080, 0x2ce9: 0x0080, + 0x2cea: 0x0080, 0x2ceb: 0x0080, 0x2cec: 0x0080, 0x2ced: 0x0080, 0x2cee: 0x0080, 0x2cef: 0x0080, + 0x2cf0: 0x0080, 0x2cf1: 0x0080, 0x2cf2: 0x0080, 0x2cf3: 0x0080, 0x2cf4: 0x0080, 0x2cf5: 0x0080, + 0x2cf6: 0x0080, 0x2cf7: 0x0080, 0x2cf8: 0x0080, 0x2cf9: 0x0080, 0x2cfa: 0x0080, 0x2cfb: 0x0080, + 0x2cfc: 0x0080, 0x2cfd: 0x0080, 0x2cfe: 0x0080, 0x2cff: 0x0080, + // Block 0xb4, offset 0x2d00 + 0x2d10: 0x0080, 0x2d11: 0x0080, + 0x2d12: 0x0080, 0x2d13: 0x0080, 0x2d14: 0x0080, 0x2d15: 0x0080, 0x2d16: 0x0080, 0x2d17: 0x0080, + 0x2d18: 0x0080, 0x2d19: 0x0080, 0x2d1a: 0x0080, 0x2d1b: 0x0080, 0x2d1c: 0x0080, 0x2d1d: 0x0080, + 0x2d1e: 0x0080, 0x2d1f: 0x0080, 0x2d20: 0x0080, 0x2d21: 0x0080, 0x2d22: 0x0080, 0x2d23: 0x0080, + 0x2d24: 0x0080, 0x2d25: 0x0080, 0x2d26: 0x0080, 0x2d27: 0x0080, 0x2d28: 0x0080, 0x2d29: 0x0080, + 0x2d2a: 0x0080, 0x2d2b: 0x0080, 0x2d2c: 0x0080, 0x2d2d: 0x0080, 0x2d2e: 0x0080, 0x2d2f: 0x0080, + 0x2d30: 0x0080, 0x2d31: 0x0080, 0x2d32: 0x0080, 0x2d33: 0x0080, 0x2d34: 0x0080, 0x2d35: 0x0080, + 0x2d36: 0x0080, 0x2d37: 0x0080, 0x2d38: 0x0080, 0x2d39: 0x0080, 0x2d3a: 0x0080, 0x2d3b: 0x0080, + 0x2d3c: 0x0080, 0x2d3d: 0x0080, 0x2d3e: 0x0080, 0x2d3f: 0x0080, + // Block 0xb5, offset 0x2d40 + 0x2d40: 0x0080, 0x2d41: 0x0080, 0x2d42: 0x0080, 0x2d43: 0x0080, 0x2d44: 0x0080, 0x2d45: 0x0080, + 0x2d46: 0x0080, 0x2d47: 0x0080, 0x2d48: 0x0080, 0x2d49: 0x0080, 0x2d4a: 0x0080, 0x2d4b: 0x0080, + 0x2d4c: 0x0080, 0x2d4d: 0x0080, 0x2d4e: 0x0080, 0x2d4f: 0x0080, + 0x2d52: 0x0080, 0x2d53: 0x0080, 0x2d54: 0x0080, 0x2d55: 0x0080, 0x2d56: 0x0080, 0x2d57: 0x0080, + 0x2d58: 0x0080, 0x2d59: 0x0080, 0x2d5a: 0x0080, 0x2d5b: 0x0080, 0x2d5c: 0x0080, 0x2d5d: 0x0080, + 0x2d5e: 0x0080, 0x2d5f: 0x0080, 0x2d60: 0x0080, 0x2d61: 0x0080, 0x2d62: 0x0080, 0x2d63: 0x0080, + 0x2d64: 0x0080, 0x2d65: 0x0080, 0x2d66: 0x0080, 0x2d67: 0x0080, 0x2d68: 0x0080, 0x2d69: 0x0080, + 0x2d6a: 0x0080, 0x2d6b: 0x0080, 0x2d6c: 0x0080, 0x2d6d: 0x0080, 0x2d6e: 0x0080, 0x2d6f: 0x0080, + 0x2d70: 0x0080, 0x2d71: 0x0080, 0x2d72: 0x0080, 0x2d73: 0x0080, 0x2d74: 0x0080, 0x2d75: 0x0080, + 0x2d76: 0x0080, 0x2d77: 0x0080, 0x2d78: 0x0080, 0x2d79: 0x0080, 0x2d7a: 0x0080, 0x2d7b: 0x0080, + 0x2d7c: 0x0080, 0x2d7d: 0x0080, 0x2d7e: 0x0080, 0x2d7f: 0x0080, + // Block 0xb6, offset 0x2d80 + 0x2d80: 0x0080, 0x2d81: 0x0080, 0x2d82: 0x0080, 0x2d83: 0x0080, 0x2d84: 0x0080, 0x2d85: 0x0080, + 0x2d86: 0x0080, 0x2d87: 0x0080, + 0x2db0: 0x0080, 0x2db1: 0x0080, 0x2db2: 0x0080, 0x2db3: 0x0080, 0x2db4: 0x0080, 0x2db5: 0x0080, + 0x2db6: 0x0080, 0x2db7: 0x0080, 0x2db8: 0x0080, 0x2db9: 0x0080, 0x2dba: 0x0080, 0x2dbb: 0x0080, + 0x2dbc: 0x0080, 0x2dbd: 0x0080, + // Block 0xb7, offset 0x2dc0 + 0x2dc0: 0x0040, 0x2dc1: 0x0040, 0x2dc2: 0x0040, 0x2dc3: 0x0040, 0x2dc4: 0x0040, 0x2dc5: 0x0040, + 0x2dc6: 0x0040, 0x2dc7: 0x0040, 0x2dc8: 0x0040, 0x2dc9: 0x0040, 0x2dca: 0x0040, 0x2dcb: 0x0040, + 0x2dcc: 0x0040, 0x2dcd: 0x0040, 0x2dce: 0x0040, 0x2dcf: 0x0040, 0x2dd0: 0x0080, 0x2dd1: 0x0080, + 0x2dd2: 0x0080, 0x2dd3: 0x0080, 0x2dd4: 0x0080, 0x2dd5: 0x0080, 0x2dd6: 0x0080, 0x2dd7: 0x0080, + 0x2dd8: 0x0080, 0x2dd9: 0x0080, + 0x2de0: 0x00c3, 0x2de1: 0x00c3, 0x2de2: 0x00c3, 0x2de3: 0x00c3, + 0x2de4: 0x00c3, 0x2de5: 0x00c3, 0x2de6: 0x00c3, 0x2de7: 0x00c3, 0x2de8: 0x00c3, 0x2de9: 0x00c3, + 0x2dea: 0x00c3, 0x2deb: 0x00c3, 0x2dec: 0x00c3, 0x2ded: 0x00c3, 0x2dee: 0x00c3, 0x2def: 0x00c3, + 0x2df0: 0x0080, 0x2df1: 0x0080, 0x2df2: 0x0080, 0x2df3: 0x0080, 0x2df4: 0x0080, 0x2df5: 0x0080, + 0x2df6: 0x0080, 0x2df7: 0x0080, 0x2df8: 0x0080, 0x2df9: 0x0080, 0x2dfa: 0x0080, 0x2dfb: 0x0080, + 0x2dfc: 0x0080, 0x2dfd: 0x0080, 0x2dfe: 0x0080, 0x2dff: 0x0080, + // Block 0xb8, offset 0x2e00 + 0x2e00: 0x0080, 0x2e01: 0x0080, 0x2e02: 0x0080, 0x2e03: 0x0080, 0x2e04: 0x0080, 0x2e05: 0x0080, + 0x2e06: 0x0080, 0x2e07: 0x0080, 0x2e08: 0x0080, 0x2e09: 0x0080, 0x2e0a: 0x0080, 0x2e0b: 0x0080, + 0x2e0c: 0x0080, 0x2e0d: 0x0080, 0x2e0e: 0x0080, 0x2e0f: 0x0080, 0x2e10: 0x0080, 0x2e11: 0x0080, + 0x2e12: 0x0080, 0x2e14: 0x0080, 0x2e15: 0x0080, 0x2e16: 0x0080, 0x2e17: 0x0080, + 0x2e18: 0x0080, 0x2e19: 0x0080, 0x2e1a: 0x0080, 0x2e1b: 0x0080, 0x2e1c: 0x0080, 0x2e1d: 0x0080, + 0x2e1e: 0x0080, 0x2e1f: 0x0080, 0x2e20: 0x0080, 0x2e21: 0x0080, 0x2e22: 0x0080, 0x2e23: 0x0080, + 0x2e24: 0x0080, 0x2e25: 0x0080, 0x2e26: 0x0080, 0x2e28: 0x0080, 0x2e29: 0x0080, + 0x2e2a: 0x0080, 0x2e2b: 0x0080, + 0x2e30: 0x0080, 0x2e31: 0x0080, 0x2e32: 0x0080, 0x2e33: 0x00c0, 0x2e34: 0x0080, + 0x2e36: 0x0080, 0x2e37: 0x0080, 0x2e38: 0x0080, 0x2e39: 0x0080, 0x2e3a: 0x0080, 0x2e3b: 0x0080, + 0x2e3c: 0x0080, 0x2e3d: 0x0080, 0x2e3e: 0x0080, 0x2e3f: 0x0080, + // Block 0xb9, offset 0x2e40 + 0x2e40: 0x0080, 0x2e41: 0x0080, 0x2e42: 0x0080, 0x2e43: 0x0080, 0x2e44: 0x0080, 0x2e45: 0x0080, + 0x2e46: 0x0080, 0x2e47: 0x0080, 0x2e48: 0x0080, 0x2e49: 0x0080, 0x2e4a: 0x0080, 0x2e4b: 0x0080, + 0x2e4c: 0x0080, 0x2e4d: 0x0080, 0x2e4e: 0x0080, 0x2e4f: 0x0080, 0x2e50: 0x0080, 0x2e51: 0x0080, + 0x2e52: 0x0080, 0x2e53: 0x0080, 0x2e54: 0x0080, 0x2e55: 0x0080, 0x2e56: 0x0080, 0x2e57: 0x0080, + 0x2e58: 0x0080, 0x2e59: 0x0080, 0x2e5a: 0x0080, 0x2e5b: 0x0080, 0x2e5c: 0x0080, 0x2e5d: 0x0080, + 0x2e5e: 0x0080, 0x2e5f: 0x0080, 0x2e60: 0x0080, 0x2e61: 0x0080, 0x2e62: 0x0080, 0x2e63: 0x0080, + 0x2e64: 0x0080, 0x2e65: 0x0080, 0x2e66: 0x0080, 0x2e67: 0x0080, 0x2e68: 0x0080, 0x2e69: 0x0080, + 0x2e6a: 0x0080, 0x2e6b: 0x0080, 0x2e6c: 0x0080, 0x2e6d: 0x0080, 0x2e6e: 0x0080, 0x2e6f: 0x0080, + 0x2e70: 0x0080, 0x2e71: 0x0080, 0x2e72: 0x0080, 0x2e73: 0x0080, 0x2e74: 0x0080, 0x2e75: 0x0080, + 0x2e76: 0x0080, 0x2e77: 0x0080, 0x2e78: 0x0080, 0x2e79: 0x0080, 0x2e7a: 0x0080, 0x2e7b: 0x0080, + 0x2e7c: 0x0080, 0x2e7f: 0x0040, + // Block 0xba, offset 0x2e80 + 0x2e81: 0x0080, 0x2e82: 0x0080, 0x2e83: 0x0080, 0x2e84: 0x0080, 0x2e85: 0x0080, + 0x2e86: 0x0080, 0x2e87: 0x0080, 0x2e88: 0x0080, 0x2e89: 0x0080, 0x2e8a: 0x0080, 0x2e8b: 0x0080, + 0x2e8c: 0x0080, 0x2e8d: 0x0080, 0x2e8e: 0x0080, 0x2e8f: 0x0080, 0x2e90: 0x0080, 0x2e91: 0x0080, + 0x2e92: 0x0080, 0x2e93: 0x0080, 0x2e94: 0x0080, 0x2e95: 0x0080, 0x2e96: 0x0080, 0x2e97: 0x0080, + 0x2e98: 0x0080, 0x2e99: 0x0080, 0x2e9a: 0x0080, 0x2e9b: 0x0080, 0x2e9c: 0x0080, 0x2e9d: 0x0080, + 0x2e9e: 0x0080, 0x2e9f: 0x0080, 0x2ea0: 0x0080, 0x2ea1: 0x0080, 0x2ea2: 0x0080, 0x2ea3: 0x0080, + 0x2ea4: 0x0080, 0x2ea5: 0x0080, 0x2ea6: 0x0080, 0x2ea7: 0x0080, 0x2ea8: 0x0080, 0x2ea9: 0x0080, + 0x2eaa: 0x0080, 0x2eab: 0x0080, 0x2eac: 0x0080, 0x2ead: 0x0080, 0x2eae: 0x0080, 0x2eaf: 0x0080, + 0x2eb0: 0x0080, 0x2eb1: 0x0080, 0x2eb2: 0x0080, 0x2eb3: 0x0080, 0x2eb4: 0x0080, 0x2eb5: 0x0080, + 0x2eb6: 0x0080, 0x2eb7: 0x0080, 0x2eb8: 0x0080, 0x2eb9: 0x0080, 0x2eba: 0x0080, 0x2ebb: 0x0080, + 0x2ebc: 0x0080, 0x2ebd: 0x0080, 0x2ebe: 0x0080, 0x2ebf: 0x0080, + // Block 0xbb, offset 0x2ec0 + 0x2ec0: 0x0080, 0x2ec1: 0x0080, 0x2ec2: 0x0080, 0x2ec3: 0x0080, 0x2ec4: 0x0080, 0x2ec5: 0x0080, + 0x2ec6: 0x0080, 0x2ec7: 0x0080, 0x2ec8: 0x0080, 0x2ec9: 0x0080, 0x2eca: 0x0080, 0x2ecb: 0x0080, + 0x2ecc: 0x0080, 0x2ecd: 0x0080, 0x2ece: 0x0080, 0x2ecf: 0x0080, 0x2ed0: 0x0080, 0x2ed1: 0x0080, + 0x2ed2: 0x0080, 0x2ed3: 0x0080, 0x2ed4: 0x0080, 0x2ed5: 0x0080, 0x2ed6: 0x0080, 0x2ed7: 0x0080, + 0x2ed8: 0x0080, 0x2ed9: 0x0080, 0x2eda: 0x0080, 0x2edb: 0x0080, 0x2edc: 0x0080, 0x2edd: 0x0080, + 0x2ede: 0x0080, 0x2edf: 0x0080, 0x2ee0: 0x0080, 0x2ee1: 0x0080, 0x2ee2: 0x0080, 0x2ee3: 0x0080, + 0x2ee4: 0x0080, 0x2ee5: 0x0080, 0x2ee6: 0x008c, 0x2ee7: 0x008c, 0x2ee8: 0x008c, 0x2ee9: 0x008c, + 0x2eea: 0x008c, 0x2eeb: 0x008c, 0x2eec: 0x008c, 0x2eed: 0x008c, 0x2eee: 0x008c, 0x2eef: 0x008c, + 0x2ef0: 0x0080, 0x2ef1: 0x008c, 0x2ef2: 0x008c, 0x2ef3: 0x008c, 0x2ef4: 0x008c, 0x2ef5: 0x008c, + 0x2ef6: 0x008c, 0x2ef7: 0x008c, 0x2ef8: 0x008c, 0x2ef9: 0x008c, 0x2efa: 0x008c, 0x2efb: 0x008c, + 0x2efc: 0x008c, 0x2efd: 0x008c, 0x2efe: 0x008c, 0x2eff: 0x008c, + // Block 0xbc, offset 0x2f00 + 0x2f00: 0x008c, 0x2f01: 0x008c, 0x2f02: 0x008c, 0x2f03: 0x008c, 0x2f04: 0x008c, 0x2f05: 0x008c, + 0x2f06: 0x008c, 0x2f07: 0x008c, 0x2f08: 0x008c, 0x2f09: 0x008c, 0x2f0a: 0x008c, 0x2f0b: 0x008c, + 0x2f0c: 0x008c, 0x2f0d: 0x008c, 0x2f0e: 0x008c, 0x2f0f: 0x008c, 0x2f10: 0x008c, 0x2f11: 0x008c, + 0x2f12: 0x008c, 0x2f13: 0x008c, 0x2f14: 0x008c, 0x2f15: 0x008c, 0x2f16: 0x008c, 0x2f17: 0x008c, + 0x2f18: 0x008c, 0x2f19: 0x008c, 0x2f1a: 0x008c, 0x2f1b: 0x008c, 0x2f1c: 0x008c, 0x2f1d: 0x008c, + 0x2f1e: 0x0080, 0x2f1f: 0x0080, 0x2f20: 0x0040, 0x2f21: 0x0080, 0x2f22: 0x0080, 0x2f23: 0x0080, + 0x2f24: 0x0080, 0x2f25: 0x0080, 0x2f26: 0x0080, 0x2f27: 0x0080, 0x2f28: 0x0080, 0x2f29: 0x0080, + 0x2f2a: 0x0080, 0x2f2b: 0x0080, 0x2f2c: 0x0080, 0x2f2d: 0x0080, 0x2f2e: 0x0080, 0x2f2f: 0x0080, + 0x2f30: 0x0080, 0x2f31: 0x0080, 0x2f32: 0x0080, 0x2f33: 0x0080, 0x2f34: 0x0080, 0x2f35: 0x0080, + 0x2f36: 0x0080, 0x2f37: 0x0080, 0x2f38: 0x0080, 0x2f39: 0x0080, 0x2f3a: 0x0080, 0x2f3b: 0x0080, + 0x2f3c: 0x0080, 0x2f3d: 0x0080, 0x2f3e: 0x0080, + // Block 0xbd, offset 0x2f40 + 0x2f42: 0x0080, 0x2f43: 0x0080, 0x2f44: 0x0080, 0x2f45: 0x0080, + 0x2f46: 0x0080, 0x2f47: 0x0080, 0x2f4a: 0x0080, 0x2f4b: 0x0080, + 0x2f4c: 0x0080, 0x2f4d: 0x0080, 0x2f4e: 0x0080, 0x2f4f: 0x0080, + 0x2f52: 0x0080, 0x2f53: 0x0080, 0x2f54: 0x0080, 0x2f55: 0x0080, 0x2f56: 0x0080, 0x2f57: 0x0080, + 0x2f5a: 0x0080, 0x2f5b: 0x0080, 0x2f5c: 0x0080, + 0x2f60: 0x0080, 0x2f61: 0x0080, 0x2f62: 0x0080, 0x2f63: 0x0080, + 0x2f64: 0x0080, 0x2f65: 0x0080, 0x2f66: 0x0080, 0x2f68: 0x0080, 0x2f69: 0x0080, + 0x2f6a: 0x0080, 0x2f6b: 0x0080, 0x2f6c: 0x0080, 0x2f6d: 0x0080, 0x2f6e: 0x0080, + 0x2f79: 0x0040, 0x2f7a: 0x0040, 0x2f7b: 0x0040, + 0x2f7c: 0x0080, 0x2f7d: 0x0080, + // Block 0xbe, offset 0x2f80 + 0x2f80: 0x00c0, 0x2f81: 0x00c0, 0x2f82: 0x00c0, 0x2f83: 0x00c0, 0x2f84: 0x00c0, 0x2f85: 0x00c0, + 0x2f86: 0x00c0, 0x2f87: 0x00c0, 0x2f88: 0x00c0, 0x2f89: 0x00c0, 0x2f8a: 0x00c0, 0x2f8b: 0x00c0, + 0x2f8d: 0x00c0, 0x2f8e: 0x00c0, 0x2f8f: 0x00c0, 0x2f90: 0x00c0, 0x2f91: 0x00c0, + 0x2f92: 0x00c0, 0x2f93: 0x00c0, 0x2f94: 0x00c0, 0x2f95: 0x00c0, 0x2f96: 0x00c0, 0x2f97: 0x00c0, + 0x2f98: 0x00c0, 0x2f99: 0x00c0, 0x2f9a: 0x00c0, 0x2f9b: 0x00c0, 0x2f9c: 0x00c0, 0x2f9d: 0x00c0, + 0x2f9e: 0x00c0, 0x2f9f: 0x00c0, 0x2fa0: 0x00c0, 0x2fa1: 0x00c0, 0x2fa2: 0x00c0, 0x2fa3: 0x00c0, + 0x2fa4: 0x00c0, 0x2fa5: 0x00c0, 0x2fa6: 0x00c0, 0x2fa8: 0x00c0, 0x2fa9: 0x00c0, + 0x2faa: 0x00c0, 0x2fab: 0x00c0, 0x2fac: 0x00c0, 0x2fad: 0x00c0, 0x2fae: 0x00c0, 0x2faf: 0x00c0, + 0x2fb0: 0x00c0, 0x2fb1: 0x00c0, 0x2fb2: 0x00c0, 0x2fb3: 0x00c0, 0x2fb4: 0x00c0, 0x2fb5: 0x00c0, + 0x2fb6: 0x00c0, 0x2fb7: 0x00c0, 0x2fb8: 0x00c0, 0x2fb9: 0x00c0, 0x2fba: 0x00c0, + 0x2fbc: 0x00c0, 0x2fbd: 0x00c0, 0x2fbf: 0x00c0, + // Block 0xbf, offset 0x2fc0 + 0x2fc0: 0x00c0, 0x2fc1: 0x00c0, 0x2fc2: 0x00c0, 0x2fc3: 0x00c0, 0x2fc4: 0x00c0, 0x2fc5: 0x00c0, + 0x2fc6: 0x00c0, 0x2fc7: 0x00c0, 0x2fc8: 0x00c0, 0x2fc9: 0x00c0, 0x2fca: 0x00c0, 0x2fcb: 0x00c0, + 0x2fcc: 0x00c0, 0x2fcd: 0x00c0, 0x2fd0: 0x00c0, 0x2fd1: 0x00c0, + 0x2fd2: 0x00c0, 0x2fd3: 0x00c0, 0x2fd4: 0x00c0, 0x2fd5: 0x00c0, 0x2fd6: 0x00c0, 0x2fd7: 0x00c0, + 0x2fd8: 0x00c0, 0x2fd9: 0x00c0, 0x2fda: 0x00c0, 0x2fdb: 0x00c0, 0x2fdc: 0x00c0, 0x2fdd: 0x00c0, + // Block 0xc0, offset 0x3000 + 0x3000: 0x00c0, 0x3001: 0x00c0, 0x3002: 0x00c0, 0x3003: 0x00c0, 0x3004: 0x00c0, 0x3005: 0x00c0, + 0x3006: 0x00c0, 0x3007: 0x00c0, 0x3008: 0x00c0, 0x3009: 0x00c0, 0x300a: 0x00c0, 0x300b: 0x00c0, + 0x300c: 0x00c0, 0x300d: 0x00c0, 0x300e: 0x00c0, 0x300f: 0x00c0, 0x3010: 0x00c0, 0x3011: 0x00c0, + 0x3012: 0x00c0, 0x3013: 0x00c0, 0x3014: 0x00c0, 0x3015: 0x00c0, 0x3016: 0x00c0, 0x3017: 0x00c0, + 0x3018: 0x00c0, 0x3019: 0x00c0, 0x301a: 0x00c0, 0x301b: 0x00c0, 0x301c: 0x00c0, 0x301d: 0x00c0, + 0x301e: 0x00c0, 0x301f: 0x00c0, 0x3020: 0x00c0, 0x3021: 0x00c0, 0x3022: 0x00c0, 0x3023: 0x00c0, + 0x3024: 0x00c0, 0x3025: 0x00c0, 0x3026: 0x00c0, 0x3027: 0x00c0, 0x3028: 0x00c0, 0x3029: 0x00c0, + 0x302a: 0x00c0, 0x302b: 0x00c0, 0x302c: 0x00c0, 0x302d: 0x00c0, 0x302e: 0x00c0, 0x302f: 0x00c0, + 0x3030: 0x00c0, 0x3031: 0x00c0, 0x3032: 0x00c0, 0x3033: 0x00c0, 0x3034: 0x00c0, 0x3035: 0x00c0, + 0x3036: 0x00c0, 0x3037: 0x00c0, 0x3038: 0x00c0, 0x3039: 0x00c0, 0x303a: 0x00c0, + // Block 0xc1, offset 0x3040 + 0x3040: 0x0080, 0x3041: 0x0080, 0x3042: 0x0080, + 0x3047: 0x0080, 0x3048: 0x0080, 0x3049: 0x0080, 0x304a: 0x0080, 0x304b: 0x0080, + 0x304c: 0x0080, 0x304d: 0x0080, 0x304e: 0x0080, 0x304f: 0x0080, 0x3050: 0x0080, 0x3051: 0x0080, + 0x3052: 0x0080, 0x3053: 0x0080, 0x3054: 0x0080, 0x3055: 0x0080, 0x3056: 0x0080, 0x3057: 0x0080, + 0x3058: 0x0080, 0x3059: 0x0080, 0x305a: 0x0080, 0x305b: 0x0080, 0x305c: 0x0080, 0x305d: 0x0080, + 0x305e: 0x0080, 0x305f: 0x0080, 0x3060: 0x0080, 0x3061: 0x0080, 0x3062: 0x0080, 0x3063: 0x0080, + 0x3064: 0x0080, 0x3065: 0x0080, 0x3066: 0x0080, 0x3067: 0x0080, 0x3068: 0x0080, 0x3069: 0x0080, + 0x306a: 0x0080, 0x306b: 0x0080, 0x306c: 0x0080, 0x306d: 0x0080, 0x306e: 0x0080, 0x306f: 0x0080, + 0x3070: 0x0080, 0x3071: 0x0080, 0x3072: 0x0080, 0x3073: 0x0080, + 0x3077: 0x0080, 0x3078: 0x0080, 0x3079: 0x0080, 0x307a: 0x0080, 0x307b: 0x0080, + 0x307c: 0x0080, 0x307d: 0x0080, 0x307e: 0x0080, 0x307f: 0x0080, + // Block 0xc2, offset 0x3080 + 0x3080: 0x0088, 0x3081: 0x0088, 0x3082: 0x0088, 0x3083: 0x0088, 0x3084: 0x0088, 0x3085: 0x0088, + 0x3086: 0x0088, 0x3087: 0x0088, 0x3088: 0x0088, 0x3089: 0x0088, 0x308a: 0x0088, 0x308b: 0x0088, + 0x308c: 0x0088, 0x308d: 0x0088, 0x308e: 0x0088, 0x308f: 0x0088, 0x3090: 0x0088, 0x3091: 0x0088, + 0x3092: 0x0088, 0x3093: 0x0088, 0x3094: 0x0088, 0x3095: 0x0088, 0x3096: 0x0088, 0x3097: 0x0088, + 0x3098: 0x0088, 0x3099: 0x0088, 0x309a: 0x0088, 0x309b: 0x0088, 0x309c: 0x0088, 0x309d: 0x0088, + 0x309e: 0x0088, 0x309f: 0x0088, 0x30a0: 0x0088, 0x30a1: 0x0088, 0x30a2: 0x0088, 0x30a3: 0x0088, + 0x30a4: 0x0088, 0x30a5: 0x0088, 0x30a6: 0x0088, 0x30a7: 0x0088, 0x30a8: 0x0088, 0x30a9: 0x0088, + 0x30aa: 0x0088, 0x30ab: 0x0088, 0x30ac: 0x0088, 0x30ad: 0x0088, 0x30ae: 0x0088, 0x30af: 0x0088, + 0x30b0: 0x0088, 0x30b1: 0x0088, 0x30b2: 0x0088, 0x30b3: 0x0088, 0x30b4: 0x0088, 0x30b5: 0x0088, + 0x30b6: 0x0088, 0x30b7: 0x0088, 0x30b8: 0x0088, 0x30b9: 0x0088, 0x30ba: 0x0088, 0x30bb: 0x0088, + 0x30bc: 0x0088, 0x30bd: 0x0088, 0x30be: 0x0088, 0x30bf: 0x0088, + // Block 0xc3, offset 0x30c0 + 0x30c0: 0x0088, 0x30c1: 0x0088, 0x30c2: 0x0088, 0x30c3: 0x0088, 0x30c4: 0x0088, 0x30c5: 0x0088, + 0x30c6: 0x0088, 0x30c7: 0x0088, 0x30c8: 0x0088, 0x30c9: 0x0088, 0x30ca: 0x0088, 0x30cb: 0x0088, + 0x30cc: 0x0088, 0x30cd: 0x0088, 0x30ce: 0x0088, 0x30d0: 0x0080, 0x30d1: 0x0080, + 0x30d2: 0x0080, 0x30d3: 0x0080, 0x30d4: 0x0080, 0x30d5: 0x0080, 0x30d6: 0x0080, 0x30d7: 0x0080, + 0x30d8: 0x0080, 0x30d9: 0x0080, 0x30da: 0x0080, 0x30db: 0x0080, + 0x30e0: 0x0088, + // Block 0xc4, offset 0x3100 + 0x3110: 0x0080, 0x3111: 0x0080, + 0x3112: 0x0080, 0x3113: 0x0080, 0x3114: 0x0080, 0x3115: 0x0080, 0x3116: 0x0080, 0x3117: 0x0080, + 0x3118: 0x0080, 0x3119: 0x0080, 0x311a: 0x0080, 0x311b: 0x0080, 0x311c: 0x0080, 0x311d: 0x0080, + 0x311e: 0x0080, 0x311f: 0x0080, 0x3120: 0x0080, 0x3121: 0x0080, 0x3122: 0x0080, 0x3123: 0x0080, + 0x3124: 0x0080, 0x3125: 0x0080, 0x3126: 0x0080, 0x3127: 0x0080, 0x3128: 0x0080, 0x3129: 0x0080, + 0x312a: 0x0080, 0x312b: 0x0080, 0x312c: 0x0080, 0x312d: 0x0080, 0x312e: 0x0080, 0x312f: 0x0080, + 0x3130: 0x0080, 0x3131: 0x0080, 0x3132: 0x0080, 0x3133: 0x0080, 0x3134: 0x0080, 0x3135: 0x0080, + 0x3136: 0x0080, 0x3137: 0x0080, 0x3138: 0x0080, 0x3139: 0x0080, 0x313a: 0x0080, 0x313b: 0x0080, + 0x313c: 0x0080, 0x313d: 0x00c3, + // Block 0xc5, offset 0x3140 + 0x3140: 0x00c0, 0x3141: 0x00c0, 0x3142: 0x00c0, 0x3143: 0x00c0, 0x3144: 0x00c0, 0x3145: 0x00c0, + 0x3146: 0x00c0, 0x3147: 0x00c0, 0x3148: 0x00c0, 0x3149: 0x00c0, 0x314a: 0x00c0, 0x314b: 0x00c0, + 0x314c: 0x00c0, 0x314d: 0x00c0, 0x314e: 0x00c0, 0x314f: 0x00c0, 0x3150: 0x00c0, 0x3151: 0x00c0, + 0x3152: 0x00c0, 0x3153: 0x00c0, 0x3154: 0x00c0, 0x3155: 0x00c0, 0x3156: 0x00c0, 0x3157: 0x00c0, + 0x3158: 0x00c0, 0x3159: 0x00c0, 0x315a: 0x00c0, 0x315b: 0x00c0, 0x315c: 0x00c0, + 0x3160: 0x00c0, 0x3161: 0x00c0, 0x3162: 0x00c0, 0x3163: 0x00c0, + 0x3164: 0x00c0, 0x3165: 0x00c0, 0x3166: 0x00c0, 0x3167: 0x00c0, 0x3168: 0x00c0, 0x3169: 0x00c0, + 0x316a: 0x00c0, 0x316b: 0x00c0, 0x316c: 0x00c0, 0x316d: 0x00c0, 0x316e: 0x00c0, 0x316f: 0x00c0, + 0x3170: 0x00c0, 0x3171: 0x00c0, 0x3172: 0x00c0, 0x3173: 0x00c0, 0x3174: 0x00c0, 0x3175: 0x00c0, + 0x3176: 0x00c0, 0x3177: 0x00c0, 0x3178: 0x00c0, 0x3179: 0x00c0, 0x317a: 0x00c0, 0x317b: 0x00c0, + 0x317c: 0x00c0, 0x317d: 0x00c0, 0x317e: 0x00c0, 0x317f: 0x00c0, + // Block 0xc6, offset 0x3180 + 0x3180: 0x00c0, 0x3181: 0x00c0, 0x3182: 0x00c0, 0x3183: 0x00c0, 0x3184: 0x00c0, 0x3185: 0x00c0, + 0x3186: 0x00c0, 0x3187: 0x00c0, 0x3188: 0x00c0, 0x3189: 0x00c0, 0x318a: 0x00c0, 0x318b: 0x00c0, + 0x318c: 0x00c0, 0x318d: 0x00c0, 0x318e: 0x00c0, 0x318f: 0x00c0, 0x3190: 0x00c0, + 0x31a0: 0x00c3, 0x31a1: 0x0080, 0x31a2: 0x0080, 0x31a3: 0x0080, + 0x31a4: 0x0080, 0x31a5: 0x0080, 0x31a6: 0x0080, 0x31a7: 0x0080, 0x31a8: 0x0080, 0x31a9: 0x0080, + 0x31aa: 0x0080, 0x31ab: 0x0080, 0x31ac: 0x0080, 0x31ad: 0x0080, 0x31ae: 0x0080, 0x31af: 0x0080, + 0x31b0: 0x0080, 0x31b1: 0x0080, 0x31b2: 0x0080, 0x31b3: 0x0080, 0x31b4: 0x0080, 0x31b5: 0x0080, + 0x31b6: 0x0080, 0x31b7: 0x0080, 0x31b8: 0x0080, 0x31b9: 0x0080, 0x31ba: 0x0080, 0x31bb: 0x0080, + // Block 0xc7, offset 0x31c0 + 0x31c0: 0x00c0, 0x31c1: 0x00c0, 0x31c2: 0x00c0, 0x31c3: 0x00c0, 0x31c4: 0x00c0, 0x31c5: 0x00c0, + 0x31c6: 0x00c0, 0x31c7: 0x00c0, 0x31c8: 0x00c0, 0x31c9: 0x00c0, 0x31ca: 0x00c0, 0x31cb: 0x00c0, + 0x31cc: 0x00c0, 0x31cd: 0x00c0, 0x31ce: 0x00c0, 0x31cf: 0x00c0, 0x31d0: 0x00c0, 0x31d1: 0x00c0, + 0x31d2: 0x00c0, 0x31d3: 0x00c0, 0x31d4: 0x00c0, 0x31d5: 0x00c0, 0x31d6: 0x00c0, 0x31d7: 0x00c0, + 0x31d8: 0x00c0, 0x31d9: 0x00c0, 0x31da: 0x00c0, 0x31db: 0x00c0, 0x31dc: 0x00c0, 0x31dd: 0x00c0, + 0x31de: 0x00c0, 0x31df: 0x00c0, 0x31e0: 0x0080, 0x31e1: 0x0080, 0x31e2: 0x0080, 0x31e3: 0x0080, + 0x31ed: 0x00c0, 0x31ee: 0x00c0, 0x31ef: 0x00c0, + 0x31f0: 0x00c0, 0x31f1: 0x00c0, 0x31f2: 0x00c0, 0x31f3: 0x00c0, 0x31f4: 0x00c0, 0x31f5: 0x00c0, + 0x31f6: 0x00c0, 0x31f7: 0x00c0, 0x31f8: 0x00c0, 0x31f9: 0x00c0, 0x31fa: 0x00c0, 0x31fb: 0x00c0, + 0x31fc: 0x00c0, 0x31fd: 0x00c0, 0x31fe: 0x00c0, 0x31ff: 0x00c0, + // Block 0xc8, offset 0x3200 + 0x3200: 0x00c0, 0x3201: 0x0080, 0x3202: 0x00c0, 0x3203: 0x00c0, 0x3204: 0x00c0, 0x3205: 0x00c0, + 0x3206: 0x00c0, 0x3207: 0x00c0, 0x3208: 0x00c0, 0x3209: 0x00c0, 0x320a: 0x0080, + 0x3210: 0x00c0, 0x3211: 0x00c0, + 0x3212: 0x00c0, 0x3213: 0x00c0, 0x3214: 0x00c0, 0x3215: 0x00c0, 0x3216: 0x00c0, 0x3217: 0x00c0, + 0x3218: 0x00c0, 0x3219: 0x00c0, 0x321a: 0x00c0, 0x321b: 0x00c0, 0x321c: 0x00c0, 0x321d: 0x00c0, + 0x321e: 0x00c0, 0x321f: 0x00c0, 0x3220: 0x00c0, 0x3221: 0x00c0, 0x3222: 0x00c0, 0x3223: 0x00c0, + 0x3224: 0x00c0, 0x3225: 0x00c0, 0x3226: 0x00c0, 0x3227: 0x00c0, 0x3228: 0x00c0, 0x3229: 0x00c0, + 0x322a: 0x00c0, 0x322b: 0x00c0, 0x322c: 0x00c0, 0x322d: 0x00c0, 0x322e: 0x00c0, 0x322f: 0x00c0, + 0x3230: 0x00c0, 0x3231: 0x00c0, 0x3232: 0x00c0, 0x3233: 0x00c0, 0x3234: 0x00c0, 0x3235: 0x00c0, + 0x3236: 0x00c3, 0x3237: 0x00c3, 0x3238: 0x00c3, 0x3239: 0x00c3, 0x323a: 0x00c3, + // Block 0xc9, offset 0x3240 + 0x3240: 0x00c0, 0x3241: 0x00c0, 0x3242: 0x00c0, 0x3243: 0x00c0, 0x3244: 0x00c0, 0x3245: 0x00c0, + 0x3246: 0x00c0, 0x3247: 0x00c0, 0x3248: 0x00c0, 0x3249: 0x00c0, 0x324a: 0x00c0, 0x324b: 0x00c0, + 0x324c: 0x00c0, 0x324d: 0x00c0, 0x324e: 0x00c0, 0x324f: 0x00c0, 0x3250: 0x00c0, 0x3251: 0x00c0, + 0x3252: 0x00c0, 0x3253: 0x00c0, 0x3254: 0x00c0, 0x3255: 0x00c0, 0x3256: 0x00c0, 0x3257: 0x00c0, + 0x3258: 0x00c0, 0x3259: 0x00c0, 0x325a: 0x00c0, 0x325b: 0x00c0, 0x325c: 0x00c0, 0x325d: 0x00c0, + 0x325f: 0x0080, 0x3260: 0x00c0, 0x3261: 0x00c0, 0x3262: 0x00c0, 0x3263: 0x00c0, + 0x3264: 0x00c0, 0x3265: 0x00c0, 0x3266: 0x00c0, 0x3267: 0x00c0, 0x3268: 0x00c0, 0x3269: 0x00c0, + 0x326a: 0x00c0, 0x326b: 0x00c0, 0x326c: 0x00c0, 0x326d: 0x00c0, 0x326e: 0x00c0, 0x326f: 0x00c0, + 0x3270: 0x00c0, 0x3271: 0x00c0, 0x3272: 0x00c0, 0x3273: 0x00c0, 0x3274: 0x00c0, 0x3275: 0x00c0, + 0x3276: 0x00c0, 0x3277: 0x00c0, 0x3278: 0x00c0, 0x3279: 0x00c0, 0x327a: 0x00c0, 0x327b: 0x00c0, + 0x327c: 0x00c0, 0x327d: 0x00c0, 0x327e: 0x00c0, 0x327f: 0x00c0, + // Block 0xca, offset 0x3280 + 0x3280: 0x00c0, 0x3281: 0x00c0, 0x3282: 0x00c0, 0x3283: 0x00c0, + 0x3288: 0x00c0, 0x3289: 0x00c0, 0x328a: 0x00c0, 0x328b: 0x00c0, + 0x328c: 0x00c0, 0x328d: 0x00c0, 0x328e: 0x00c0, 0x328f: 0x00c0, 0x3290: 0x0080, 0x3291: 0x0080, + 0x3292: 0x0080, 0x3293: 0x0080, 0x3294: 0x0080, 0x3295: 0x0080, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x00c0, 0x32c1: 0x00c0, 0x32c2: 0x00c0, 0x32c3: 0x00c0, 0x32c4: 0x00c0, 0x32c5: 0x00c0, + 0x32c6: 0x00c0, 0x32c7: 0x00c0, 0x32c8: 0x00c0, 0x32c9: 0x00c0, 0x32ca: 0x00c0, 0x32cb: 0x00c0, + 0x32cc: 0x00c0, 0x32cd: 0x00c0, 0x32ce: 0x00c0, 0x32cf: 0x00c0, 0x32d0: 0x00c0, 0x32d1: 0x00c0, + 0x32d2: 0x00c0, 0x32d3: 0x00c0, 0x32d4: 0x00c0, 0x32d5: 0x00c0, 0x32d6: 0x00c0, 0x32d7: 0x00c0, + 0x32d8: 0x00c0, 0x32d9: 0x00c0, 0x32da: 0x00c0, 0x32db: 0x00c0, 0x32dc: 0x00c0, 0x32dd: 0x00c0, + 0x32e0: 0x00c0, 0x32e1: 0x00c0, 0x32e2: 0x00c0, 0x32e3: 0x00c0, + 0x32e4: 0x00c0, 0x32e5: 0x00c0, 0x32e6: 0x00c0, 0x32e7: 0x00c0, 0x32e8: 0x00c0, 0x32e9: 0x00c0, + 0x32f0: 0x00c0, 0x32f1: 0x00c0, 0x32f2: 0x00c0, 0x32f3: 0x00c0, 0x32f4: 0x00c0, 0x32f5: 0x00c0, + 0x32f6: 0x00c0, 0x32f7: 0x00c0, 0x32f8: 0x00c0, 0x32f9: 0x00c0, 0x32fa: 0x00c0, 0x32fb: 0x00c0, + 0x32fc: 0x00c0, 0x32fd: 0x00c0, 0x32fe: 0x00c0, 0x32ff: 0x00c0, + // Block 0xcc, offset 0x3300 + 0x3300: 0x00c0, 0x3301: 0x00c0, 0x3302: 0x00c0, 0x3303: 0x00c0, 0x3304: 0x00c0, 0x3305: 0x00c0, + 0x3306: 0x00c0, 0x3307: 0x00c0, 0x3308: 0x00c0, 0x3309: 0x00c0, 0x330a: 0x00c0, 0x330b: 0x00c0, + 0x330c: 0x00c0, 0x330d: 0x00c0, 0x330e: 0x00c0, 0x330f: 0x00c0, 0x3310: 0x00c0, 0x3311: 0x00c0, + 0x3312: 0x00c0, 0x3313: 0x00c0, + 0x3318: 0x00c0, 0x3319: 0x00c0, 0x331a: 0x00c0, 0x331b: 0x00c0, 0x331c: 0x00c0, 0x331d: 0x00c0, + 0x331e: 0x00c0, 0x331f: 0x00c0, 0x3320: 0x00c0, 0x3321: 0x00c0, 0x3322: 0x00c0, 0x3323: 0x00c0, + 0x3324: 0x00c0, 0x3325: 0x00c0, 0x3326: 0x00c0, 0x3327: 0x00c0, 0x3328: 0x00c0, 0x3329: 0x00c0, + 0x332a: 0x00c0, 0x332b: 0x00c0, 0x332c: 0x00c0, 0x332d: 0x00c0, 0x332e: 0x00c0, 0x332f: 0x00c0, + 0x3330: 0x00c0, 0x3331: 0x00c0, 0x3332: 0x00c0, 0x3333: 0x00c0, 0x3334: 0x00c0, 0x3335: 0x00c0, + 0x3336: 0x00c0, 0x3337: 0x00c0, 0x3338: 0x00c0, 0x3339: 0x00c0, 0x333a: 0x00c0, 0x333b: 0x00c0, + // Block 0xcd, offset 0x3340 + 0x3340: 0x00c0, 0x3341: 0x00c0, 0x3342: 0x00c0, 0x3343: 0x00c0, 0x3344: 0x00c0, 0x3345: 0x00c0, + 0x3346: 0x00c0, 0x3347: 0x00c0, 0x3348: 0x00c0, 0x3349: 0x00c0, 0x334a: 0x00c0, 0x334b: 0x00c0, + 0x334c: 0x00c0, 0x334d: 0x00c0, 0x334e: 0x00c0, 0x334f: 0x00c0, 0x3350: 0x00c0, 0x3351: 0x00c0, + 0x3352: 0x00c0, 0x3353: 0x00c0, 0x3354: 0x00c0, 0x3355: 0x00c0, 0x3356: 0x00c0, 0x3357: 0x00c0, + 0x3358: 0x00c0, 0x3359: 0x00c0, 0x335a: 0x00c0, 0x335b: 0x00c0, 0x335c: 0x00c0, 0x335d: 0x00c0, + 0x335e: 0x00c0, 0x335f: 0x00c0, 0x3360: 0x00c0, 0x3361: 0x00c0, 0x3362: 0x00c0, 0x3363: 0x00c0, + 0x3364: 0x00c0, 0x3365: 0x00c0, 0x3366: 0x00c0, 0x3367: 0x00c0, + 0x3370: 0x00c0, 0x3371: 0x00c0, 0x3372: 0x00c0, 0x3373: 0x00c0, 0x3374: 0x00c0, 0x3375: 0x00c0, + 0x3376: 0x00c0, 0x3377: 0x00c0, 0x3378: 0x00c0, 0x3379: 0x00c0, 0x337a: 0x00c0, 0x337b: 0x00c0, + 0x337c: 0x00c0, 0x337d: 0x00c0, 0x337e: 0x00c0, 0x337f: 0x00c0, + // Block 0xce, offset 0x3380 + 0x3380: 0x00c0, 0x3381: 0x00c0, 0x3382: 0x00c0, 0x3383: 0x00c0, 0x3384: 0x00c0, 0x3385: 0x00c0, + 0x3386: 0x00c0, 0x3387: 0x00c0, 0x3388: 0x00c0, 0x3389: 0x00c0, 0x338a: 0x00c0, 0x338b: 0x00c0, + 0x338c: 0x00c0, 0x338d: 0x00c0, 0x338e: 0x00c0, 0x338f: 0x00c0, 0x3390: 0x00c0, 0x3391: 0x00c0, + 0x3392: 0x00c0, 0x3393: 0x00c0, 0x3394: 0x00c0, 0x3395: 0x00c0, 0x3396: 0x00c0, 0x3397: 0x00c0, + 0x3398: 0x00c0, 0x3399: 0x00c0, 0x339a: 0x00c0, 0x339b: 0x00c0, 0x339c: 0x00c0, 0x339d: 0x00c0, + 0x339e: 0x00c0, 0x339f: 0x00c0, 0x33a0: 0x00c0, 0x33a1: 0x00c0, 0x33a2: 0x00c0, 0x33a3: 0x00c0, + 0x33af: 0x0080, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x00c0, 0x33c1: 0x00c0, 0x33c2: 0x00c0, 0x33c3: 0x00c0, 0x33c4: 0x00c0, 0x33c5: 0x00c0, + 0x33c6: 0x00c0, 0x33c7: 0x00c0, 0x33c8: 0x00c0, 0x33c9: 0x00c0, 0x33ca: 0x00c0, 0x33cb: 0x00c0, + 0x33cc: 0x00c0, 0x33cd: 0x00c0, 0x33ce: 0x00c0, 0x33cf: 0x00c0, 0x33d0: 0x00c0, 0x33d1: 0x00c0, + 0x33d2: 0x00c0, 0x33d3: 0x00c0, 0x33d4: 0x00c0, 0x33d5: 0x00c0, 0x33d6: 0x00c0, 0x33d7: 0x00c0, + 0x33d8: 0x00c0, 0x33d9: 0x00c0, 0x33da: 0x00c0, 0x33db: 0x00c0, 0x33dc: 0x00c0, 0x33dd: 0x00c0, + 0x33de: 0x00c0, 0x33df: 0x00c0, 0x33e0: 0x00c0, 0x33e1: 0x00c0, 0x33e2: 0x00c0, 0x33e3: 0x00c0, + 0x33e4: 0x00c0, 0x33e5: 0x00c0, 0x33e6: 0x00c0, 0x33e7: 0x00c0, 0x33e8: 0x00c0, 0x33e9: 0x00c0, + 0x33ea: 0x00c0, 0x33eb: 0x00c0, 0x33ec: 0x00c0, 0x33ed: 0x00c0, 0x33ee: 0x00c0, 0x33ef: 0x00c0, + 0x33f0: 0x00c0, 0x33f1: 0x00c0, 0x33f2: 0x00c0, 0x33f3: 0x00c0, 0x33f4: 0x00c0, 0x33f5: 0x00c0, + 0x33f6: 0x00c0, + // Block 0xd0, offset 0x3400 + 0x3400: 0x00c0, 0x3401: 0x00c0, 0x3402: 0x00c0, 0x3403: 0x00c0, 0x3404: 0x00c0, 0x3405: 0x00c0, + 0x3406: 0x00c0, 0x3407: 0x00c0, 0x3408: 0x00c0, 0x3409: 0x00c0, 0x340a: 0x00c0, 0x340b: 0x00c0, + 0x340c: 0x00c0, 0x340d: 0x00c0, 0x340e: 0x00c0, 0x340f: 0x00c0, 0x3410: 0x00c0, 0x3411: 0x00c0, + 0x3412: 0x00c0, 0x3413: 0x00c0, 0x3414: 0x00c0, 0x3415: 0x00c0, + 0x3420: 0x00c0, 0x3421: 0x00c0, 0x3422: 0x00c0, 0x3423: 0x00c0, + 0x3424: 0x00c0, 0x3425: 0x00c0, 0x3426: 0x00c0, 0x3427: 0x00c0, + // Block 0xd1, offset 0x3440 + 0x3440: 0x00c0, 0x3441: 0x00c0, 0x3442: 0x00c0, 0x3443: 0x00c0, 0x3444: 0x00c0, 0x3445: 0x00c0, + 0x3448: 0x00c0, 0x344a: 0x00c0, 0x344b: 0x00c0, + 0x344c: 0x00c0, 0x344d: 0x00c0, 0x344e: 0x00c0, 0x344f: 0x00c0, 0x3450: 0x00c0, 0x3451: 0x00c0, + 0x3452: 0x00c0, 0x3453: 0x00c0, 0x3454: 0x00c0, 0x3455: 0x00c0, 0x3456: 0x00c0, 0x3457: 0x00c0, + 0x3458: 0x00c0, 0x3459: 0x00c0, 0x345a: 0x00c0, 0x345b: 0x00c0, 0x345c: 0x00c0, 0x345d: 0x00c0, + 0x345e: 0x00c0, 0x345f: 0x00c0, 0x3460: 0x00c0, 0x3461: 0x00c0, 0x3462: 0x00c0, 0x3463: 0x00c0, + 0x3464: 0x00c0, 0x3465: 0x00c0, 0x3466: 0x00c0, 0x3467: 0x00c0, 0x3468: 0x00c0, 0x3469: 0x00c0, + 0x346a: 0x00c0, 0x346b: 0x00c0, 0x346c: 0x00c0, 0x346d: 0x00c0, 0x346e: 0x00c0, 0x346f: 0x00c0, + 0x3470: 0x00c0, 0x3471: 0x00c0, 0x3472: 0x00c0, 0x3473: 0x00c0, 0x3474: 0x00c0, 0x3475: 0x00c0, + 0x3477: 0x00c0, 0x3478: 0x00c0, + 0x347c: 0x00c0, 0x347f: 0x00c0, + // Block 0xd2, offset 0x3480 + 0x3480: 0x00c0, 0x3481: 0x00c0, 0x3482: 0x00c0, 0x3483: 0x00c0, 0x3484: 0x00c0, 0x3485: 0x00c0, + 0x3486: 0x00c0, 0x3487: 0x00c0, 0x3488: 0x00c0, 0x3489: 0x00c0, 0x348a: 0x00c0, 0x348b: 0x00c0, + 0x348c: 0x00c0, 0x348d: 0x00c0, 0x348e: 0x00c0, 0x348f: 0x00c0, 0x3490: 0x00c0, 0x3491: 0x00c0, + 0x3492: 0x00c0, 0x3493: 0x00c0, 0x3494: 0x00c0, 0x3495: 0x00c0, 0x3497: 0x0080, + 0x3498: 0x0080, 0x3499: 0x0080, 0x349a: 0x0080, 0x349b: 0x0080, 0x349c: 0x0080, 0x349d: 0x0080, + 0x349e: 0x0080, 0x349f: 0x0080, 0x34a0: 0x00c0, 0x34a1: 0x00c0, 0x34a2: 0x00c0, 0x34a3: 0x00c0, + 0x34a4: 0x00c0, 0x34a5: 0x00c0, 0x34a6: 0x00c0, 0x34a7: 0x00c0, 0x34a8: 0x00c0, 0x34a9: 0x00c0, + 0x34aa: 0x00c0, 0x34ab: 0x00c0, 0x34ac: 0x00c0, 0x34ad: 0x00c0, 0x34ae: 0x00c0, 0x34af: 0x00c0, + 0x34b0: 0x00c0, 0x34b1: 0x00c0, 0x34b2: 0x00c0, 0x34b3: 0x00c0, 0x34b4: 0x00c0, 0x34b5: 0x00c0, + 0x34b6: 0x00c0, 0x34b7: 0x0080, 0x34b8: 0x0080, 0x34b9: 0x0080, 0x34ba: 0x0080, 0x34bb: 0x0080, + 0x34bc: 0x0080, 0x34bd: 0x0080, 0x34be: 0x0080, 0x34bf: 0x0080, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x00c0, 0x34c1: 0x00c0, 0x34c2: 0x00c0, 0x34c3: 0x00c0, 0x34c4: 0x00c0, 0x34c5: 0x00c0, + 0x34c6: 0x00c0, 0x34c7: 0x00c0, 0x34c8: 0x00c0, 0x34c9: 0x00c0, 0x34ca: 0x00c0, 0x34cb: 0x00c0, + 0x34cc: 0x00c0, 0x34cd: 0x00c0, 0x34ce: 0x00c0, 0x34cf: 0x00c0, 0x34d0: 0x00c0, 0x34d1: 0x00c0, + 0x34d2: 0x00c0, 0x34d3: 0x00c0, 0x34d4: 0x00c0, 0x34d5: 0x00c0, 0x34d6: 0x00c0, 0x34d7: 0x00c0, + 0x34d8: 0x00c0, 0x34d9: 0x00c0, 0x34da: 0x00c0, 0x34db: 0x00c0, 0x34dc: 0x00c0, 0x34dd: 0x00c0, + 0x34de: 0x00c0, + 0x34e7: 0x0080, 0x34e8: 0x0080, 0x34e9: 0x0080, + 0x34ea: 0x0080, 0x34eb: 0x0080, 0x34ec: 0x0080, 0x34ed: 0x0080, 0x34ee: 0x0080, 0x34ef: 0x0080, + // Block 0xd4, offset 0x3500 + 0x3520: 0x00c0, 0x3521: 0x00c0, 0x3522: 0x00c0, 0x3523: 0x00c0, + 0x3524: 0x00c0, 0x3525: 0x00c0, 0x3526: 0x00c0, 0x3527: 0x00c0, 0x3528: 0x00c0, 0x3529: 0x00c0, + 0x352a: 0x00c0, 0x352b: 0x00c0, 0x352c: 0x00c0, 0x352d: 0x00c0, 0x352e: 0x00c0, 0x352f: 0x00c0, + 0x3530: 0x00c0, 0x3531: 0x00c0, 0x3532: 0x00c0, 0x3534: 0x00c0, 0x3535: 0x00c0, + 0x353b: 0x0080, + 0x353c: 0x0080, 0x353d: 0x0080, 0x353e: 0x0080, 0x353f: 0x0080, + // Block 0xd5, offset 0x3540 + 0x3540: 0x00c0, 0x3541: 0x00c0, 0x3542: 0x00c0, 0x3543: 0x00c0, 0x3544: 0x00c0, 0x3545: 0x00c0, + 0x3546: 0x00c0, 0x3547: 0x00c0, 0x3548: 0x00c0, 0x3549: 0x00c0, 0x354a: 0x00c0, 0x354b: 0x00c0, + 0x354c: 0x00c0, 0x354d: 0x00c0, 0x354e: 0x00c0, 0x354f: 0x00c0, 0x3550: 0x00c0, 0x3551: 0x00c0, + 0x3552: 0x00c0, 0x3553: 0x00c0, 0x3554: 0x00c0, 0x3555: 0x00c0, 0x3556: 0x0080, 0x3557: 0x0080, + 0x3558: 0x0080, 0x3559: 0x0080, 0x355a: 0x0080, 0x355b: 0x0080, + 0x355f: 0x0080, 0x3560: 0x00c0, 0x3561: 0x00c0, 0x3562: 0x00c0, 0x3563: 0x00c0, + 0x3564: 0x00c0, 0x3565: 0x00c0, 0x3566: 0x00c0, 0x3567: 0x00c0, 0x3568: 0x00c0, 0x3569: 0x00c0, + 0x356a: 0x00c0, 0x356b: 0x00c0, 0x356c: 0x00c0, 0x356d: 0x00c0, 0x356e: 0x00c0, 0x356f: 0x00c0, + 0x3570: 0x00c0, 0x3571: 0x00c0, 0x3572: 0x00c0, 0x3573: 0x00c0, 0x3574: 0x00c0, 0x3575: 0x00c0, + 0x3576: 0x00c0, 0x3577: 0x00c0, 0x3578: 0x00c0, 0x3579: 0x00c0, + 0x357f: 0x0080, + // Block 0xd6, offset 0x3580 + 0x3580: 0x00c0, 0x3581: 0x00c0, 0x3582: 0x00c0, 0x3583: 0x00c0, 0x3584: 0x00c0, 0x3585: 0x00c0, + 0x3586: 0x00c0, 0x3587: 0x00c0, 0x3588: 0x00c0, 0x3589: 0x00c0, 0x358a: 0x00c0, 0x358b: 0x00c0, + 0x358c: 0x00c0, 0x358d: 0x00c0, 0x358e: 0x00c0, 0x358f: 0x00c0, 0x3590: 0x00c0, 0x3591: 0x00c0, + 0x3592: 0x00c0, 0x3593: 0x00c0, 0x3594: 0x00c0, 0x3595: 0x00c0, 0x3596: 0x00c0, 0x3597: 0x00c0, + 0x3598: 0x00c0, 0x3599: 0x00c0, 0x359a: 0x00c0, 0x359b: 0x00c0, 0x359c: 0x00c0, 0x359d: 0x00c0, + 0x359e: 0x00c0, 0x359f: 0x00c0, 0x35a0: 0x00c0, 0x35a1: 0x00c0, 0x35a2: 0x00c0, 0x35a3: 0x00c0, + 0x35a4: 0x00c0, 0x35a5: 0x00c0, 0x35a6: 0x00c0, 0x35a7: 0x00c0, 0x35a8: 0x00c0, 0x35a9: 0x00c0, + 0x35aa: 0x00c0, 0x35ab: 0x00c0, 0x35ac: 0x00c0, 0x35ad: 0x00c0, 0x35ae: 0x00c0, 0x35af: 0x00c0, + 0x35b0: 0x00c0, 0x35b1: 0x00c0, 0x35b2: 0x00c0, 0x35b3: 0x00c0, 0x35b4: 0x00c0, 0x35b5: 0x00c0, + 0x35b6: 0x00c0, 0x35b7: 0x00c0, + 0x35bc: 0x0080, 0x35bd: 0x0080, 0x35be: 0x00c0, 0x35bf: 0x00c0, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x00c0, 0x35c1: 0x00c3, 0x35c2: 0x00c3, 0x35c3: 0x00c3, 0x35c5: 0x00c3, + 0x35c6: 0x00c3, + 0x35cc: 0x00c3, 0x35cd: 0x00c3, 0x35ce: 0x00c3, 0x35cf: 0x00c3, 0x35d0: 0x00c0, 0x35d1: 0x00c0, + 0x35d2: 0x00c0, 0x35d3: 0x00c0, 0x35d5: 0x00c0, 0x35d6: 0x00c0, 0x35d7: 0x00c0, + 0x35d9: 0x00c0, 0x35da: 0x00c0, 0x35db: 0x00c0, 0x35dc: 0x00c0, 0x35dd: 0x00c0, + 0x35de: 0x00c0, 0x35df: 0x00c0, 0x35e0: 0x00c0, 0x35e1: 0x00c0, 0x35e2: 0x00c0, 0x35e3: 0x00c0, + 0x35e4: 0x00c0, 0x35e5: 0x00c0, 0x35e6: 0x00c0, 0x35e7: 0x00c0, 0x35e8: 0x00c0, 0x35e9: 0x00c0, + 0x35ea: 0x00c0, 0x35eb: 0x00c0, 0x35ec: 0x00c0, 0x35ed: 0x00c0, 0x35ee: 0x00c0, 0x35ef: 0x00c0, + 0x35f0: 0x00c0, 0x35f1: 0x00c0, 0x35f2: 0x00c0, 0x35f3: 0x00c0, + 0x35f8: 0x00c3, 0x35f9: 0x00c3, 0x35fa: 0x00c3, + 0x35ff: 0x00c6, + // Block 0xd8, offset 0x3600 + 0x3600: 0x0080, 0x3601: 0x0080, 0x3602: 0x0080, 0x3603: 0x0080, 0x3604: 0x0080, 0x3605: 0x0080, + 0x3606: 0x0080, 0x3607: 0x0080, + 0x3610: 0x0080, 0x3611: 0x0080, + 0x3612: 0x0080, 0x3613: 0x0080, 0x3614: 0x0080, 0x3615: 0x0080, 0x3616: 0x0080, 0x3617: 0x0080, + 0x3618: 0x0080, + 0x3620: 0x00c0, 0x3621: 0x00c0, 0x3622: 0x00c0, 0x3623: 0x00c0, + 0x3624: 0x00c0, 0x3625: 0x00c0, 0x3626: 0x00c0, 0x3627: 0x00c0, 0x3628: 0x00c0, 0x3629: 0x00c0, + 0x362a: 0x00c0, 0x362b: 0x00c0, 0x362c: 0x00c0, 0x362d: 0x00c0, 0x362e: 0x00c0, 0x362f: 0x00c0, + 0x3630: 0x00c0, 0x3631: 0x00c0, 0x3632: 0x00c0, 0x3633: 0x00c0, 0x3634: 0x00c0, 0x3635: 0x00c0, + 0x3636: 0x00c0, 0x3637: 0x00c0, 0x3638: 0x00c0, 0x3639: 0x00c0, 0x363a: 0x00c0, 0x363b: 0x00c0, + 0x363c: 0x00c0, 0x363d: 0x0080, 0x363e: 0x0080, 0x363f: 0x0080, + // Block 0xd9, offset 0x3640 + 0x3640: 0x00c0, 0x3641: 0x00c0, 0x3642: 0x00c0, 0x3643: 0x00c0, 0x3644: 0x00c0, 0x3645: 0x00c0, + 0x3646: 0x00c0, 0x3647: 0x00c0, 0x3648: 0x00c0, 0x3649: 0x00c0, 0x364a: 0x00c0, 0x364b: 0x00c0, + 0x364c: 0x00c0, 0x364d: 0x00c0, 0x364e: 0x00c0, 0x364f: 0x00c0, 0x3650: 0x00c0, 0x3651: 0x00c0, + 0x3652: 0x00c0, 0x3653: 0x00c0, 0x3654: 0x00c0, 0x3655: 0x00c0, 0x3656: 0x00c0, 0x3657: 0x00c0, + 0x3658: 0x00c0, 0x3659: 0x00c0, 0x365a: 0x00c0, 0x365b: 0x00c0, 0x365c: 0x00c0, 0x365d: 0x0080, + 0x365e: 0x0080, 0x365f: 0x0080, + // Block 0xda, offset 0x3680 + 0x3680: 0x00c2, 0x3681: 0x00c2, 0x3682: 0x00c2, 0x3683: 0x00c2, 0x3684: 0x00c2, 0x3685: 0x00c4, + 0x3686: 0x00c0, 0x3687: 0x00c4, 0x3688: 0x0080, 0x3689: 0x00c4, 0x368a: 0x00c4, 0x368b: 0x00c0, + 0x368c: 0x00c0, 0x368d: 0x00c1, 0x368e: 0x00c4, 0x368f: 0x00c4, 0x3690: 0x00c4, 0x3691: 0x00c4, + 0x3692: 0x00c4, 0x3693: 0x00c2, 0x3694: 0x00c2, 0x3695: 0x00c2, 0x3696: 0x00c2, 0x3697: 0x00c1, + 0x3698: 0x00c2, 0x3699: 0x00c2, 0x369a: 0x00c2, 0x369b: 0x00c2, 0x369c: 0x00c2, 0x369d: 0x00c4, + 0x369e: 0x00c2, 0x369f: 0x00c2, 0x36a0: 0x00c2, 0x36a1: 0x00c4, 0x36a2: 0x00c0, 0x36a3: 0x00c0, + 0x36a4: 0x00c4, 0x36a5: 0x00c3, 0x36a6: 0x00c3, + 0x36ab: 0x0082, 0x36ac: 0x0082, 0x36ad: 0x0082, 0x36ae: 0x0082, 0x36af: 0x0084, + 0x36b0: 0x0080, 0x36b1: 0x0080, 0x36b2: 0x0080, 0x36b3: 0x0080, 0x36b4: 0x0080, 0x36b5: 0x0080, + 0x36b6: 0x0080, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x00c0, 0x36c1: 0x00c0, 0x36c2: 0x00c0, 0x36c3: 0x00c0, 0x36c4: 0x00c0, 0x36c5: 0x00c0, + 0x36c6: 0x00c0, 0x36c7: 0x00c0, 0x36c8: 0x00c0, 0x36c9: 0x00c0, 0x36ca: 0x00c0, 0x36cb: 0x00c0, + 0x36cc: 0x00c0, 0x36cd: 0x00c0, 0x36ce: 0x00c0, 0x36cf: 0x00c0, 0x36d0: 0x00c0, 0x36d1: 0x00c0, + 0x36d2: 0x00c0, 0x36d3: 0x00c0, 0x36d4: 0x00c0, 0x36d5: 0x00c0, 0x36d6: 0x00c0, 0x36d7: 0x00c0, + 0x36d8: 0x00c0, 0x36d9: 0x00c0, 0x36da: 0x00c0, 0x36db: 0x00c0, 0x36dc: 0x00c0, 0x36dd: 0x00c0, + 0x36de: 0x00c0, 0x36df: 0x00c0, 0x36e0: 0x00c0, 0x36e1: 0x00c0, 0x36e2: 0x00c0, 0x36e3: 0x00c0, + 0x36e4: 0x00c0, 0x36e5: 0x00c0, 0x36e6: 0x00c0, 0x36e7: 0x00c0, 0x36e8: 0x00c0, 0x36e9: 0x00c0, + 0x36ea: 0x00c0, 0x36eb: 0x00c0, 0x36ec: 0x00c0, 0x36ed: 0x00c0, 0x36ee: 0x00c0, 0x36ef: 0x00c0, + 0x36f0: 0x00c0, 0x36f1: 0x00c0, 0x36f2: 0x00c0, 0x36f3: 0x00c0, 0x36f4: 0x00c0, 0x36f5: 0x00c0, + 0x36f9: 0x0080, 0x36fa: 0x0080, 0x36fb: 0x0080, + 0x36fc: 0x0080, 0x36fd: 0x0080, 0x36fe: 0x0080, 0x36ff: 0x0080, + // Block 0xdc, offset 0x3700 + 0x3700: 0x00c0, 0x3701: 0x00c0, 0x3702: 0x00c0, 0x3703: 0x00c0, 0x3704: 0x00c0, 0x3705: 0x00c0, + 0x3706: 0x00c0, 0x3707: 0x00c0, 0x3708: 0x00c0, 0x3709: 0x00c0, 0x370a: 0x00c0, 0x370b: 0x00c0, + 0x370c: 0x00c0, 0x370d: 0x00c0, 0x370e: 0x00c0, 0x370f: 0x00c0, 0x3710: 0x00c0, 0x3711: 0x00c0, + 0x3712: 0x00c0, 0x3713: 0x00c0, 0x3714: 0x00c0, 0x3715: 0x00c0, + 0x3718: 0x0080, 0x3719: 0x0080, 0x371a: 0x0080, 0x371b: 0x0080, 0x371c: 0x0080, 0x371d: 0x0080, + 0x371e: 0x0080, 0x371f: 0x0080, 0x3720: 0x00c0, 0x3721: 0x00c0, 0x3722: 0x00c0, 0x3723: 0x00c0, + 0x3724: 0x00c0, 0x3725: 0x00c0, 0x3726: 0x00c0, 0x3727: 0x00c0, 0x3728: 0x00c0, 0x3729: 0x00c0, + 0x372a: 0x00c0, 0x372b: 0x00c0, 0x372c: 0x00c0, 0x372d: 0x00c0, 0x372e: 0x00c0, 0x372f: 0x00c0, + 0x3730: 0x00c0, 0x3731: 0x00c0, 0x3732: 0x00c0, + 0x3738: 0x0080, 0x3739: 0x0080, 0x373a: 0x0080, 0x373b: 0x0080, + 0x373c: 0x0080, 0x373d: 0x0080, 0x373e: 0x0080, 0x373f: 0x0080, + // Block 0xdd, offset 0x3740 + 0x3740: 0x00c2, 0x3741: 0x00c4, 0x3742: 0x00c2, 0x3743: 0x00c4, 0x3744: 0x00c4, 0x3745: 0x00c4, + 0x3746: 0x00c2, 0x3747: 0x00c2, 0x3748: 0x00c2, 0x3749: 0x00c4, 0x374a: 0x00c2, 0x374b: 0x00c2, + 0x374c: 0x00c4, 0x374d: 0x00c2, 0x374e: 0x00c4, 0x374f: 0x00c4, 0x3750: 0x00c2, 0x3751: 0x00c4, + 0x3759: 0x0080, 0x375a: 0x0080, 0x375b: 0x0080, 0x375c: 0x0080, + 0x3769: 0x0084, + 0x376a: 0x0084, 0x376b: 0x0084, 0x376c: 0x0084, 0x376d: 0x0082, 0x376e: 0x0082, 0x376f: 0x0080, + // Block 0xde, offset 0x3780 + 0x3780: 0x00c0, 0x3781: 0x00c0, 0x3782: 0x00c0, 0x3783: 0x00c0, 0x3784: 0x00c0, 0x3785: 0x00c0, + 0x3786: 0x00c0, 0x3787: 0x00c0, 0x3788: 0x00c0, 0x3789: 0x00c0, 0x378a: 0x00c0, 0x378b: 0x00c0, + 0x378c: 0x00c0, 0x378d: 0x00c0, 0x378e: 0x00c0, 0x378f: 0x00c0, 0x3790: 0x00c0, 0x3791: 0x00c0, + 0x3792: 0x00c0, 0x3793: 0x00c0, 0x3794: 0x00c0, 0x3795: 0x00c0, 0x3796: 0x00c0, 0x3797: 0x00c0, + 0x3798: 0x00c0, 0x3799: 0x00c0, 0x379a: 0x00c0, 0x379b: 0x00c0, 0x379c: 0x00c0, 0x379d: 0x00c0, + 0x379e: 0x00c0, 0x379f: 0x00c0, 0x37a0: 0x00c0, 0x37a1: 0x00c0, 0x37a2: 0x00c0, 0x37a3: 0x00c0, + 0x37a4: 0x00c0, 0x37a5: 0x00c0, 0x37a6: 0x00c0, 0x37a7: 0x00c0, 0x37a8: 0x00c0, 0x37a9: 0x00c0, + 0x37aa: 0x00c0, 0x37ab: 0x00c0, 0x37ac: 0x00c0, 0x37ad: 0x00c0, 0x37ae: 0x00c0, 0x37af: 0x00c0, + 0x37b0: 0x00c0, 0x37b1: 0x00c0, 0x37b2: 0x00c0, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x00c0, 0x37c1: 0x00c0, 0x37c2: 0x00c0, 0x37c3: 0x00c0, 0x37c4: 0x00c0, 0x37c5: 0x00c0, + 0x37c6: 0x00c0, 0x37c7: 0x00c0, 0x37c8: 0x00c0, 0x37c9: 0x00c0, 0x37ca: 0x00c0, 0x37cb: 0x00c0, + 0x37cc: 0x00c0, 0x37cd: 0x00c0, 0x37ce: 0x00c0, 0x37cf: 0x00c0, 0x37d0: 0x00c0, 0x37d1: 0x00c0, + 0x37d2: 0x00c0, 0x37d3: 0x00c0, 0x37d4: 0x00c0, 0x37d5: 0x00c0, 0x37d6: 0x00c0, 0x37d7: 0x00c0, + 0x37d8: 0x00c0, 0x37d9: 0x00c0, 0x37da: 0x00c0, 0x37db: 0x00c0, 0x37dc: 0x00c0, 0x37dd: 0x00c0, + 0x37de: 0x00c0, 0x37df: 0x00c0, 0x37e0: 0x00c0, 0x37e1: 0x00c0, 0x37e2: 0x00c0, 0x37e3: 0x00c0, + 0x37e4: 0x00c0, 0x37e5: 0x00c0, 0x37e6: 0x00c0, 0x37e7: 0x00c0, 0x37e8: 0x00c0, 0x37e9: 0x00c0, + 0x37ea: 0x00c0, 0x37eb: 0x00c0, 0x37ec: 0x00c0, 0x37ed: 0x00c0, 0x37ee: 0x00c0, 0x37ef: 0x00c0, + 0x37f0: 0x00c0, 0x37f1: 0x00c0, 0x37f2: 0x00c0, + 0x37fa: 0x0080, 0x37fb: 0x0080, + 0x37fc: 0x0080, 0x37fd: 0x0080, 0x37fe: 0x0080, 0x37ff: 0x0080, + // Block 0xe0, offset 0x3800 + 0x3820: 0x0080, 0x3821: 0x0080, 0x3822: 0x0080, 0x3823: 0x0080, + 0x3824: 0x0080, 0x3825: 0x0080, 0x3826: 0x0080, 0x3827: 0x0080, 0x3828: 0x0080, 0x3829: 0x0080, + 0x382a: 0x0080, 0x382b: 0x0080, 0x382c: 0x0080, 0x382d: 0x0080, 0x382e: 0x0080, 0x382f: 0x0080, + 0x3830: 0x0080, 0x3831: 0x0080, 0x3832: 0x0080, 0x3833: 0x0080, 0x3834: 0x0080, 0x3835: 0x0080, + 0x3836: 0x0080, 0x3837: 0x0080, 0x3838: 0x0080, 0x3839: 0x0080, 0x383a: 0x0080, 0x383b: 0x0080, + 0x383c: 0x0080, 0x383d: 0x0080, 0x383e: 0x0080, + // Block 0xe1, offset 0x3840 + 0x3840: 0x00c0, 0x3841: 0x00c3, 0x3842: 0x00c0, 0x3843: 0x00c0, 0x3844: 0x00c0, 0x3845: 0x00c0, + 0x3846: 0x00c0, 0x3847: 0x00c0, 0x3848: 0x00c0, 0x3849: 0x00c0, 0x384a: 0x00c0, 0x384b: 0x00c0, + 0x384c: 0x00c0, 0x384d: 0x00c0, 0x384e: 0x00c0, 0x384f: 0x00c0, 0x3850: 0x00c0, 0x3851: 0x00c0, + 0x3852: 0x00c0, 0x3853: 0x00c0, 0x3854: 0x00c0, 0x3855: 0x00c0, 0x3856: 0x00c0, 0x3857: 0x00c0, + 0x3858: 0x00c0, 0x3859: 0x00c0, 0x385a: 0x00c0, 0x385b: 0x00c0, 0x385c: 0x00c0, 0x385d: 0x00c0, + 0x385e: 0x00c0, 0x385f: 0x00c0, 0x3860: 0x00c0, 0x3861: 0x00c0, 0x3862: 0x00c0, 0x3863: 0x00c0, + 0x3864: 0x00c0, 0x3865: 0x00c0, 0x3866: 0x00c0, 0x3867: 0x00c0, 0x3868: 0x00c0, 0x3869: 0x00c0, + 0x386a: 0x00c0, 0x386b: 0x00c0, 0x386c: 0x00c0, 0x386d: 0x00c0, 0x386e: 0x00c0, 0x386f: 0x00c0, + 0x3870: 0x00c0, 0x3871: 0x00c0, 0x3872: 0x00c0, 0x3873: 0x00c0, 0x3874: 0x00c0, 0x3875: 0x00c0, + 0x3876: 0x00c0, 0x3877: 0x00c0, 0x3878: 0x00c3, 0x3879: 0x00c3, 0x387a: 0x00c3, 0x387b: 0x00c3, + 0x387c: 0x00c3, 0x387d: 0x00c3, 0x387e: 0x00c3, 0x387f: 0x00c3, + // Block 0xe2, offset 0x3880 + 0x3880: 0x00c3, 0x3881: 0x00c3, 0x3882: 0x00c3, 0x3883: 0x00c3, 0x3884: 0x00c3, 0x3885: 0x00c3, + 0x3886: 0x00c6, 0x3887: 0x0080, 0x3888: 0x0080, 0x3889: 0x0080, 0x388a: 0x0080, 0x388b: 0x0080, + 0x388c: 0x0080, 0x388d: 0x0080, + 0x3892: 0x0080, 0x3893: 0x0080, 0x3894: 0x0080, 0x3895: 0x0080, 0x3896: 0x0080, 0x3897: 0x0080, + 0x3898: 0x0080, 0x3899: 0x0080, 0x389a: 0x0080, 0x389b: 0x0080, 0x389c: 0x0080, 0x389d: 0x0080, + 0x389e: 0x0080, 0x389f: 0x0080, 0x38a0: 0x0080, 0x38a1: 0x0080, 0x38a2: 0x0080, 0x38a3: 0x0080, + 0x38a4: 0x0080, 0x38a5: 0x0080, 0x38a6: 0x00c0, 0x38a7: 0x00c0, 0x38a8: 0x00c0, 0x38a9: 0x00c0, + 0x38aa: 0x00c0, 0x38ab: 0x00c0, 0x38ac: 0x00c0, 0x38ad: 0x00c0, 0x38ae: 0x00c0, 0x38af: 0x00c0, + 0x38bf: 0x00c6, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x00c3, 0x38c1: 0x00c3, 0x38c2: 0x00c0, 0x38c3: 0x00c0, 0x38c4: 0x00c0, 0x38c5: 0x00c0, + 0x38c6: 0x00c0, 0x38c7: 0x00c0, 0x38c8: 0x00c0, 0x38c9: 0x00c0, 0x38ca: 0x00c0, 0x38cb: 0x00c0, + 0x38cc: 0x00c0, 0x38cd: 0x00c0, 0x38ce: 0x00c0, 0x38cf: 0x00c0, 0x38d0: 0x00c0, 0x38d1: 0x00c0, + 0x38d2: 0x00c0, 0x38d3: 0x00c0, 0x38d4: 0x00c0, 0x38d5: 0x00c0, 0x38d6: 0x00c0, 0x38d7: 0x00c0, + 0x38d8: 0x00c0, 0x38d9: 0x00c0, 0x38da: 0x00c0, 0x38db: 0x00c0, 0x38dc: 0x00c0, 0x38dd: 0x00c0, + 0x38de: 0x00c0, 0x38df: 0x00c0, 0x38e0: 0x00c0, 0x38e1: 0x00c0, 0x38e2: 0x00c0, 0x38e3: 0x00c0, + 0x38e4: 0x00c0, 0x38e5: 0x00c0, 0x38e6: 0x00c0, 0x38e7: 0x00c0, 0x38e8: 0x00c0, 0x38e9: 0x00c0, + 0x38ea: 0x00c0, 0x38eb: 0x00c0, 0x38ec: 0x00c0, 0x38ed: 0x00c0, 0x38ee: 0x00c0, 0x38ef: 0x00c0, + 0x38f0: 0x00c0, 0x38f1: 0x00c0, 0x38f2: 0x00c0, 0x38f3: 0x00c3, 0x38f4: 0x00c3, 0x38f5: 0x00c3, + 0x38f6: 0x00c3, 0x38f7: 0x00c0, 0x38f8: 0x00c0, 0x38f9: 0x00c6, 0x38fa: 0x00c3, 0x38fb: 0x0080, + 0x38fc: 0x0080, 0x38fd: 0x0040, 0x38fe: 0x0080, 0x38ff: 0x0080, + // Block 0xe4, offset 0x3900 + 0x3900: 0x0080, 0x3901: 0x0080, + 0x3910: 0x00c0, 0x3911: 0x00c0, + 0x3912: 0x00c0, 0x3913: 0x00c0, 0x3914: 0x00c0, 0x3915: 0x00c0, 0x3916: 0x00c0, 0x3917: 0x00c0, + 0x3918: 0x00c0, 0x3919: 0x00c0, 0x391a: 0x00c0, 0x391b: 0x00c0, 0x391c: 0x00c0, 0x391d: 0x00c0, + 0x391e: 0x00c0, 0x391f: 0x00c0, 0x3920: 0x00c0, 0x3921: 0x00c0, 0x3922: 0x00c0, 0x3923: 0x00c0, + 0x3924: 0x00c0, 0x3925: 0x00c0, 0x3926: 0x00c0, 0x3927: 0x00c0, 0x3928: 0x00c0, + 0x3930: 0x00c0, 0x3931: 0x00c0, 0x3932: 0x00c0, 0x3933: 0x00c0, 0x3934: 0x00c0, 0x3935: 0x00c0, + 0x3936: 0x00c0, 0x3937: 0x00c0, 0x3938: 0x00c0, 0x3939: 0x00c0, + // Block 0xe5, offset 0x3940 + 0x3940: 0x00c3, 0x3941: 0x00c3, 0x3942: 0x00c3, 0x3943: 0x00c0, 0x3944: 0x00c0, 0x3945: 0x00c0, + 0x3946: 0x00c0, 0x3947: 0x00c0, 0x3948: 0x00c0, 0x3949: 0x00c0, 0x394a: 0x00c0, 0x394b: 0x00c0, + 0x394c: 0x00c0, 0x394d: 0x00c0, 0x394e: 0x00c0, 0x394f: 0x00c0, 0x3950: 0x00c0, 0x3951: 0x00c0, + 0x3952: 0x00c0, 0x3953: 0x00c0, 0x3954: 0x00c0, 0x3955: 0x00c0, 0x3956: 0x00c0, 0x3957: 0x00c0, + 0x3958: 0x00c0, 0x3959: 0x00c0, 0x395a: 0x00c0, 0x395b: 0x00c0, 0x395c: 0x00c0, 0x395d: 0x00c0, + 0x395e: 0x00c0, 0x395f: 0x00c0, 0x3960: 0x00c0, 0x3961: 0x00c0, 0x3962: 0x00c0, 0x3963: 0x00c0, + 0x3964: 0x00c0, 0x3965: 0x00c0, 0x3966: 0x00c0, 0x3967: 0x00c3, 0x3968: 0x00c3, 0x3969: 0x00c3, + 0x396a: 0x00c3, 0x396b: 0x00c3, 0x396c: 0x00c0, 0x396d: 0x00c3, 0x396e: 0x00c3, 0x396f: 0x00c3, + 0x3970: 0x00c3, 0x3971: 0x00c3, 0x3972: 0x00c3, 0x3973: 0x00c6, 0x3974: 0x00c6, + 0x3976: 0x00c0, 0x3977: 0x00c0, 0x3978: 0x00c0, 0x3979: 0x00c0, 0x397a: 0x00c0, 0x397b: 0x00c0, + 0x397c: 0x00c0, 0x397d: 0x00c0, 0x397e: 0x00c0, 0x397f: 0x00c0, + // Block 0xe6, offset 0x3980 + 0x3980: 0x0080, 0x3981: 0x0080, 0x3982: 0x0080, 0x3983: 0x0080, + 0x3990: 0x00c0, 0x3991: 0x00c0, + 0x3992: 0x00c0, 0x3993: 0x00c0, 0x3994: 0x00c0, 0x3995: 0x00c0, 0x3996: 0x00c0, 0x3997: 0x00c0, + 0x3998: 0x00c0, 0x3999: 0x00c0, 0x399a: 0x00c0, 0x399b: 0x00c0, 0x399c: 0x00c0, 0x399d: 0x00c0, + 0x399e: 0x00c0, 0x399f: 0x00c0, 0x39a0: 0x00c0, 0x39a1: 0x00c0, 0x39a2: 0x00c0, 0x39a3: 0x00c0, + 0x39a4: 0x00c0, 0x39a5: 0x00c0, 0x39a6: 0x00c0, 0x39a7: 0x00c0, 0x39a8: 0x00c0, 0x39a9: 0x00c0, + 0x39aa: 0x00c0, 0x39ab: 0x00c0, 0x39ac: 0x00c0, 0x39ad: 0x00c0, 0x39ae: 0x00c0, 0x39af: 0x00c0, + 0x39b0: 0x00c0, 0x39b1: 0x00c0, 0x39b2: 0x00c0, 0x39b3: 0x00c3, 0x39b4: 0x0080, 0x39b5: 0x0080, + 0x39b6: 0x00c0, + // Block 0xe7, offset 0x39c0 + 0x39c0: 0x00c3, 0x39c1: 0x00c3, 0x39c2: 0x00c0, 0x39c3: 0x00c0, 0x39c4: 0x00c0, 0x39c5: 0x00c0, + 0x39c6: 0x00c0, 0x39c7: 0x00c0, 0x39c8: 0x00c0, 0x39c9: 0x00c0, 0x39ca: 0x00c0, 0x39cb: 0x00c0, + 0x39cc: 0x00c0, 0x39cd: 0x00c0, 0x39ce: 0x00c0, 0x39cf: 0x00c0, 0x39d0: 0x00c0, 0x39d1: 0x00c0, + 0x39d2: 0x00c0, 0x39d3: 0x00c0, 0x39d4: 0x00c0, 0x39d5: 0x00c0, 0x39d6: 0x00c0, 0x39d7: 0x00c0, + 0x39d8: 0x00c0, 0x39d9: 0x00c0, 0x39da: 0x00c0, 0x39db: 0x00c0, 0x39dc: 0x00c0, 0x39dd: 0x00c0, + 0x39de: 0x00c0, 0x39df: 0x00c0, 0x39e0: 0x00c0, 0x39e1: 0x00c0, 0x39e2: 0x00c0, 0x39e3: 0x00c0, + 0x39e4: 0x00c0, 0x39e5: 0x00c0, 0x39e6: 0x00c0, 0x39e7: 0x00c0, 0x39e8: 0x00c0, 0x39e9: 0x00c0, + 0x39ea: 0x00c0, 0x39eb: 0x00c0, 0x39ec: 0x00c0, 0x39ed: 0x00c0, 0x39ee: 0x00c0, 0x39ef: 0x00c0, + 0x39f0: 0x00c0, 0x39f1: 0x00c0, 0x39f2: 0x00c0, 0x39f3: 0x00c0, 0x39f4: 0x00c0, 0x39f5: 0x00c0, + 0x39f6: 0x00c3, 0x39f7: 0x00c3, 0x39f8: 0x00c3, 0x39f9: 0x00c3, 0x39fa: 0x00c3, 0x39fb: 0x00c3, + 0x39fc: 0x00c3, 0x39fd: 0x00c3, 0x39fe: 0x00c3, 0x39ff: 0x00c0, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0x00c5, 0x3a01: 0x00c0, 0x3a02: 0x00c0, 0x3a03: 0x00c0, 0x3a04: 0x00c0, 0x3a05: 0x0080, + 0x3a06: 0x0080, 0x3a07: 0x0080, 0x3a08: 0x0080, 0x3a09: 0x0080, 0x3a0a: 0x00c3, 0x3a0b: 0x00c3, + 0x3a0c: 0x00c3, 0x3a0d: 0x0080, 0x3a10: 0x00c0, 0x3a11: 0x00c0, + 0x3a12: 0x00c0, 0x3a13: 0x00c0, 0x3a14: 0x00c0, 0x3a15: 0x00c0, 0x3a16: 0x00c0, 0x3a17: 0x00c0, + 0x3a18: 0x00c0, 0x3a19: 0x00c0, 0x3a1a: 0x00c0, 0x3a1b: 0x0080, 0x3a1c: 0x00c0, 0x3a1d: 0x0080, + 0x3a1e: 0x0080, 0x3a1f: 0x0080, 0x3a21: 0x0080, 0x3a22: 0x0080, 0x3a23: 0x0080, + 0x3a24: 0x0080, 0x3a25: 0x0080, 0x3a26: 0x0080, 0x3a27: 0x0080, 0x3a28: 0x0080, 0x3a29: 0x0080, + 0x3a2a: 0x0080, 0x3a2b: 0x0080, 0x3a2c: 0x0080, 0x3a2d: 0x0080, 0x3a2e: 0x0080, 0x3a2f: 0x0080, + 0x3a30: 0x0080, 0x3a31: 0x0080, 0x3a32: 0x0080, 0x3a33: 0x0080, 0x3a34: 0x0080, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x00c0, 0x3a41: 0x00c0, 0x3a42: 0x00c0, 0x3a43: 0x00c0, 0x3a44: 0x00c0, 0x3a45: 0x00c0, + 0x3a46: 0x00c0, 0x3a47: 0x00c0, 0x3a48: 0x00c0, 0x3a49: 0x00c0, 0x3a4a: 0x00c0, 0x3a4b: 0x00c0, + 0x3a4c: 0x00c0, 0x3a4d: 0x00c0, 0x3a4e: 0x00c0, 0x3a4f: 0x00c0, 0x3a50: 0x00c0, 0x3a51: 0x00c0, + 0x3a53: 0x00c0, 0x3a54: 0x00c0, 0x3a55: 0x00c0, 0x3a56: 0x00c0, 0x3a57: 0x00c0, + 0x3a58: 0x00c0, 0x3a59: 0x00c0, 0x3a5a: 0x00c0, 0x3a5b: 0x00c0, 0x3a5c: 0x00c0, 0x3a5d: 0x00c0, + 0x3a5e: 0x00c0, 0x3a5f: 0x00c0, 0x3a60: 0x00c0, 0x3a61: 0x00c0, 0x3a62: 0x00c0, 0x3a63: 0x00c0, + 0x3a64: 0x00c0, 0x3a65: 0x00c0, 0x3a66: 0x00c0, 0x3a67: 0x00c0, 0x3a68: 0x00c0, 0x3a69: 0x00c0, + 0x3a6a: 0x00c0, 0x3a6b: 0x00c0, 0x3a6c: 0x00c0, 0x3a6d: 0x00c0, 0x3a6e: 0x00c0, 0x3a6f: 0x00c3, + 0x3a70: 0x00c3, 0x3a71: 0x00c3, 0x3a72: 0x00c0, 0x3a73: 0x00c0, 0x3a74: 0x00c3, 0x3a75: 0x00c5, + 0x3a76: 0x00c3, 0x3a77: 0x00c3, 0x3a78: 0x0080, 0x3a79: 0x0080, 0x3a7a: 0x0080, 0x3a7b: 0x0080, + 0x3a7c: 0x0080, 0x3a7d: 0x0080, 0x3a7e: 0x00c3, + // Block 0xea, offset 0x3a80 + 0x3a80: 0x00c0, 0x3a81: 0x00c0, 0x3a82: 0x00c0, 0x3a83: 0x00c0, 0x3a84: 0x00c0, 0x3a85: 0x00c0, + 0x3a86: 0x00c0, 0x3a88: 0x00c0, 0x3a8a: 0x00c0, 0x3a8b: 0x00c0, + 0x3a8c: 0x00c0, 0x3a8d: 0x00c0, 0x3a8f: 0x00c0, 0x3a90: 0x00c0, 0x3a91: 0x00c0, + 0x3a92: 0x00c0, 0x3a93: 0x00c0, 0x3a94: 0x00c0, 0x3a95: 0x00c0, 0x3a96: 0x00c0, 0x3a97: 0x00c0, + 0x3a98: 0x00c0, 0x3a99: 0x00c0, 0x3a9a: 0x00c0, 0x3a9b: 0x00c0, 0x3a9c: 0x00c0, 0x3a9d: 0x00c0, + 0x3a9f: 0x00c0, 0x3aa0: 0x00c0, 0x3aa1: 0x00c0, 0x3aa2: 0x00c0, 0x3aa3: 0x00c0, + 0x3aa4: 0x00c0, 0x3aa5: 0x00c0, 0x3aa6: 0x00c0, 0x3aa7: 0x00c0, 0x3aa8: 0x00c0, 0x3aa9: 0x0080, + 0x3ab0: 0x00c0, 0x3ab1: 0x00c0, 0x3ab2: 0x00c0, 0x3ab3: 0x00c0, 0x3ab4: 0x00c0, 0x3ab5: 0x00c0, + 0x3ab6: 0x00c0, 0x3ab7: 0x00c0, 0x3ab8: 0x00c0, 0x3ab9: 0x00c0, 0x3aba: 0x00c0, 0x3abb: 0x00c0, + 0x3abc: 0x00c0, 0x3abd: 0x00c0, 0x3abe: 0x00c0, 0x3abf: 0x00c0, + // Block 0xeb, offset 0x3ac0 + 0x3ac0: 0x00c0, 0x3ac1: 0x00c0, 0x3ac2: 0x00c0, 0x3ac3: 0x00c0, 0x3ac4: 0x00c0, 0x3ac5: 0x00c0, + 0x3ac6: 0x00c0, 0x3ac7: 0x00c0, 0x3ac8: 0x00c0, 0x3ac9: 0x00c0, 0x3aca: 0x00c0, 0x3acb: 0x00c0, + 0x3acc: 0x00c0, 0x3acd: 0x00c0, 0x3ace: 0x00c0, 0x3acf: 0x00c0, 0x3ad0: 0x00c0, 0x3ad1: 0x00c0, + 0x3ad2: 0x00c0, 0x3ad3: 0x00c0, 0x3ad4: 0x00c0, 0x3ad5: 0x00c0, 0x3ad6: 0x00c0, 0x3ad7: 0x00c0, + 0x3ad8: 0x00c0, 0x3ad9: 0x00c0, 0x3ada: 0x00c0, 0x3adb: 0x00c0, 0x3adc: 0x00c0, 0x3add: 0x00c0, + 0x3ade: 0x00c0, 0x3adf: 0x00c3, 0x3ae0: 0x00c0, 0x3ae1: 0x00c0, 0x3ae2: 0x00c0, 0x3ae3: 0x00c3, + 0x3ae4: 0x00c3, 0x3ae5: 0x00c3, 0x3ae6: 0x00c3, 0x3ae7: 0x00c3, 0x3ae8: 0x00c3, 0x3ae9: 0x00c3, + 0x3aea: 0x00c6, + 0x3af0: 0x00c0, 0x3af1: 0x00c0, 0x3af2: 0x00c0, 0x3af3: 0x00c0, 0x3af4: 0x00c0, 0x3af5: 0x00c0, + 0x3af6: 0x00c0, 0x3af7: 0x00c0, 0x3af8: 0x00c0, 0x3af9: 0x00c0, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x00c3, 0x3b01: 0x00c3, 0x3b02: 0x00c0, 0x3b03: 0x00c0, 0x3b05: 0x00c0, + 0x3b06: 0x00c0, 0x3b07: 0x00c0, 0x3b08: 0x00c0, 0x3b09: 0x00c0, 0x3b0a: 0x00c0, 0x3b0b: 0x00c0, + 0x3b0c: 0x00c0, 0x3b0f: 0x00c0, 0x3b10: 0x00c0, + 0x3b13: 0x00c0, 0x3b14: 0x00c0, 0x3b15: 0x00c0, 0x3b16: 0x00c0, 0x3b17: 0x00c0, + 0x3b18: 0x00c0, 0x3b19: 0x00c0, 0x3b1a: 0x00c0, 0x3b1b: 0x00c0, 0x3b1c: 0x00c0, 0x3b1d: 0x00c0, + 0x3b1e: 0x00c0, 0x3b1f: 0x00c0, 0x3b20: 0x00c0, 0x3b21: 0x00c0, 0x3b22: 0x00c0, 0x3b23: 0x00c0, + 0x3b24: 0x00c0, 0x3b25: 0x00c0, 0x3b26: 0x00c0, 0x3b27: 0x00c0, 0x3b28: 0x00c0, + 0x3b2a: 0x00c0, 0x3b2b: 0x00c0, 0x3b2c: 0x00c0, 0x3b2d: 0x00c0, 0x3b2e: 0x00c0, 0x3b2f: 0x00c0, + 0x3b30: 0x00c0, 0x3b32: 0x00c0, 0x3b33: 0x00c0, 0x3b35: 0x00c0, + 0x3b36: 0x00c0, 0x3b37: 0x00c0, 0x3b38: 0x00c0, 0x3b39: 0x00c0, + 0x3b3c: 0x00c3, 0x3b3d: 0x00c0, 0x3b3e: 0x00c0, 0x3b3f: 0x00c0, + // Block 0xed, offset 0x3b40 + 0x3b40: 0x00c3, 0x3b41: 0x00c0, 0x3b42: 0x00c0, 0x3b43: 0x00c0, 0x3b44: 0x00c0, + 0x3b47: 0x00c0, 0x3b48: 0x00c0, 0x3b4b: 0x00c0, + 0x3b4c: 0x00c0, 0x3b4d: 0x00c5, 0x3b50: 0x00c0, + 0x3b57: 0x00c0, + 0x3b5d: 0x00c0, + 0x3b5e: 0x00c0, 0x3b5f: 0x00c0, 0x3b60: 0x00c0, 0x3b61: 0x00c0, 0x3b62: 0x00c0, 0x3b63: 0x00c0, + 0x3b66: 0x00c3, 0x3b67: 0x00c3, 0x3b68: 0x00c3, 0x3b69: 0x00c3, + 0x3b6a: 0x00c3, 0x3b6b: 0x00c3, 0x3b6c: 0x00c3, + 0x3b70: 0x00c3, 0x3b71: 0x00c3, 0x3b72: 0x00c3, 0x3b73: 0x00c3, 0x3b74: 0x00c3, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x00c0, 0x3b81: 0x00c0, 0x3b82: 0x00c0, 0x3b83: 0x00c0, 0x3b84: 0x00c0, 0x3b85: 0x00c0, + 0x3b86: 0x00c0, 0x3b87: 0x00c0, 0x3b88: 0x00c0, 0x3b89: 0x00c0, 0x3b8a: 0x00c0, 0x3b8b: 0x00c0, + 0x3b8c: 0x00c0, 0x3b8d: 0x00c0, 0x3b8e: 0x00c0, 0x3b8f: 0x00c0, 0x3b90: 0x00c0, 0x3b91: 0x00c0, + 0x3b92: 0x00c0, 0x3b93: 0x00c0, 0x3b94: 0x00c0, 0x3b95: 0x00c0, 0x3b96: 0x00c0, 0x3b97: 0x00c0, + 0x3b98: 0x00c0, 0x3b99: 0x00c0, 0x3b9a: 0x00c0, 0x3b9b: 0x00c0, 0x3b9c: 0x00c0, 0x3b9d: 0x00c0, + 0x3b9e: 0x00c0, 0x3b9f: 0x00c0, 0x3ba0: 0x00c0, 0x3ba1: 0x00c0, 0x3ba2: 0x00c0, 0x3ba3: 0x00c0, + 0x3ba4: 0x00c0, 0x3ba5: 0x00c0, 0x3ba6: 0x00c0, 0x3ba7: 0x00c0, 0x3ba8: 0x00c0, 0x3ba9: 0x00c0, + 0x3baa: 0x00c0, 0x3bab: 0x00c0, 0x3bac: 0x00c0, 0x3bad: 0x00c0, 0x3bae: 0x00c0, 0x3baf: 0x00c0, + 0x3bb0: 0x00c0, 0x3bb1: 0x00c0, 0x3bb2: 0x00c0, 0x3bb3: 0x00c0, 0x3bb4: 0x00c0, 0x3bb5: 0x00c0, + 0x3bb6: 0x00c0, 0x3bb7: 0x00c0, 0x3bb8: 0x00c3, 0x3bb9: 0x00c3, 0x3bba: 0x00c3, 0x3bbb: 0x00c3, + 0x3bbc: 0x00c3, 0x3bbd: 0x00c3, 0x3bbe: 0x00c3, 0x3bbf: 0x00c3, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x00c0, 0x3bc1: 0x00c0, 0x3bc2: 0x00c6, 0x3bc3: 0x00c3, 0x3bc4: 0x00c3, 0x3bc5: 0x00c0, + 0x3bc6: 0x00c3, 0x3bc7: 0x00c0, 0x3bc8: 0x00c0, 0x3bc9: 0x00c0, 0x3bca: 0x00c0, 0x3bcb: 0x0080, + 0x3bcc: 0x0080, 0x3bcd: 0x0080, 0x3bce: 0x0080, 0x3bcf: 0x0080, 0x3bd0: 0x00c0, 0x3bd1: 0x00c0, + 0x3bd2: 0x00c0, 0x3bd3: 0x00c0, 0x3bd4: 0x00c0, 0x3bd5: 0x00c0, 0x3bd6: 0x00c0, 0x3bd7: 0x00c0, + 0x3bd8: 0x00c0, 0x3bd9: 0x00c0, 0x3bdb: 0x0080, 0x3bdd: 0x0080, + // Block 0xf0, offset 0x3c00 + 0x3c00: 0x00c0, 0x3c01: 0x00c0, 0x3c02: 0x00c0, 0x3c03: 0x00c0, 0x3c04: 0x00c0, 0x3c05: 0x00c0, + 0x3c06: 0x00c0, 0x3c07: 0x00c0, 0x3c08: 0x00c0, 0x3c09: 0x00c0, 0x3c0a: 0x00c0, 0x3c0b: 0x00c0, + 0x3c0c: 0x00c0, 0x3c0d: 0x00c0, 0x3c0e: 0x00c0, 0x3c0f: 0x00c0, 0x3c10: 0x00c0, 0x3c11: 0x00c0, + 0x3c12: 0x00c0, 0x3c13: 0x00c0, 0x3c14: 0x00c0, 0x3c15: 0x00c0, 0x3c16: 0x00c0, 0x3c17: 0x00c0, + 0x3c18: 0x00c0, 0x3c19: 0x00c0, 0x3c1a: 0x00c0, 0x3c1b: 0x00c0, 0x3c1c: 0x00c0, 0x3c1d: 0x00c0, + 0x3c1e: 0x00c0, 0x3c1f: 0x00c0, 0x3c20: 0x00c0, 0x3c21: 0x00c0, 0x3c22: 0x00c0, 0x3c23: 0x00c0, + 0x3c24: 0x00c0, 0x3c25: 0x00c0, 0x3c26: 0x00c0, 0x3c27: 0x00c0, 0x3c28: 0x00c0, 0x3c29: 0x00c0, + 0x3c2a: 0x00c0, 0x3c2b: 0x00c0, 0x3c2c: 0x00c0, 0x3c2d: 0x00c0, 0x3c2e: 0x00c0, 0x3c2f: 0x00c0, + 0x3c30: 0x00c0, 0x3c31: 0x00c0, 0x3c32: 0x00c0, 0x3c33: 0x00c3, 0x3c34: 0x00c3, 0x3c35: 0x00c3, + 0x3c36: 0x00c3, 0x3c37: 0x00c3, 0x3c38: 0x00c3, 0x3c39: 0x00c0, 0x3c3a: 0x00c3, 0x3c3b: 0x00c0, + 0x3c3c: 0x00c0, 0x3c3d: 0x00c0, 0x3c3e: 0x00c0, 0x3c3f: 0x00c3, + // Block 0xf1, offset 0x3c40 + 0x3c40: 0x00c3, 0x3c41: 0x00c0, 0x3c42: 0x00c6, 0x3c43: 0x00c3, 0x3c44: 0x00c0, 0x3c45: 0x00c0, + 0x3c46: 0x0080, 0x3c47: 0x00c0, + 0x3c50: 0x00c0, 0x3c51: 0x00c0, + 0x3c52: 0x00c0, 0x3c53: 0x00c0, 0x3c54: 0x00c0, 0x3c55: 0x00c0, 0x3c56: 0x00c0, 0x3c57: 0x00c0, + 0x3c58: 0x00c0, 0x3c59: 0x00c0, + // Block 0xf2, offset 0x3c80 + 0x3c80: 0x00c0, 0x3c81: 0x00c0, 0x3c82: 0x00c0, 0x3c83: 0x00c0, 0x3c84: 0x00c0, 0x3c85: 0x00c0, + 0x3c86: 0x00c0, 0x3c87: 0x00c0, 0x3c88: 0x00c0, 0x3c89: 0x00c0, 0x3c8a: 0x00c0, 0x3c8b: 0x00c0, + 0x3c8c: 0x00c0, 0x3c8d: 0x00c0, 0x3c8e: 0x00c0, 0x3c8f: 0x00c0, 0x3c90: 0x00c0, 0x3c91: 0x00c0, + 0x3c92: 0x00c0, 0x3c93: 0x00c0, 0x3c94: 0x00c0, 0x3c95: 0x00c0, 0x3c96: 0x00c0, 0x3c97: 0x00c0, + 0x3c98: 0x00c0, 0x3c99: 0x00c0, 0x3c9a: 0x00c0, 0x3c9b: 0x00c0, 0x3c9c: 0x00c0, 0x3c9d: 0x00c0, + 0x3c9e: 0x00c0, 0x3c9f: 0x00c0, 0x3ca0: 0x00c0, 0x3ca1: 0x00c0, 0x3ca2: 0x00c0, 0x3ca3: 0x00c0, + 0x3ca4: 0x00c0, 0x3ca5: 0x00c0, 0x3ca6: 0x00c0, 0x3ca7: 0x00c0, 0x3ca8: 0x00c0, 0x3ca9: 0x00c0, + 0x3caa: 0x00c0, 0x3cab: 0x00c0, 0x3cac: 0x00c0, 0x3cad: 0x00c0, 0x3cae: 0x00c0, 0x3caf: 0x00c0, + 0x3cb0: 0x00c0, 0x3cb1: 0x00c0, 0x3cb2: 0x00c3, 0x3cb3: 0x00c3, 0x3cb4: 0x00c3, 0x3cb5: 0x00c3, + 0x3cb8: 0x00c0, 0x3cb9: 0x00c0, 0x3cba: 0x00c0, 0x3cbb: 0x00c0, + 0x3cbc: 0x00c3, 0x3cbd: 0x00c3, 0x3cbe: 0x00c0, 0x3cbf: 0x00c6, + // Block 0xf3, offset 0x3cc0 + 0x3cc0: 0x00c3, 0x3cc1: 0x0080, 0x3cc2: 0x0080, 0x3cc3: 0x0080, 0x3cc4: 0x0080, 0x3cc5: 0x0080, + 0x3cc6: 0x0080, 0x3cc7: 0x0080, 0x3cc8: 0x0080, 0x3cc9: 0x0080, 0x3cca: 0x0080, 0x3ccb: 0x0080, + 0x3ccc: 0x0080, 0x3ccd: 0x0080, 0x3cce: 0x0080, 0x3ccf: 0x0080, 0x3cd0: 0x0080, 0x3cd1: 0x0080, + 0x3cd2: 0x0080, 0x3cd3: 0x0080, 0x3cd4: 0x0080, 0x3cd5: 0x0080, 0x3cd6: 0x0080, 0x3cd7: 0x0080, + 0x3cd8: 0x00c0, 0x3cd9: 0x00c0, 0x3cda: 0x00c0, 0x3cdb: 0x00c0, 0x3cdc: 0x00c3, 0x3cdd: 0x00c3, + // Block 0xf4, offset 0x3d00 + 0x3d00: 0x00c0, 0x3d01: 0x00c0, 0x3d02: 0x00c0, 0x3d03: 0x00c0, 0x3d04: 0x00c0, 0x3d05: 0x00c0, + 0x3d06: 0x00c0, 0x3d07: 0x00c0, 0x3d08: 0x00c0, 0x3d09: 0x00c0, 0x3d0a: 0x00c0, 0x3d0b: 0x00c0, + 0x3d0c: 0x00c0, 0x3d0d: 0x00c0, 0x3d0e: 0x00c0, 0x3d0f: 0x00c0, 0x3d10: 0x00c0, 0x3d11: 0x00c0, + 0x3d12: 0x00c0, 0x3d13: 0x00c0, 0x3d14: 0x00c0, 0x3d15: 0x00c0, 0x3d16: 0x00c0, 0x3d17: 0x00c0, + 0x3d18: 0x00c0, 0x3d19: 0x00c0, 0x3d1a: 0x00c0, 0x3d1b: 0x00c0, 0x3d1c: 0x00c0, 0x3d1d: 0x00c0, + 0x3d1e: 0x00c0, 0x3d1f: 0x00c0, 0x3d20: 0x00c0, 0x3d21: 0x00c0, 0x3d22: 0x00c0, 0x3d23: 0x00c0, + 0x3d24: 0x00c0, 0x3d25: 0x00c0, 0x3d26: 0x00c0, 0x3d27: 0x00c0, 0x3d28: 0x00c0, 0x3d29: 0x00c0, + 0x3d2a: 0x00c0, 0x3d2b: 0x00c0, 0x3d2c: 0x00c0, 0x3d2d: 0x00c0, 0x3d2e: 0x00c0, 0x3d2f: 0x00c0, + 0x3d30: 0x00c0, 0x3d31: 0x00c0, 0x3d32: 0x00c0, 0x3d33: 0x00c3, 0x3d34: 0x00c3, 0x3d35: 0x00c3, + 0x3d36: 0x00c3, 0x3d37: 0x00c3, 0x3d38: 0x00c3, 0x3d39: 0x00c3, 0x3d3a: 0x00c3, 0x3d3b: 0x00c0, + 0x3d3c: 0x00c0, 0x3d3d: 0x00c3, 0x3d3e: 0x00c0, 0x3d3f: 0x00c6, + // Block 0xf5, offset 0x3d40 + 0x3d40: 0x00c3, 0x3d41: 0x0080, 0x3d42: 0x0080, 0x3d43: 0x0080, 0x3d44: 0x00c0, + 0x3d50: 0x00c0, 0x3d51: 0x00c0, + 0x3d52: 0x00c0, 0x3d53: 0x00c0, 0x3d54: 0x00c0, 0x3d55: 0x00c0, 0x3d56: 0x00c0, 0x3d57: 0x00c0, + 0x3d58: 0x00c0, 0x3d59: 0x00c0, + 0x3d60: 0x0080, 0x3d61: 0x0080, 0x3d62: 0x0080, 0x3d63: 0x0080, + 0x3d64: 0x0080, 0x3d65: 0x0080, 0x3d66: 0x0080, 0x3d67: 0x0080, 0x3d68: 0x0080, 0x3d69: 0x0080, + 0x3d6a: 0x0080, 0x3d6b: 0x0080, 0x3d6c: 0x0080, + // Block 0xf6, offset 0x3d80 + 0x3d80: 0x00c0, 0x3d81: 0x00c0, 0x3d82: 0x00c0, 0x3d83: 0x00c0, 0x3d84: 0x00c0, 0x3d85: 0x00c0, + 0x3d86: 0x00c0, 0x3d87: 0x00c0, 0x3d88: 0x00c0, 0x3d89: 0x00c0, 0x3d8a: 0x00c0, 0x3d8b: 0x00c0, + 0x3d8c: 0x00c0, 0x3d8d: 0x00c0, 0x3d8e: 0x00c0, 0x3d8f: 0x00c0, 0x3d90: 0x00c0, 0x3d91: 0x00c0, + 0x3d92: 0x00c0, 0x3d93: 0x00c0, 0x3d94: 0x00c0, 0x3d95: 0x00c0, 0x3d96: 0x00c0, 0x3d97: 0x00c0, + 0x3d98: 0x00c0, 0x3d99: 0x00c0, 0x3d9a: 0x00c0, 0x3d9b: 0x00c0, 0x3d9c: 0x00c0, 0x3d9d: 0x00c0, + 0x3d9e: 0x00c0, 0x3d9f: 0x00c0, 0x3da0: 0x00c0, 0x3da1: 0x00c0, 0x3da2: 0x00c0, 0x3da3: 0x00c0, + 0x3da4: 0x00c0, 0x3da5: 0x00c0, 0x3da6: 0x00c0, 0x3da7: 0x00c0, 0x3da8: 0x00c0, 0x3da9: 0x00c0, + 0x3daa: 0x00c0, 0x3dab: 0x00c3, 0x3dac: 0x00c0, 0x3dad: 0x00c3, 0x3dae: 0x00c0, 0x3daf: 0x00c0, + 0x3db0: 0x00c3, 0x3db1: 0x00c3, 0x3db2: 0x00c3, 0x3db3: 0x00c3, 0x3db4: 0x00c3, 0x3db5: 0x00c3, + 0x3db6: 0x00c5, 0x3db7: 0x00c3, + // Block 0xf7, offset 0x3dc0 + 0x3dc0: 0x00c0, 0x3dc1: 0x00c0, 0x3dc2: 0x00c0, 0x3dc3: 0x00c0, 0x3dc4: 0x00c0, 0x3dc5: 0x00c0, + 0x3dc6: 0x00c0, 0x3dc7: 0x00c0, 0x3dc8: 0x00c0, 0x3dc9: 0x00c0, + // Block 0xf8, offset 0x3e00 + 0x3e00: 0x00c0, 0x3e01: 0x00c0, 0x3e02: 0x00c0, 0x3e03: 0x00c0, 0x3e04: 0x00c0, 0x3e05: 0x00c0, + 0x3e06: 0x00c0, 0x3e07: 0x00c0, 0x3e08: 0x00c0, 0x3e09: 0x00c0, 0x3e0a: 0x00c0, 0x3e0b: 0x00c0, + 0x3e0c: 0x00c0, 0x3e0d: 0x00c0, 0x3e0e: 0x00c0, 0x3e0f: 0x00c0, 0x3e10: 0x00c0, 0x3e11: 0x00c0, + 0x3e12: 0x00c0, 0x3e13: 0x00c0, 0x3e14: 0x00c0, 0x3e15: 0x00c0, 0x3e16: 0x00c0, 0x3e17: 0x00c0, + 0x3e18: 0x00c0, 0x3e19: 0x00c0, 0x3e1d: 0x00c3, + 0x3e1e: 0x00c3, 0x3e1f: 0x00c3, 0x3e20: 0x00c0, 0x3e21: 0x00c0, 0x3e22: 0x00c3, 0x3e23: 0x00c3, + 0x3e24: 0x00c3, 0x3e25: 0x00c3, 0x3e26: 0x00c0, 0x3e27: 0x00c3, 0x3e28: 0x00c3, 0x3e29: 0x00c3, + 0x3e2a: 0x00c3, 0x3e2b: 0x00c6, + 0x3e30: 0x00c0, 0x3e31: 0x00c0, 0x3e32: 0x00c0, 0x3e33: 0x00c0, 0x3e34: 0x00c0, 0x3e35: 0x00c0, + 0x3e36: 0x00c0, 0x3e37: 0x00c0, 0x3e38: 0x00c0, 0x3e39: 0x00c0, 0x3e3a: 0x0080, 0x3e3b: 0x0080, + 0x3e3c: 0x0080, 0x3e3d: 0x0080, 0x3e3e: 0x0080, 0x3e3f: 0x0080, + // Block 0xf9, offset 0x3e40 + 0x3e60: 0x00c0, 0x3e61: 0x00c0, 0x3e62: 0x00c0, 0x3e63: 0x00c0, + 0x3e64: 0x00c0, 0x3e65: 0x00c0, 0x3e66: 0x00c0, 0x3e67: 0x00c0, 0x3e68: 0x00c0, 0x3e69: 0x00c0, + 0x3e6a: 0x00c0, 0x3e6b: 0x00c0, 0x3e6c: 0x00c0, 0x3e6d: 0x00c0, 0x3e6e: 0x00c0, 0x3e6f: 0x00c0, + 0x3e70: 0x00c0, 0x3e71: 0x00c0, 0x3e72: 0x00c0, 0x3e73: 0x00c0, 0x3e74: 0x00c0, 0x3e75: 0x00c0, + 0x3e76: 0x00c0, 0x3e77: 0x00c0, 0x3e78: 0x00c0, 0x3e79: 0x00c0, 0x3e7a: 0x00c0, 0x3e7b: 0x00c0, + 0x3e7c: 0x00c0, 0x3e7d: 0x00c0, 0x3e7e: 0x00c0, 0x3e7f: 0x00c0, + // Block 0xfa, offset 0x3e80 + 0x3e80: 0x00c0, 0x3e81: 0x00c0, 0x3e82: 0x00c0, 0x3e83: 0x00c0, 0x3e84: 0x00c0, 0x3e85: 0x00c0, + 0x3e86: 0x00c0, 0x3e87: 0x00c0, 0x3e88: 0x00c0, 0x3e89: 0x00c0, 0x3e8a: 0x00c0, 0x3e8b: 0x00c0, + 0x3e8c: 0x00c0, 0x3e8d: 0x00c0, 0x3e8e: 0x00c0, 0x3e8f: 0x00c0, 0x3e90: 0x00c0, 0x3e91: 0x00c0, + 0x3e92: 0x00c0, 0x3e93: 0x00c0, 0x3e94: 0x00c0, 0x3e95: 0x00c0, 0x3e96: 0x00c0, 0x3e97: 0x00c0, + 0x3e98: 0x00c0, 0x3e99: 0x00c0, 0x3e9a: 0x00c0, 0x3e9b: 0x00c0, 0x3e9c: 0x00c0, 0x3e9d: 0x00c0, + 0x3e9e: 0x00c0, 0x3e9f: 0x00c0, 0x3ea0: 0x00c0, 0x3ea1: 0x00c0, 0x3ea2: 0x00c0, 0x3ea3: 0x00c0, + 0x3ea4: 0x00c0, 0x3ea5: 0x00c0, 0x3ea6: 0x00c0, 0x3ea7: 0x00c0, 0x3ea8: 0x00c0, 0x3ea9: 0x00c0, + 0x3eaa: 0x0080, 0x3eab: 0x0080, 0x3eac: 0x0080, 0x3ead: 0x0080, 0x3eae: 0x0080, 0x3eaf: 0x0080, + 0x3eb0: 0x0080, 0x3eb1: 0x0080, 0x3eb2: 0x0080, + 0x3ebf: 0x00c0, + // Block 0xfb, offset 0x3ec0 + 0x3ec0: 0x00c0, 0x3ec1: 0x00c3, 0x3ec2: 0x00c3, 0x3ec3: 0x00c3, 0x3ec4: 0x00c3, 0x3ec5: 0x00c3, + 0x3ec6: 0x00c3, 0x3ec7: 0x00c0, 0x3ec8: 0x00c0, 0x3ec9: 0x00c3, 0x3eca: 0x00c3, 0x3ecb: 0x00c0, + 0x3ecc: 0x00c0, 0x3ecd: 0x00c0, 0x3ece: 0x00c0, 0x3ecf: 0x00c0, 0x3ed0: 0x00c0, 0x3ed1: 0x00c0, + 0x3ed2: 0x00c0, 0x3ed3: 0x00c0, 0x3ed4: 0x00c0, 0x3ed5: 0x00c0, 0x3ed6: 0x00c0, 0x3ed7: 0x00c0, + 0x3ed8: 0x00c0, 0x3ed9: 0x00c0, 0x3eda: 0x00c0, 0x3edb: 0x00c0, 0x3edc: 0x00c0, 0x3edd: 0x00c0, + 0x3ede: 0x00c0, 0x3edf: 0x00c0, 0x3ee0: 0x00c0, 0x3ee1: 0x00c0, 0x3ee2: 0x00c0, 0x3ee3: 0x00c0, + 0x3ee4: 0x00c0, 0x3ee5: 0x00c0, 0x3ee6: 0x00c0, 0x3ee7: 0x00c0, 0x3ee8: 0x00c0, 0x3ee9: 0x00c0, + 0x3eea: 0x00c0, 0x3eeb: 0x00c0, 0x3eec: 0x00c0, 0x3eed: 0x00c0, 0x3eee: 0x00c0, 0x3eef: 0x00c0, + 0x3ef0: 0x00c0, 0x3ef1: 0x00c0, 0x3ef2: 0x00c0, 0x3ef3: 0x00c3, 0x3ef4: 0x00c6, 0x3ef5: 0x00c3, + 0x3ef6: 0x00c3, 0x3ef7: 0x00c3, 0x3ef8: 0x00c3, 0x3ef9: 0x00c0, 0x3efa: 0x00c0, 0x3efb: 0x00c3, + 0x3efc: 0x00c3, 0x3efd: 0x00c3, 0x3efe: 0x00c3, 0x3eff: 0x0080, + // Block 0xfc, offset 0x3f00 + 0x3f00: 0x0080, 0x3f01: 0x0080, 0x3f02: 0x0080, 0x3f03: 0x0080, 0x3f04: 0x0080, 0x3f05: 0x0080, + 0x3f06: 0x0080, 0x3f07: 0x00c6, + 0x3f10: 0x00c0, 0x3f11: 0x00c3, + 0x3f12: 0x00c3, 0x3f13: 0x00c3, 0x3f14: 0x00c3, 0x3f15: 0x00c3, 0x3f16: 0x00c3, 0x3f17: 0x00c0, + 0x3f18: 0x00c0, 0x3f19: 0x00c3, 0x3f1a: 0x00c3, 0x3f1b: 0x00c3, 0x3f1c: 0x00c0, 0x3f1d: 0x00c0, + 0x3f1e: 0x00c0, 0x3f1f: 0x00c0, 0x3f20: 0x00c0, 0x3f21: 0x00c0, 0x3f22: 0x00c0, 0x3f23: 0x00c0, + 0x3f24: 0x00c0, 0x3f25: 0x00c0, 0x3f26: 0x00c0, 0x3f27: 0x00c0, 0x3f28: 0x00c0, 0x3f29: 0x00c0, + 0x3f2a: 0x00c0, 0x3f2b: 0x00c0, 0x3f2c: 0x00c0, 0x3f2d: 0x00c0, 0x3f2e: 0x00c0, 0x3f2f: 0x00c0, + 0x3f30: 0x00c0, 0x3f31: 0x00c0, 0x3f32: 0x00c0, 0x3f33: 0x00c0, 0x3f34: 0x00c0, 0x3f35: 0x00c0, + 0x3f36: 0x00c0, 0x3f37: 0x00c0, 0x3f38: 0x00c0, 0x3f39: 0x00c0, 0x3f3a: 0x00c0, 0x3f3b: 0x00c0, + 0x3f3c: 0x00c0, 0x3f3d: 0x00c0, 0x3f3e: 0x00c0, 0x3f3f: 0x00c0, + // Block 0xfd, offset 0x3f40 + 0x3f40: 0x00c0, 0x3f41: 0x00c0, 0x3f42: 0x00c0, 0x3f43: 0x00c0, + 0x3f46: 0x00c0, 0x3f47: 0x00c0, 0x3f48: 0x00c0, 0x3f49: 0x00c0, 0x3f4a: 0x00c3, 0x3f4b: 0x00c3, + 0x3f4c: 0x00c3, 0x3f4d: 0x00c3, 0x3f4e: 0x00c3, 0x3f4f: 0x00c3, 0x3f50: 0x00c3, 0x3f51: 0x00c3, + 0x3f52: 0x00c3, 0x3f53: 0x00c3, 0x3f54: 0x00c3, 0x3f55: 0x00c3, 0x3f56: 0x00c3, 0x3f57: 0x00c0, + 0x3f58: 0x00c3, 0x3f59: 0x00c6, 0x3f5a: 0x0080, 0x3f5b: 0x0080, 0x3f5c: 0x0080, + 0x3f5e: 0x0080, 0x3f5f: 0x0080, 0x3f60: 0x0080, 0x3f61: 0x0080, 0x3f62: 0x0080, + // Block 0xfe, offset 0x3f80 + 0x3f80: 0x00c0, 0x3f81: 0x00c0, 0x3f82: 0x00c0, 0x3f83: 0x00c0, 0x3f84: 0x00c0, 0x3f85: 0x00c0, + 0x3f86: 0x00c0, 0x3f87: 0x00c0, 0x3f88: 0x00c0, 0x3f89: 0x00c0, 0x3f8a: 0x00c0, 0x3f8b: 0x00c0, + 0x3f8c: 0x00c0, 0x3f8d: 0x00c0, 0x3f8e: 0x00c0, 0x3f8f: 0x00c0, 0x3f90: 0x00c0, 0x3f91: 0x00c0, + 0x3f92: 0x00c0, 0x3f93: 0x00c0, 0x3f94: 0x00c0, 0x3f95: 0x00c0, 0x3f96: 0x00c0, 0x3f97: 0x00c0, + 0x3f98: 0x00c0, 0x3f99: 0x00c0, 0x3f9a: 0x00c0, 0x3f9b: 0x00c0, 0x3f9c: 0x00c0, 0x3f9d: 0x00c0, + 0x3f9e: 0x00c0, 0x3f9f: 0x00c0, 0x3fa0: 0x00c0, 0x3fa1: 0x00c0, 0x3fa2: 0x00c0, 0x3fa3: 0x00c0, + 0x3fa4: 0x00c0, 0x3fa5: 0x00c0, 0x3fa6: 0x00c0, 0x3fa7: 0x00c0, 0x3fa8: 0x00c0, 0x3fa9: 0x00c0, + 0x3faa: 0x00c0, 0x3fab: 0x00c0, 0x3fac: 0x00c0, 0x3fad: 0x00c0, 0x3fae: 0x00c0, 0x3faf: 0x00c0, + 0x3fb0: 0x00c0, 0x3fb1: 0x00c0, 0x3fb2: 0x00c0, 0x3fb3: 0x00c0, 0x3fb4: 0x00c0, 0x3fb5: 0x00c0, + 0x3fb6: 0x00c0, 0x3fb7: 0x00c0, 0x3fb8: 0x00c0, + // Block 0xff, offset 0x3fc0 + 0x3fc0: 0x00c0, 0x3fc1: 0x00c0, 0x3fc2: 0x00c0, 0x3fc3: 0x00c0, 0x3fc4: 0x00c0, 0x3fc5: 0x00c0, + 0x3fc6: 0x00c0, 0x3fc7: 0x00c0, 0x3fc8: 0x00c0, 0x3fca: 0x00c0, 0x3fcb: 0x00c0, + 0x3fcc: 0x00c0, 0x3fcd: 0x00c0, 0x3fce: 0x00c0, 0x3fcf: 0x00c0, 0x3fd0: 0x00c0, 0x3fd1: 0x00c0, + 0x3fd2: 0x00c0, 0x3fd3: 0x00c0, 0x3fd4: 0x00c0, 0x3fd5: 0x00c0, 0x3fd6: 0x00c0, 0x3fd7: 0x00c0, + 0x3fd8: 0x00c0, 0x3fd9: 0x00c0, 0x3fda: 0x00c0, 0x3fdb: 0x00c0, 0x3fdc: 0x00c0, 0x3fdd: 0x00c0, + 0x3fde: 0x00c0, 0x3fdf: 0x00c0, 0x3fe0: 0x00c0, 0x3fe1: 0x00c0, 0x3fe2: 0x00c0, 0x3fe3: 0x00c0, + 0x3fe4: 0x00c0, 0x3fe5: 0x00c0, 0x3fe6: 0x00c0, 0x3fe7: 0x00c0, 0x3fe8: 0x00c0, 0x3fe9: 0x00c0, + 0x3fea: 0x00c0, 0x3feb: 0x00c0, 0x3fec: 0x00c0, 0x3fed: 0x00c0, 0x3fee: 0x00c0, 0x3fef: 0x00c0, + 0x3ff0: 0x00c3, 0x3ff1: 0x00c3, 0x3ff2: 0x00c3, 0x3ff3: 0x00c3, 0x3ff4: 0x00c3, 0x3ff5: 0x00c3, + 0x3ff6: 0x00c3, 0x3ff8: 0x00c3, 0x3ff9: 0x00c3, 0x3ffa: 0x00c3, 0x3ffb: 0x00c3, + 0x3ffc: 0x00c3, 0x3ffd: 0x00c3, 0x3ffe: 0x00c0, 0x3fff: 0x00c6, + // Block 0x100, offset 0x4000 + 0x4000: 0x00c0, 0x4001: 0x0080, 0x4002: 0x0080, 0x4003: 0x0080, 0x4004: 0x0080, 0x4005: 0x0080, + 0x4010: 0x00c0, 0x4011: 0x00c0, + 0x4012: 0x00c0, 0x4013: 0x00c0, 0x4014: 0x00c0, 0x4015: 0x00c0, 0x4016: 0x00c0, 0x4017: 0x00c0, + 0x4018: 0x00c0, 0x4019: 0x00c0, 0x401a: 0x0080, 0x401b: 0x0080, 0x401c: 0x0080, 0x401d: 0x0080, + 0x401e: 0x0080, 0x401f: 0x0080, 0x4020: 0x0080, 0x4021: 0x0080, 0x4022: 0x0080, 0x4023: 0x0080, + 0x4024: 0x0080, 0x4025: 0x0080, 0x4026: 0x0080, 0x4027: 0x0080, 0x4028: 0x0080, 0x4029: 0x0080, + 0x402a: 0x0080, 0x402b: 0x0080, 0x402c: 0x0080, + 0x4030: 0x0080, 0x4031: 0x0080, 0x4032: 0x00c0, 0x4033: 0x00c0, 0x4034: 0x00c0, 0x4035: 0x00c0, + 0x4036: 0x00c0, 0x4037: 0x00c0, 0x4038: 0x00c0, 0x4039: 0x00c0, 0x403a: 0x00c0, 0x403b: 0x00c0, + 0x403c: 0x00c0, 0x403d: 0x00c0, 0x403e: 0x00c0, 0x403f: 0x00c0, + // Block 0x101, offset 0x4040 + 0x4040: 0x00c0, 0x4041: 0x00c0, 0x4042: 0x00c0, 0x4043: 0x00c0, 0x4044: 0x00c0, 0x4045: 0x00c0, + 0x4046: 0x00c0, 0x4047: 0x00c0, 0x4048: 0x00c0, 0x4049: 0x00c0, 0x404a: 0x00c0, 0x404b: 0x00c0, + 0x404c: 0x00c0, 0x404d: 0x00c0, 0x404e: 0x00c0, 0x404f: 0x00c0, + 0x4052: 0x00c3, 0x4053: 0x00c3, 0x4054: 0x00c3, 0x4055: 0x00c3, 0x4056: 0x00c3, 0x4057: 0x00c3, + 0x4058: 0x00c3, 0x4059: 0x00c3, 0x405a: 0x00c3, 0x405b: 0x00c3, 0x405c: 0x00c3, 0x405d: 0x00c3, + 0x405e: 0x00c3, 0x405f: 0x00c3, 0x4060: 0x00c3, 0x4061: 0x00c3, 0x4062: 0x00c3, 0x4063: 0x00c3, + 0x4064: 0x00c3, 0x4065: 0x00c3, 0x4066: 0x00c3, 0x4067: 0x00c3, 0x4069: 0x00c0, + 0x406a: 0x00c3, 0x406b: 0x00c3, 0x406c: 0x00c3, 0x406d: 0x00c3, 0x406e: 0x00c3, 0x406f: 0x00c3, + 0x4070: 0x00c3, 0x4071: 0x00c0, 0x4072: 0x00c3, 0x4073: 0x00c3, 0x4074: 0x00c0, 0x4075: 0x00c3, + 0x4076: 0x00c3, + // Block 0x102, offset 0x4080 + 0x4080: 0x00c0, 0x4081: 0x00c0, 0x4082: 0x00c0, 0x4083: 0x00c0, 0x4084: 0x00c0, 0x4085: 0x00c0, + 0x4086: 0x00c0, 0x4088: 0x00c0, 0x4089: 0x00c0, 0x408b: 0x00c0, + 0x408c: 0x00c0, 0x408d: 0x00c0, 0x408e: 0x00c0, 0x408f: 0x00c0, 0x4090: 0x00c0, 0x4091: 0x00c0, + 0x4092: 0x00c0, 0x4093: 0x00c0, 0x4094: 0x00c0, 0x4095: 0x00c0, 0x4096: 0x00c0, 0x4097: 0x00c0, + 0x4098: 0x00c0, 0x4099: 0x00c0, 0x409a: 0x00c0, 0x409b: 0x00c0, 0x409c: 0x00c0, 0x409d: 0x00c0, + 0x409e: 0x00c0, 0x409f: 0x00c0, 0x40a0: 0x00c0, 0x40a1: 0x00c0, 0x40a2: 0x00c0, 0x40a3: 0x00c0, + 0x40a4: 0x00c0, 0x40a5: 0x00c0, 0x40a6: 0x00c0, 0x40a7: 0x00c0, 0x40a8: 0x00c0, 0x40a9: 0x00c0, + 0x40aa: 0x00c0, 0x40ab: 0x00c0, 0x40ac: 0x00c0, 0x40ad: 0x00c0, 0x40ae: 0x00c0, 0x40af: 0x00c0, + 0x40b0: 0x00c0, 0x40b1: 0x00c3, 0x40b2: 0x00c3, 0x40b3: 0x00c3, 0x40b4: 0x00c3, 0x40b5: 0x00c3, + 0x40b6: 0x00c3, 0x40ba: 0x00c3, + 0x40bc: 0x00c3, 0x40bd: 0x00c3, 0x40bf: 0x00c3, + // Block 0x103, offset 0x40c0 + 0x40c0: 0x00c3, 0x40c1: 0x00c3, 0x40c2: 0x00c3, 0x40c3: 0x00c3, 0x40c4: 0x00c6, 0x40c5: 0x00c6, + 0x40c6: 0x00c0, 0x40c7: 0x00c3, + 0x40d0: 0x00c0, 0x40d1: 0x00c0, + 0x40d2: 0x00c0, 0x40d3: 0x00c0, 0x40d4: 0x00c0, 0x40d5: 0x00c0, 0x40d6: 0x00c0, 0x40d7: 0x00c0, + 0x40d8: 0x00c0, 0x40d9: 0x00c0, + // Block 0x104, offset 0x4100 + 0x4100: 0x00c0, 0x4101: 0x00c0, 0x4102: 0x00c0, 0x4103: 0x00c0, 0x4104: 0x00c0, 0x4105: 0x00c0, + 0x4106: 0x00c0, 0x4107: 0x00c0, 0x4108: 0x00c0, 0x4109: 0x00c0, 0x410a: 0x00c0, 0x410b: 0x00c0, + 0x410c: 0x00c0, 0x410d: 0x00c0, 0x410e: 0x00c0, 0x410f: 0x00c0, 0x4110: 0x00c0, 0x4111: 0x00c0, + 0x4112: 0x00c0, 0x4113: 0x00c0, 0x4114: 0x00c0, 0x4115: 0x00c0, 0x4116: 0x00c0, 0x4117: 0x00c0, + 0x4118: 0x00c0, 0x4119: 0x00c0, + // Block 0x105, offset 0x4140 + 0x4140: 0x0080, 0x4141: 0x0080, 0x4142: 0x0080, 0x4143: 0x0080, 0x4144: 0x0080, 0x4145: 0x0080, + 0x4146: 0x0080, 0x4147: 0x0080, 0x4148: 0x0080, 0x4149: 0x0080, 0x414a: 0x0080, 0x414b: 0x0080, + 0x414c: 0x0080, 0x414d: 0x0080, 0x414e: 0x0080, 0x414f: 0x0080, 0x4150: 0x0080, 0x4151: 0x0080, + 0x4152: 0x0080, 0x4153: 0x0080, 0x4154: 0x0080, 0x4155: 0x0080, 0x4156: 0x0080, 0x4157: 0x0080, + 0x4158: 0x0080, 0x4159: 0x0080, 0x415a: 0x0080, 0x415b: 0x0080, 0x415c: 0x0080, 0x415d: 0x0080, + 0x415e: 0x0080, 0x415f: 0x0080, 0x4160: 0x0080, 0x4161: 0x0080, 0x4162: 0x0080, 0x4163: 0x0080, + 0x4164: 0x0080, 0x4165: 0x0080, 0x4166: 0x0080, 0x4167: 0x0080, 0x4168: 0x0080, 0x4169: 0x0080, + 0x416a: 0x0080, 0x416b: 0x0080, 0x416c: 0x0080, 0x416d: 0x0080, 0x416e: 0x0080, + 0x4170: 0x0080, 0x4171: 0x0080, 0x4172: 0x0080, 0x4173: 0x0080, 0x4174: 0x0080, + // Block 0x106, offset 0x4180 + 0x4180: 0x00c0, 0x4181: 0x00c0, 0x4182: 0x00c0, 0x4183: 0x00c0, + // Block 0x107, offset 0x41c0 + 0x41c0: 0x00c0, 0x41c1: 0x00c0, 0x41c2: 0x00c0, 0x41c3: 0x00c0, 0x41c4: 0x00c0, 0x41c5: 0x00c0, + 0x41c6: 0x00c0, 0x41c7: 0x00c0, 0x41c8: 0x00c0, 0x41c9: 0x00c0, 0x41ca: 0x00c0, 0x41cb: 0x00c0, + 0x41cc: 0x00c0, 0x41cd: 0x00c0, 0x41ce: 0x00c0, 0x41cf: 0x00c0, 0x41d0: 0x00c0, 0x41d1: 0x00c0, + 0x41d2: 0x00c0, 0x41d3: 0x00c0, 0x41d4: 0x00c0, 0x41d5: 0x00c0, 0x41d6: 0x00c0, 0x41d7: 0x00c0, + 0x41d8: 0x00c0, 0x41d9: 0x00c0, 0x41da: 0x00c0, 0x41db: 0x00c0, 0x41dc: 0x00c0, 0x41dd: 0x00c0, + 0x41de: 0x00c0, 0x41df: 0x00c0, 0x41e0: 0x00c0, 0x41e1: 0x00c0, 0x41e2: 0x00c0, 0x41e3: 0x00c0, + 0x41e4: 0x00c0, 0x41e5: 0x00c0, 0x41e6: 0x00c0, 0x41e7: 0x00c0, 0x41e8: 0x00c0, 0x41e9: 0x00c0, + 0x41ea: 0x00c0, 0x41eb: 0x00c0, 0x41ec: 0x00c0, 0x41ed: 0x00c0, 0x41ee: 0x00c0, + // Block 0x108, offset 0x4200 + 0x4200: 0x00c0, 0x4201: 0x00c0, 0x4202: 0x00c0, 0x4203: 0x00c0, 0x4204: 0x00c0, 0x4205: 0x00c0, + 0x4206: 0x00c0, + // Block 0x109, offset 0x4240 + 0x4240: 0x00c0, 0x4241: 0x00c0, 0x4242: 0x00c0, 0x4243: 0x00c0, 0x4244: 0x00c0, 0x4245: 0x00c0, + 0x4246: 0x00c0, 0x4247: 0x00c0, 0x4248: 0x00c0, 0x4249: 0x00c0, 0x424a: 0x00c0, 0x424b: 0x00c0, + 0x424c: 0x00c0, 0x424d: 0x00c0, 0x424e: 0x00c0, 0x424f: 0x00c0, 0x4250: 0x00c0, 0x4251: 0x00c0, + 0x4252: 0x00c0, 0x4253: 0x00c0, 0x4254: 0x00c0, 0x4255: 0x00c0, 0x4256: 0x00c0, 0x4257: 0x00c0, + 0x4258: 0x00c0, 0x4259: 0x00c0, 0x425a: 0x00c0, 0x425b: 0x00c0, 0x425c: 0x00c0, 0x425d: 0x00c0, + 0x425e: 0x00c0, 0x4260: 0x00c0, 0x4261: 0x00c0, 0x4262: 0x00c0, 0x4263: 0x00c0, + 0x4264: 0x00c0, 0x4265: 0x00c0, 0x4266: 0x00c0, 0x4267: 0x00c0, 0x4268: 0x00c0, 0x4269: 0x00c0, + 0x426e: 0x0080, 0x426f: 0x0080, + // Block 0x10a, offset 0x4280 + 0x4290: 0x00c0, 0x4291: 0x00c0, + 0x4292: 0x00c0, 0x4293: 0x00c0, 0x4294: 0x00c0, 0x4295: 0x00c0, 0x4296: 0x00c0, 0x4297: 0x00c0, + 0x4298: 0x00c0, 0x4299: 0x00c0, 0x429a: 0x00c0, 0x429b: 0x00c0, 0x429c: 0x00c0, 0x429d: 0x00c0, + 0x429e: 0x00c0, 0x429f: 0x00c0, 0x42a0: 0x00c0, 0x42a1: 0x00c0, 0x42a2: 0x00c0, 0x42a3: 0x00c0, + 0x42a4: 0x00c0, 0x42a5: 0x00c0, 0x42a6: 0x00c0, 0x42a7: 0x00c0, 0x42a8: 0x00c0, 0x42a9: 0x00c0, + 0x42aa: 0x00c0, 0x42ab: 0x00c0, 0x42ac: 0x00c0, 0x42ad: 0x00c0, + 0x42b0: 0x00c3, 0x42b1: 0x00c3, 0x42b2: 0x00c3, 0x42b3: 0x00c3, 0x42b4: 0x00c3, 0x42b5: 0x0080, + // Block 0x10b, offset 0x42c0 + 0x42c0: 0x00c0, 0x42c1: 0x00c0, 0x42c2: 0x00c0, 0x42c3: 0x00c0, 0x42c4: 0x00c0, 0x42c5: 0x00c0, + 0x42c6: 0x00c0, 0x42c7: 0x00c0, 0x42c8: 0x00c0, 0x42c9: 0x00c0, 0x42ca: 0x00c0, 0x42cb: 0x00c0, + 0x42cc: 0x00c0, 0x42cd: 0x00c0, 0x42ce: 0x00c0, 0x42cf: 0x00c0, 0x42d0: 0x00c0, 0x42d1: 0x00c0, + 0x42d2: 0x00c0, 0x42d3: 0x00c0, 0x42d4: 0x00c0, 0x42d5: 0x00c0, 0x42d6: 0x00c0, 0x42d7: 0x00c0, + 0x42d8: 0x00c0, 0x42d9: 0x00c0, 0x42da: 0x00c0, 0x42db: 0x00c0, 0x42dc: 0x00c0, 0x42dd: 0x00c0, + 0x42de: 0x00c0, 0x42df: 0x00c0, 0x42e0: 0x00c0, 0x42e1: 0x00c0, 0x42e2: 0x00c0, 0x42e3: 0x00c0, + 0x42e4: 0x00c0, 0x42e5: 0x00c0, 0x42e6: 0x00c0, 0x42e7: 0x00c0, 0x42e8: 0x00c0, 0x42e9: 0x00c0, + 0x42ea: 0x00c0, 0x42eb: 0x00c0, 0x42ec: 0x00c0, 0x42ed: 0x00c0, 0x42ee: 0x00c0, 0x42ef: 0x00c0, + 0x42f0: 0x00c3, 0x42f1: 0x00c3, 0x42f2: 0x00c3, 0x42f3: 0x00c3, 0x42f4: 0x00c3, 0x42f5: 0x00c3, + 0x42f6: 0x00c3, 0x42f7: 0x0080, 0x42f8: 0x0080, 0x42f9: 0x0080, 0x42fa: 0x0080, 0x42fb: 0x0080, + 0x42fc: 0x0080, 0x42fd: 0x0080, 0x42fe: 0x0080, 0x42ff: 0x0080, + // Block 0x10c, offset 0x4300 + 0x4300: 0x00c0, 0x4301: 0x00c0, 0x4302: 0x00c0, 0x4303: 0x00c0, 0x4304: 0x0080, 0x4305: 0x0080, + 0x4310: 0x00c0, 0x4311: 0x00c0, + 0x4312: 0x00c0, 0x4313: 0x00c0, 0x4314: 0x00c0, 0x4315: 0x00c0, 0x4316: 0x00c0, 0x4317: 0x00c0, + 0x4318: 0x00c0, 0x4319: 0x00c0, 0x431b: 0x0080, 0x431c: 0x0080, 0x431d: 0x0080, + 0x431e: 0x0080, 0x431f: 0x0080, 0x4320: 0x0080, 0x4321: 0x0080, 0x4323: 0x00c0, + 0x4324: 0x00c0, 0x4325: 0x00c0, 0x4326: 0x00c0, 0x4327: 0x00c0, 0x4328: 0x00c0, 0x4329: 0x00c0, + 0x432a: 0x00c0, 0x432b: 0x00c0, 0x432c: 0x00c0, 0x432d: 0x00c0, 0x432e: 0x00c0, 0x432f: 0x00c0, + 0x4330: 0x00c0, 0x4331: 0x00c0, 0x4332: 0x00c0, 0x4333: 0x00c0, 0x4334: 0x00c0, 0x4335: 0x00c0, + 0x4336: 0x00c0, 0x4337: 0x00c0, + 0x433d: 0x00c0, 0x433e: 0x00c0, 0x433f: 0x00c0, + // Block 0x10d, offset 0x4340 + 0x4340: 0x00c0, 0x4341: 0x00c0, 0x4342: 0x00c0, 0x4343: 0x00c0, 0x4344: 0x00c0, 0x4345: 0x00c0, + 0x4346: 0x00c0, 0x4347: 0x00c0, 0x4348: 0x00c0, 0x4349: 0x00c0, 0x434a: 0x00c0, 0x434b: 0x00c0, + 0x434c: 0x00c0, 0x434d: 0x00c0, 0x434e: 0x00c0, 0x434f: 0x00c0, + // Block 0x10e, offset 0x4380 + 0x4380: 0x00c0, 0x4381: 0x00c0, 0x4382: 0x00c0, 0x4383: 0x00c0, 0x4384: 0x00c0, + 0x4390: 0x00c0, 0x4391: 0x00c0, + 0x4392: 0x00c0, 0x4393: 0x00c0, 0x4394: 0x00c0, 0x4395: 0x00c0, 0x4396: 0x00c0, 0x4397: 0x00c0, + 0x4398: 0x00c0, 0x4399: 0x00c0, 0x439a: 0x00c0, 0x439b: 0x00c0, 0x439c: 0x00c0, 0x439d: 0x00c0, + 0x439e: 0x00c0, 0x439f: 0x00c0, 0x43a0: 0x00c0, 0x43a1: 0x00c0, 0x43a2: 0x00c0, 0x43a3: 0x00c0, + 0x43a4: 0x00c0, 0x43a5: 0x00c0, 0x43a6: 0x00c0, 0x43a7: 0x00c0, 0x43a8: 0x00c0, 0x43a9: 0x00c0, + 0x43aa: 0x00c0, 0x43ab: 0x00c0, 0x43ac: 0x00c0, 0x43ad: 0x00c0, 0x43ae: 0x00c0, 0x43af: 0x00c0, + 0x43b0: 0x00c0, 0x43b1: 0x00c0, 0x43b2: 0x00c0, 0x43b3: 0x00c0, 0x43b4: 0x00c0, 0x43b5: 0x00c0, + 0x43b6: 0x00c0, 0x43b7: 0x00c0, 0x43b8: 0x00c0, 0x43b9: 0x00c0, 0x43ba: 0x00c0, 0x43bb: 0x00c0, + 0x43bc: 0x00c0, 0x43bd: 0x00c0, 0x43be: 0x00c0, + // Block 0x10f, offset 0x43c0 + 0x43cf: 0x00c3, 0x43d0: 0x00c3, 0x43d1: 0x00c3, + 0x43d2: 0x00c3, 0x43d3: 0x00c0, 0x43d4: 0x00c0, 0x43d5: 0x00c0, 0x43d6: 0x00c0, 0x43d7: 0x00c0, + 0x43d8: 0x00c0, 0x43d9: 0x00c0, 0x43da: 0x00c0, 0x43db: 0x00c0, 0x43dc: 0x00c0, 0x43dd: 0x00c0, + 0x43de: 0x00c0, 0x43df: 0x00c0, + // Block 0x110, offset 0x4400 + 0x4420: 0x00c0, 0x4421: 0x00c0, + // Block 0x111, offset 0x4440 + 0x4440: 0x00c0, 0x4441: 0x00c0, 0x4442: 0x00c0, 0x4443: 0x00c0, 0x4444: 0x00c0, 0x4445: 0x00c0, + 0x4446: 0x00c0, 0x4447: 0x00c0, 0x4448: 0x00c0, 0x4449: 0x00c0, 0x444a: 0x00c0, 0x444b: 0x00c0, + 0x444c: 0x00c0, 0x444d: 0x00c0, 0x444e: 0x00c0, 0x444f: 0x00c0, 0x4450: 0x00c0, 0x4451: 0x00c0, + 0x4452: 0x00c0, 0x4453: 0x00c0, 0x4454: 0x00c0, 0x4455: 0x00c0, 0x4456: 0x00c0, 0x4457: 0x00c0, + 0x4458: 0x00c0, 0x4459: 0x00c0, 0x445a: 0x00c0, 0x445b: 0x00c0, 0x445c: 0x00c0, 0x445d: 0x00c0, + 0x445e: 0x00c0, 0x445f: 0x00c0, 0x4460: 0x00c0, 0x4461: 0x00c0, 0x4462: 0x00c0, 0x4463: 0x00c0, + 0x4464: 0x00c0, 0x4465: 0x00c0, 0x4466: 0x00c0, 0x4467: 0x00c0, 0x4468: 0x00c0, 0x4469: 0x00c0, + 0x446a: 0x00c0, 0x446b: 0x00c0, 0x446c: 0x00c0, + // Block 0x112, offset 0x4480 + 0x4480: 0x00cc, 0x4481: 0x00cc, 0x4482: 0x00cc, 0x4483: 0x00cc, 0x4484: 0x00cc, 0x4485: 0x00cc, + 0x4486: 0x00cc, 0x4487: 0x00cc, 0x4488: 0x00cc, 0x4489: 0x00cc, 0x448a: 0x00cc, 0x448b: 0x00cc, + 0x448c: 0x00cc, 0x448d: 0x00cc, 0x448e: 0x00cc, 0x448f: 0x00cc, 0x4490: 0x00cc, 0x4491: 0x00cc, + 0x4492: 0x00cc, 0x4493: 0x00cc, 0x4494: 0x00cc, 0x4495: 0x00cc, 0x4496: 0x00cc, 0x4497: 0x00cc, + 0x4498: 0x00cc, 0x4499: 0x00cc, 0x449a: 0x00cc, 0x449b: 0x00cc, 0x449c: 0x00cc, 0x449d: 0x00cc, + 0x449e: 0x00cc, + // Block 0x113, offset 0x44c0 + 0x44f0: 0x00c0, 0x44f1: 0x00c0, 0x44f2: 0x00c0, 0x44f3: 0x00c0, 0x44f4: 0x00c0, 0x44f5: 0x00c0, + 0x44f6: 0x00c0, 0x44f7: 0x00c0, 0x44f8: 0x00c0, 0x44f9: 0x00c0, 0x44fa: 0x00c0, 0x44fb: 0x00c0, + 0x44fc: 0x00c0, 0x44fd: 0x00c0, 0x44fe: 0x00c0, 0x44ff: 0x00c0, + // Block 0x114, offset 0x4500 + 0x4500: 0x00c0, 0x4501: 0x00c0, 0x4502: 0x00c0, 0x4503: 0x00c0, 0x4504: 0x00c0, 0x4505: 0x00c0, + 0x4506: 0x00c0, 0x4507: 0x00c0, 0x4508: 0x00c0, 0x4509: 0x00c0, 0x450a: 0x00c0, 0x450b: 0x00c0, + 0x450c: 0x00c0, 0x450d: 0x00c0, 0x450e: 0x00c0, 0x450f: 0x00c0, 0x4510: 0x00c0, 0x4511: 0x00c0, + 0x4512: 0x00c0, 0x4513: 0x00c0, 0x4514: 0x00c0, 0x4515: 0x00c0, 0x4516: 0x00c0, 0x4517: 0x00c0, + 0x4518: 0x00c0, 0x4519: 0x00c0, 0x451a: 0x00c0, 0x451b: 0x00c0, 0x451c: 0x00c0, 0x451d: 0x00c0, + 0x451e: 0x00c0, 0x451f: 0x00c0, 0x4520: 0x00c0, 0x4521: 0x00c0, 0x4522: 0x00c0, 0x4523: 0x00c0, + 0x4524: 0x00c0, 0x4525: 0x00c0, 0x4526: 0x00c0, 0x4527: 0x00c0, 0x4528: 0x00c0, 0x4529: 0x00c0, + 0x452a: 0x00c0, 0x452b: 0x00c0, 0x452c: 0x00c0, 0x452d: 0x00c0, 0x452e: 0x00c0, 0x452f: 0x00c0, + 0x4530: 0x00c0, 0x4531: 0x00c0, 0x4532: 0x00c0, 0x4533: 0x00c0, 0x4534: 0x00c0, 0x4535: 0x00c0, + 0x4536: 0x00c0, 0x4537: 0x00c0, 0x4538: 0x00c0, 0x4539: 0x00c0, 0x453a: 0x00c0, 0x453b: 0x00c0, + // Block 0x115, offset 0x4540 + 0x4540: 0x00c0, 0x4541: 0x00c0, 0x4542: 0x00c0, 0x4543: 0x00c0, 0x4544: 0x00c0, 0x4545: 0x00c0, + 0x4546: 0x00c0, 0x4547: 0x00c0, 0x4548: 0x00c0, 0x4549: 0x00c0, 0x454a: 0x00c0, 0x454b: 0x00c0, + 0x454c: 0x00c0, 0x454d: 0x00c0, 0x454e: 0x00c0, 0x454f: 0x00c0, 0x4550: 0x00c0, 0x4551: 0x00c0, + 0x4552: 0x00c0, 0x4553: 0x00c0, 0x4554: 0x00c0, 0x4555: 0x00c0, 0x4556: 0x00c0, 0x4557: 0x00c0, + 0x4558: 0x00c0, 0x4559: 0x00c0, 0x455a: 0x00c0, 0x455b: 0x00c0, 0x455c: 0x00c0, 0x455d: 0x00c0, + 0x455e: 0x00c0, 0x455f: 0x00c0, 0x4560: 0x00c0, 0x4561: 0x00c0, 0x4562: 0x00c0, 0x4563: 0x00c0, + 0x4564: 0x00c0, 0x4565: 0x00c0, 0x4566: 0x00c0, 0x4567: 0x00c0, 0x4568: 0x00c0, 0x4569: 0x00c0, + 0x456a: 0x00c0, + 0x4570: 0x00c0, 0x4571: 0x00c0, 0x4572: 0x00c0, 0x4573: 0x00c0, 0x4574: 0x00c0, 0x4575: 0x00c0, + 0x4576: 0x00c0, 0x4577: 0x00c0, 0x4578: 0x00c0, 0x4579: 0x00c0, 0x457a: 0x00c0, 0x457b: 0x00c0, + 0x457c: 0x00c0, + // Block 0x116, offset 0x4580 + 0x4580: 0x00c0, 0x4581: 0x00c0, 0x4582: 0x00c0, 0x4583: 0x00c0, 0x4584: 0x00c0, 0x4585: 0x00c0, + 0x4586: 0x00c0, 0x4587: 0x00c0, 0x4588: 0x00c0, + 0x4590: 0x00c0, 0x4591: 0x00c0, + 0x4592: 0x00c0, 0x4593: 0x00c0, 0x4594: 0x00c0, 0x4595: 0x00c0, 0x4596: 0x00c0, 0x4597: 0x00c0, + 0x4598: 0x00c0, 0x4599: 0x00c0, 0x459c: 0x0080, 0x459d: 0x00c3, + 0x459e: 0x00c3, 0x459f: 0x0080, 0x45a0: 0x0040, 0x45a1: 0x0040, 0x45a2: 0x0040, 0x45a3: 0x0040, + // Block 0x117, offset 0x45c0 + 0x45c0: 0x0080, 0x45c1: 0x0080, 0x45c2: 0x0080, 0x45c3: 0x0080, 0x45c4: 0x0080, 0x45c5: 0x0080, + 0x45c6: 0x0080, 0x45c7: 0x0080, 0x45c8: 0x0080, 0x45c9: 0x0080, 0x45ca: 0x0080, 0x45cb: 0x0080, + 0x45cc: 0x0080, 0x45cd: 0x0080, 0x45ce: 0x0080, 0x45cf: 0x0080, 0x45d0: 0x0080, 0x45d1: 0x0080, + 0x45d2: 0x0080, 0x45d3: 0x0080, 0x45d4: 0x0080, 0x45d5: 0x0080, 0x45d6: 0x0080, 0x45d7: 0x0080, + 0x45d8: 0x0080, 0x45d9: 0x0080, 0x45da: 0x0080, 0x45db: 0x0080, 0x45dc: 0x0080, 0x45dd: 0x0080, + 0x45de: 0x0080, 0x45df: 0x0080, 0x45e0: 0x0080, 0x45e1: 0x0080, 0x45e2: 0x0080, 0x45e3: 0x0080, + 0x45e4: 0x0080, 0x45e5: 0x0080, 0x45e6: 0x0080, 0x45e7: 0x0080, 0x45e8: 0x0080, 0x45e9: 0x0080, + 0x45ea: 0x0080, 0x45eb: 0x0080, 0x45ec: 0x0080, 0x45ed: 0x0080, 0x45ee: 0x0080, 0x45ef: 0x0080, + 0x45f0: 0x0080, 0x45f1: 0x0080, 0x45f2: 0x0080, 0x45f3: 0x0080, 0x45f4: 0x0080, 0x45f5: 0x0080, + // Block 0x118, offset 0x4600 + 0x4600: 0x0080, 0x4601: 0x0080, 0x4602: 0x0080, 0x4603: 0x0080, 0x4604: 0x0080, 0x4605: 0x0080, + 0x4606: 0x0080, 0x4607: 0x0080, 0x4608: 0x0080, 0x4609: 0x0080, 0x460a: 0x0080, 0x460b: 0x0080, + 0x460c: 0x0080, 0x460d: 0x0080, 0x460e: 0x0080, 0x460f: 0x0080, 0x4610: 0x0080, 0x4611: 0x0080, + 0x4612: 0x0080, 0x4613: 0x0080, 0x4614: 0x0080, 0x4615: 0x0080, 0x4616: 0x0080, 0x4617: 0x0080, + 0x4618: 0x0080, 0x4619: 0x0080, 0x461a: 0x0080, 0x461b: 0x0080, 0x461c: 0x0080, 0x461d: 0x0080, + 0x461e: 0x0080, 0x461f: 0x0080, 0x4620: 0x0080, 0x4621: 0x0080, 0x4622: 0x0080, 0x4623: 0x0080, + 0x4624: 0x0080, 0x4625: 0x0080, 0x4626: 0x0080, 0x4629: 0x0080, + 0x462a: 0x0080, 0x462b: 0x0080, 0x462c: 0x0080, 0x462d: 0x0080, 0x462e: 0x0080, 0x462f: 0x0080, + 0x4630: 0x0080, 0x4631: 0x0080, 0x4632: 0x0080, 0x4633: 0x0080, 0x4634: 0x0080, 0x4635: 0x0080, + 0x4636: 0x0080, 0x4637: 0x0080, 0x4638: 0x0080, 0x4639: 0x0080, 0x463a: 0x0080, 0x463b: 0x0080, + 0x463c: 0x0080, 0x463d: 0x0080, 0x463e: 0x0080, 0x463f: 0x0080, + // Block 0x119, offset 0x4640 + 0x4640: 0x0080, 0x4641: 0x0080, 0x4642: 0x0080, 0x4643: 0x0080, 0x4644: 0x0080, 0x4645: 0x0080, + 0x4646: 0x0080, 0x4647: 0x0080, 0x4648: 0x0080, 0x4649: 0x0080, 0x464a: 0x0080, 0x464b: 0x0080, + 0x464c: 0x0080, 0x464d: 0x0080, 0x464e: 0x0080, 0x464f: 0x0080, 0x4650: 0x0080, 0x4651: 0x0080, + 0x4652: 0x0080, 0x4653: 0x0080, 0x4654: 0x0080, 0x4655: 0x0080, 0x4656: 0x0080, 0x4657: 0x0080, + 0x4658: 0x0080, 0x4659: 0x0080, 0x465a: 0x0080, 0x465b: 0x0080, 0x465c: 0x0080, 0x465d: 0x0080, + 0x465e: 0x0080, 0x465f: 0x0080, 0x4660: 0x0080, 0x4661: 0x0080, 0x4662: 0x0080, 0x4663: 0x0080, + 0x4664: 0x0080, 0x4665: 0x00c0, 0x4666: 0x00c0, 0x4667: 0x00c3, 0x4668: 0x00c3, 0x4669: 0x00c3, + 0x466a: 0x0080, 0x466b: 0x0080, 0x466c: 0x0080, 0x466d: 0x00c0, 0x466e: 0x00c0, 0x466f: 0x00c0, + 0x4670: 0x00c0, 0x4671: 0x00c0, 0x4672: 0x00c0, 0x4673: 0x0040, 0x4674: 0x0040, 0x4675: 0x0040, + 0x4676: 0x0040, 0x4677: 0x0040, 0x4678: 0x0040, 0x4679: 0x0040, 0x467a: 0x0040, 0x467b: 0x00c3, + 0x467c: 0x00c3, 0x467d: 0x00c3, 0x467e: 0x00c3, 0x467f: 0x00c3, + // Block 0x11a, offset 0x4680 + 0x4680: 0x00c3, 0x4681: 0x00c3, 0x4682: 0x00c3, 0x4683: 0x0080, 0x4684: 0x0080, 0x4685: 0x00c3, + 0x4686: 0x00c3, 0x4687: 0x00c3, 0x4688: 0x00c3, 0x4689: 0x00c3, 0x468a: 0x00c3, 0x468b: 0x00c3, + 0x468c: 0x0080, 0x468d: 0x0080, 0x468e: 0x0080, 0x468f: 0x0080, 0x4690: 0x0080, 0x4691: 0x0080, + 0x4692: 0x0080, 0x4693: 0x0080, 0x4694: 0x0080, 0x4695: 0x0080, 0x4696: 0x0080, 0x4697: 0x0080, + 0x4698: 0x0080, 0x4699: 0x0080, 0x469a: 0x0080, 0x469b: 0x0080, 0x469c: 0x0080, 0x469d: 0x0080, + 0x469e: 0x0080, 0x469f: 0x0080, 0x46a0: 0x0080, 0x46a1: 0x0080, 0x46a2: 0x0080, 0x46a3: 0x0080, + 0x46a4: 0x0080, 0x46a5: 0x0080, 0x46a6: 0x0080, 0x46a7: 0x0080, 0x46a8: 0x0080, 0x46a9: 0x0080, + 0x46aa: 0x00c3, 0x46ab: 0x00c3, 0x46ac: 0x00c3, 0x46ad: 0x00c3, 0x46ae: 0x0080, 0x46af: 0x0080, + 0x46b0: 0x0080, 0x46b1: 0x0080, 0x46b2: 0x0080, 0x46b3: 0x0080, 0x46b4: 0x0080, 0x46b5: 0x0080, + 0x46b6: 0x0080, 0x46b7: 0x0080, 0x46b8: 0x0080, 0x46b9: 0x0080, 0x46ba: 0x0080, 0x46bb: 0x0080, + 0x46bc: 0x0080, 0x46bd: 0x0080, 0x46be: 0x0080, 0x46bf: 0x0080, + // Block 0x11b, offset 0x46c0 + 0x46c0: 0x0080, 0x46c1: 0x0080, 0x46c2: 0x0080, 0x46c3: 0x0080, 0x46c4: 0x0080, 0x46c5: 0x0080, + 0x46c6: 0x0080, 0x46c7: 0x0080, 0x46c8: 0x0080, 0x46c9: 0x0080, 0x46ca: 0x0080, 0x46cb: 0x0080, + 0x46cc: 0x0080, 0x46cd: 0x0080, 0x46ce: 0x0080, 0x46cf: 0x0080, 0x46d0: 0x0080, 0x46d1: 0x0080, + 0x46d2: 0x0080, 0x46d3: 0x0080, 0x46d4: 0x0080, 0x46d5: 0x0080, 0x46d6: 0x0080, 0x46d7: 0x0080, + 0x46d8: 0x0080, 0x46d9: 0x0080, 0x46da: 0x0080, 0x46db: 0x0080, 0x46dc: 0x0080, 0x46dd: 0x0080, + 0x46de: 0x0080, 0x46df: 0x0080, 0x46e0: 0x0080, 0x46e1: 0x0080, 0x46e2: 0x0080, 0x46e3: 0x0080, + 0x46e4: 0x0080, 0x46e5: 0x0080, 0x46e6: 0x0080, 0x46e7: 0x0080, 0x46e8: 0x0080, + // Block 0x11c, offset 0x4700 + 0x4700: 0x0088, 0x4701: 0x0088, 0x4702: 0x00c9, 0x4703: 0x00c9, 0x4704: 0x00c9, 0x4705: 0x0088, + // Block 0x11d, offset 0x4740 + 0x4740: 0x0080, 0x4741: 0x0080, 0x4742: 0x0080, 0x4743: 0x0080, 0x4744: 0x0080, 0x4745: 0x0080, + 0x4746: 0x0080, 0x4747: 0x0080, 0x4748: 0x0080, 0x4749: 0x0080, 0x474a: 0x0080, 0x474b: 0x0080, + 0x474c: 0x0080, 0x474d: 0x0080, 0x474e: 0x0080, 0x474f: 0x0080, 0x4750: 0x0080, 0x4751: 0x0080, + 0x4752: 0x0080, 0x4753: 0x0080, 0x4754: 0x0080, 0x4755: 0x0080, 0x4756: 0x0080, + 0x4760: 0x0080, 0x4761: 0x0080, 0x4762: 0x0080, 0x4763: 0x0080, + 0x4764: 0x0080, 0x4765: 0x0080, 0x4766: 0x0080, 0x4767: 0x0080, 0x4768: 0x0080, 0x4769: 0x0080, + 0x476a: 0x0080, 0x476b: 0x0080, 0x476c: 0x0080, 0x476d: 0x0080, 0x476e: 0x0080, 0x476f: 0x0080, + 0x4770: 0x0080, 0x4771: 0x0080, + // Block 0x11e, offset 0x4780 + 0x4780: 0x0080, 0x4781: 0x0080, 0x4782: 0x0080, 0x4783: 0x0080, 0x4784: 0x0080, 0x4785: 0x0080, + 0x4786: 0x0080, 0x4787: 0x0080, 0x4788: 0x0080, 0x4789: 0x0080, 0x478a: 0x0080, 0x478b: 0x0080, + 0x478c: 0x0080, 0x478d: 0x0080, 0x478e: 0x0080, 0x478f: 0x0080, 0x4790: 0x0080, 0x4791: 0x0080, + 0x4792: 0x0080, 0x4793: 0x0080, 0x4794: 0x0080, 0x4796: 0x0080, 0x4797: 0x0080, + 0x4798: 0x0080, 0x4799: 0x0080, 0x479a: 0x0080, 0x479b: 0x0080, 0x479c: 0x0080, 0x479d: 0x0080, + 0x479e: 0x0080, 0x479f: 0x0080, 0x47a0: 0x0080, 0x47a1: 0x0080, 0x47a2: 0x0080, 0x47a3: 0x0080, + 0x47a4: 0x0080, 0x47a5: 0x0080, 0x47a6: 0x0080, 0x47a7: 0x0080, 0x47a8: 0x0080, 0x47a9: 0x0080, + 0x47aa: 0x0080, 0x47ab: 0x0080, 0x47ac: 0x0080, 0x47ad: 0x0080, 0x47ae: 0x0080, 0x47af: 0x0080, + 0x47b0: 0x0080, 0x47b1: 0x0080, 0x47b2: 0x0080, 0x47b3: 0x0080, 0x47b4: 0x0080, 0x47b5: 0x0080, + 0x47b6: 0x0080, 0x47b7: 0x0080, 0x47b8: 0x0080, 0x47b9: 0x0080, 0x47ba: 0x0080, 0x47bb: 0x0080, + 0x47bc: 0x0080, 0x47bd: 0x0080, 0x47be: 0x0080, 0x47bf: 0x0080, + // Block 0x11f, offset 0x47c0 + 0x47c0: 0x0080, 0x47c1: 0x0080, 0x47c2: 0x0080, 0x47c3: 0x0080, 0x47c4: 0x0080, 0x47c5: 0x0080, + 0x47c6: 0x0080, 0x47c7: 0x0080, 0x47c8: 0x0080, 0x47c9: 0x0080, 0x47ca: 0x0080, 0x47cb: 0x0080, + 0x47cc: 0x0080, 0x47cd: 0x0080, 0x47ce: 0x0080, 0x47cf: 0x0080, 0x47d0: 0x0080, 0x47d1: 0x0080, + 0x47d2: 0x0080, 0x47d3: 0x0080, 0x47d4: 0x0080, 0x47d5: 0x0080, 0x47d6: 0x0080, 0x47d7: 0x0080, + 0x47d8: 0x0080, 0x47d9: 0x0080, 0x47da: 0x0080, 0x47db: 0x0080, 0x47dc: 0x0080, + 0x47de: 0x0080, 0x47df: 0x0080, 0x47e2: 0x0080, + 0x47e5: 0x0080, 0x47e6: 0x0080, 0x47e9: 0x0080, + 0x47ea: 0x0080, 0x47eb: 0x0080, 0x47ec: 0x0080, 0x47ee: 0x0080, 0x47ef: 0x0080, + 0x47f0: 0x0080, 0x47f1: 0x0080, 0x47f2: 0x0080, 0x47f3: 0x0080, 0x47f4: 0x0080, 0x47f5: 0x0080, + 0x47f6: 0x0080, 0x47f7: 0x0080, 0x47f8: 0x0080, 0x47f9: 0x0080, 0x47fb: 0x0080, + 0x47fd: 0x0080, 0x47fe: 0x0080, 0x47ff: 0x0080, + // Block 0x120, offset 0x4800 + 0x4800: 0x0080, 0x4801: 0x0080, 0x4802: 0x0080, 0x4803: 0x0080, 0x4805: 0x0080, + 0x4806: 0x0080, 0x4807: 0x0080, 0x4808: 0x0080, 0x4809: 0x0080, 0x480a: 0x0080, 0x480b: 0x0080, + 0x480c: 0x0080, 0x480d: 0x0080, 0x480e: 0x0080, 0x480f: 0x0080, 0x4810: 0x0080, 0x4811: 0x0080, + 0x4812: 0x0080, 0x4813: 0x0080, 0x4814: 0x0080, 0x4815: 0x0080, 0x4816: 0x0080, 0x4817: 0x0080, + 0x4818: 0x0080, 0x4819: 0x0080, 0x481a: 0x0080, 0x481b: 0x0080, 0x481c: 0x0080, 0x481d: 0x0080, + 0x481e: 0x0080, 0x481f: 0x0080, 0x4820: 0x0080, 0x4821: 0x0080, 0x4822: 0x0080, 0x4823: 0x0080, + 0x4824: 0x0080, 0x4825: 0x0080, 0x4826: 0x0080, 0x4827: 0x0080, 0x4828: 0x0080, 0x4829: 0x0080, + 0x482a: 0x0080, 0x482b: 0x0080, 0x482c: 0x0080, 0x482d: 0x0080, 0x482e: 0x0080, 0x482f: 0x0080, + 0x4830: 0x0080, 0x4831: 0x0080, 0x4832: 0x0080, 0x4833: 0x0080, 0x4834: 0x0080, 0x4835: 0x0080, + 0x4836: 0x0080, 0x4837: 0x0080, 0x4838: 0x0080, 0x4839: 0x0080, 0x483a: 0x0080, 0x483b: 0x0080, + 0x483c: 0x0080, 0x483d: 0x0080, 0x483e: 0x0080, 0x483f: 0x0080, + // Block 0x121, offset 0x4840 + 0x4840: 0x0080, 0x4841: 0x0080, 0x4842: 0x0080, 0x4843: 0x0080, 0x4844: 0x0080, 0x4845: 0x0080, + 0x4847: 0x0080, 0x4848: 0x0080, 0x4849: 0x0080, 0x484a: 0x0080, + 0x484d: 0x0080, 0x484e: 0x0080, 0x484f: 0x0080, 0x4850: 0x0080, 0x4851: 0x0080, + 0x4852: 0x0080, 0x4853: 0x0080, 0x4854: 0x0080, 0x4856: 0x0080, 0x4857: 0x0080, + 0x4858: 0x0080, 0x4859: 0x0080, 0x485a: 0x0080, 0x485b: 0x0080, 0x485c: 0x0080, + 0x485e: 0x0080, 0x485f: 0x0080, 0x4860: 0x0080, 0x4861: 0x0080, 0x4862: 0x0080, 0x4863: 0x0080, + 0x4864: 0x0080, 0x4865: 0x0080, 0x4866: 0x0080, 0x4867: 0x0080, 0x4868: 0x0080, 0x4869: 0x0080, + 0x486a: 0x0080, 0x486b: 0x0080, 0x486c: 0x0080, 0x486d: 0x0080, 0x486e: 0x0080, 0x486f: 0x0080, + 0x4870: 0x0080, 0x4871: 0x0080, 0x4872: 0x0080, 0x4873: 0x0080, 0x4874: 0x0080, 0x4875: 0x0080, + 0x4876: 0x0080, 0x4877: 0x0080, 0x4878: 0x0080, 0x4879: 0x0080, 0x487b: 0x0080, + 0x487c: 0x0080, 0x487d: 0x0080, 0x487e: 0x0080, + // Block 0x122, offset 0x4880 + 0x4880: 0x0080, 0x4881: 0x0080, 0x4882: 0x0080, 0x4883: 0x0080, 0x4884: 0x0080, + 0x4886: 0x0080, 0x488a: 0x0080, 0x488b: 0x0080, + 0x488c: 0x0080, 0x488d: 0x0080, 0x488e: 0x0080, 0x488f: 0x0080, 0x4890: 0x0080, + 0x4892: 0x0080, 0x4893: 0x0080, 0x4894: 0x0080, 0x4895: 0x0080, 0x4896: 0x0080, 0x4897: 0x0080, + 0x4898: 0x0080, 0x4899: 0x0080, 0x489a: 0x0080, 0x489b: 0x0080, 0x489c: 0x0080, 0x489d: 0x0080, + 0x489e: 0x0080, 0x489f: 0x0080, 0x48a0: 0x0080, 0x48a1: 0x0080, 0x48a2: 0x0080, 0x48a3: 0x0080, + 0x48a4: 0x0080, 0x48a5: 0x0080, 0x48a6: 0x0080, 0x48a7: 0x0080, 0x48a8: 0x0080, 0x48a9: 0x0080, + 0x48aa: 0x0080, 0x48ab: 0x0080, 0x48ac: 0x0080, 0x48ad: 0x0080, 0x48ae: 0x0080, 0x48af: 0x0080, + 0x48b0: 0x0080, 0x48b1: 0x0080, 0x48b2: 0x0080, 0x48b3: 0x0080, 0x48b4: 0x0080, 0x48b5: 0x0080, + 0x48b6: 0x0080, 0x48b7: 0x0080, 0x48b8: 0x0080, 0x48b9: 0x0080, 0x48ba: 0x0080, 0x48bb: 0x0080, + 0x48bc: 0x0080, 0x48bd: 0x0080, 0x48be: 0x0080, 0x48bf: 0x0080, + // Block 0x123, offset 0x48c0 + 0x48c0: 0x0080, 0x48c1: 0x0080, 0x48c2: 0x0080, 0x48c3: 0x0080, 0x48c4: 0x0080, 0x48c5: 0x0080, + 0x48c6: 0x0080, 0x48c7: 0x0080, 0x48c8: 0x0080, 0x48c9: 0x0080, 0x48ca: 0x0080, 0x48cb: 0x0080, + 0x48cc: 0x0080, 0x48cd: 0x0080, 0x48ce: 0x0080, 0x48cf: 0x0080, 0x48d0: 0x0080, 0x48d1: 0x0080, + 0x48d2: 0x0080, 0x48d3: 0x0080, 0x48d4: 0x0080, 0x48d5: 0x0080, 0x48d6: 0x0080, 0x48d7: 0x0080, + 0x48d8: 0x0080, 0x48d9: 0x0080, 0x48da: 0x0080, 0x48db: 0x0080, 0x48dc: 0x0080, 0x48dd: 0x0080, + 0x48de: 0x0080, 0x48df: 0x0080, 0x48e0: 0x0080, 0x48e1: 0x0080, 0x48e2: 0x0080, 0x48e3: 0x0080, + 0x48e4: 0x0080, 0x48e5: 0x0080, 0x48e8: 0x0080, 0x48e9: 0x0080, + 0x48ea: 0x0080, 0x48eb: 0x0080, 0x48ec: 0x0080, 0x48ed: 0x0080, 0x48ee: 0x0080, 0x48ef: 0x0080, + 0x48f0: 0x0080, 0x48f1: 0x0080, 0x48f2: 0x0080, 0x48f3: 0x0080, 0x48f4: 0x0080, 0x48f5: 0x0080, + 0x48f6: 0x0080, 0x48f7: 0x0080, 0x48f8: 0x0080, 0x48f9: 0x0080, 0x48fa: 0x0080, 0x48fb: 0x0080, + 0x48fc: 0x0080, 0x48fd: 0x0080, 0x48fe: 0x0080, 0x48ff: 0x0080, + // Block 0x124, offset 0x4900 + 0x4900: 0x0080, 0x4901: 0x0080, 0x4902: 0x0080, 0x4903: 0x0080, 0x4904: 0x0080, 0x4905: 0x0080, + 0x4906: 0x0080, 0x4907: 0x0080, 0x4908: 0x0080, 0x4909: 0x0080, 0x490a: 0x0080, 0x490b: 0x0080, + 0x490e: 0x0080, 0x490f: 0x0080, 0x4910: 0x0080, 0x4911: 0x0080, + 0x4912: 0x0080, 0x4913: 0x0080, 0x4914: 0x0080, 0x4915: 0x0080, 0x4916: 0x0080, 0x4917: 0x0080, + 0x4918: 0x0080, 0x4919: 0x0080, 0x491a: 0x0080, 0x491b: 0x0080, 0x491c: 0x0080, 0x491d: 0x0080, + 0x491e: 0x0080, 0x491f: 0x0080, 0x4920: 0x0080, 0x4921: 0x0080, 0x4922: 0x0080, 0x4923: 0x0080, + 0x4924: 0x0080, 0x4925: 0x0080, 0x4926: 0x0080, 0x4927: 0x0080, 0x4928: 0x0080, 0x4929: 0x0080, + 0x492a: 0x0080, 0x492b: 0x0080, 0x492c: 0x0080, 0x492d: 0x0080, 0x492e: 0x0080, 0x492f: 0x0080, + 0x4930: 0x0080, 0x4931: 0x0080, 0x4932: 0x0080, 0x4933: 0x0080, 0x4934: 0x0080, 0x4935: 0x0080, + 0x4936: 0x0080, 0x4937: 0x0080, 0x4938: 0x0080, 0x4939: 0x0080, 0x493a: 0x0080, 0x493b: 0x0080, + 0x493c: 0x0080, 0x493d: 0x0080, 0x493e: 0x0080, 0x493f: 0x0080, + // Block 0x125, offset 0x4940 + 0x4940: 0x00c3, 0x4941: 0x00c3, 0x4942: 0x00c3, 0x4943: 0x00c3, 0x4944: 0x00c3, 0x4945: 0x00c3, + 0x4946: 0x00c3, 0x4947: 0x00c3, 0x4948: 0x00c3, 0x4949: 0x00c3, 0x494a: 0x00c3, 0x494b: 0x00c3, + 0x494c: 0x00c3, 0x494d: 0x00c3, 0x494e: 0x00c3, 0x494f: 0x00c3, 0x4950: 0x00c3, 0x4951: 0x00c3, + 0x4952: 0x00c3, 0x4953: 0x00c3, 0x4954: 0x00c3, 0x4955: 0x00c3, 0x4956: 0x00c3, 0x4957: 0x00c3, + 0x4958: 0x00c3, 0x4959: 0x00c3, 0x495a: 0x00c3, 0x495b: 0x00c3, 0x495c: 0x00c3, 0x495d: 0x00c3, + 0x495e: 0x00c3, 0x495f: 0x00c3, 0x4960: 0x00c3, 0x4961: 0x00c3, 0x4962: 0x00c3, 0x4963: 0x00c3, + 0x4964: 0x00c3, 0x4965: 0x00c3, 0x4966: 0x00c3, 0x4967: 0x00c3, 0x4968: 0x00c3, 0x4969: 0x00c3, + 0x496a: 0x00c3, 0x496b: 0x00c3, 0x496c: 0x00c3, 0x496d: 0x00c3, 0x496e: 0x00c3, 0x496f: 0x00c3, + 0x4970: 0x00c3, 0x4971: 0x00c3, 0x4972: 0x00c3, 0x4973: 0x00c3, 0x4974: 0x00c3, 0x4975: 0x00c3, + 0x4976: 0x00c3, 0x4977: 0x0080, 0x4978: 0x0080, 0x4979: 0x0080, 0x497a: 0x0080, 0x497b: 0x00c3, + 0x497c: 0x00c3, 0x497d: 0x00c3, 0x497e: 0x00c3, 0x497f: 0x00c3, + // Block 0x126, offset 0x4980 + 0x4980: 0x00c3, 0x4981: 0x00c3, 0x4982: 0x00c3, 0x4983: 0x00c3, 0x4984: 0x00c3, 0x4985: 0x00c3, + 0x4986: 0x00c3, 0x4987: 0x00c3, 0x4988: 0x00c3, 0x4989: 0x00c3, 0x498a: 0x00c3, 0x498b: 0x00c3, + 0x498c: 0x00c3, 0x498d: 0x00c3, 0x498e: 0x00c3, 0x498f: 0x00c3, 0x4990: 0x00c3, 0x4991: 0x00c3, + 0x4992: 0x00c3, 0x4993: 0x00c3, 0x4994: 0x00c3, 0x4995: 0x00c3, 0x4996: 0x00c3, 0x4997: 0x00c3, + 0x4998: 0x00c3, 0x4999: 0x00c3, 0x499a: 0x00c3, 0x499b: 0x00c3, 0x499c: 0x00c3, 0x499d: 0x00c3, + 0x499e: 0x00c3, 0x499f: 0x00c3, 0x49a0: 0x00c3, 0x49a1: 0x00c3, 0x49a2: 0x00c3, 0x49a3: 0x00c3, + 0x49a4: 0x00c3, 0x49a5: 0x00c3, 0x49a6: 0x00c3, 0x49a7: 0x00c3, 0x49a8: 0x00c3, 0x49a9: 0x00c3, + 0x49aa: 0x00c3, 0x49ab: 0x00c3, 0x49ac: 0x00c3, 0x49ad: 0x0080, 0x49ae: 0x0080, 0x49af: 0x0080, + 0x49b0: 0x0080, 0x49b1: 0x0080, 0x49b2: 0x0080, 0x49b3: 0x0080, 0x49b4: 0x0080, 0x49b5: 0x00c3, + 0x49b6: 0x0080, 0x49b7: 0x0080, 0x49b8: 0x0080, 0x49b9: 0x0080, 0x49ba: 0x0080, 0x49bb: 0x0080, + 0x49bc: 0x0080, 0x49bd: 0x0080, 0x49be: 0x0080, 0x49bf: 0x0080, + // Block 0x127, offset 0x49c0 + 0x49c0: 0x0080, 0x49c1: 0x0080, 0x49c2: 0x0080, 0x49c3: 0x0080, 0x49c4: 0x00c3, 0x49c5: 0x0080, + 0x49c6: 0x0080, 0x49c7: 0x0080, 0x49c8: 0x0080, 0x49c9: 0x0080, 0x49ca: 0x0080, 0x49cb: 0x0080, + 0x49db: 0x00c3, 0x49dc: 0x00c3, 0x49dd: 0x00c3, + 0x49de: 0x00c3, 0x49df: 0x00c3, 0x49e1: 0x00c3, 0x49e2: 0x00c3, 0x49e3: 0x00c3, + 0x49e4: 0x00c3, 0x49e5: 0x00c3, 0x49e6: 0x00c3, 0x49e7: 0x00c3, 0x49e8: 0x00c3, 0x49e9: 0x00c3, + 0x49ea: 0x00c3, 0x49eb: 0x00c3, 0x49ec: 0x00c3, 0x49ed: 0x00c3, 0x49ee: 0x00c3, 0x49ef: 0x00c3, + // Block 0x128, offset 0x4a00 + 0x4a00: 0x00c3, 0x4a01: 0x00c3, 0x4a02: 0x00c3, 0x4a03: 0x00c3, 0x4a04: 0x00c3, 0x4a05: 0x00c3, + 0x4a06: 0x00c3, 0x4a08: 0x00c3, 0x4a09: 0x00c3, 0x4a0a: 0x00c3, 0x4a0b: 0x00c3, + 0x4a0c: 0x00c3, 0x4a0d: 0x00c3, 0x4a0e: 0x00c3, 0x4a0f: 0x00c3, 0x4a10: 0x00c3, 0x4a11: 0x00c3, + 0x4a12: 0x00c3, 0x4a13: 0x00c3, 0x4a14: 0x00c3, 0x4a15: 0x00c3, 0x4a16: 0x00c3, 0x4a17: 0x00c3, + 0x4a18: 0x00c3, 0x4a1b: 0x00c3, 0x4a1c: 0x00c3, 0x4a1d: 0x00c3, + 0x4a1e: 0x00c3, 0x4a1f: 0x00c3, 0x4a20: 0x00c3, 0x4a21: 0x00c3, 0x4a23: 0x00c3, + 0x4a24: 0x00c3, 0x4a26: 0x00c3, 0x4a27: 0x00c3, 0x4a28: 0x00c3, 0x4a29: 0x00c3, + 0x4a2a: 0x00c3, + // Block 0x129, offset 0x4a40 + 0x4a40: 0x00c0, 0x4a41: 0x00c0, 0x4a42: 0x00c0, 0x4a43: 0x00c0, 0x4a44: 0x00c0, + 0x4a47: 0x0080, 0x4a48: 0x0080, 0x4a49: 0x0080, 0x4a4a: 0x0080, 0x4a4b: 0x0080, + 0x4a4c: 0x0080, 0x4a4d: 0x0080, 0x4a4e: 0x0080, 0x4a4f: 0x0080, 0x4a50: 0x00c3, 0x4a51: 0x00c3, + 0x4a52: 0x00c3, 0x4a53: 0x00c3, 0x4a54: 0x00c3, 0x4a55: 0x00c3, 0x4a56: 0x00c3, + // Block 0x12a, offset 0x4a80 + 0x4a80: 0x00c2, 0x4a81: 0x00c2, 0x4a82: 0x00c2, 0x4a83: 0x00c2, 0x4a84: 0x00c2, 0x4a85: 0x00c2, + 0x4a86: 0x00c2, 0x4a87: 0x00c2, 0x4a88: 0x00c2, 0x4a89: 0x00c2, 0x4a8a: 0x00c2, 0x4a8b: 0x00c2, + 0x4a8c: 0x00c2, 0x4a8d: 0x00c2, 0x4a8e: 0x00c2, 0x4a8f: 0x00c2, 0x4a90: 0x00c2, 0x4a91: 0x00c2, + 0x4a92: 0x00c2, 0x4a93: 0x00c2, 0x4a94: 0x00c2, 0x4a95: 0x00c2, 0x4a96: 0x00c2, 0x4a97: 0x00c2, + 0x4a98: 0x00c2, 0x4a99: 0x00c2, 0x4a9a: 0x00c2, 0x4a9b: 0x00c2, 0x4a9c: 0x00c2, 0x4a9d: 0x00c2, + 0x4a9e: 0x00c2, 0x4a9f: 0x00c2, 0x4aa0: 0x00c2, 0x4aa1: 0x00c2, 0x4aa2: 0x00c2, 0x4aa3: 0x00c2, + 0x4aa4: 0x00c2, 0x4aa5: 0x00c2, 0x4aa6: 0x00c2, 0x4aa7: 0x00c2, 0x4aa8: 0x00c2, 0x4aa9: 0x00c2, + 0x4aaa: 0x00c2, 0x4aab: 0x00c2, 0x4aac: 0x00c2, 0x4aad: 0x00c2, 0x4aae: 0x00c2, 0x4aaf: 0x00c2, + 0x4ab0: 0x00c2, 0x4ab1: 0x00c2, 0x4ab2: 0x00c2, 0x4ab3: 0x00c2, 0x4ab4: 0x00c2, 0x4ab5: 0x00c2, + 0x4ab6: 0x00c2, 0x4ab7: 0x00c2, 0x4ab8: 0x00c2, 0x4ab9: 0x00c2, 0x4aba: 0x00c2, 0x4abb: 0x00c2, + 0x4abc: 0x00c2, 0x4abd: 0x00c2, 0x4abe: 0x00c2, 0x4abf: 0x00c2, + // Block 0x12b, offset 0x4ac0 + 0x4ac0: 0x00c2, 0x4ac1: 0x00c2, 0x4ac2: 0x00c2, 0x4ac3: 0x00c2, 0x4ac4: 0x00c3, 0x4ac5: 0x00c3, + 0x4ac6: 0x00c3, 0x4ac7: 0x00c3, 0x4ac8: 0x00c3, 0x4ac9: 0x00c3, 0x4aca: 0x00c3, + 0x4ad0: 0x00c0, 0x4ad1: 0x00c0, + 0x4ad2: 0x00c0, 0x4ad3: 0x00c0, 0x4ad4: 0x00c0, 0x4ad5: 0x00c0, 0x4ad6: 0x00c0, 0x4ad7: 0x00c0, + 0x4ad8: 0x00c0, 0x4ad9: 0x00c0, + 0x4ade: 0x0080, 0x4adf: 0x0080, + // Block 0x12c, offset 0x4b00 + 0x4b00: 0x0080, 0x4b01: 0x0080, 0x4b02: 0x0080, 0x4b03: 0x0080, 0x4b05: 0x0080, + 0x4b06: 0x0080, 0x4b07: 0x0080, 0x4b08: 0x0080, 0x4b09: 0x0080, 0x4b0a: 0x0080, 0x4b0b: 0x0080, + 0x4b0c: 0x0080, 0x4b0d: 0x0080, 0x4b0e: 0x0080, 0x4b0f: 0x0080, 0x4b10: 0x0080, 0x4b11: 0x0080, + 0x4b12: 0x0080, 0x4b13: 0x0080, 0x4b14: 0x0080, 0x4b15: 0x0080, 0x4b16: 0x0080, 0x4b17: 0x0080, + 0x4b18: 0x0080, 0x4b19: 0x0080, 0x4b1a: 0x0080, 0x4b1b: 0x0080, 0x4b1c: 0x0080, 0x4b1d: 0x0080, + 0x4b1e: 0x0080, 0x4b1f: 0x0080, 0x4b21: 0x0080, 0x4b22: 0x0080, + 0x4b24: 0x0080, 0x4b27: 0x0080, 0x4b29: 0x0080, + 0x4b2a: 0x0080, 0x4b2b: 0x0080, 0x4b2c: 0x0080, 0x4b2d: 0x0080, 0x4b2e: 0x0080, 0x4b2f: 0x0080, + 0x4b30: 0x0080, 0x4b31: 0x0080, 0x4b32: 0x0080, 0x4b34: 0x0080, 0x4b35: 0x0080, + 0x4b36: 0x0080, 0x4b37: 0x0080, 0x4b39: 0x0080, 0x4b3b: 0x0080, + // Block 0x12d, offset 0x4b40 + 0x4b42: 0x0080, + 0x4b47: 0x0080, 0x4b49: 0x0080, 0x4b4b: 0x0080, + 0x4b4d: 0x0080, 0x4b4e: 0x0080, 0x4b4f: 0x0080, 0x4b51: 0x0080, + 0x4b52: 0x0080, 0x4b54: 0x0080, 0x4b57: 0x0080, + 0x4b59: 0x0080, 0x4b5b: 0x0080, 0x4b5d: 0x0080, + 0x4b5f: 0x0080, 0x4b61: 0x0080, 0x4b62: 0x0080, + 0x4b64: 0x0080, 0x4b67: 0x0080, 0x4b68: 0x0080, 0x4b69: 0x0080, + 0x4b6a: 0x0080, 0x4b6c: 0x0080, 0x4b6d: 0x0080, 0x4b6e: 0x0080, 0x4b6f: 0x0080, + 0x4b70: 0x0080, 0x4b71: 0x0080, 0x4b72: 0x0080, 0x4b74: 0x0080, 0x4b75: 0x0080, + 0x4b76: 0x0080, 0x4b77: 0x0080, 0x4b79: 0x0080, 0x4b7a: 0x0080, 0x4b7b: 0x0080, + 0x4b7c: 0x0080, 0x4b7e: 0x0080, + // Block 0x12e, offset 0x4b80 + 0x4b80: 0x0080, 0x4b81: 0x0080, 0x4b82: 0x0080, 0x4b83: 0x0080, 0x4b84: 0x0080, 0x4b85: 0x0080, + 0x4b86: 0x0080, 0x4b87: 0x0080, 0x4b88: 0x0080, 0x4b89: 0x0080, 0x4b8b: 0x0080, + 0x4b8c: 0x0080, 0x4b8d: 0x0080, 0x4b8e: 0x0080, 0x4b8f: 0x0080, 0x4b90: 0x0080, 0x4b91: 0x0080, + 0x4b92: 0x0080, 0x4b93: 0x0080, 0x4b94: 0x0080, 0x4b95: 0x0080, 0x4b96: 0x0080, 0x4b97: 0x0080, + 0x4b98: 0x0080, 0x4b99: 0x0080, 0x4b9a: 0x0080, 0x4b9b: 0x0080, + 0x4ba1: 0x0080, 0x4ba2: 0x0080, 0x4ba3: 0x0080, + 0x4ba5: 0x0080, 0x4ba6: 0x0080, 0x4ba7: 0x0080, 0x4ba8: 0x0080, 0x4ba9: 0x0080, + 0x4bab: 0x0080, 0x4bac: 0x0080, 0x4bad: 0x0080, 0x4bae: 0x0080, 0x4baf: 0x0080, + 0x4bb0: 0x0080, 0x4bb1: 0x0080, 0x4bb2: 0x0080, 0x4bb3: 0x0080, 0x4bb4: 0x0080, 0x4bb5: 0x0080, + 0x4bb6: 0x0080, 0x4bb7: 0x0080, 0x4bb8: 0x0080, 0x4bb9: 0x0080, 0x4bba: 0x0080, 0x4bbb: 0x0080, + // Block 0x12f, offset 0x4bc0 + 0x4bf0: 0x0080, 0x4bf1: 0x0080, + // Block 0x130, offset 0x4c00 + 0x4c00: 0x0080, 0x4c01: 0x0080, 0x4c02: 0x0080, 0x4c03: 0x0080, 0x4c04: 0x0080, 0x4c05: 0x0080, + 0x4c06: 0x0080, 0x4c07: 0x0080, 0x4c08: 0x0080, 0x4c09: 0x0080, 0x4c0a: 0x0080, 0x4c0b: 0x0080, + 0x4c0c: 0x0080, 0x4c0d: 0x0080, 0x4c0e: 0x0080, 0x4c0f: 0x0080, 0x4c10: 0x0080, 0x4c11: 0x0080, + 0x4c12: 0x0080, 0x4c13: 0x0080, 0x4c14: 0x0080, 0x4c15: 0x0080, 0x4c16: 0x0080, 0x4c17: 0x0080, + 0x4c18: 0x0080, 0x4c19: 0x0080, 0x4c1a: 0x0080, 0x4c1b: 0x0080, 0x4c1c: 0x0080, 0x4c1d: 0x0080, + 0x4c1e: 0x0080, 0x4c1f: 0x0080, 0x4c20: 0x0080, 0x4c21: 0x0080, 0x4c22: 0x0080, 0x4c23: 0x0080, + 0x4c24: 0x0080, 0x4c25: 0x0080, 0x4c26: 0x0080, 0x4c27: 0x0080, 0x4c28: 0x0080, 0x4c29: 0x0080, + 0x4c2a: 0x0080, 0x4c2b: 0x0080, + 0x4c30: 0x0080, 0x4c31: 0x0080, 0x4c32: 0x0080, 0x4c33: 0x0080, 0x4c34: 0x0080, 0x4c35: 0x0080, + 0x4c36: 0x0080, 0x4c37: 0x0080, 0x4c38: 0x0080, 0x4c39: 0x0080, 0x4c3a: 0x0080, 0x4c3b: 0x0080, + 0x4c3c: 0x0080, 0x4c3d: 0x0080, 0x4c3e: 0x0080, 0x4c3f: 0x0080, + // Block 0x131, offset 0x4c40 + 0x4c40: 0x0080, 0x4c41: 0x0080, 0x4c42: 0x0080, 0x4c43: 0x0080, 0x4c44: 0x0080, 0x4c45: 0x0080, + 0x4c46: 0x0080, 0x4c47: 0x0080, 0x4c48: 0x0080, 0x4c49: 0x0080, 0x4c4a: 0x0080, 0x4c4b: 0x0080, + 0x4c4c: 0x0080, 0x4c4d: 0x0080, 0x4c4e: 0x0080, 0x4c4f: 0x0080, 0x4c50: 0x0080, 0x4c51: 0x0080, + 0x4c52: 0x0080, 0x4c53: 0x0080, + 0x4c60: 0x0080, 0x4c61: 0x0080, 0x4c62: 0x0080, 0x4c63: 0x0080, + 0x4c64: 0x0080, 0x4c65: 0x0080, 0x4c66: 0x0080, 0x4c67: 0x0080, 0x4c68: 0x0080, 0x4c69: 0x0080, + 0x4c6a: 0x0080, 0x4c6b: 0x0080, 0x4c6c: 0x0080, 0x4c6d: 0x0080, 0x4c6e: 0x0080, + 0x4c71: 0x0080, 0x4c72: 0x0080, 0x4c73: 0x0080, 0x4c74: 0x0080, 0x4c75: 0x0080, + 0x4c76: 0x0080, 0x4c77: 0x0080, 0x4c78: 0x0080, 0x4c79: 0x0080, 0x4c7a: 0x0080, 0x4c7b: 0x0080, + 0x4c7c: 0x0080, 0x4c7d: 0x0080, 0x4c7e: 0x0080, 0x4c7f: 0x0080, + // Block 0x132, offset 0x4c80 + 0x4c81: 0x0080, 0x4c82: 0x0080, 0x4c83: 0x0080, 0x4c84: 0x0080, 0x4c85: 0x0080, + 0x4c86: 0x0080, 0x4c87: 0x0080, 0x4c88: 0x0080, 0x4c89: 0x0080, 0x4c8a: 0x0080, 0x4c8b: 0x0080, + 0x4c8c: 0x0080, 0x4c8d: 0x0080, 0x4c8e: 0x0080, 0x4c8f: 0x0080, 0x4c91: 0x0080, + 0x4c92: 0x0080, 0x4c93: 0x0080, 0x4c94: 0x0080, 0x4c95: 0x0080, 0x4c96: 0x0080, 0x4c97: 0x0080, + 0x4c98: 0x0080, 0x4c99: 0x0080, 0x4c9a: 0x0080, 0x4c9b: 0x0080, 0x4c9c: 0x0080, 0x4c9d: 0x0080, + 0x4c9e: 0x0080, 0x4c9f: 0x0080, 0x4ca0: 0x0080, 0x4ca1: 0x0080, 0x4ca2: 0x0080, 0x4ca3: 0x0080, + 0x4ca4: 0x0080, 0x4ca5: 0x0080, 0x4ca6: 0x0080, 0x4ca7: 0x0080, 0x4ca8: 0x0080, 0x4ca9: 0x0080, + 0x4caa: 0x0080, 0x4cab: 0x0080, 0x4cac: 0x0080, 0x4cad: 0x0080, 0x4cae: 0x0080, 0x4caf: 0x0080, + 0x4cb0: 0x0080, 0x4cb1: 0x0080, 0x4cb2: 0x0080, 0x4cb3: 0x0080, 0x4cb4: 0x0080, 0x4cb5: 0x0080, + // Block 0x133, offset 0x4cc0 + 0x4cc0: 0x0080, 0x4cc1: 0x0080, 0x4cc2: 0x0080, 0x4cc3: 0x0080, 0x4cc4: 0x0080, 0x4cc5: 0x0080, + 0x4cc6: 0x0080, 0x4cc7: 0x0080, 0x4cc8: 0x0080, 0x4cc9: 0x0080, 0x4cca: 0x0080, 0x4ccb: 0x0080, + 0x4ccc: 0x0080, 0x4cd0: 0x0080, 0x4cd1: 0x0080, + 0x4cd2: 0x0080, 0x4cd3: 0x0080, 0x4cd4: 0x0080, 0x4cd5: 0x0080, 0x4cd6: 0x0080, 0x4cd7: 0x0080, + 0x4cd8: 0x0080, 0x4cd9: 0x0080, 0x4cda: 0x0080, 0x4cdb: 0x0080, 0x4cdc: 0x0080, 0x4cdd: 0x0080, + 0x4cde: 0x0080, 0x4cdf: 0x0080, 0x4ce0: 0x0080, 0x4ce1: 0x0080, 0x4ce2: 0x0080, 0x4ce3: 0x0080, + 0x4ce4: 0x0080, 0x4ce5: 0x0080, 0x4ce6: 0x0080, 0x4ce7: 0x0080, 0x4ce8: 0x0080, 0x4ce9: 0x0080, + 0x4cea: 0x0080, 0x4ceb: 0x0080, 0x4cec: 0x0080, 0x4ced: 0x0080, 0x4cee: 0x0080, + 0x4cf0: 0x0080, 0x4cf1: 0x0080, 0x4cf2: 0x0080, 0x4cf3: 0x0080, 0x4cf4: 0x0080, 0x4cf5: 0x0080, + 0x4cf6: 0x0080, 0x4cf7: 0x0080, 0x4cf8: 0x0080, 0x4cf9: 0x0080, 0x4cfa: 0x0080, 0x4cfb: 0x0080, + 0x4cfc: 0x0080, 0x4cfd: 0x0080, 0x4cfe: 0x0080, 0x4cff: 0x0080, + // Block 0x134, offset 0x4d00 + 0x4d00: 0x0080, 0x4d01: 0x0080, 0x4d02: 0x0080, 0x4d03: 0x0080, 0x4d04: 0x0080, 0x4d05: 0x0080, + 0x4d06: 0x0080, 0x4d07: 0x0080, 0x4d08: 0x0080, 0x4d09: 0x0080, 0x4d0a: 0x0080, 0x4d0b: 0x0080, + 0x4d0c: 0x0080, 0x4d0d: 0x0080, 0x4d0e: 0x0080, 0x4d0f: 0x0080, 0x4d10: 0x0080, 0x4d11: 0x0080, + 0x4d12: 0x0080, 0x4d13: 0x0080, 0x4d14: 0x0080, 0x4d15: 0x0080, 0x4d16: 0x0080, 0x4d17: 0x0080, + 0x4d18: 0x0080, 0x4d19: 0x0080, 0x4d1a: 0x0080, 0x4d1b: 0x0080, 0x4d1c: 0x0080, 0x4d1d: 0x0080, + 0x4d1e: 0x0080, 0x4d1f: 0x0080, 0x4d20: 0x0080, 0x4d21: 0x0080, 0x4d22: 0x0080, 0x4d23: 0x0080, + 0x4d24: 0x0080, 0x4d25: 0x0080, 0x4d26: 0x0080, 0x4d27: 0x0080, 0x4d28: 0x0080, 0x4d29: 0x0080, + 0x4d2a: 0x0080, 0x4d2b: 0x0080, 0x4d2c: 0x0080, + // Block 0x135, offset 0x4d40 + 0x4d66: 0x0080, 0x4d67: 0x0080, 0x4d68: 0x0080, 0x4d69: 0x0080, + 0x4d6a: 0x0080, 0x4d6b: 0x0080, 0x4d6c: 0x0080, 0x4d6d: 0x0080, 0x4d6e: 0x0080, 0x4d6f: 0x0080, + 0x4d70: 0x0080, 0x4d71: 0x0080, 0x4d72: 0x0080, 0x4d73: 0x0080, 0x4d74: 0x0080, 0x4d75: 0x0080, + 0x4d76: 0x0080, 0x4d77: 0x0080, 0x4d78: 0x0080, 0x4d79: 0x0080, 0x4d7a: 0x0080, 0x4d7b: 0x0080, + 0x4d7c: 0x0080, 0x4d7d: 0x0080, 0x4d7e: 0x0080, 0x4d7f: 0x0080, + // Block 0x136, offset 0x4d80 + 0x4d80: 0x008c, 0x4d81: 0x0080, 0x4d82: 0x0080, + 0x4d90: 0x0080, 0x4d91: 0x0080, + 0x4d92: 0x0080, 0x4d93: 0x0080, 0x4d94: 0x0080, 0x4d95: 0x0080, 0x4d96: 0x0080, 0x4d97: 0x0080, + 0x4d98: 0x0080, 0x4d99: 0x0080, 0x4d9a: 0x0080, 0x4d9b: 0x0080, 0x4d9c: 0x0080, 0x4d9d: 0x0080, + 0x4d9e: 0x0080, 0x4d9f: 0x0080, 0x4da0: 0x0080, 0x4da1: 0x0080, 0x4da2: 0x0080, 0x4da3: 0x0080, + 0x4da4: 0x0080, 0x4da5: 0x0080, 0x4da6: 0x0080, 0x4da7: 0x0080, 0x4da8: 0x0080, 0x4da9: 0x0080, + 0x4daa: 0x0080, 0x4dab: 0x0080, 0x4dac: 0x0080, 0x4dad: 0x0080, 0x4dae: 0x0080, 0x4daf: 0x0080, + 0x4db0: 0x0080, 0x4db1: 0x0080, 0x4db2: 0x0080, 0x4db3: 0x0080, 0x4db4: 0x0080, 0x4db5: 0x0080, + 0x4db6: 0x0080, 0x4db7: 0x0080, 0x4db8: 0x0080, 0x4db9: 0x0080, 0x4dba: 0x0080, 0x4dbb: 0x0080, + // Block 0x137, offset 0x4dc0 + 0x4dc0: 0x0080, 0x4dc1: 0x0080, 0x4dc2: 0x0080, 0x4dc3: 0x0080, 0x4dc4: 0x0080, 0x4dc5: 0x0080, + 0x4dc6: 0x0080, 0x4dc7: 0x0080, 0x4dc8: 0x0080, + 0x4dd0: 0x0080, 0x4dd1: 0x0080, + 0x4de0: 0x0080, 0x4de1: 0x0080, 0x4de2: 0x0080, 0x4de3: 0x0080, + 0x4de4: 0x0080, 0x4de5: 0x0080, + // Block 0x138, offset 0x4e00 + 0x4e00: 0x0080, 0x4e01: 0x0080, 0x4e02: 0x0080, 0x4e03: 0x0080, 0x4e04: 0x0080, 0x4e05: 0x0080, + 0x4e06: 0x0080, 0x4e07: 0x0080, 0x4e08: 0x0080, 0x4e09: 0x0080, 0x4e0a: 0x0080, 0x4e0b: 0x0080, + 0x4e0c: 0x0080, 0x4e0d: 0x0080, 0x4e0e: 0x0080, 0x4e0f: 0x0080, 0x4e10: 0x0080, 0x4e11: 0x0080, + 0x4e12: 0x0080, 0x4e13: 0x0080, 0x4e14: 0x0080, + 0x4e20: 0x0080, 0x4e21: 0x0080, 0x4e22: 0x0080, 0x4e23: 0x0080, + 0x4e24: 0x0080, 0x4e25: 0x0080, 0x4e26: 0x0080, 0x4e27: 0x0080, 0x4e28: 0x0080, 0x4e29: 0x0080, + 0x4e2a: 0x0080, 0x4e2b: 0x0080, 0x4e2c: 0x0080, + 0x4e30: 0x0080, 0x4e31: 0x0080, 0x4e32: 0x0080, 0x4e33: 0x0080, 0x4e34: 0x0080, 0x4e35: 0x0080, + 0x4e36: 0x0080, 0x4e37: 0x0080, 0x4e38: 0x0080, + // Block 0x139, offset 0x4e40 + 0x4e40: 0x0080, 0x4e41: 0x0080, 0x4e42: 0x0080, 0x4e43: 0x0080, 0x4e44: 0x0080, 0x4e45: 0x0080, + 0x4e46: 0x0080, 0x4e47: 0x0080, 0x4e48: 0x0080, 0x4e49: 0x0080, 0x4e4a: 0x0080, 0x4e4b: 0x0080, + 0x4e4c: 0x0080, 0x4e4d: 0x0080, 0x4e4e: 0x0080, 0x4e4f: 0x0080, 0x4e50: 0x0080, 0x4e51: 0x0080, + 0x4e52: 0x0080, 0x4e53: 0x0080, 0x4e54: 0x0080, 0x4e55: 0x0080, 0x4e56: 0x0080, 0x4e57: 0x0080, + 0x4e58: 0x0080, 0x4e59: 0x0080, 0x4e5a: 0x0080, 0x4e5b: 0x0080, 0x4e5c: 0x0080, 0x4e5d: 0x0080, + 0x4e5e: 0x0080, 0x4e5f: 0x0080, 0x4e60: 0x0080, 0x4e61: 0x0080, 0x4e62: 0x0080, 0x4e63: 0x0080, + 0x4e64: 0x0080, 0x4e65: 0x0080, 0x4e66: 0x0080, 0x4e67: 0x0080, 0x4e68: 0x0080, 0x4e69: 0x0080, + 0x4e6a: 0x0080, 0x4e6b: 0x0080, 0x4e6c: 0x0080, 0x4e6d: 0x0080, 0x4e6e: 0x0080, 0x4e6f: 0x0080, + 0x4e70: 0x0080, 0x4e71: 0x0080, 0x4e72: 0x0080, 0x4e73: 0x0080, + // Block 0x13a, offset 0x4e80 + 0x4e80: 0x0080, 0x4e81: 0x0080, 0x4e82: 0x0080, 0x4e83: 0x0080, 0x4e84: 0x0080, 0x4e85: 0x0080, + 0x4e86: 0x0080, 0x4e87: 0x0080, 0x4e88: 0x0080, 0x4e89: 0x0080, 0x4e8a: 0x0080, 0x4e8b: 0x0080, + 0x4e8c: 0x0080, 0x4e8d: 0x0080, 0x4e8e: 0x0080, 0x4e8f: 0x0080, 0x4e90: 0x0080, 0x4e91: 0x0080, + 0x4e92: 0x0080, 0x4e93: 0x0080, 0x4e94: 0x0080, + // Block 0x13b, offset 0x4ec0 + 0x4ec0: 0x0080, 0x4ec1: 0x0080, 0x4ec2: 0x0080, 0x4ec3: 0x0080, 0x4ec4: 0x0080, 0x4ec5: 0x0080, + 0x4ec6: 0x0080, 0x4ec7: 0x0080, 0x4ec8: 0x0080, 0x4ec9: 0x0080, 0x4eca: 0x0080, 0x4ecb: 0x0080, + 0x4ed0: 0x0080, 0x4ed1: 0x0080, + 0x4ed2: 0x0080, 0x4ed3: 0x0080, 0x4ed4: 0x0080, 0x4ed5: 0x0080, 0x4ed6: 0x0080, 0x4ed7: 0x0080, + 0x4ed8: 0x0080, 0x4ed9: 0x0080, 0x4eda: 0x0080, 0x4edb: 0x0080, 0x4edc: 0x0080, 0x4edd: 0x0080, + 0x4ede: 0x0080, 0x4edf: 0x0080, 0x4ee0: 0x0080, 0x4ee1: 0x0080, 0x4ee2: 0x0080, 0x4ee3: 0x0080, + 0x4ee4: 0x0080, 0x4ee5: 0x0080, 0x4ee6: 0x0080, 0x4ee7: 0x0080, 0x4ee8: 0x0080, 0x4ee9: 0x0080, + 0x4eea: 0x0080, 0x4eeb: 0x0080, 0x4eec: 0x0080, 0x4eed: 0x0080, 0x4eee: 0x0080, 0x4eef: 0x0080, + 0x4ef0: 0x0080, 0x4ef1: 0x0080, 0x4ef2: 0x0080, 0x4ef3: 0x0080, 0x4ef4: 0x0080, 0x4ef5: 0x0080, + 0x4ef6: 0x0080, 0x4ef7: 0x0080, 0x4ef8: 0x0080, 0x4ef9: 0x0080, 0x4efa: 0x0080, 0x4efb: 0x0080, + 0x4efc: 0x0080, 0x4efd: 0x0080, 0x4efe: 0x0080, 0x4eff: 0x0080, + // Block 0x13c, offset 0x4f00 + 0x4f00: 0x0080, 0x4f01: 0x0080, 0x4f02: 0x0080, 0x4f03: 0x0080, 0x4f04: 0x0080, 0x4f05: 0x0080, + 0x4f06: 0x0080, 0x4f07: 0x0080, + 0x4f10: 0x0080, 0x4f11: 0x0080, + 0x4f12: 0x0080, 0x4f13: 0x0080, 0x4f14: 0x0080, 0x4f15: 0x0080, 0x4f16: 0x0080, 0x4f17: 0x0080, + 0x4f18: 0x0080, 0x4f19: 0x0080, + 0x4f20: 0x0080, 0x4f21: 0x0080, 0x4f22: 0x0080, 0x4f23: 0x0080, + 0x4f24: 0x0080, 0x4f25: 0x0080, 0x4f26: 0x0080, 0x4f27: 0x0080, 0x4f28: 0x0080, 0x4f29: 0x0080, + 0x4f2a: 0x0080, 0x4f2b: 0x0080, 0x4f2c: 0x0080, 0x4f2d: 0x0080, 0x4f2e: 0x0080, 0x4f2f: 0x0080, + 0x4f30: 0x0080, 0x4f31: 0x0080, 0x4f32: 0x0080, 0x4f33: 0x0080, 0x4f34: 0x0080, 0x4f35: 0x0080, + 0x4f36: 0x0080, 0x4f37: 0x0080, 0x4f38: 0x0080, 0x4f39: 0x0080, 0x4f3a: 0x0080, 0x4f3b: 0x0080, + 0x4f3c: 0x0080, 0x4f3d: 0x0080, 0x4f3e: 0x0080, 0x4f3f: 0x0080, + // Block 0x13d, offset 0x4f40 + 0x4f40: 0x0080, 0x4f41: 0x0080, 0x4f42: 0x0080, 0x4f43: 0x0080, 0x4f44: 0x0080, 0x4f45: 0x0080, + 0x4f46: 0x0080, 0x4f47: 0x0080, + 0x4f50: 0x0080, 0x4f51: 0x0080, + 0x4f52: 0x0080, 0x4f53: 0x0080, 0x4f54: 0x0080, 0x4f55: 0x0080, 0x4f56: 0x0080, 0x4f57: 0x0080, + 0x4f58: 0x0080, 0x4f59: 0x0080, 0x4f5a: 0x0080, 0x4f5b: 0x0080, 0x4f5c: 0x0080, 0x4f5d: 0x0080, + 0x4f5e: 0x0080, 0x4f5f: 0x0080, 0x4f60: 0x0080, 0x4f61: 0x0080, 0x4f62: 0x0080, 0x4f63: 0x0080, + 0x4f64: 0x0080, 0x4f65: 0x0080, 0x4f66: 0x0080, 0x4f67: 0x0080, 0x4f68: 0x0080, 0x4f69: 0x0080, + 0x4f6a: 0x0080, 0x4f6b: 0x0080, 0x4f6c: 0x0080, 0x4f6d: 0x0080, + // Block 0x13e, offset 0x4f80 + 0x4f80: 0x0080, 0x4f81: 0x0080, 0x4f82: 0x0080, 0x4f83: 0x0080, 0x4f84: 0x0080, 0x4f85: 0x0080, + 0x4f86: 0x0080, 0x4f87: 0x0080, 0x4f88: 0x0080, 0x4f89: 0x0080, 0x4f8a: 0x0080, 0x4f8b: 0x0080, + 0x4f90: 0x0080, 0x4f91: 0x0080, + 0x4f92: 0x0080, 0x4f93: 0x0080, 0x4f94: 0x0080, 0x4f95: 0x0080, 0x4f96: 0x0080, 0x4f97: 0x0080, + 0x4f98: 0x0080, 0x4f99: 0x0080, 0x4f9a: 0x0080, 0x4f9b: 0x0080, 0x4f9c: 0x0080, 0x4f9d: 0x0080, + 0x4f9e: 0x0080, 0x4f9f: 0x0080, 0x4fa0: 0x0080, 0x4fa1: 0x0080, 0x4fa2: 0x0080, 0x4fa3: 0x0080, + 0x4fa4: 0x0080, 0x4fa5: 0x0080, 0x4fa6: 0x0080, 0x4fa7: 0x0080, 0x4fa8: 0x0080, 0x4fa9: 0x0080, + 0x4faa: 0x0080, 0x4fab: 0x0080, 0x4fac: 0x0080, 0x4fad: 0x0080, 0x4fae: 0x0080, 0x4faf: 0x0080, + 0x4fb0: 0x0080, 0x4fb1: 0x0080, 0x4fb2: 0x0080, 0x4fb3: 0x0080, 0x4fb4: 0x0080, 0x4fb5: 0x0080, + 0x4fb6: 0x0080, 0x4fb7: 0x0080, 0x4fb8: 0x0080, 0x4fb9: 0x0080, 0x4fba: 0x0080, 0x4fbb: 0x0080, + 0x4fbc: 0x0080, 0x4fbd: 0x0080, 0x4fbe: 0x0080, + // Block 0x13f, offset 0x4fc0 + 0x4fc0: 0x0080, 0x4fc1: 0x0080, 0x4fc2: 0x0080, 0x4fc3: 0x0080, 0x4fc4: 0x0080, 0x4fc5: 0x0080, + 0x4fc6: 0x0080, 0x4fc7: 0x0080, 0x4fc8: 0x0080, 0x4fc9: 0x0080, 0x4fca: 0x0080, 0x4fcb: 0x0080, + 0x4fcc: 0x0080, 0x4fd0: 0x0080, 0x4fd1: 0x0080, + 0x4fd2: 0x0080, 0x4fd3: 0x0080, 0x4fd4: 0x0080, 0x4fd5: 0x0080, 0x4fd6: 0x0080, 0x4fd7: 0x0080, + 0x4fd8: 0x0080, 0x4fd9: 0x0080, 0x4fda: 0x0080, 0x4fdb: 0x0080, 0x4fdc: 0x0080, 0x4fdd: 0x0080, + 0x4fde: 0x0080, 0x4fdf: 0x0080, 0x4fe0: 0x0080, 0x4fe1: 0x0080, 0x4fe2: 0x0080, 0x4fe3: 0x0080, + 0x4fe4: 0x0080, 0x4fe5: 0x0080, 0x4fe6: 0x0080, 0x4fe7: 0x0080, 0x4fe8: 0x0080, 0x4fe9: 0x0080, + 0x4fea: 0x0080, 0x4feb: 0x0080, + // Block 0x140, offset 0x5000 + 0x5000: 0x0080, 0x5001: 0x0080, 0x5002: 0x0080, 0x5003: 0x0080, 0x5004: 0x0080, 0x5005: 0x0080, + 0x5006: 0x0080, 0x5007: 0x0080, 0x5008: 0x0080, 0x5009: 0x0080, 0x500a: 0x0080, 0x500b: 0x0080, + 0x500c: 0x0080, 0x500d: 0x0080, 0x500e: 0x0080, 0x500f: 0x0080, 0x5010: 0x0080, 0x5011: 0x0080, + 0x5012: 0x0080, 0x5013: 0x0080, 0x5014: 0x0080, 0x5015: 0x0080, 0x5016: 0x0080, 0x5017: 0x0080, + // Block 0x141, offset 0x5040 + 0x5040: 0x0080, + 0x5050: 0x0080, 0x5051: 0x0080, + 0x5052: 0x0080, 0x5053: 0x0080, 0x5054: 0x0080, 0x5055: 0x0080, 0x5056: 0x0080, 0x5057: 0x0080, + 0x5058: 0x0080, 0x5059: 0x0080, 0x505a: 0x0080, 0x505b: 0x0080, 0x505c: 0x0080, 0x505d: 0x0080, + 0x505e: 0x0080, 0x505f: 0x0080, 0x5060: 0x0080, 0x5061: 0x0080, 0x5062: 0x0080, 0x5063: 0x0080, + 0x5064: 0x0080, 0x5065: 0x0080, 0x5066: 0x0080, + // Block 0x142, offset 0x5080 + 0x5080: 0x00cc, 0x5081: 0x00cc, 0x5082: 0x00cc, 0x5083: 0x00cc, 0x5084: 0x00cc, 0x5085: 0x00cc, + 0x5086: 0x00cc, 0x5087: 0x00cc, 0x5088: 0x00cc, 0x5089: 0x00cc, 0x508a: 0x00cc, 0x508b: 0x00cc, + 0x508c: 0x00cc, 0x508d: 0x00cc, 0x508e: 0x00cc, 0x508f: 0x00cc, 0x5090: 0x00cc, 0x5091: 0x00cc, + 0x5092: 0x00cc, 0x5093: 0x00cc, 0x5094: 0x00cc, 0x5095: 0x00cc, 0x5096: 0x00cc, + // Block 0x143, offset 0x50c0 + 0x50c0: 0x00cc, 0x50c1: 0x00cc, 0x50c2: 0x00cc, 0x50c3: 0x00cc, 0x50c4: 0x00cc, 0x50c5: 0x00cc, + 0x50c6: 0x00cc, 0x50c7: 0x00cc, 0x50c8: 0x00cc, 0x50c9: 0x00cc, 0x50ca: 0x00cc, 0x50cb: 0x00cc, + 0x50cc: 0x00cc, 0x50cd: 0x00cc, 0x50ce: 0x00cc, 0x50cf: 0x00cc, 0x50d0: 0x00cc, 0x50d1: 0x00cc, + 0x50d2: 0x00cc, 0x50d3: 0x00cc, 0x50d4: 0x00cc, 0x50d5: 0x00cc, 0x50d6: 0x00cc, 0x50d7: 0x00cc, + 0x50d8: 0x00cc, 0x50d9: 0x00cc, 0x50da: 0x00cc, 0x50db: 0x00cc, 0x50dc: 0x00cc, 0x50dd: 0x00cc, + 0x50de: 0x00cc, 0x50df: 0x00cc, 0x50e0: 0x00cc, 0x50e1: 0x00cc, 0x50e2: 0x00cc, 0x50e3: 0x00cc, + 0x50e4: 0x00cc, 0x50e5: 0x00cc, 0x50e6: 0x00cc, 0x50e7: 0x00cc, 0x50e8: 0x00cc, 0x50e9: 0x00cc, + 0x50ea: 0x00cc, 0x50eb: 0x00cc, 0x50ec: 0x00cc, 0x50ed: 0x00cc, 0x50ee: 0x00cc, 0x50ef: 0x00cc, + 0x50f0: 0x00cc, 0x50f1: 0x00cc, 0x50f2: 0x00cc, 0x50f3: 0x00cc, 0x50f4: 0x00cc, + // Block 0x144, offset 0x5100 + 0x5100: 0x00cc, 0x5101: 0x00cc, 0x5102: 0x00cc, 0x5103: 0x00cc, 0x5104: 0x00cc, 0x5105: 0x00cc, + 0x5106: 0x00cc, 0x5107: 0x00cc, 0x5108: 0x00cc, 0x5109: 0x00cc, 0x510a: 0x00cc, 0x510b: 0x00cc, + 0x510c: 0x00cc, 0x510d: 0x00cc, 0x510e: 0x00cc, 0x510f: 0x00cc, 0x5110: 0x00cc, 0x5111: 0x00cc, + 0x5112: 0x00cc, 0x5113: 0x00cc, 0x5114: 0x00cc, 0x5115: 0x00cc, 0x5116: 0x00cc, 0x5117: 0x00cc, + 0x5118: 0x00cc, 0x5119: 0x00cc, 0x511a: 0x00cc, 0x511b: 0x00cc, 0x511c: 0x00cc, 0x511d: 0x00cc, + 0x5120: 0x00cc, 0x5121: 0x00cc, 0x5122: 0x00cc, 0x5123: 0x00cc, + 0x5124: 0x00cc, 0x5125: 0x00cc, 0x5126: 0x00cc, 0x5127: 0x00cc, 0x5128: 0x00cc, 0x5129: 0x00cc, + 0x512a: 0x00cc, 0x512b: 0x00cc, 0x512c: 0x00cc, 0x512d: 0x00cc, 0x512e: 0x00cc, 0x512f: 0x00cc, + 0x5130: 0x00cc, 0x5131: 0x00cc, 0x5132: 0x00cc, 0x5133: 0x00cc, 0x5134: 0x00cc, 0x5135: 0x00cc, + 0x5136: 0x00cc, 0x5137: 0x00cc, 0x5138: 0x00cc, 0x5139: 0x00cc, 0x513a: 0x00cc, 0x513b: 0x00cc, + 0x513c: 0x00cc, 0x513d: 0x00cc, 0x513e: 0x00cc, 0x513f: 0x00cc, + // Block 0x145, offset 0x5140 + 0x5140: 0x00cc, 0x5141: 0x00cc, 0x5142: 0x00cc, 0x5143: 0x00cc, 0x5144: 0x00cc, 0x5145: 0x00cc, + 0x5146: 0x00cc, 0x5147: 0x00cc, 0x5148: 0x00cc, 0x5149: 0x00cc, 0x514a: 0x00cc, 0x514b: 0x00cc, + 0x514c: 0x00cc, 0x514d: 0x00cc, 0x514e: 0x00cc, 0x514f: 0x00cc, 0x5150: 0x00cc, 0x5151: 0x00cc, + 0x5152: 0x00cc, 0x5153: 0x00cc, 0x5154: 0x00cc, 0x5155: 0x00cc, 0x5156: 0x00cc, 0x5157: 0x00cc, + 0x5158: 0x00cc, 0x5159: 0x00cc, 0x515a: 0x00cc, 0x515b: 0x00cc, 0x515c: 0x00cc, 0x515d: 0x00cc, + 0x515e: 0x00cc, 0x515f: 0x00cc, 0x5160: 0x00cc, 0x5161: 0x00cc, + 0x5170: 0x00cc, 0x5171: 0x00cc, 0x5172: 0x00cc, 0x5173: 0x00cc, 0x5174: 0x00cc, 0x5175: 0x00cc, + 0x5176: 0x00cc, 0x5177: 0x00cc, 0x5178: 0x00cc, 0x5179: 0x00cc, 0x517a: 0x00cc, 0x517b: 0x00cc, + 0x517c: 0x00cc, 0x517d: 0x00cc, 0x517e: 0x00cc, 0x517f: 0x00cc, + // Block 0x146, offset 0x5180 + 0x5180: 0x00cc, 0x5181: 0x00cc, 0x5182: 0x00cc, 0x5183: 0x00cc, 0x5184: 0x00cc, 0x5185: 0x00cc, + 0x5186: 0x00cc, 0x5187: 0x00cc, 0x5188: 0x00cc, 0x5189: 0x00cc, 0x518a: 0x00cc, 0x518b: 0x00cc, + 0x518c: 0x00cc, 0x518d: 0x00cc, 0x518e: 0x00cc, 0x518f: 0x00cc, 0x5190: 0x00cc, 0x5191: 0x00cc, + 0x5192: 0x00cc, 0x5193: 0x00cc, 0x5194: 0x00cc, 0x5195: 0x00cc, 0x5196: 0x00cc, 0x5197: 0x00cc, + 0x5198: 0x00cc, 0x5199: 0x00cc, 0x519a: 0x00cc, 0x519b: 0x00cc, 0x519c: 0x00cc, 0x519d: 0x00cc, + 0x519e: 0x00cc, 0x519f: 0x00cc, 0x51a0: 0x00cc, + // Block 0x147, offset 0x51c0 + 0x51c0: 0x008c, 0x51c1: 0x008c, 0x51c2: 0x008c, 0x51c3: 0x008c, 0x51c4: 0x008c, 0x51c5: 0x008c, + 0x51c6: 0x008c, 0x51c7: 0x008c, 0x51c8: 0x008c, 0x51c9: 0x008c, 0x51ca: 0x008c, 0x51cb: 0x008c, + 0x51cc: 0x008c, 0x51cd: 0x008c, 0x51ce: 0x008c, 0x51cf: 0x008c, 0x51d0: 0x008c, 0x51d1: 0x008c, + 0x51d2: 0x008c, 0x51d3: 0x008c, 0x51d4: 0x008c, 0x51d5: 0x008c, 0x51d6: 0x008c, 0x51d7: 0x008c, + 0x51d8: 0x008c, 0x51d9: 0x008c, 0x51da: 0x008c, 0x51db: 0x008c, 0x51dc: 0x008c, 0x51dd: 0x008c, + // Block 0x148, offset 0x5200 + 0x5201: 0x0040, + 0x5220: 0x0040, 0x5221: 0x0040, 0x5222: 0x0040, 0x5223: 0x0040, + 0x5224: 0x0040, 0x5225: 0x0040, 0x5226: 0x0040, 0x5227: 0x0040, 0x5228: 0x0040, 0x5229: 0x0040, + 0x522a: 0x0040, 0x522b: 0x0040, 0x522c: 0x0040, 0x522d: 0x0040, 0x522e: 0x0040, 0x522f: 0x0040, + 0x5230: 0x0040, 0x5231: 0x0040, 0x5232: 0x0040, 0x5233: 0x0040, 0x5234: 0x0040, 0x5235: 0x0040, + 0x5236: 0x0040, 0x5237: 0x0040, 0x5238: 0x0040, 0x5239: 0x0040, 0x523a: 0x0040, 0x523b: 0x0040, + 0x523c: 0x0040, 0x523d: 0x0040, 0x523e: 0x0040, 0x523f: 0x0040, + // Block 0x149, offset 0x5240 + 0x5240: 0x0040, 0x5241: 0x0040, 0x5242: 0x0040, 0x5243: 0x0040, 0x5244: 0x0040, 0x5245: 0x0040, + 0x5246: 0x0040, 0x5247: 0x0040, 0x5248: 0x0040, 0x5249: 0x0040, 0x524a: 0x0040, 0x524b: 0x0040, + 0x524c: 0x0040, 0x524d: 0x0040, 0x524e: 0x0040, 0x524f: 0x0040, 0x5250: 0x0040, 0x5251: 0x0040, + 0x5252: 0x0040, 0x5253: 0x0040, 0x5254: 0x0040, 0x5255: 0x0040, 0x5256: 0x0040, 0x5257: 0x0040, + 0x5258: 0x0040, 0x5259: 0x0040, 0x525a: 0x0040, 0x525b: 0x0040, 0x525c: 0x0040, 0x525d: 0x0040, + 0x525e: 0x0040, 0x525f: 0x0040, 0x5260: 0x0040, 0x5261: 0x0040, 0x5262: 0x0040, 0x5263: 0x0040, + 0x5264: 0x0040, 0x5265: 0x0040, 0x5266: 0x0040, 0x5267: 0x0040, 0x5268: 0x0040, 0x5269: 0x0040, + 0x526a: 0x0040, 0x526b: 0x0040, 0x526c: 0x0040, 0x526d: 0x0040, 0x526e: 0x0040, 0x526f: 0x0040, + // Block 0x14a, offset 0x5280 + 0x5280: 0x0040, 0x5281: 0x0040, 0x5282: 0x0040, 0x5283: 0x0040, 0x5284: 0x0040, 0x5285: 0x0040, + 0x5286: 0x0040, 0x5287: 0x0040, 0x5288: 0x0040, 0x5289: 0x0040, 0x528a: 0x0040, 0x528b: 0x0040, + 0x528c: 0x0040, 0x528d: 0x0040, 0x528e: 0x0040, 0x528f: 0x0040, 0x5290: 0x0040, 0x5291: 0x0040, + 0x5292: 0x0040, 0x5293: 0x0040, 0x5294: 0x0040, 0x5295: 0x0040, 0x5296: 0x0040, 0x5297: 0x0040, + 0x5298: 0x0040, 0x5299: 0x0040, 0x529a: 0x0040, 0x529b: 0x0040, 0x529c: 0x0040, 0x529d: 0x0040, + 0x529e: 0x0040, 0x529f: 0x0040, 0x52a0: 0x0040, 0x52a1: 0x0040, 0x52a2: 0x0040, 0x52a3: 0x0040, + 0x52a4: 0x0040, 0x52a5: 0x0040, 0x52a6: 0x0040, 0x52a7: 0x0040, 0x52a8: 0x0040, 0x52a9: 0x0040, + 0x52aa: 0x0040, 0x52ab: 0x0040, 0x52ac: 0x0040, 0x52ad: 0x0040, 0x52ae: 0x0040, 0x52af: 0x0040, + 0x52b0: 0x0040, 0x52b1: 0x0040, 0x52b2: 0x0040, 0x52b3: 0x0040, 0x52b4: 0x0040, 0x52b5: 0x0040, + 0x52b6: 0x0040, 0x52b7: 0x0040, 0x52b8: 0x0040, 0x52b9: 0x0040, 0x52ba: 0x0040, 0x52bb: 0x0040, + 0x52bc: 0x0040, 0x52bd: 0x0040, +} + +// derivedPropertiesIndex: 37 blocks, 2368 entries, 4736 bytes +// Block 0 is the zero block. +var derivedPropertiesIndex = [2368]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc6: 0x05, 0xc7: 0x06, + 0xc8: 0x05, 0xc9: 0x05, 0xca: 0x07, 0xcb: 0x08, 0xcc: 0x09, 0xcd: 0x0a, 0xce: 0x0b, 0xcf: 0x0c, + 0xd0: 0x05, 0xd1: 0x05, 0xd2: 0x0d, 0xd3: 0x05, 0xd4: 0x0e, 0xd5: 0x0f, 0xd6: 0x10, 0xd7: 0x11, + 0xd8: 0x12, 0xd9: 0x13, 0xda: 0x14, 0xdb: 0x15, 0xdc: 0x16, 0xdd: 0x17, 0xde: 0x18, 0xdf: 0x19, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x0a, 0xec: 0x0a, 0xed: 0x0b, 0xee: 0x0c, 0xef: 0x0d, + 0xf0: 0x1e, 0xf3: 0x21, 0xf4: 0x22, + // Block 0x4, offset 0x100 + 0x120: 0x1a, 0x121: 0x1b, 0x122: 0x1c, 0x123: 0x1d, 0x124: 0x1e, 0x125: 0x1f, 0x126: 0x20, 0x127: 0x21, + 0x128: 0x22, 0x129: 0x23, 0x12a: 0x24, 0x12b: 0x25, 0x12c: 0x26, 0x12d: 0x27, 0x12e: 0x28, 0x12f: 0x29, + 0x130: 0x2a, 0x131: 0x2b, 0x132: 0x2c, 0x133: 0x2d, 0x134: 0x2e, 0x135: 0x2f, 0x136: 0x30, 0x137: 0x31, + 0x138: 0x32, 0x139: 0x33, 0x13a: 0x34, 0x13b: 0x35, 0x13c: 0x36, 0x13d: 0x37, 0x13e: 0x38, 0x13f: 0x39, + // Block 0x5, offset 0x140 + 0x140: 0x3a, 0x141: 0x3b, 0x142: 0x3c, 0x143: 0x3d, 0x144: 0x3e, 0x145: 0x3e, 0x146: 0x3e, 0x147: 0x3e, + 0x148: 0x05, 0x149: 0x3f, 0x14a: 0x40, 0x14b: 0x41, 0x14c: 0x42, 0x14d: 0x43, 0x14e: 0x44, 0x14f: 0x45, + 0x150: 0x46, 0x151: 0x05, 0x152: 0x05, 0x153: 0x05, 0x154: 0x05, 0x155: 0x05, 0x156: 0x05, 0x157: 0x05, + 0x158: 0x05, 0x159: 0x47, 0x15a: 0x48, 0x15b: 0x49, 0x15c: 0x4a, 0x15d: 0x4b, 0x15e: 0x4c, 0x15f: 0x4d, + 0x160: 0x4e, 0x161: 0x4f, 0x162: 0x50, 0x163: 0x51, 0x164: 0x52, 0x165: 0x53, 0x166: 0x54, 0x167: 0x55, + 0x168: 0x56, 0x169: 0x57, 0x16a: 0x58, 0x16c: 0x59, 0x16d: 0x5a, 0x16e: 0x5b, 0x16f: 0x5c, + 0x170: 0x5d, 0x171: 0x5e, 0x172: 0x5f, 0x173: 0x60, 0x174: 0x61, 0x175: 0x62, 0x176: 0x63, 0x177: 0x64, + 0x178: 0x05, 0x179: 0x05, 0x17a: 0x65, 0x17b: 0x05, 0x17c: 0x66, 0x17d: 0x67, 0x17e: 0x68, 0x17f: 0x69, + // Block 0x6, offset 0x180 + 0x180: 0x6a, 0x181: 0x6b, 0x182: 0x6c, 0x183: 0x6d, 0x184: 0x6e, 0x185: 0x6f, 0x186: 0x70, 0x187: 0x71, + 0x188: 0x71, 0x189: 0x71, 0x18a: 0x71, 0x18b: 0x71, 0x18c: 0x71, 0x18d: 0x71, 0x18e: 0x71, 0x18f: 0x71, + 0x190: 0x72, 0x191: 0x73, 0x192: 0x71, 0x193: 0x71, 0x194: 0x71, 0x195: 0x71, 0x196: 0x71, 0x197: 0x71, + 0x198: 0x71, 0x199: 0x71, 0x19a: 0x71, 0x19b: 0x71, 0x19c: 0x71, 0x19d: 0x71, 0x19e: 0x71, 0x19f: 0x71, + 0x1a0: 0x71, 0x1a1: 0x71, 0x1a2: 0x71, 0x1a3: 0x71, 0x1a4: 0x71, 0x1a5: 0x71, 0x1a6: 0x71, 0x1a7: 0x71, + 0x1a8: 0x71, 0x1a9: 0x71, 0x1aa: 0x71, 0x1ab: 0x71, 0x1ac: 0x71, 0x1ad: 0x74, 0x1ae: 0x75, 0x1af: 0x76, + 0x1b0: 0x77, 0x1b1: 0x78, 0x1b2: 0x05, 0x1b3: 0x79, 0x1b4: 0x7a, 0x1b5: 0x7b, 0x1b6: 0x7c, 0x1b7: 0x7d, + 0x1b8: 0x7e, 0x1b9: 0x7f, 0x1ba: 0x80, 0x1bb: 0x81, 0x1bc: 0x82, 0x1bd: 0x82, 0x1be: 0x82, 0x1bf: 0x83, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x84, 0x1c1: 0x85, 0x1c2: 0x86, 0x1c3: 0x87, 0x1c4: 0x88, 0x1c5: 0x89, 0x1c6: 0x8a, 0x1c7: 0x8b, + 0x1c8: 0x8c, 0x1c9: 0x71, 0x1ca: 0x71, 0x1cb: 0x8d, 0x1cc: 0x82, 0x1cd: 0x8e, 0x1ce: 0x71, 0x1cf: 0x71, + 0x1d0: 0x8f, 0x1d1: 0x8f, 0x1d2: 0x8f, 0x1d3: 0x8f, 0x1d4: 0x8f, 0x1d5: 0x8f, 0x1d6: 0x8f, 0x1d7: 0x8f, + 0x1d8: 0x8f, 0x1d9: 0x8f, 0x1da: 0x8f, 0x1db: 0x8f, 0x1dc: 0x8f, 0x1dd: 0x8f, 0x1de: 0x8f, 0x1df: 0x8f, + 0x1e0: 0x8f, 0x1e1: 0x8f, 0x1e2: 0x8f, 0x1e3: 0x8f, 0x1e4: 0x8f, 0x1e5: 0x8f, 0x1e6: 0x8f, 0x1e7: 0x8f, + 0x1e8: 0x8f, 0x1e9: 0x8f, 0x1ea: 0x8f, 0x1eb: 0x8f, 0x1ec: 0x8f, 0x1ed: 0x8f, 0x1ee: 0x8f, 0x1ef: 0x8f, + 0x1f0: 0x8f, 0x1f1: 0x8f, 0x1f2: 0x8f, 0x1f3: 0x8f, 0x1f4: 0x8f, 0x1f5: 0x8f, 0x1f6: 0x8f, 0x1f7: 0x8f, + 0x1f8: 0x8f, 0x1f9: 0x8f, 0x1fa: 0x8f, 0x1fb: 0x8f, 0x1fc: 0x8f, 0x1fd: 0x8f, 0x1fe: 0x8f, 0x1ff: 0x8f, + // Block 0x8, offset 0x200 + 0x200: 0x8f, 0x201: 0x8f, 0x202: 0x8f, 0x203: 0x8f, 0x204: 0x8f, 0x205: 0x8f, 0x206: 0x8f, 0x207: 0x8f, + 0x208: 0x8f, 0x209: 0x8f, 0x20a: 0x8f, 0x20b: 0x8f, 0x20c: 0x8f, 0x20d: 0x8f, 0x20e: 0x8f, 0x20f: 0x8f, + 0x210: 0x8f, 0x211: 0x8f, 0x212: 0x8f, 0x213: 0x8f, 0x214: 0x8f, 0x215: 0x8f, 0x216: 0x8f, 0x217: 0x8f, + 0x218: 0x8f, 0x219: 0x8f, 0x21a: 0x8f, 0x21b: 0x8f, 0x21c: 0x8f, 0x21d: 0x8f, 0x21e: 0x8f, 0x21f: 0x8f, + 0x220: 0x8f, 0x221: 0x8f, 0x222: 0x8f, 0x223: 0x8f, 0x224: 0x8f, 0x225: 0x8f, 0x226: 0x8f, 0x227: 0x8f, + 0x228: 0x8f, 0x229: 0x8f, 0x22a: 0x8f, 0x22b: 0x8f, 0x22c: 0x8f, 0x22d: 0x8f, 0x22e: 0x8f, 0x22f: 0x8f, + 0x230: 0x8f, 0x231: 0x8f, 0x232: 0x8f, 0x233: 0x8f, 0x234: 0x8f, 0x235: 0x8f, 0x236: 0x90, 0x237: 0x71, + 0x238: 0x8f, 0x239: 0x8f, 0x23a: 0x8f, 0x23b: 0x8f, 0x23c: 0x8f, 0x23d: 0x8f, 0x23e: 0x8f, 0x23f: 0x8f, + // Block 0x9, offset 0x240 + 0x240: 0x8f, 0x241: 0x8f, 0x242: 0x8f, 0x243: 0x8f, 0x244: 0x8f, 0x245: 0x8f, 0x246: 0x8f, 0x247: 0x8f, + 0x248: 0x8f, 0x249: 0x8f, 0x24a: 0x8f, 0x24b: 0x8f, 0x24c: 0x8f, 0x24d: 0x8f, 0x24e: 0x8f, 0x24f: 0x8f, + 0x250: 0x8f, 0x251: 0x8f, 0x252: 0x8f, 0x253: 0x8f, 0x254: 0x8f, 0x255: 0x8f, 0x256: 0x8f, 0x257: 0x8f, + 0x258: 0x8f, 0x259: 0x8f, 0x25a: 0x8f, 0x25b: 0x8f, 0x25c: 0x8f, 0x25d: 0x8f, 0x25e: 0x8f, 0x25f: 0x8f, + 0x260: 0x8f, 0x261: 0x8f, 0x262: 0x8f, 0x263: 0x8f, 0x264: 0x8f, 0x265: 0x8f, 0x266: 0x8f, 0x267: 0x8f, + 0x268: 0x8f, 0x269: 0x8f, 0x26a: 0x8f, 0x26b: 0x8f, 0x26c: 0x8f, 0x26d: 0x8f, 0x26e: 0x8f, 0x26f: 0x8f, + 0x270: 0x8f, 0x271: 0x8f, 0x272: 0x8f, 0x273: 0x8f, 0x274: 0x8f, 0x275: 0x8f, 0x276: 0x8f, 0x277: 0x8f, + 0x278: 0x8f, 0x279: 0x8f, 0x27a: 0x8f, 0x27b: 0x8f, 0x27c: 0x8f, 0x27d: 0x8f, 0x27e: 0x8f, 0x27f: 0x8f, + // Block 0xa, offset 0x280 + 0x280: 0x8f, 0x281: 0x8f, 0x282: 0x8f, 0x283: 0x8f, 0x284: 0x8f, 0x285: 0x8f, 0x286: 0x8f, 0x287: 0x8f, + 0x288: 0x8f, 0x289: 0x8f, 0x28a: 0x8f, 0x28b: 0x8f, 0x28c: 0x8f, 0x28d: 0x8f, 0x28e: 0x8f, 0x28f: 0x8f, + 0x290: 0x8f, 0x291: 0x8f, 0x292: 0x8f, 0x293: 0x8f, 0x294: 0x8f, 0x295: 0x8f, 0x296: 0x8f, 0x297: 0x8f, + 0x298: 0x8f, 0x299: 0x8f, 0x29a: 0x8f, 0x29b: 0x8f, 0x29c: 0x8f, 0x29d: 0x8f, 0x29e: 0x8f, 0x29f: 0x8f, + 0x2a0: 0x8f, 0x2a1: 0x8f, 0x2a2: 0x8f, 0x2a3: 0x8f, 0x2a4: 0x8f, 0x2a5: 0x8f, 0x2a6: 0x8f, 0x2a7: 0x8f, + 0x2a8: 0x8f, 0x2a9: 0x8f, 0x2aa: 0x8f, 0x2ab: 0x8f, 0x2ac: 0x8f, 0x2ad: 0x8f, 0x2ae: 0x8f, 0x2af: 0x8f, + 0x2b0: 0x8f, 0x2b1: 0x8f, 0x2b2: 0x8f, 0x2b3: 0x8f, 0x2b4: 0x8f, 0x2b5: 0x8f, 0x2b6: 0x8f, 0x2b7: 0x8f, + 0x2b8: 0x8f, 0x2b9: 0x8f, 0x2ba: 0x8f, 0x2bb: 0x8f, 0x2bc: 0x8f, 0x2bd: 0x8f, 0x2be: 0x8f, 0x2bf: 0x91, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x05, 0x2c1: 0x05, 0x2c2: 0x05, 0x2c3: 0x05, 0x2c4: 0x05, 0x2c5: 0x05, 0x2c6: 0x05, 0x2c7: 0x05, + 0x2c8: 0x05, 0x2c9: 0x05, 0x2ca: 0x05, 0x2cb: 0x05, 0x2cc: 0x05, 0x2cd: 0x05, 0x2ce: 0x05, 0x2cf: 0x05, + 0x2d0: 0x05, 0x2d1: 0x05, 0x2d2: 0x92, 0x2d3: 0x93, 0x2d4: 0x05, 0x2d5: 0x05, 0x2d6: 0x05, 0x2d7: 0x05, + 0x2d8: 0x94, 0x2d9: 0x95, 0x2da: 0x96, 0x2db: 0x97, 0x2dc: 0x98, 0x2dd: 0x99, 0x2de: 0x9a, 0x2df: 0x9b, + 0x2e0: 0x9c, 0x2e1: 0x9d, 0x2e2: 0x05, 0x2e3: 0x9e, 0x2e4: 0x9f, 0x2e5: 0xa0, 0x2e6: 0xa1, 0x2e7: 0xa2, + 0x2e8: 0xa3, 0x2e9: 0xa4, 0x2ea: 0xa5, 0x2eb: 0xa6, 0x2ec: 0xa7, 0x2ed: 0xa8, 0x2ee: 0x05, 0x2ef: 0xa9, + 0x2f0: 0x05, 0x2f1: 0x05, 0x2f2: 0x05, 0x2f3: 0x05, 0x2f4: 0x05, 0x2f5: 0x05, 0x2f6: 0x05, 0x2f7: 0x05, + 0x2f8: 0x05, 0x2f9: 0x05, 0x2fa: 0x05, 0x2fb: 0x05, 0x2fc: 0x05, 0x2fd: 0x05, 0x2fe: 0x05, 0x2ff: 0x05, + // Block 0xc, offset 0x300 + 0x300: 0x05, 0x301: 0x05, 0x302: 0x05, 0x303: 0x05, 0x304: 0x05, 0x305: 0x05, 0x306: 0x05, 0x307: 0x05, + 0x308: 0x05, 0x309: 0x05, 0x30a: 0x05, 0x30b: 0x05, 0x30c: 0x05, 0x30d: 0x05, 0x30e: 0x05, 0x30f: 0x05, + 0x310: 0x05, 0x311: 0x05, 0x312: 0x05, 0x313: 0x05, 0x314: 0x05, 0x315: 0x05, 0x316: 0x05, 0x317: 0x05, + 0x318: 0x05, 0x319: 0x05, 0x31a: 0x05, 0x31b: 0x05, 0x31c: 0x05, 0x31d: 0x05, 0x31e: 0x05, 0x31f: 0x05, + 0x320: 0x05, 0x321: 0x05, 0x322: 0x05, 0x323: 0x05, 0x324: 0x05, 0x325: 0x05, 0x326: 0x05, 0x327: 0x05, + 0x328: 0x05, 0x329: 0x05, 0x32a: 0x05, 0x32b: 0x05, 0x32c: 0x05, 0x32d: 0x05, 0x32e: 0x05, 0x32f: 0x05, + 0x330: 0x05, 0x331: 0x05, 0x332: 0x05, 0x333: 0x05, 0x334: 0x05, 0x335: 0x05, 0x336: 0x05, 0x337: 0x05, + 0x338: 0x05, 0x339: 0x05, 0x33a: 0x05, 0x33b: 0x05, 0x33c: 0x05, 0x33d: 0x05, 0x33e: 0x05, 0x33f: 0x05, + // Block 0xd, offset 0x340 + 0x340: 0x05, 0x341: 0x05, 0x342: 0x05, 0x343: 0x05, 0x344: 0x05, 0x345: 0x05, 0x346: 0x05, 0x347: 0x05, + 0x348: 0x05, 0x349: 0x05, 0x34a: 0x05, 0x34b: 0x05, 0x34c: 0x05, 0x34d: 0x05, 0x34e: 0x05, 0x34f: 0x05, + 0x350: 0x05, 0x351: 0x05, 0x352: 0x05, 0x353: 0x05, 0x354: 0x05, 0x355: 0x05, 0x356: 0x05, 0x357: 0x05, + 0x358: 0x05, 0x359: 0x05, 0x35a: 0x05, 0x35b: 0x05, 0x35c: 0x05, 0x35d: 0x05, 0x35e: 0xaa, 0x35f: 0xab, + // Block 0xe, offset 0x380 + 0x380: 0x3e, 0x381: 0x3e, 0x382: 0x3e, 0x383: 0x3e, 0x384: 0x3e, 0x385: 0x3e, 0x386: 0x3e, 0x387: 0x3e, + 0x388: 0x3e, 0x389: 0x3e, 0x38a: 0x3e, 0x38b: 0x3e, 0x38c: 0x3e, 0x38d: 0x3e, 0x38e: 0x3e, 0x38f: 0x3e, + 0x390: 0x3e, 0x391: 0x3e, 0x392: 0x3e, 0x393: 0x3e, 0x394: 0x3e, 0x395: 0x3e, 0x396: 0x3e, 0x397: 0x3e, + 0x398: 0x3e, 0x399: 0x3e, 0x39a: 0x3e, 0x39b: 0x3e, 0x39c: 0x3e, 0x39d: 0x3e, 0x39e: 0x3e, 0x39f: 0x3e, + 0x3a0: 0x3e, 0x3a1: 0x3e, 0x3a2: 0x3e, 0x3a3: 0x3e, 0x3a4: 0x3e, 0x3a5: 0x3e, 0x3a6: 0x3e, 0x3a7: 0x3e, + 0x3a8: 0x3e, 0x3a9: 0x3e, 0x3aa: 0x3e, 0x3ab: 0x3e, 0x3ac: 0x3e, 0x3ad: 0x3e, 0x3ae: 0x3e, 0x3af: 0x3e, + 0x3b0: 0x3e, 0x3b1: 0x3e, 0x3b2: 0x3e, 0x3b3: 0x3e, 0x3b4: 0x3e, 0x3b5: 0x3e, 0x3b6: 0x3e, 0x3b7: 0x3e, + 0x3b8: 0x3e, 0x3b9: 0x3e, 0x3ba: 0x3e, 0x3bb: 0x3e, 0x3bc: 0x3e, 0x3bd: 0x3e, 0x3be: 0x3e, 0x3bf: 0x3e, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x3e, 0x3c1: 0x3e, 0x3c2: 0x3e, 0x3c3: 0x3e, 0x3c4: 0x3e, 0x3c5: 0x3e, 0x3c6: 0x3e, 0x3c7: 0x3e, + 0x3c8: 0x3e, 0x3c9: 0x3e, 0x3ca: 0x3e, 0x3cb: 0x3e, 0x3cc: 0x3e, 0x3cd: 0x3e, 0x3ce: 0x3e, 0x3cf: 0x3e, + 0x3d0: 0x3e, 0x3d1: 0x3e, 0x3d2: 0x3e, 0x3d3: 0x3e, 0x3d4: 0x3e, 0x3d5: 0x3e, 0x3d6: 0x3e, 0x3d7: 0x3e, + 0x3d8: 0x3e, 0x3d9: 0x3e, 0x3da: 0x3e, 0x3db: 0x3e, 0x3dc: 0x3e, 0x3dd: 0x3e, 0x3de: 0x3e, 0x3df: 0x3e, + 0x3e0: 0x3e, 0x3e1: 0x3e, 0x3e2: 0x3e, 0x3e3: 0x3e, 0x3e4: 0x82, 0x3e5: 0x82, 0x3e6: 0x82, 0x3e7: 0x82, + 0x3e8: 0xac, 0x3e9: 0xad, 0x3ea: 0x82, 0x3eb: 0xae, 0x3ec: 0xaf, 0x3ed: 0xb0, 0x3ee: 0x71, 0x3ef: 0xb1, + 0x3f0: 0x71, 0x3f1: 0x71, 0x3f2: 0x71, 0x3f3: 0x71, 0x3f4: 0x71, 0x3f5: 0xb2, 0x3f6: 0xb3, 0x3f7: 0xb4, + 0x3f8: 0xb5, 0x3f9: 0xb6, 0x3fa: 0x71, 0x3fb: 0xb7, 0x3fc: 0xb8, 0x3fd: 0xb9, 0x3fe: 0xba, 0x3ff: 0xbb, + // Block 0x10, offset 0x400 + 0x400: 0xbc, 0x401: 0xbd, 0x402: 0x05, 0x403: 0xbe, 0x404: 0xbf, 0x405: 0xc0, 0x406: 0xc1, 0x407: 0xc2, + 0x40a: 0xc3, 0x40b: 0xc4, 0x40c: 0xc5, 0x40d: 0xc6, 0x40e: 0xc7, 0x40f: 0xc8, + 0x410: 0x05, 0x411: 0x05, 0x412: 0xc9, 0x413: 0xca, 0x414: 0xcb, 0x415: 0xcc, + 0x418: 0x05, 0x419: 0x05, 0x41a: 0x05, 0x41b: 0x05, 0x41c: 0xcd, 0x41d: 0xce, + 0x420: 0xcf, 0x421: 0xd0, 0x422: 0xd1, 0x423: 0xd2, 0x424: 0xd3, 0x426: 0xd4, 0x427: 0xb3, + 0x428: 0xd5, 0x429: 0xd6, 0x42a: 0xd7, 0x42b: 0xd8, 0x42c: 0xd9, 0x42d: 0xda, 0x42e: 0xdb, + 0x430: 0x05, 0x431: 0x5f, 0x432: 0xdc, 0x433: 0xdd, + 0x439: 0xde, + // Block 0x11, offset 0x440 + 0x440: 0xdf, 0x441: 0xe0, 0x442: 0xe1, 0x443: 0xe2, 0x444: 0xe3, 0x445: 0xe4, 0x446: 0xe5, 0x447: 0xe6, + 0x448: 0xe7, 0x44a: 0xe8, 0x44b: 0xe9, 0x44c: 0xea, 0x44d: 0xeb, + 0x450: 0xec, 0x451: 0xed, 0x452: 0xee, 0x453: 0xef, 0x456: 0xf0, 0x457: 0xf1, + 0x458: 0xf2, 0x459: 0xf3, 0x45a: 0xf4, 0x45b: 0xf5, 0x45c: 0xf6, + 0x462: 0xf7, 0x463: 0xf8, + 0x468: 0xf9, 0x469: 0xfa, 0x46a: 0xfb, 0x46b: 0xfc, + 0x470: 0xfd, 0x471: 0xfe, 0x472: 0xff, 0x474: 0x100, 0x475: 0x101, + // Block 0x12, offset 0x480 + 0x480: 0x05, 0x481: 0x05, 0x482: 0x05, 0x483: 0x05, 0x484: 0x05, 0x485: 0x05, 0x486: 0x05, 0x487: 0x05, + 0x488: 0x05, 0x489: 0x05, 0x48a: 0x05, 0x48b: 0x05, 0x48c: 0x05, 0x48d: 0x05, 0x48e: 0x102, + 0x490: 0x71, 0x491: 0x103, 0x492: 0x05, 0x493: 0x05, 0x494: 0x05, 0x495: 0x104, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x05, 0x4c1: 0x05, 0x4c2: 0x05, 0x4c3: 0x05, 0x4c4: 0x05, 0x4c5: 0x05, 0x4c6: 0x05, 0x4c7: 0x05, + 0x4c8: 0x05, 0x4c9: 0x05, 0x4ca: 0x05, 0x4cb: 0x05, 0x4cc: 0x05, 0x4cd: 0x05, 0x4ce: 0x05, 0x4cf: 0x05, + 0x4d0: 0x105, + // Block 0x14, offset 0x500 + 0x510: 0x05, 0x511: 0x05, 0x512: 0x05, 0x513: 0x05, 0x514: 0x05, 0x515: 0x05, 0x516: 0x05, 0x517: 0x05, + 0x518: 0x05, 0x519: 0x106, + // Block 0x15, offset 0x540 + 0x560: 0x05, 0x561: 0x05, 0x562: 0x05, 0x563: 0x05, 0x564: 0x05, 0x565: 0x05, 0x566: 0x05, 0x567: 0x05, + 0x568: 0xfc, 0x569: 0x107, 0x56b: 0x108, 0x56c: 0x109, 0x56d: 0x10a, 0x56e: 0x10b, + 0x57c: 0x05, 0x57d: 0x10c, 0x57e: 0x10d, 0x57f: 0x10e, + // Block 0x16, offset 0x580 + 0x580: 0x05, 0x581: 0x05, 0x582: 0x05, 0x583: 0x05, 0x584: 0x05, 0x585: 0x05, 0x586: 0x05, 0x587: 0x05, + 0x588: 0x05, 0x589: 0x05, 0x58a: 0x05, 0x58b: 0x05, 0x58c: 0x05, 0x58d: 0x05, 0x58e: 0x05, 0x58f: 0x05, + 0x590: 0x05, 0x591: 0x05, 0x592: 0x05, 0x593: 0x05, 0x594: 0x05, 0x595: 0x05, 0x596: 0x05, 0x597: 0x05, + 0x598: 0x05, 0x599: 0x05, 0x59a: 0x05, 0x59b: 0x05, 0x59c: 0x05, 0x59d: 0x05, 0x59e: 0x05, 0x59f: 0x10f, + 0x5a0: 0x05, 0x5a1: 0x05, 0x5a2: 0x05, 0x5a3: 0x05, 0x5a4: 0x05, 0x5a5: 0x05, 0x5a6: 0x05, 0x5a7: 0x05, + 0x5a8: 0x05, 0x5a9: 0x05, 0x5aa: 0x05, 0x5ab: 0xdc, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x8f, 0x5c1: 0x8f, 0x5c2: 0x8f, 0x5c3: 0x8f, 0x5c4: 0x110, 0x5c5: 0x111, 0x5c6: 0x05, 0x5c7: 0x05, + 0x5c8: 0x05, 0x5c9: 0x05, 0x5ca: 0x05, 0x5cb: 0x112, + 0x5f0: 0x05, 0x5f1: 0x113, 0x5f2: 0x114, + // Block 0x18, offset 0x600 + 0x600: 0x71, 0x601: 0x71, 0x602: 0x71, 0x603: 0x115, 0x604: 0x116, 0x605: 0x117, 0x606: 0x118, 0x607: 0x119, + 0x608: 0xc0, 0x609: 0x11a, 0x60c: 0x71, 0x60d: 0x11b, + 0x610: 0x71, 0x611: 0x11c, 0x612: 0x11d, 0x613: 0x11e, 0x614: 0x11f, 0x615: 0x120, 0x616: 0x71, 0x617: 0x71, + 0x618: 0x71, 0x619: 0x71, 0x61a: 0x121, 0x61b: 0x71, 0x61c: 0x71, 0x61d: 0x71, 0x61e: 0x71, 0x61f: 0x122, + 0x620: 0x71, 0x621: 0x71, 0x622: 0x71, 0x623: 0x71, 0x624: 0x71, 0x625: 0x71, 0x626: 0x71, 0x627: 0x71, + 0x628: 0x123, 0x629: 0x124, 0x62a: 0x125, + // Block 0x19, offset 0x640 + 0x640: 0x126, + 0x660: 0x05, 0x661: 0x05, 0x662: 0x05, 0x663: 0x127, 0x664: 0x128, 0x665: 0x129, + 0x678: 0x12a, 0x679: 0x12b, 0x67a: 0x12c, 0x67b: 0x12d, + // Block 0x1a, offset 0x680 + 0x680: 0x12e, 0x681: 0x71, 0x682: 0x12f, 0x683: 0x130, 0x684: 0x131, 0x685: 0x12e, 0x686: 0x132, 0x687: 0x133, + 0x688: 0x134, 0x689: 0x135, 0x68c: 0x71, 0x68d: 0x71, 0x68e: 0x71, 0x68f: 0x71, + 0x690: 0x71, 0x691: 0x71, 0x692: 0x71, 0x693: 0x71, 0x694: 0x71, 0x695: 0x71, 0x696: 0x71, 0x697: 0x71, + 0x698: 0x71, 0x699: 0x71, 0x69a: 0x71, 0x69b: 0x136, 0x69c: 0x71, 0x69d: 0x137, 0x69e: 0x71, 0x69f: 0x138, + 0x6a0: 0x139, 0x6a1: 0x13a, 0x6a2: 0x13b, 0x6a4: 0x13c, 0x6a5: 0x13d, 0x6a6: 0x13e, 0x6a7: 0x13f, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x8f, 0x6c1: 0x8f, 0x6c2: 0x8f, 0x6c3: 0x8f, 0x6c4: 0x8f, 0x6c5: 0x8f, 0x6c6: 0x8f, 0x6c7: 0x8f, + 0x6c8: 0x8f, 0x6c9: 0x8f, 0x6ca: 0x8f, 0x6cb: 0x8f, 0x6cc: 0x8f, 0x6cd: 0x8f, 0x6ce: 0x8f, 0x6cf: 0x8f, + 0x6d0: 0x8f, 0x6d1: 0x8f, 0x6d2: 0x8f, 0x6d3: 0x8f, 0x6d4: 0x8f, 0x6d5: 0x8f, 0x6d6: 0x8f, 0x6d7: 0x8f, + 0x6d8: 0x8f, 0x6d9: 0x8f, 0x6da: 0x8f, 0x6db: 0x140, 0x6dc: 0x8f, 0x6dd: 0x8f, 0x6de: 0x8f, 0x6df: 0x8f, + 0x6e0: 0x8f, 0x6e1: 0x8f, 0x6e2: 0x8f, 0x6e3: 0x8f, 0x6e4: 0x8f, 0x6e5: 0x8f, 0x6e6: 0x8f, 0x6e7: 0x8f, + 0x6e8: 0x8f, 0x6e9: 0x8f, 0x6ea: 0x8f, 0x6eb: 0x8f, 0x6ec: 0x8f, 0x6ed: 0x8f, 0x6ee: 0x8f, 0x6ef: 0x8f, + 0x6f0: 0x8f, 0x6f1: 0x8f, 0x6f2: 0x8f, 0x6f3: 0x8f, 0x6f4: 0x8f, 0x6f5: 0x8f, 0x6f6: 0x8f, 0x6f7: 0x8f, + 0x6f8: 0x8f, 0x6f9: 0x8f, 0x6fa: 0x8f, 0x6fb: 0x8f, 0x6fc: 0x8f, 0x6fd: 0x8f, 0x6fe: 0x8f, 0x6ff: 0x8f, + // Block 0x1c, offset 0x700 + 0x700: 0x8f, 0x701: 0x8f, 0x702: 0x8f, 0x703: 0x8f, 0x704: 0x8f, 0x705: 0x8f, 0x706: 0x8f, 0x707: 0x8f, + 0x708: 0x8f, 0x709: 0x8f, 0x70a: 0x8f, 0x70b: 0x8f, 0x70c: 0x8f, 0x70d: 0x8f, 0x70e: 0x8f, 0x70f: 0x8f, + 0x710: 0x8f, 0x711: 0x8f, 0x712: 0x8f, 0x713: 0x8f, 0x714: 0x8f, 0x715: 0x8f, 0x716: 0x8f, 0x717: 0x8f, + 0x718: 0x8f, 0x719: 0x8f, 0x71a: 0x8f, 0x71b: 0x8f, 0x71c: 0x141, 0x71d: 0x8f, 0x71e: 0x8f, 0x71f: 0x8f, + 0x720: 0x142, 0x721: 0x8f, 0x722: 0x8f, 0x723: 0x8f, 0x724: 0x8f, 0x725: 0x8f, 0x726: 0x8f, 0x727: 0x8f, + 0x728: 0x8f, 0x729: 0x8f, 0x72a: 0x8f, 0x72b: 0x8f, 0x72c: 0x8f, 0x72d: 0x8f, 0x72e: 0x8f, 0x72f: 0x8f, + 0x730: 0x8f, 0x731: 0x8f, 0x732: 0x8f, 0x733: 0x8f, 0x734: 0x8f, 0x735: 0x8f, 0x736: 0x8f, 0x737: 0x8f, + 0x738: 0x8f, 0x739: 0x8f, 0x73a: 0x8f, 0x73b: 0x8f, 0x73c: 0x8f, 0x73d: 0x8f, 0x73e: 0x8f, 0x73f: 0x8f, + // Block 0x1d, offset 0x740 + 0x740: 0x8f, 0x741: 0x8f, 0x742: 0x8f, 0x743: 0x8f, 0x744: 0x8f, 0x745: 0x8f, 0x746: 0x8f, 0x747: 0x8f, + 0x748: 0x8f, 0x749: 0x8f, 0x74a: 0x8f, 0x74b: 0x8f, 0x74c: 0x8f, 0x74d: 0x8f, 0x74e: 0x8f, 0x74f: 0x8f, + 0x750: 0x8f, 0x751: 0x8f, 0x752: 0x8f, 0x753: 0x8f, 0x754: 0x8f, 0x755: 0x8f, 0x756: 0x8f, 0x757: 0x8f, + 0x758: 0x8f, 0x759: 0x8f, 0x75a: 0x8f, 0x75b: 0x8f, 0x75c: 0x8f, 0x75d: 0x8f, 0x75e: 0x8f, 0x75f: 0x8f, + 0x760: 0x8f, 0x761: 0x8f, 0x762: 0x8f, 0x763: 0x8f, 0x764: 0x8f, 0x765: 0x8f, 0x766: 0x8f, 0x767: 0x8f, + 0x768: 0x8f, 0x769: 0x8f, 0x76a: 0x8f, 0x76b: 0x8f, 0x76c: 0x8f, 0x76d: 0x8f, 0x76e: 0x8f, 0x76f: 0x8f, + 0x770: 0x8f, 0x771: 0x8f, 0x772: 0x8f, 0x773: 0x8f, 0x774: 0x8f, 0x775: 0x8f, 0x776: 0x8f, 0x777: 0x8f, + 0x778: 0x8f, 0x779: 0x8f, 0x77a: 0x143, 0x77b: 0x8f, 0x77c: 0x8f, 0x77d: 0x8f, 0x77e: 0x8f, 0x77f: 0x8f, + // Block 0x1e, offset 0x780 + 0x780: 0x8f, 0x781: 0x8f, 0x782: 0x8f, 0x783: 0x8f, 0x784: 0x8f, 0x785: 0x8f, 0x786: 0x8f, 0x787: 0x8f, + 0x788: 0x8f, 0x789: 0x8f, 0x78a: 0x8f, 0x78b: 0x8f, 0x78c: 0x8f, 0x78d: 0x8f, 0x78e: 0x8f, 0x78f: 0x8f, + 0x790: 0x8f, 0x791: 0x8f, 0x792: 0x8f, 0x793: 0x8f, 0x794: 0x8f, 0x795: 0x8f, 0x796: 0x8f, 0x797: 0x8f, + 0x798: 0x8f, 0x799: 0x8f, 0x79a: 0x8f, 0x79b: 0x8f, 0x79c: 0x8f, 0x79d: 0x8f, 0x79e: 0x8f, 0x79f: 0x8f, + 0x7a0: 0x8f, 0x7a1: 0x8f, 0x7a2: 0x8f, 0x7a3: 0x8f, 0x7a4: 0x8f, 0x7a5: 0x8f, 0x7a6: 0x8f, 0x7a7: 0x8f, + 0x7a8: 0x8f, 0x7a9: 0x8f, 0x7aa: 0x8f, 0x7ab: 0x8f, 0x7ac: 0x8f, 0x7ad: 0x8f, 0x7ae: 0x8f, 0x7af: 0x144, + // Block 0x1f, offset 0x7c0 + 0x7e0: 0x82, 0x7e1: 0x82, 0x7e2: 0x82, 0x7e3: 0x82, 0x7e4: 0x82, 0x7e5: 0x82, 0x7e6: 0x82, 0x7e7: 0x82, + 0x7e8: 0x145, + // Block 0x20, offset 0x800 + 0x810: 0x0e, 0x811: 0x0f, 0x812: 0x10, 0x813: 0x11, 0x814: 0x12, 0x816: 0x13, 0x817: 0x0a, + 0x818: 0x14, 0x81b: 0x15, 0x81d: 0x16, 0x81e: 0x17, 0x81f: 0x18, + 0x820: 0x07, 0x821: 0x07, 0x822: 0x07, 0x823: 0x07, 0x824: 0x07, 0x825: 0x07, 0x826: 0x07, 0x827: 0x07, + 0x828: 0x07, 0x829: 0x07, 0x82a: 0x19, 0x82b: 0x1a, 0x82c: 0x1b, 0x82d: 0x07, 0x82e: 0x1c, 0x82f: 0x1d, + // Block 0x21, offset 0x840 + 0x840: 0x146, 0x841: 0x3e, 0x844: 0x3e, 0x845: 0x3e, 0x846: 0x3e, 0x847: 0x147, + // Block 0x22, offset 0x880 + 0x880: 0x3e, 0x881: 0x3e, 0x882: 0x3e, 0x883: 0x3e, 0x884: 0x3e, 0x885: 0x3e, 0x886: 0x3e, 0x887: 0x3e, + 0x888: 0x3e, 0x889: 0x3e, 0x88a: 0x3e, 0x88b: 0x3e, 0x88c: 0x3e, 0x88d: 0x3e, 0x88e: 0x3e, 0x88f: 0x3e, + 0x890: 0x3e, 0x891: 0x3e, 0x892: 0x3e, 0x893: 0x3e, 0x894: 0x3e, 0x895: 0x3e, 0x896: 0x3e, 0x897: 0x3e, + 0x898: 0x3e, 0x899: 0x3e, 0x89a: 0x3e, 0x89b: 0x3e, 0x89c: 0x3e, 0x89d: 0x3e, 0x89e: 0x3e, 0x89f: 0x3e, + 0x8a0: 0x3e, 0x8a1: 0x3e, 0x8a2: 0x3e, 0x8a3: 0x3e, 0x8a4: 0x3e, 0x8a5: 0x3e, 0x8a6: 0x3e, 0x8a7: 0x3e, + 0x8a8: 0x3e, 0x8a9: 0x3e, 0x8aa: 0x3e, 0x8ab: 0x3e, 0x8ac: 0x3e, 0x8ad: 0x3e, 0x8ae: 0x3e, 0x8af: 0x3e, + 0x8b0: 0x3e, 0x8b1: 0x3e, 0x8b2: 0x3e, 0x8b3: 0x3e, 0x8b4: 0x3e, 0x8b5: 0x3e, 0x8b6: 0x3e, 0x8b7: 0x3e, + 0x8b8: 0x3e, 0x8b9: 0x3e, 0x8ba: 0x3e, 0x8bb: 0x3e, 0x8bc: 0x3e, 0x8bd: 0x3e, 0x8be: 0x3e, 0x8bf: 0x148, + // Block 0x23, offset 0x8c0 + 0x8e0: 0x1f, + 0x8f0: 0x0c, 0x8f1: 0x0c, 0x8f2: 0x0c, 0x8f3: 0x0c, 0x8f4: 0x0c, 0x8f5: 0x0c, 0x8f6: 0x0c, 0x8f7: 0x0c, + 0x8f8: 0x0c, 0x8f9: 0x0c, 0x8fa: 0x0c, 0x8fb: 0x0c, 0x8fc: 0x0c, 0x8fd: 0x0c, 0x8fe: 0x0c, 0x8ff: 0x20, + // Block 0x24, offset 0x900 + 0x900: 0x0c, 0x901: 0x0c, 0x902: 0x0c, 0x903: 0x0c, 0x904: 0x0c, 0x905: 0x0c, 0x906: 0x0c, 0x907: 0x0c, + 0x908: 0x0c, 0x909: 0x0c, 0x90a: 0x0c, 0x90b: 0x0c, 0x90c: 0x0c, 0x90d: 0x0c, 0x90e: 0x0c, 0x90f: 0x20, +} + +// Total table size 25920 bytes (25KiB); checksum: 811C9DC5 diff --git a/vendor/golang.org/x/text/secure/precis/tables11.0.0.go b/vendor/golang.org/x/text/secure/precis/tables11.0.0.go new file mode 100644 index 00000000000..a40e55d6c94 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/tables11.0.0.go @@ -0,0 +1,4017 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +//go:build go1.13 && !go1.14 +// +build go1.13,!go1.14 + +package precis + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "11.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// derivedPropertiesTrie. Total size: 26688 bytes (26.06 KiB). Checksum: e3220a77004d02ba. +type derivedPropertiesTrie struct{} + +func newDerivedPropertiesTrie(i int) *derivedPropertiesTrie { + return &derivedPropertiesTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *derivedPropertiesTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(derivedPropertiesValues[n<<6+uint32(b)]) + } +} + +// derivedPropertiesValues: 343 blocks, 21952 entries, 21952 bytes +// The third block is the zero block. +var derivedPropertiesValues = [21952]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x0040, 0x01: 0x0040, 0x02: 0x0040, 0x03: 0x0040, 0x04: 0x0040, 0x05: 0x0040, + 0x06: 0x0040, 0x07: 0x0040, 0x08: 0x0040, 0x09: 0x0040, 0x0a: 0x0040, 0x0b: 0x0040, + 0x0c: 0x0040, 0x0d: 0x0040, 0x0e: 0x0040, 0x0f: 0x0040, 0x10: 0x0040, 0x11: 0x0040, + 0x12: 0x0040, 0x13: 0x0040, 0x14: 0x0040, 0x15: 0x0040, 0x16: 0x0040, 0x17: 0x0040, + 0x18: 0x0040, 0x19: 0x0040, 0x1a: 0x0040, 0x1b: 0x0040, 0x1c: 0x0040, 0x1d: 0x0040, + 0x1e: 0x0040, 0x1f: 0x0040, 0x20: 0x0080, 0x21: 0x00c0, 0x22: 0x00c0, 0x23: 0x00c0, + 0x24: 0x00c0, 0x25: 0x00c0, 0x26: 0x00c0, 0x27: 0x00c0, 0x28: 0x00c0, 0x29: 0x00c0, + 0x2a: 0x00c0, 0x2b: 0x00c0, 0x2c: 0x00c0, 0x2d: 0x00c0, 0x2e: 0x00c0, 0x2f: 0x00c0, + 0x30: 0x00c0, 0x31: 0x00c0, 0x32: 0x00c0, 0x33: 0x00c0, 0x34: 0x00c0, 0x35: 0x00c0, + 0x36: 0x00c0, 0x37: 0x00c0, 0x38: 0x00c0, 0x39: 0x00c0, 0x3a: 0x00c0, 0x3b: 0x00c0, + 0x3c: 0x00c0, 0x3d: 0x00c0, 0x3e: 0x00c0, 0x3f: 0x00c0, + // Block 0x1, offset 0x40 + 0x40: 0x00c0, 0x41: 0x00c0, 0x42: 0x00c0, 0x43: 0x00c0, 0x44: 0x00c0, 0x45: 0x00c0, + 0x46: 0x00c0, 0x47: 0x00c0, 0x48: 0x00c0, 0x49: 0x00c0, 0x4a: 0x00c0, 0x4b: 0x00c0, + 0x4c: 0x00c0, 0x4d: 0x00c0, 0x4e: 0x00c0, 0x4f: 0x00c0, 0x50: 0x00c0, 0x51: 0x00c0, + 0x52: 0x00c0, 0x53: 0x00c0, 0x54: 0x00c0, 0x55: 0x00c0, 0x56: 0x00c0, 0x57: 0x00c0, + 0x58: 0x00c0, 0x59: 0x00c0, 0x5a: 0x00c0, 0x5b: 0x00c0, 0x5c: 0x00c0, 0x5d: 0x00c0, + 0x5e: 0x00c0, 0x5f: 0x00c0, 0x60: 0x00c0, 0x61: 0x00c0, 0x62: 0x00c0, 0x63: 0x00c0, + 0x64: 0x00c0, 0x65: 0x00c0, 0x66: 0x00c0, 0x67: 0x00c0, 0x68: 0x00c0, 0x69: 0x00c0, + 0x6a: 0x00c0, 0x6b: 0x00c0, 0x6c: 0x00c7, 0x6d: 0x00c0, 0x6e: 0x00c0, 0x6f: 0x00c0, + 0x70: 0x00c0, 0x71: 0x00c0, 0x72: 0x00c0, 0x73: 0x00c0, 0x74: 0x00c0, 0x75: 0x00c0, + 0x76: 0x00c0, 0x77: 0x00c0, 0x78: 0x00c0, 0x79: 0x00c0, 0x7a: 0x00c0, 0x7b: 0x00c0, + 0x7c: 0x00c0, 0x7d: 0x00c0, 0x7e: 0x00c0, 0x7f: 0x0040, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x0080, 0xe1: 0x0080, 0xe2: 0x0080, 0xe3: 0x0080, + 0xe4: 0x0080, 0xe5: 0x0080, 0xe6: 0x0080, 0xe7: 0x0080, 0xe8: 0x0080, 0xe9: 0x0080, + 0xea: 0x0080, 0xeb: 0x0080, 0xec: 0x0080, 0xed: 0x0040, 0xee: 0x0080, 0xef: 0x0080, + 0xf0: 0x0080, 0xf1: 0x0080, 0xf2: 0x0080, 0xf3: 0x0080, 0xf4: 0x0080, 0xf5: 0x0080, + 0xf6: 0x0080, 0xf7: 0x004f, 0xf8: 0x0080, 0xf9: 0x0080, 0xfa: 0x0080, 0xfb: 0x0080, + 0xfc: 0x0080, 0xfd: 0x0080, 0xfe: 0x0080, 0xff: 0x0080, + // Block 0x4, offset 0x100 + 0x100: 0x00c0, 0x101: 0x00c0, 0x102: 0x00c0, 0x103: 0x00c0, 0x104: 0x00c0, 0x105: 0x00c0, + 0x106: 0x00c0, 0x107: 0x00c0, 0x108: 0x00c0, 0x109: 0x00c0, 0x10a: 0x00c0, 0x10b: 0x00c0, + 0x10c: 0x00c0, 0x10d: 0x00c0, 0x10e: 0x00c0, 0x10f: 0x00c0, 0x110: 0x00c0, 0x111: 0x00c0, + 0x112: 0x00c0, 0x113: 0x00c0, 0x114: 0x00c0, 0x115: 0x00c0, 0x116: 0x00c0, 0x117: 0x0080, + 0x118: 0x00c0, 0x119: 0x00c0, 0x11a: 0x00c0, 0x11b: 0x00c0, 0x11c: 0x00c0, 0x11d: 0x00c0, + 0x11e: 0x00c0, 0x11f: 0x00c0, 0x120: 0x00c0, 0x121: 0x00c0, 0x122: 0x00c0, 0x123: 0x00c0, + 0x124: 0x00c0, 0x125: 0x00c0, 0x126: 0x00c0, 0x127: 0x00c0, 0x128: 0x00c0, 0x129: 0x00c0, + 0x12a: 0x00c0, 0x12b: 0x00c0, 0x12c: 0x00c0, 0x12d: 0x00c0, 0x12e: 0x00c0, 0x12f: 0x00c0, + 0x130: 0x00c0, 0x131: 0x00c0, 0x132: 0x00c0, 0x133: 0x00c0, 0x134: 0x00c0, 0x135: 0x00c0, + 0x136: 0x00c0, 0x137: 0x0080, 0x138: 0x00c0, 0x139: 0x00c0, 0x13a: 0x00c0, 0x13b: 0x00c0, + 0x13c: 0x00c0, 0x13d: 0x00c0, 0x13e: 0x00c0, 0x13f: 0x00c0, + // Block 0x5, offset 0x140 + 0x140: 0x00c0, 0x141: 0x00c0, 0x142: 0x00c0, 0x143: 0x00c0, 0x144: 0x00c0, 0x145: 0x00c0, + 0x146: 0x00c0, 0x147: 0x00c0, 0x148: 0x00c0, 0x149: 0x00c0, 0x14a: 0x00c0, 0x14b: 0x00c0, + 0x14c: 0x00c0, 0x14d: 0x00c0, 0x14e: 0x00c0, 0x14f: 0x00c0, 0x150: 0x00c0, 0x151: 0x00c0, + 0x152: 0x00c0, 0x153: 0x00c0, 0x154: 0x00c0, 0x155: 0x00c0, 0x156: 0x00c0, 0x157: 0x00c0, + 0x158: 0x00c0, 0x159: 0x00c0, 0x15a: 0x00c0, 0x15b: 0x00c0, 0x15c: 0x00c0, 0x15d: 0x00c0, + 0x15e: 0x00c0, 0x15f: 0x00c0, 0x160: 0x00c0, 0x161: 0x00c0, 0x162: 0x00c0, 0x163: 0x00c0, + 0x164: 0x00c0, 0x165: 0x00c0, 0x166: 0x00c0, 0x167: 0x00c0, 0x168: 0x00c0, 0x169: 0x00c0, + 0x16a: 0x00c0, 0x16b: 0x00c0, 0x16c: 0x00c0, 0x16d: 0x00c0, 0x16e: 0x00c0, 0x16f: 0x00c0, + 0x170: 0x00c0, 0x171: 0x00c0, 0x172: 0x0080, 0x173: 0x0080, 0x174: 0x00c0, 0x175: 0x00c0, + 0x176: 0x00c0, 0x177: 0x00c0, 0x178: 0x00c0, 0x179: 0x00c0, 0x17a: 0x00c0, 0x17b: 0x00c0, + 0x17c: 0x00c0, 0x17d: 0x00c0, 0x17e: 0x00c0, 0x17f: 0x0080, + // Block 0x6, offset 0x180 + 0x180: 0x0080, 0x181: 0x00c0, 0x182: 0x00c0, 0x183: 0x00c0, 0x184: 0x00c0, 0x185: 0x00c0, + 0x186: 0x00c0, 0x187: 0x00c0, 0x188: 0x00c0, 0x189: 0x0080, 0x18a: 0x00c0, 0x18b: 0x00c0, + 0x18c: 0x00c0, 0x18d: 0x00c0, 0x18e: 0x00c0, 0x18f: 0x00c0, 0x190: 0x00c0, 0x191: 0x00c0, + 0x192: 0x00c0, 0x193: 0x00c0, 0x194: 0x00c0, 0x195: 0x00c0, 0x196: 0x00c0, 0x197: 0x00c0, + 0x198: 0x00c0, 0x199: 0x00c0, 0x19a: 0x00c0, 0x19b: 0x00c0, 0x19c: 0x00c0, 0x19d: 0x00c0, + 0x19e: 0x00c0, 0x19f: 0x00c0, 0x1a0: 0x00c0, 0x1a1: 0x00c0, 0x1a2: 0x00c0, 0x1a3: 0x00c0, + 0x1a4: 0x00c0, 0x1a5: 0x00c0, 0x1a6: 0x00c0, 0x1a7: 0x00c0, 0x1a8: 0x00c0, 0x1a9: 0x00c0, + 0x1aa: 0x00c0, 0x1ab: 0x00c0, 0x1ac: 0x00c0, 0x1ad: 0x00c0, 0x1ae: 0x00c0, 0x1af: 0x00c0, + 0x1b0: 0x00c0, 0x1b1: 0x00c0, 0x1b2: 0x00c0, 0x1b3: 0x00c0, 0x1b4: 0x00c0, 0x1b5: 0x00c0, + 0x1b6: 0x00c0, 0x1b7: 0x00c0, 0x1b8: 0x00c0, 0x1b9: 0x00c0, 0x1ba: 0x00c0, 0x1bb: 0x00c0, + 0x1bc: 0x00c0, 0x1bd: 0x00c0, 0x1be: 0x00c0, 0x1bf: 0x0080, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x00c0, 0x1c1: 0x00c0, 0x1c2: 0x00c0, 0x1c3: 0x00c0, 0x1c4: 0x00c0, 0x1c5: 0x00c0, + 0x1c6: 0x00c0, 0x1c7: 0x00c0, 0x1c8: 0x00c0, 0x1c9: 0x00c0, 0x1ca: 0x00c0, 0x1cb: 0x00c0, + 0x1cc: 0x00c0, 0x1cd: 0x00c0, 0x1ce: 0x00c0, 0x1cf: 0x00c0, 0x1d0: 0x00c0, 0x1d1: 0x00c0, + 0x1d2: 0x00c0, 0x1d3: 0x00c0, 0x1d4: 0x00c0, 0x1d5: 0x00c0, 0x1d6: 0x00c0, 0x1d7: 0x00c0, + 0x1d8: 0x00c0, 0x1d9: 0x00c0, 0x1da: 0x00c0, 0x1db: 0x00c0, 0x1dc: 0x00c0, 0x1dd: 0x00c0, + 0x1de: 0x00c0, 0x1df: 0x00c0, 0x1e0: 0x00c0, 0x1e1: 0x00c0, 0x1e2: 0x00c0, 0x1e3: 0x00c0, + 0x1e4: 0x00c0, 0x1e5: 0x00c0, 0x1e6: 0x00c0, 0x1e7: 0x00c0, 0x1e8: 0x00c0, 0x1e9: 0x00c0, + 0x1ea: 0x00c0, 0x1eb: 0x00c0, 0x1ec: 0x00c0, 0x1ed: 0x00c0, 0x1ee: 0x00c0, 0x1ef: 0x00c0, + 0x1f0: 0x00c0, 0x1f1: 0x00c0, 0x1f2: 0x00c0, 0x1f3: 0x00c0, 0x1f4: 0x00c0, 0x1f5: 0x00c0, + 0x1f6: 0x00c0, 0x1f7: 0x00c0, 0x1f8: 0x00c0, 0x1f9: 0x00c0, 0x1fa: 0x00c0, 0x1fb: 0x00c0, + 0x1fc: 0x00c0, 0x1fd: 0x00c0, 0x1fe: 0x00c0, 0x1ff: 0x00c0, + // Block 0x8, offset 0x200 + 0x200: 0x00c0, 0x201: 0x00c0, 0x202: 0x00c0, 0x203: 0x00c0, 0x204: 0x0080, 0x205: 0x0080, + 0x206: 0x0080, 0x207: 0x0080, 0x208: 0x0080, 0x209: 0x0080, 0x20a: 0x0080, 0x20b: 0x0080, + 0x20c: 0x0080, 0x20d: 0x00c0, 0x20e: 0x00c0, 0x20f: 0x00c0, 0x210: 0x00c0, 0x211: 0x00c0, + 0x212: 0x00c0, 0x213: 0x00c0, 0x214: 0x00c0, 0x215: 0x00c0, 0x216: 0x00c0, 0x217: 0x00c0, + 0x218: 0x00c0, 0x219: 0x00c0, 0x21a: 0x00c0, 0x21b: 0x00c0, 0x21c: 0x00c0, 0x21d: 0x00c0, + 0x21e: 0x00c0, 0x21f: 0x00c0, 0x220: 0x00c0, 0x221: 0x00c0, 0x222: 0x00c0, 0x223: 0x00c0, + 0x224: 0x00c0, 0x225: 0x00c0, 0x226: 0x00c0, 0x227: 0x00c0, 0x228: 0x00c0, 0x229: 0x00c0, + 0x22a: 0x00c0, 0x22b: 0x00c0, 0x22c: 0x00c0, 0x22d: 0x00c0, 0x22e: 0x00c0, 0x22f: 0x00c0, + 0x230: 0x00c0, 0x231: 0x0080, 0x232: 0x0080, 0x233: 0x0080, 0x234: 0x00c0, 0x235: 0x00c0, + 0x236: 0x00c0, 0x237: 0x00c0, 0x238: 0x00c0, 0x239: 0x00c0, 0x23a: 0x00c0, 0x23b: 0x00c0, + 0x23c: 0x00c0, 0x23d: 0x00c0, 0x23e: 0x00c0, 0x23f: 0x00c0, + // Block 0x9, offset 0x240 + 0x240: 0x00c0, 0x241: 0x00c0, 0x242: 0x00c0, 0x243: 0x00c0, 0x244: 0x00c0, 0x245: 0x00c0, + 0x246: 0x00c0, 0x247: 0x00c0, 0x248: 0x00c0, 0x249: 0x00c0, 0x24a: 0x00c0, 0x24b: 0x00c0, + 0x24c: 0x00c0, 0x24d: 0x00c0, 0x24e: 0x00c0, 0x24f: 0x00c0, 0x250: 0x00c0, 0x251: 0x00c0, + 0x252: 0x00c0, 0x253: 0x00c0, 0x254: 0x00c0, 0x255: 0x00c0, 0x256: 0x00c0, 0x257: 0x00c0, + 0x258: 0x00c0, 0x259: 0x00c0, 0x25a: 0x00c0, 0x25b: 0x00c0, 0x25c: 0x00c0, 0x25d: 0x00c0, + 0x25e: 0x00c0, 0x25f: 0x00c0, 0x260: 0x00c0, 0x261: 0x00c0, 0x262: 0x00c0, 0x263: 0x00c0, + 0x264: 0x00c0, 0x265: 0x00c0, 0x266: 0x00c0, 0x267: 0x00c0, 0x268: 0x00c0, 0x269: 0x00c0, + 0x26a: 0x00c0, 0x26b: 0x00c0, 0x26c: 0x00c0, 0x26d: 0x00c0, 0x26e: 0x00c0, 0x26f: 0x00c0, + 0x270: 0x0080, 0x271: 0x0080, 0x272: 0x0080, 0x273: 0x0080, 0x274: 0x0080, 0x275: 0x0080, + 0x276: 0x0080, 0x277: 0x0080, 0x278: 0x0080, 0x279: 0x00c0, 0x27a: 0x00c0, 0x27b: 0x00c0, + 0x27c: 0x00c0, 0x27d: 0x00c0, 0x27e: 0x00c0, 0x27f: 0x00c0, + // Block 0xa, offset 0x280 + 0x280: 0x00c0, 0x281: 0x00c0, 0x282: 0x0080, 0x283: 0x0080, 0x284: 0x0080, 0x285: 0x0080, + 0x286: 0x00c0, 0x287: 0x00c0, 0x288: 0x00c0, 0x289: 0x00c0, 0x28a: 0x00c0, 0x28b: 0x00c0, + 0x28c: 0x00c0, 0x28d: 0x00c0, 0x28e: 0x00c0, 0x28f: 0x00c0, 0x290: 0x00c0, 0x291: 0x00c0, + 0x292: 0x0080, 0x293: 0x0080, 0x294: 0x0080, 0x295: 0x0080, 0x296: 0x0080, 0x297: 0x0080, + 0x298: 0x0080, 0x299: 0x0080, 0x29a: 0x0080, 0x29b: 0x0080, 0x29c: 0x0080, 0x29d: 0x0080, + 0x29e: 0x0080, 0x29f: 0x0080, 0x2a0: 0x0080, 0x2a1: 0x0080, 0x2a2: 0x0080, 0x2a3: 0x0080, + 0x2a4: 0x0080, 0x2a5: 0x0080, 0x2a6: 0x0080, 0x2a7: 0x0080, 0x2a8: 0x0080, 0x2a9: 0x0080, + 0x2aa: 0x0080, 0x2ab: 0x0080, 0x2ac: 0x00c0, 0x2ad: 0x0080, 0x2ae: 0x00c0, 0x2af: 0x0080, + 0x2b0: 0x0080, 0x2b1: 0x0080, 0x2b2: 0x0080, 0x2b3: 0x0080, 0x2b4: 0x0080, 0x2b5: 0x0080, + 0x2b6: 0x0080, 0x2b7: 0x0080, 0x2b8: 0x0080, 0x2b9: 0x0080, 0x2ba: 0x0080, 0x2bb: 0x0080, + 0x2bc: 0x0080, 0x2bd: 0x0080, 0x2be: 0x0080, 0x2bf: 0x0080, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x00c3, 0x2c1: 0x00c3, 0x2c2: 0x00c3, 0x2c3: 0x00c3, 0x2c4: 0x00c3, 0x2c5: 0x00c3, + 0x2c6: 0x00c3, 0x2c7: 0x00c3, 0x2c8: 0x00c3, 0x2c9: 0x00c3, 0x2ca: 0x00c3, 0x2cb: 0x00c3, + 0x2cc: 0x00c3, 0x2cd: 0x00c3, 0x2ce: 0x00c3, 0x2cf: 0x00c3, 0x2d0: 0x00c3, 0x2d1: 0x00c3, + 0x2d2: 0x00c3, 0x2d3: 0x00c3, 0x2d4: 0x00c3, 0x2d5: 0x00c3, 0x2d6: 0x00c3, 0x2d7: 0x00c3, + 0x2d8: 0x00c3, 0x2d9: 0x00c3, 0x2da: 0x00c3, 0x2db: 0x00c3, 0x2dc: 0x00c3, 0x2dd: 0x00c3, + 0x2de: 0x00c3, 0x2df: 0x00c3, 0x2e0: 0x00c3, 0x2e1: 0x00c3, 0x2e2: 0x00c3, 0x2e3: 0x00c3, + 0x2e4: 0x00c3, 0x2e5: 0x00c3, 0x2e6: 0x00c3, 0x2e7: 0x00c3, 0x2e8: 0x00c3, 0x2e9: 0x00c3, + 0x2ea: 0x00c3, 0x2eb: 0x00c3, 0x2ec: 0x00c3, 0x2ed: 0x00c3, 0x2ee: 0x00c3, 0x2ef: 0x00c3, + 0x2f0: 0x00c3, 0x2f1: 0x00c3, 0x2f2: 0x00c3, 0x2f3: 0x00c3, 0x2f4: 0x00c3, 0x2f5: 0x00c3, + 0x2f6: 0x00c3, 0x2f7: 0x00c3, 0x2f8: 0x00c3, 0x2f9: 0x00c3, 0x2fa: 0x00c3, 0x2fb: 0x00c3, + 0x2fc: 0x00c3, 0x2fd: 0x00c3, 0x2fe: 0x00c3, 0x2ff: 0x00c3, + // Block 0xc, offset 0x300 + 0x300: 0x0083, 0x301: 0x0083, 0x302: 0x00c3, 0x303: 0x0083, 0x304: 0x0083, 0x305: 0x00c3, + 0x306: 0x00c3, 0x307: 0x00c3, 0x308: 0x00c3, 0x309: 0x00c3, 0x30a: 0x00c3, 0x30b: 0x00c3, + 0x30c: 0x00c3, 0x30d: 0x00c3, 0x30e: 0x00c3, 0x30f: 0x0040, 0x310: 0x00c3, 0x311: 0x00c3, + 0x312: 0x00c3, 0x313: 0x00c3, 0x314: 0x00c3, 0x315: 0x00c3, 0x316: 0x00c3, 0x317: 0x00c3, + 0x318: 0x00c3, 0x319: 0x00c3, 0x31a: 0x00c3, 0x31b: 0x00c3, 0x31c: 0x00c3, 0x31d: 0x00c3, + 0x31e: 0x00c3, 0x31f: 0x00c3, 0x320: 0x00c3, 0x321: 0x00c3, 0x322: 0x00c3, 0x323: 0x00c3, + 0x324: 0x00c3, 0x325: 0x00c3, 0x326: 0x00c3, 0x327: 0x00c3, 0x328: 0x00c3, 0x329: 0x00c3, + 0x32a: 0x00c3, 0x32b: 0x00c3, 0x32c: 0x00c3, 0x32d: 0x00c3, 0x32e: 0x00c3, 0x32f: 0x00c3, + 0x330: 0x00c8, 0x331: 0x00c8, 0x332: 0x00c8, 0x333: 0x00c8, 0x334: 0x0080, 0x335: 0x0050, + 0x336: 0x00c8, 0x337: 0x00c8, 0x33a: 0x0088, 0x33b: 0x00c8, + 0x33c: 0x00c8, 0x33d: 0x00c8, 0x33e: 0x0080, 0x33f: 0x00c8, + // Block 0xd, offset 0x340 + 0x344: 0x0088, 0x345: 0x0080, + 0x346: 0x00c8, 0x347: 0x0080, 0x348: 0x00c8, 0x349: 0x00c8, 0x34a: 0x00c8, + 0x34c: 0x00c8, 0x34e: 0x00c8, 0x34f: 0x00c8, 0x350: 0x00c8, 0x351: 0x00c8, + 0x352: 0x00c8, 0x353: 0x00c8, 0x354: 0x00c8, 0x355: 0x00c8, 0x356: 0x00c8, 0x357: 0x00c8, + 0x358: 0x00c8, 0x359: 0x00c8, 0x35a: 0x00c8, 0x35b: 0x00c8, 0x35c: 0x00c8, 0x35d: 0x00c8, + 0x35e: 0x00c8, 0x35f: 0x00c8, 0x360: 0x00c8, 0x361: 0x00c8, 0x363: 0x00c8, + 0x364: 0x00c8, 0x365: 0x00c8, 0x366: 0x00c8, 0x367: 0x00c8, 0x368: 0x00c8, 0x369: 0x00c8, + 0x36a: 0x00c8, 0x36b: 0x00c8, 0x36c: 0x00c8, 0x36d: 0x00c8, 0x36e: 0x00c8, 0x36f: 0x00c8, + 0x370: 0x00c8, 0x371: 0x00c8, 0x372: 0x00c8, 0x373: 0x00c8, 0x374: 0x00c8, 0x375: 0x00c8, + 0x376: 0x00c8, 0x377: 0x00c8, 0x378: 0x00c8, 0x379: 0x00c8, 0x37a: 0x00c8, 0x37b: 0x00c8, + 0x37c: 0x00c8, 0x37d: 0x00c8, 0x37e: 0x00c8, 0x37f: 0x00c8, + // Block 0xe, offset 0x380 + 0x380: 0x00c8, 0x381: 0x00c8, 0x382: 0x00c8, 0x383: 0x00c8, 0x384: 0x00c8, 0x385: 0x00c8, + 0x386: 0x00c8, 0x387: 0x00c8, 0x388: 0x00c8, 0x389: 0x00c8, 0x38a: 0x00c8, 0x38b: 0x00c8, + 0x38c: 0x00c8, 0x38d: 0x00c8, 0x38e: 0x00c8, 0x38f: 0x00c8, 0x390: 0x0088, 0x391: 0x0088, + 0x392: 0x0088, 0x393: 0x0088, 0x394: 0x0088, 0x395: 0x0088, 0x396: 0x0088, 0x397: 0x00c8, + 0x398: 0x00c8, 0x399: 0x00c8, 0x39a: 0x00c8, 0x39b: 0x00c8, 0x39c: 0x00c8, 0x39d: 0x00c8, + 0x39e: 0x00c8, 0x39f: 0x00c8, 0x3a0: 0x00c8, 0x3a1: 0x00c8, 0x3a2: 0x00c0, 0x3a3: 0x00c0, + 0x3a4: 0x00c0, 0x3a5: 0x00c0, 0x3a6: 0x00c0, 0x3a7: 0x00c0, 0x3a8: 0x00c0, 0x3a9: 0x00c0, + 0x3aa: 0x00c0, 0x3ab: 0x00c0, 0x3ac: 0x00c0, 0x3ad: 0x00c0, 0x3ae: 0x00c0, 0x3af: 0x00c0, + 0x3b0: 0x0088, 0x3b1: 0x0088, 0x3b2: 0x0088, 0x3b3: 0x00c8, 0x3b4: 0x0088, 0x3b5: 0x0088, + 0x3b6: 0x0088, 0x3b7: 0x00c8, 0x3b8: 0x00c8, 0x3b9: 0x0088, 0x3ba: 0x00c8, 0x3bb: 0x00c8, + 0x3bc: 0x00c8, 0x3bd: 0x00c8, 0x3be: 0x00c8, 0x3bf: 0x00c8, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x00c0, 0x3c1: 0x00c0, 0x3c2: 0x0080, 0x3c3: 0x00c3, 0x3c4: 0x00c3, 0x3c5: 0x00c3, + 0x3c6: 0x00c3, 0x3c7: 0x00c3, 0x3c8: 0x0083, 0x3c9: 0x0083, 0x3ca: 0x00c0, 0x3cb: 0x00c0, + 0x3cc: 0x00c0, 0x3cd: 0x00c0, 0x3ce: 0x00c0, 0x3cf: 0x00c0, 0x3d0: 0x00c0, 0x3d1: 0x00c0, + 0x3d2: 0x00c0, 0x3d3: 0x00c0, 0x3d4: 0x00c0, 0x3d5: 0x00c0, 0x3d6: 0x00c0, 0x3d7: 0x00c0, + 0x3d8: 0x00c0, 0x3d9: 0x00c0, 0x3da: 0x00c0, 0x3db: 0x00c0, 0x3dc: 0x00c0, 0x3dd: 0x00c0, + 0x3de: 0x00c0, 0x3df: 0x00c0, 0x3e0: 0x00c0, 0x3e1: 0x00c0, 0x3e2: 0x00c0, 0x3e3: 0x00c0, + 0x3e4: 0x00c0, 0x3e5: 0x00c0, 0x3e6: 0x00c0, 0x3e7: 0x00c0, 0x3e8: 0x00c0, 0x3e9: 0x00c0, + 0x3ea: 0x00c0, 0x3eb: 0x00c0, 0x3ec: 0x00c0, 0x3ed: 0x00c0, 0x3ee: 0x00c0, 0x3ef: 0x00c0, + 0x3f0: 0x00c0, 0x3f1: 0x00c0, 0x3f2: 0x00c0, 0x3f3: 0x00c0, 0x3f4: 0x00c0, 0x3f5: 0x00c0, + 0x3f6: 0x00c0, 0x3f7: 0x00c0, 0x3f8: 0x00c0, 0x3f9: 0x00c0, 0x3fa: 0x00c0, 0x3fb: 0x00c0, + 0x3fc: 0x00c0, 0x3fd: 0x00c0, 0x3fe: 0x00c0, 0x3ff: 0x00c0, + // Block 0x10, offset 0x400 + 0x400: 0x00c0, 0x401: 0x00c0, 0x402: 0x00c0, 0x403: 0x00c0, 0x404: 0x00c0, 0x405: 0x00c0, + 0x406: 0x00c0, 0x407: 0x00c0, 0x408: 0x00c0, 0x409: 0x00c0, 0x40a: 0x00c0, 0x40b: 0x00c0, + 0x40c: 0x00c0, 0x40d: 0x00c0, 0x40e: 0x00c0, 0x40f: 0x00c0, 0x410: 0x00c0, 0x411: 0x00c0, + 0x412: 0x00c0, 0x413: 0x00c0, 0x414: 0x00c0, 0x415: 0x00c0, 0x416: 0x00c0, 0x417: 0x00c0, + 0x418: 0x00c0, 0x419: 0x00c0, 0x41a: 0x00c0, 0x41b: 0x00c0, 0x41c: 0x00c0, 0x41d: 0x00c0, + 0x41e: 0x00c0, 0x41f: 0x00c0, 0x420: 0x00c0, 0x421: 0x00c0, 0x422: 0x00c0, 0x423: 0x00c0, + 0x424: 0x00c0, 0x425: 0x00c0, 0x426: 0x00c0, 0x427: 0x00c0, 0x428: 0x00c0, 0x429: 0x00c0, + 0x42a: 0x00c0, 0x42b: 0x00c0, 0x42c: 0x00c0, 0x42d: 0x00c0, 0x42e: 0x00c0, 0x42f: 0x00c0, + 0x431: 0x00c0, 0x432: 0x00c0, 0x433: 0x00c0, 0x434: 0x00c0, 0x435: 0x00c0, + 0x436: 0x00c0, 0x437: 0x00c0, 0x438: 0x00c0, 0x439: 0x00c0, 0x43a: 0x00c0, 0x43b: 0x00c0, + 0x43c: 0x00c0, 0x43d: 0x00c0, 0x43e: 0x00c0, 0x43f: 0x00c0, + // Block 0x11, offset 0x440 + 0x440: 0x00c0, 0x441: 0x00c0, 0x442: 0x00c0, 0x443: 0x00c0, 0x444: 0x00c0, 0x445: 0x00c0, + 0x446: 0x00c0, 0x447: 0x00c0, 0x448: 0x00c0, 0x449: 0x00c0, 0x44a: 0x00c0, 0x44b: 0x00c0, + 0x44c: 0x00c0, 0x44d: 0x00c0, 0x44e: 0x00c0, 0x44f: 0x00c0, 0x450: 0x00c0, 0x451: 0x00c0, + 0x452: 0x00c0, 0x453: 0x00c0, 0x454: 0x00c0, 0x455: 0x00c0, 0x456: 0x00c0, + 0x459: 0x00c0, 0x45a: 0x0080, 0x45b: 0x0080, 0x45c: 0x0080, 0x45d: 0x0080, + 0x45e: 0x0080, 0x45f: 0x0080, 0x460: 0x00c0, 0x461: 0x00c0, 0x462: 0x00c0, 0x463: 0x00c0, + 0x464: 0x00c0, 0x465: 0x00c0, 0x466: 0x00c0, 0x467: 0x00c0, 0x468: 0x00c0, 0x469: 0x00c0, + 0x46a: 0x00c0, 0x46b: 0x00c0, 0x46c: 0x00c0, 0x46d: 0x00c0, 0x46e: 0x00c0, 0x46f: 0x00c0, + 0x470: 0x00c0, 0x471: 0x00c0, 0x472: 0x00c0, 0x473: 0x00c0, 0x474: 0x00c0, 0x475: 0x00c0, + 0x476: 0x00c0, 0x477: 0x00c0, 0x478: 0x00c0, 0x479: 0x00c0, 0x47a: 0x00c0, 0x47b: 0x00c0, + 0x47c: 0x00c0, 0x47d: 0x00c0, 0x47e: 0x00c0, 0x47f: 0x00c0, + // Block 0x12, offset 0x480 + 0x480: 0x00c0, 0x481: 0x00c0, 0x482: 0x00c0, 0x483: 0x00c0, 0x484: 0x00c0, 0x485: 0x00c0, + 0x486: 0x00c0, 0x487: 0x0080, 0x488: 0x00c0, 0x489: 0x0080, 0x48a: 0x0080, + 0x48d: 0x0080, 0x48e: 0x0080, 0x48f: 0x0080, 0x491: 0x00cb, + 0x492: 0x00cb, 0x493: 0x00cb, 0x494: 0x00cb, 0x495: 0x00cb, 0x496: 0x00cb, 0x497: 0x00cb, + 0x498: 0x00cb, 0x499: 0x00cb, 0x49a: 0x00cb, 0x49b: 0x00cb, 0x49c: 0x00cb, 0x49d: 0x00cb, + 0x49e: 0x00cb, 0x49f: 0x00cb, 0x4a0: 0x00cb, 0x4a1: 0x00cb, 0x4a2: 0x00cb, 0x4a3: 0x00cb, + 0x4a4: 0x00cb, 0x4a5: 0x00cb, 0x4a6: 0x00cb, 0x4a7: 0x00cb, 0x4a8: 0x00cb, 0x4a9: 0x00cb, + 0x4aa: 0x00cb, 0x4ab: 0x00cb, 0x4ac: 0x00cb, 0x4ad: 0x00cb, 0x4ae: 0x00cb, 0x4af: 0x00cb, + 0x4b0: 0x00cb, 0x4b1: 0x00cb, 0x4b2: 0x00cb, 0x4b3: 0x00cb, 0x4b4: 0x00cb, 0x4b5: 0x00cb, + 0x4b6: 0x00cb, 0x4b7: 0x00cb, 0x4b8: 0x00cb, 0x4b9: 0x00cb, 0x4ba: 0x00cb, 0x4bb: 0x00cb, + 0x4bc: 0x00cb, 0x4bd: 0x00cb, 0x4be: 0x008a, 0x4bf: 0x00cb, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x008a, 0x4c1: 0x00cb, 0x4c2: 0x00cb, 0x4c3: 0x008a, 0x4c4: 0x00cb, 0x4c5: 0x00cb, + 0x4c6: 0x008a, 0x4c7: 0x00cb, + 0x4d0: 0x00ca, 0x4d1: 0x00ca, + 0x4d2: 0x00ca, 0x4d3: 0x00ca, 0x4d4: 0x00ca, 0x4d5: 0x00ca, 0x4d6: 0x00ca, 0x4d7: 0x00ca, + 0x4d8: 0x00ca, 0x4d9: 0x00ca, 0x4da: 0x00ca, 0x4db: 0x00ca, 0x4dc: 0x00ca, 0x4dd: 0x00ca, + 0x4de: 0x00ca, 0x4df: 0x00ca, 0x4e0: 0x00ca, 0x4e1: 0x00ca, 0x4e2: 0x00ca, 0x4e3: 0x00ca, + 0x4e4: 0x00ca, 0x4e5: 0x00ca, 0x4e6: 0x00ca, 0x4e7: 0x00ca, 0x4e8: 0x00ca, 0x4e9: 0x00ca, + 0x4ea: 0x00ca, 0x4ef: 0x00ca, + 0x4f0: 0x00ca, 0x4f1: 0x00ca, 0x4f2: 0x00ca, 0x4f3: 0x0051, 0x4f4: 0x0051, + // Block 0x14, offset 0x500 + 0x500: 0x0040, 0x501: 0x0040, 0x502: 0x0040, 0x503: 0x0040, 0x504: 0x0040, 0x505: 0x0040, + 0x506: 0x0080, 0x507: 0x0080, 0x508: 0x0080, 0x509: 0x0080, 0x50a: 0x0080, 0x50b: 0x0080, + 0x50c: 0x0080, 0x50d: 0x0080, 0x50e: 0x0080, 0x50f: 0x0080, 0x510: 0x00c3, 0x511: 0x00c3, + 0x512: 0x00c3, 0x513: 0x00c3, 0x514: 0x00c3, 0x515: 0x00c3, 0x516: 0x00c3, 0x517: 0x00c3, + 0x518: 0x00c3, 0x519: 0x00c3, 0x51a: 0x00c3, 0x51b: 0x0080, 0x51c: 0x0040, + 0x51e: 0x0080, 0x51f: 0x0080, 0x520: 0x00c2, 0x521: 0x00c0, 0x522: 0x00c4, 0x523: 0x00c4, + 0x524: 0x00c4, 0x525: 0x00c4, 0x526: 0x00c2, 0x527: 0x00c4, 0x528: 0x00c2, 0x529: 0x00c4, + 0x52a: 0x00c2, 0x52b: 0x00c2, 0x52c: 0x00c2, 0x52d: 0x00c2, 0x52e: 0x00c2, 0x52f: 0x00c4, + 0x530: 0x00c4, 0x531: 0x00c4, 0x532: 0x00c4, 0x533: 0x00c2, 0x534: 0x00c2, 0x535: 0x00c2, + 0x536: 0x00c2, 0x537: 0x00c2, 0x538: 0x00c2, 0x539: 0x00c2, 0x53a: 0x00c2, 0x53b: 0x00c2, + 0x53c: 0x00c2, 0x53d: 0x00c2, 0x53e: 0x00c2, 0x53f: 0x00c2, + // Block 0x15, offset 0x540 + 0x540: 0x0040, 0x541: 0x00c2, 0x542: 0x00c2, 0x543: 0x00c2, 0x544: 0x00c2, 0x545: 0x00c2, + 0x546: 0x00c2, 0x547: 0x00c2, 0x548: 0x00c4, 0x549: 0x00c2, 0x54a: 0x00c2, 0x54b: 0x00c3, + 0x54c: 0x00c3, 0x54d: 0x00c3, 0x54e: 0x00c3, 0x54f: 0x00c3, 0x550: 0x00c3, 0x551: 0x00c3, + 0x552: 0x00c3, 0x553: 0x00c3, 0x554: 0x00c3, 0x555: 0x00c3, 0x556: 0x00c3, 0x557: 0x00c3, + 0x558: 0x00c3, 0x559: 0x00c3, 0x55a: 0x00c3, 0x55b: 0x00c3, 0x55c: 0x00c3, 0x55d: 0x00c3, + 0x55e: 0x00c3, 0x55f: 0x00c3, 0x560: 0x0053, 0x561: 0x0053, 0x562: 0x0053, 0x563: 0x0053, + 0x564: 0x0053, 0x565: 0x0053, 0x566: 0x0053, 0x567: 0x0053, 0x568: 0x0053, 0x569: 0x0053, + 0x56a: 0x0080, 0x56b: 0x0080, 0x56c: 0x0080, 0x56d: 0x0080, 0x56e: 0x00c2, 0x56f: 0x00c2, + 0x570: 0x00c3, 0x571: 0x00c4, 0x572: 0x00c4, 0x573: 0x00c4, 0x574: 0x00c0, 0x575: 0x0084, + 0x576: 0x0084, 0x577: 0x0084, 0x578: 0x0082, 0x579: 0x00c2, 0x57a: 0x00c2, 0x57b: 0x00c2, + 0x57c: 0x00c2, 0x57d: 0x00c2, 0x57e: 0x00c2, 0x57f: 0x00c2, + // Block 0x16, offset 0x580 + 0x580: 0x00c2, 0x581: 0x00c2, 0x582: 0x00c2, 0x583: 0x00c2, 0x584: 0x00c2, 0x585: 0x00c2, + 0x586: 0x00c2, 0x587: 0x00c2, 0x588: 0x00c4, 0x589: 0x00c4, 0x58a: 0x00c4, 0x58b: 0x00c4, + 0x58c: 0x00c4, 0x58d: 0x00c4, 0x58e: 0x00c4, 0x58f: 0x00c4, 0x590: 0x00c4, 0x591: 0x00c4, + 0x592: 0x00c4, 0x593: 0x00c4, 0x594: 0x00c4, 0x595: 0x00c4, 0x596: 0x00c4, 0x597: 0x00c4, + 0x598: 0x00c4, 0x599: 0x00c4, 0x59a: 0x00c2, 0x59b: 0x00c2, 0x59c: 0x00c2, 0x59d: 0x00c2, + 0x59e: 0x00c2, 0x59f: 0x00c2, 0x5a0: 0x00c2, 0x5a1: 0x00c2, 0x5a2: 0x00c2, 0x5a3: 0x00c2, + 0x5a4: 0x00c2, 0x5a5: 0x00c2, 0x5a6: 0x00c2, 0x5a7: 0x00c2, 0x5a8: 0x00c2, 0x5a9: 0x00c2, + 0x5aa: 0x00c2, 0x5ab: 0x00c2, 0x5ac: 0x00c2, 0x5ad: 0x00c2, 0x5ae: 0x00c2, 0x5af: 0x00c2, + 0x5b0: 0x00c2, 0x5b1: 0x00c2, 0x5b2: 0x00c2, 0x5b3: 0x00c2, 0x5b4: 0x00c2, 0x5b5: 0x00c2, + 0x5b6: 0x00c2, 0x5b7: 0x00c2, 0x5b8: 0x00c2, 0x5b9: 0x00c2, 0x5ba: 0x00c2, 0x5bb: 0x00c2, + 0x5bc: 0x00c2, 0x5bd: 0x00c2, 0x5be: 0x00c2, 0x5bf: 0x00c2, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x00c4, 0x5c1: 0x00c2, 0x5c2: 0x00c2, 0x5c3: 0x00c4, 0x5c4: 0x00c4, 0x5c5: 0x00c4, + 0x5c6: 0x00c4, 0x5c7: 0x00c4, 0x5c8: 0x00c4, 0x5c9: 0x00c4, 0x5ca: 0x00c4, 0x5cb: 0x00c4, + 0x5cc: 0x00c2, 0x5cd: 0x00c4, 0x5ce: 0x00c2, 0x5cf: 0x00c4, 0x5d0: 0x00c2, 0x5d1: 0x00c2, + 0x5d2: 0x00c4, 0x5d3: 0x00c4, 0x5d4: 0x0080, 0x5d5: 0x00c4, 0x5d6: 0x00c3, 0x5d7: 0x00c3, + 0x5d8: 0x00c3, 0x5d9: 0x00c3, 0x5da: 0x00c3, 0x5db: 0x00c3, 0x5dc: 0x00c3, 0x5dd: 0x0040, + 0x5de: 0x0080, 0x5df: 0x00c3, 0x5e0: 0x00c3, 0x5e1: 0x00c3, 0x5e2: 0x00c3, 0x5e3: 0x00c3, + 0x5e4: 0x00c3, 0x5e5: 0x00c0, 0x5e6: 0x00c0, 0x5e7: 0x00c3, 0x5e8: 0x00c3, 0x5e9: 0x0080, + 0x5ea: 0x00c3, 0x5eb: 0x00c3, 0x5ec: 0x00c3, 0x5ed: 0x00c3, 0x5ee: 0x00c4, 0x5ef: 0x00c4, + 0x5f0: 0x0054, 0x5f1: 0x0054, 0x5f2: 0x0054, 0x5f3: 0x0054, 0x5f4: 0x0054, 0x5f5: 0x0054, + 0x5f6: 0x0054, 0x5f7: 0x0054, 0x5f8: 0x0054, 0x5f9: 0x0054, 0x5fa: 0x00c2, 0x5fb: 0x00c2, + 0x5fc: 0x00c2, 0x5fd: 0x00c0, 0x5fe: 0x00c0, 0x5ff: 0x00c2, + // Block 0x18, offset 0x600 + 0x600: 0x0080, 0x601: 0x0080, 0x602: 0x0080, 0x603: 0x0080, 0x604: 0x0080, 0x605: 0x0080, + 0x606: 0x0080, 0x607: 0x0080, 0x608: 0x0080, 0x609: 0x0080, 0x60a: 0x0080, 0x60b: 0x0080, + 0x60c: 0x0080, 0x60d: 0x0080, 0x60f: 0x0040, 0x610: 0x00c4, 0x611: 0x00c3, + 0x612: 0x00c2, 0x613: 0x00c2, 0x614: 0x00c2, 0x615: 0x00c4, 0x616: 0x00c4, 0x617: 0x00c4, + 0x618: 0x00c4, 0x619: 0x00c4, 0x61a: 0x00c2, 0x61b: 0x00c2, 0x61c: 0x00c2, 0x61d: 0x00c2, + 0x61e: 0x00c4, 0x61f: 0x00c2, 0x620: 0x00c2, 0x621: 0x00c2, 0x622: 0x00c2, 0x623: 0x00c2, + 0x624: 0x00c2, 0x625: 0x00c2, 0x626: 0x00c2, 0x627: 0x00c2, 0x628: 0x00c4, 0x629: 0x00c2, + 0x62a: 0x00c4, 0x62b: 0x00c2, 0x62c: 0x00c4, 0x62d: 0x00c2, 0x62e: 0x00c2, 0x62f: 0x00c4, + 0x630: 0x00c3, 0x631: 0x00c3, 0x632: 0x00c3, 0x633: 0x00c3, 0x634: 0x00c3, 0x635: 0x00c3, + 0x636: 0x00c3, 0x637: 0x00c3, 0x638: 0x00c3, 0x639: 0x00c3, 0x63a: 0x00c3, 0x63b: 0x00c3, + 0x63c: 0x00c3, 0x63d: 0x00c3, 0x63e: 0x00c3, 0x63f: 0x00c3, + // Block 0x19, offset 0x640 + 0x640: 0x00c3, 0x641: 0x00c3, 0x642: 0x00c3, 0x643: 0x00c3, 0x644: 0x00c3, 0x645: 0x00c3, + 0x646: 0x00c3, 0x647: 0x00c3, 0x648: 0x00c3, 0x649: 0x00c3, 0x64a: 0x00c3, + 0x64d: 0x00c4, 0x64e: 0x00c2, 0x64f: 0x00c2, 0x650: 0x00c2, 0x651: 0x00c2, + 0x652: 0x00c2, 0x653: 0x00c2, 0x654: 0x00c2, 0x655: 0x00c2, 0x656: 0x00c2, 0x657: 0x00c2, + 0x658: 0x00c2, 0x659: 0x00c4, 0x65a: 0x00c4, 0x65b: 0x00c4, 0x65c: 0x00c2, 0x65d: 0x00c2, + 0x65e: 0x00c2, 0x65f: 0x00c2, 0x660: 0x00c2, 0x661: 0x00c2, 0x662: 0x00c2, 0x663: 0x00c2, + 0x664: 0x00c2, 0x665: 0x00c2, 0x666: 0x00c2, 0x667: 0x00c2, 0x668: 0x00c2, 0x669: 0x00c2, + 0x66a: 0x00c2, 0x66b: 0x00c4, 0x66c: 0x00c4, 0x66d: 0x00c2, 0x66e: 0x00c2, 0x66f: 0x00c2, + 0x670: 0x00c2, 0x671: 0x00c4, 0x672: 0x00c2, 0x673: 0x00c4, 0x674: 0x00c4, 0x675: 0x00c2, + 0x676: 0x00c2, 0x677: 0x00c2, 0x678: 0x00c4, 0x679: 0x00c4, 0x67a: 0x00c2, 0x67b: 0x00c2, + 0x67c: 0x00c2, 0x67d: 0x00c2, 0x67e: 0x00c2, 0x67f: 0x00c2, + // Block 0x1a, offset 0x680 + 0x680: 0x00c0, 0x681: 0x00c0, 0x682: 0x00c0, 0x683: 0x00c0, 0x684: 0x00c0, 0x685: 0x00c0, + 0x686: 0x00c0, 0x687: 0x00c0, 0x688: 0x00c0, 0x689: 0x00c0, 0x68a: 0x00c0, 0x68b: 0x00c0, + 0x68c: 0x00c0, 0x68d: 0x00c0, 0x68e: 0x00c0, 0x68f: 0x00c0, 0x690: 0x00c0, 0x691: 0x00c0, + 0x692: 0x00c0, 0x693: 0x00c0, 0x694: 0x00c0, 0x695: 0x00c0, 0x696: 0x00c0, 0x697: 0x00c0, + 0x698: 0x00c0, 0x699: 0x00c0, 0x69a: 0x00c0, 0x69b: 0x00c0, 0x69c: 0x00c0, 0x69d: 0x00c0, + 0x69e: 0x00c0, 0x69f: 0x00c0, 0x6a0: 0x00c0, 0x6a1: 0x00c0, 0x6a2: 0x00c0, 0x6a3: 0x00c0, + 0x6a4: 0x00c0, 0x6a5: 0x00c0, 0x6a6: 0x00c3, 0x6a7: 0x00c3, 0x6a8: 0x00c3, 0x6a9: 0x00c3, + 0x6aa: 0x00c3, 0x6ab: 0x00c3, 0x6ac: 0x00c3, 0x6ad: 0x00c3, 0x6ae: 0x00c3, 0x6af: 0x00c3, + 0x6b0: 0x00c3, 0x6b1: 0x00c0, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x00c0, 0x6c1: 0x00c0, 0x6c2: 0x00c0, 0x6c3: 0x00c0, 0x6c4: 0x00c0, 0x6c5: 0x00c0, + 0x6c6: 0x00c0, 0x6c7: 0x00c0, 0x6c8: 0x00c0, 0x6c9: 0x00c0, 0x6ca: 0x00c2, 0x6cb: 0x00c2, + 0x6cc: 0x00c2, 0x6cd: 0x00c2, 0x6ce: 0x00c2, 0x6cf: 0x00c2, 0x6d0: 0x00c2, 0x6d1: 0x00c2, + 0x6d2: 0x00c2, 0x6d3: 0x00c2, 0x6d4: 0x00c2, 0x6d5: 0x00c2, 0x6d6: 0x00c2, 0x6d7: 0x00c2, + 0x6d8: 0x00c2, 0x6d9: 0x00c2, 0x6da: 0x00c2, 0x6db: 0x00c2, 0x6dc: 0x00c2, 0x6dd: 0x00c2, + 0x6de: 0x00c2, 0x6df: 0x00c2, 0x6e0: 0x00c2, 0x6e1: 0x00c2, 0x6e2: 0x00c2, 0x6e3: 0x00c2, + 0x6e4: 0x00c2, 0x6e5: 0x00c2, 0x6e6: 0x00c2, 0x6e7: 0x00c2, 0x6e8: 0x00c2, 0x6e9: 0x00c2, + 0x6ea: 0x00c2, 0x6eb: 0x00c3, 0x6ec: 0x00c3, 0x6ed: 0x00c3, 0x6ee: 0x00c3, 0x6ef: 0x00c3, + 0x6f0: 0x00c3, 0x6f1: 0x00c3, 0x6f2: 0x00c3, 0x6f3: 0x00c3, 0x6f4: 0x00c0, 0x6f5: 0x00c0, + 0x6f6: 0x0080, 0x6f7: 0x0080, 0x6f8: 0x0080, 0x6f9: 0x0080, 0x6fa: 0x0040, + 0x6fd: 0x00c3, 0x6fe: 0x0080, 0x6ff: 0x0080, + // Block 0x1c, offset 0x700 + 0x700: 0x00c0, 0x701: 0x00c0, 0x702: 0x00c0, 0x703: 0x00c0, 0x704: 0x00c0, 0x705: 0x00c0, + 0x706: 0x00c0, 0x707: 0x00c0, 0x708: 0x00c0, 0x709: 0x00c0, 0x70a: 0x00c0, 0x70b: 0x00c0, + 0x70c: 0x00c0, 0x70d: 0x00c0, 0x70e: 0x00c0, 0x70f: 0x00c0, 0x710: 0x00c0, 0x711: 0x00c0, + 0x712: 0x00c0, 0x713: 0x00c0, 0x714: 0x00c0, 0x715: 0x00c0, 0x716: 0x00c3, 0x717: 0x00c3, + 0x718: 0x00c3, 0x719: 0x00c3, 0x71a: 0x00c0, 0x71b: 0x00c3, 0x71c: 0x00c3, 0x71d: 0x00c3, + 0x71e: 0x00c3, 0x71f: 0x00c3, 0x720: 0x00c3, 0x721: 0x00c3, 0x722: 0x00c3, 0x723: 0x00c3, + 0x724: 0x00c0, 0x725: 0x00c3, 0x726: 0x00c3, 0x727: 0x00c3, 0x728: 0x00c0, 0x729: 0x00c3, + 0x72a: 0x00c3, 0x72b: 0x00c3, 0x72c: 0x00c3, 0x72d: 0x00c3, + 0x730: 0x0080, 0x731: 0x0080, 0x732: 0x0080, 0x733: 0x0080, 0x734: 0x0080, 0x735: 0x0080, + 0x736: 0x0080, 0x737: 0x0080, 0x738: 0x0080, 0x739: 0x0080, 0x73a: 0x0080, 0x73b: 0x0080, + 0x73c: 0x0080, 0x73d: 0x0080, 0x73e: 0x0080, + // Block 0x1d, offset 0x740 + 0x740: 0x00c4, 0x741: 0x00c2, 0x742: 0x00c2, 0x743: 0x00c2, 0x744: 0x00c2, 0x745: 0x00c2, + 0x746: 0x00c4, 0x747: 0x00c4, 0x748: 0x00c2, 0x749: 0x00c4, 0x74a: 0x00c2, 0x74b: 0x00c2, + 0x74c: 0x00c2, 0x74d: 0x00c2, 0x74e: 0x00c2, 0x74f: 0x00c2, 0x750: 0x00c2, 0x751: 0x00c2, + 0x752: 0x00c2, 0x753: 0x00c2, 0x754: 0x00c4, 0x755: 0x00c2, 0x756: 0x00c0, 0x757: 0x00c0, + 0x758: 0x00c0, 0x759: 0x00c3, 0x75a: 0x00c3, 0x75b: 0x00c3, + 0x75e: 0x0080, 0x760: 0x00c2, 0x761: 0x00c0, 0x762: 0x00c2, 0x763: 0x00c2, + 0x764: 0x00c2, 0x765: 0x00c2, 0x766: 0x00c0, 0x767: 0x00c4, 0x768: 0x00c2, 0x769: 0x00c4, + 0x76a: 0x00c4, + // Block 0x1e, offset 0x780 + 0x7a0: 0x00c2, 0x7a1: 0x00c2, 0x7a2: 0x00c2, 0x7a3: 0x00c2, + 0x7a4: 0x00c2, 0x7a5: 0x00c2, 0x7a6: 0x00c2, 0x7a7: 0x00c2, 0x7a8: 0x00c2, 0x7a9: 0x00c2, + 0x7aa: 0x00c4, 0x7ab: 0x00c4, 0x7ac: 0x00c4, 0x7ad: 0x00c0, 0x7ae: 0x00c4, 0x7af: 0x00c2, + 0x7b0: 0x00c2, 0x7b1: 0x00c4, 0x7b2: 0x00c4, 0x7b3: 0x00c2, 0x7b4: 0x00c2, + 0x7b6: 0x00c2, 0x7b7: 0x00c2, 0x7b8: 0x00c2, 0x7b9: 0x00c4, 0x7ba: 0x00c2, 0x7bb: 0x00c2, + 0x7bc: 0x00c2, 0x7bd: 0x00c2, + // Block 0x1f, offset 0x7c0 + 0x7d3: 0x00c3, 0x7d4: 0x00c3, 0x7d5: 0x00c3, 0x7d6: 0x00c3, 0x7d7: 0x00c3, + 0x7d8: 0x00c3, 0x7d9: 0x00c3, 0x7da: 0x00c3, 0x7db: 0x00c3, 0x7dc: 0x00c3, 0x7dd: 0x00c3, + 0x7de: 0x00c3, 0x7df: 0x00c3, 0x7e0: 0x00c3, 0x7e1: 0x00c3, 0x7e2: 0x0040, 0x7e3: 0x00c3, + 0x7e4: 0x00c3, 0x7e5: 0x00c3, 0x7e6: 0x00c3, 0x7e7: 0x00c3, 0x7e8: 0x00c3, 0x7e9: 0x00c3, + 0x7ea: 0x00c3, 0x7eb: 0x00c3, 0x7ec: 0x00c3, 0x7ed: 0x00c3, 0x7ee: 0x00c3, 0x7ef: 0x00c3, + 0x7f0: 0x00c3, 0x7f1: 0x00c3, 0x7f2: 0x00c3, 0x7f3: 0x00c3, 0x7f4: 0x00c3, 0x7f5: 0x00c3, + 0x7f6: 0x00c3, 0x7f7: 0x00c3, 0x7f8: 0x00c3, 0x7f9: 0x00c3, 0x7fa: 0x00c3, 0x7fb: 0x00c3, + 0x7fc: 0x00c3, 0x7fd: 0x00c3, 0x7fe: 0x00c3, 0x7ff: 0x00c3, + // Block 0x20, offset 0x800 + 0x800: 0x00c3, 0x801: 0x00c3, 0x802: 0x00c3, 0x803: 0x00c0, 0x804: 0x00c0, 0x805: 0x00c0, + 0x806: 0x00c0, 0x807: 0x00c0, 0x808: 0x00c0, 0x809: 0x00c0, 0x80a: 0x00c0, 0x80b: 0x00c0, + 0x80c: 0x00c0, 0x80d: 0x00c0, 0x80e: 0x00c0, 0x80f: 0x00c0, 0x810: 0x00c0, 0x811: 0x00c0, + 0x812: 0x00c0, 0x813: 0x00c0, 0x814: 0x00c0, 0x815: 0x00c0, 0x816: 0x00c0, 0x817: 0x00c0, + 0x818: 0x00c0, 0x819: 0x00c0, 0x81a: 0x00c0, 0x81b: 0x00c0, 0x81c: 0x00c0, 0x81d: 0x00c0, + 0x81e: 0x00c0, 0x81f: 0x00c0, 0x820: 0x00c0, 0x821: 0x00c0, 0x822: 0x00c0, 0x823: 0x00c0, + 0x824: 0x00c0, 0x825: 0x00c0, 0x826: 0x00c0, 0x827: 0x00c0, 0x828: 0x00c0, 0x829: 0x00c0, + 0x82a: 0x00c0, 0x82b: 0x00c0, 0x82c: 0x00c0, 0x82d: 0x00c0, 0x82e: 0x00c0, 0x82f: 0x00c0, + 0x830: 0x00c0, 0x831: 0x00c0, 0x832: 0x00c0, 0x833: 0x00c0, 0x834: 0x00c0, 0x835: 0x00c0, + 0x836: 0x00c0, 0x837: 0x00c0, 0x838: 0x00c0, 0x839: 0x00c0, 0x83a: 0x00c3, 0x83b: 0x00c0, + 0x83c: 0x00c3, 0x83d: 0x00c0, 0x83e: 0x00c0, 0x83f: 0x00c0, + // Block 0x21, offset 0x840 + 0x840: 0x00c0, 0x841: 0x00c3, 0x842: 0x00c3, 0x843: 0x00c3, 0x844: 0x00c3, 0x845: 0x00c3, + 0x846: 0x00c3, 0x847: 0x00c3, 0x848: 0x00c3, 0x849: 0x00c0, 0x84a: 0x00c0, 0x84b: 0x00c0, + 0x84c: 0x00c0, 0x84d: 0x00c6, 0x84e: 0x00c0, 0x84f: 0x00c0, 0x850: 0x00c0, 0x851: 0x00c3, + 0x852: 0x00c3, 0x853: 0x00c3, 0x854: 0x00c3, 0x855: 0x00c3, 0x856: 0x00c3, 0x857: 0x00c3, + 0x858: 0x0080, 0x859: 0x0080, 0x85a: 0x0080, 0x85b: 0x0080, 0x85c: 0x0080, 0x85d: 0x0080, + 0x85e: 0x0080, 0x85f: 0x0080, 0x860: 0x00c0, 0x861: 0x00c0, 0x862: 0x00c3, 0x863: 0x00c3, + 0x864: 0x0080, 0x865: 0x0080, 0x866: 0x00c0, 0x867: 0x00c0, 0x868: 0x00c0, 0x869: 0x00c0, + 0x86a: 0x00c0, 0x86b: 0x00c0, 0x86c: 0x00c0, 0x86d: 0x00c0, 0x86e: 0x00c0, 0x86f: 0x00c0, + 0x870: 0x0080, 0x871: 0x00c0, 0x872: 0x00c0, 0x873: 0x00c0, 0x874: 0x00c0, 0x875: 0x00c0, + 0x876: 0x00c0, 0x877: 0x00c0, 0x878: 0x00c0, 0x879: 0x00c0, 0x87a: 0x00c0, 0x87b: 0x00c0, + 0x87c: 0x00c0, 0x87d: 0x00c0, 0x87e: 0x00c0, 0x87f: 0x00c0, + // Block 0x22, offset 0x880 + 0x880: 0x00c0, 0x881: 0x00c3, 0x882: 0x00c0, 0x883: 0x00c0, 0x885: 0x00c0, + 0x886: 0x00c0, 0x887: 0x00c0, 0x888: 0x00c0, 0x889: 0x00c0, 0x88a: 0x00c0, 0x88b: 0x00c0, + 0x88c: 0x00c0, 0x88f: 0x00c0, 0x890: 0x00c0, + 0x893: 0x00c0, 0x894: 0x00c0, 0x895: 0x00c0, 0x896: 0x00c0, 0x897: 0x00c0, + 0x898: 0x00c0, 0x899: 0x00c0, 0x89a: 0x00c0, 0x89b: 0x00c0, 0x89c: 0x00c0, 0x89d: 0x00c0, + 0x89e: 0x00c0, 0x89f: 0x00c0, 0x8a0: 0x00c0, 0x8a1: 0x00c0, 0x8a2: 0x00c0, 0x8a3: 0x00c0, + 0x8a4: 0x00c0, 0x8a5: 0x00c0, 0x8a6: 0x00c0, 0x8a7: 0x00c0, 0x8a8: 0x00c0, + 0x8aa: 0x00c0, 0x8ab: 0x00c0, 0x8ac: 0x00c0, 0x8ad: 0x00c0, 0x8ae: 0x00c0, 0x8af: 0x00c0, + 0x8b0: 0x00c0, 0x8b2: 0x00c0, + 0x8b6: 0x00c0, 0x8b7: 0x00c0, 0x8b8: 0x00c0, 0x8b9: 0x00c0, + 0x8bc: 0x00c3, 0x8bd: 0x00c0, 0x8be: 0x00c0, 0x8bf: 0x00c0, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x00c0, 0x8c1: 0x00c3, 0x8c2: 0x00c3, 0x8c3: 0x00c3, 0x8c4: 0x00c3, + 0x8c7: 0x00c0, 0x8c8: 0x00c0, 0x8cb: 0x00c0, + 0x8cc: 0x00c0, 0x8cd: 0x00c6, 0x8ce: 0x00c0, + 0x8d7: 0x00c0, + 0x8dc: 0x0080, 0x8dd: 0x0080, + 0x8df: 0x0080, 0x8e0: 0x00c0, 0x8e1: 0x00c0, 0x8e2: 0x00c3, 0x8e3: 0x00c3, + 0x8e6: 0x00c0, 0x8e7: 0x00c0, 0x8e8: 0x00c0, 0x8e9: 0x00c0, + 0x8ea: 0x00c0, 0x8eb: 0x00c0, 0x8ec: 0x00c0, 0x8ed: 0x00c0, 0x8ee: 0x00c0, 0x8ef: 0x00c0, + 0x8f0: 0x00c0, 0x8f1: 0x00c0, 0x8f2: 0x0080, 0x8f3: 0x0080, 0x8f4: 0x0080, 0x8f5: 0x0080, + 0x8f6: 0x0080, 0x8f7: 0x0080, 0x8f8: 0x0080, 0x8f9: 0x0080, 0x8fa: 0x0080, 0x8fb: 0x0080, + 0x8fc: 0x00c0, 0x8fd: 0x0080, 0x8fe: 0x00c3, + // Block 0x24, offset 0x900 + 0x901: 0x00c3, 0x902: 0x00c3, 0x903: 0x00c0, 0x905: 0x00c0, + 0x906: 0x00c0, 0x907: 0x00c0, 0x908: 0x00c0, 0x909: 0x00c0, 0x90a: 0x00c0, + 0x90f: 0x00c0, 0x910: 0x00c0, + 0x913: 0x00c0, 0x914: 0x00c0, 0x915: 0x00c0, 0x916: 0x00c0, 0x917: 0x00c0, + 0x918: 0x00c0, 0x919: 0x00c0, 0x91a: 0x00c0, 0x91b: 0x00c0, 0x91c: 0x00c0, 0x91d: 0x00c0, + 0x91e: 0x00c0, 0x91f: 0x00c0, 0x920: 0x00c0, 0x921: 0x00c0, 0x922: 0x00c0, 0x923: 0x00c0, + 0x924: 0x00c0, 0x925: 0x00c0, 0x926: 0x00c0, 0x927: 0x00c0, 0x928: 0x00c0, + 0x92a: 0x00c0, 0x92b: 0x00c0, 0x92c: 0x00c0, 0x92d: 0x00c0, 0x92e: 0x00c0, 0x92f: 0x00c0, + 0x930: 0x00c0, 0x932: 0x00c0, 0x933: 0x0080, 0x935: 0x00c0, + 0x936: 0x0080, 0x938: 0x00c0, 0x939: 0x00c0, + 0x93c: 0x00c3, 0x93e: 0x00c0, 0x93f: 0x00c0, + // Block 0x25, offset 0x940 + 0x940: 0x00c0, 0x941: 0x00c3, 0x942: 0x00c3, + 0x947: 0x00c3, 0x948: 0x00c3, 0x94b: 0x00c3, + 0x94c: 0x00c3, 0x94d: 0x00c6, 0x951: 0x00c3, + 0x959: 0x0080, 0x95a: 0x0080, 0x95b: 0x0080, 0x95c: 0x00c0, + 0x95e: 0x0080, + 0x966: 0x00c0, 0x967: 0x00c0, 0x968: 0x00c0, 0x969: 0x00c0, + 0x96a: 0x00c0, 0x96b: 0x00c0, 0x96c: 0x00c0, 0x96d: 0x00c0, 0x96e: 0x00c0, 0x96f: 0x00c0, + 0x970: 0x00c3, 0x971: 0x00c3, 0x972: 0x00c0, 0x973: 0x00c0, 0x974: 0x00c0, 0x975: 0x00c3, + 0x976: 0x0080, + // Block 0x26, offset 0x980 + 0x981: 0x00c3, 0x982: 0x00c3, 0x983: 0x00c0, 0x985: 0x00c0, + 0x986: 0x00c0, 0x987: 0x00c0, 0x988: 0x00c0, 0x989: 0x00c0, 0x98a: 0x00c0, 0x98b: 0x00c0, + 0x98c: 0x00c0, 0x98d: 0x00c0, 0x98f: 0x00c0, 0x990: 0x00c0, 0x991: 0x00c0, + 0x993: 0x00c0, 0x994: 0x00c0, 0x995: 0x00c0, 0x996: 0x00c0, 0x997: 0x00c0, + 0x998: 0x00c0, 0x999: 0x00c0, 0x99a: 0x00c0, 0x99b: 0x00c0, 0x99c: 0x00c0, 0x99d: 0x00c0, + 0x99e: 0x00c0, 0x99f: 0x00c0, 0x9a0: 0x00c0, 0x9a1: 0x00c0, 0x9a2: 0x00c0, 0x9a3: 0x00c0, + 0x9a4: 0x00c0, 0x9a5: 0x00c0, 0x9a6: 0x00c0, 0x9a7: 0x00c0, 0x9a8: 0x00c0, + 0x9aa: 0x00c0, 0x9ab: 0x00c0, 0x9ac: 0x00c0, 0x9ad: 0x00c0, 0x9ae: 0x00c0, 0x9af: 0x00c0, + 0x9b0: 0x00c0, 0x9b2: 0x00c0, 0x9b3: 0x00c0, 0x9b5: 0x00c0, + 0x9b6: 0x00c0, 0x9b7: 0x00c0, 0x9b8: 0x00c0, 0x9b9: 0x00c0, + 0x9bc: 0x00c3, 0x9bd: 0x00c0, 0x9be: 0x00c0, 0x9bf: 0x00c0, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x00c0, 0x9c1: 0x00c3, 0x9c2: 0x00c3, 0x9c3: 0x00c3, 0x9c4: 0x00c3, 0x9c5: 0x00c3, + 0x9c7: 0x00c3, 0x9c8: 0x00c3, 0x9c9: 0x00c0, 0x9cb: 0x00c0, + 0x9cc: 0x00c0, 0x9cd: 0x00c6, 0x9d0: 0x00c0, + 0x9e0: 0x00c0, 0x9e1: 0x00c0, 0x9e2: 0x00c3, 0x9e3: 0x00c3, + 0x9e6: 0x00c0, 0x9e7: 0x00c0, 0x9e8: 0x00c0, 0x9e9: 0x00c0, + 0x9ea: 0x00c0, 0x9eb: 0x00c0, 0x9ec: 0x00c0, 0x9ed: 0x00c0, 0x9ee: 0x00c0, 0x9ef: 0x00c0, + 0x9f0: 0x0080, 0x9f1: 0x0080, + 0x9f9: 0x00c0, 0x9fa: 0x00c3, 0x9fb: 0x00c3, + 0x9fc: 0x00c3, 0x9fd: 0x00c3, 0x9fe: 0x00c3, 0x9ff: 0x00c3, + // Block 0x28, offset 0xa00 + 0xa01: 0x00c3, 0xa02: 0x00c0, 0xa03: 0x00c0, 0xa05: 0x00c0, + 0xa06: 0x00c0, 0xa07: 0x00c0, 0xa08: 0x00c0, 0xa09: 0x00c0, 0xa0a: 0x00c0, 0xa0b: 0x00c0, + 0xa0c: 0x00c0, 0xa0f: 0x00c0, 0xa10: 0x00c0, + 0xa13: 0x00c0, 0xa14: 0x00c0, 0xa15: 0x00c0, 0xa16: 0x00c0, 0xa17: 0x00c0, + 0xa18: 0x00c0, 0xa19: 0x00c0, 0xa1a: 0x00c0, 0xa1b: 0x00c0, 0xa1c: 0x00c0, 0xa1d: 0x00c0, + 0xa1e: 0x00c0, 0xa1f: 0x00c0, 0xa20: 0x00c0, 0xa21: 0x00c0, 0xa22: 0x00c0, 0xa23: 0x00c0, + 0xa24: 0x00c0, 0xa25: 0x00c0, 0xa26: 0x00c0, 0xa27: 0x00c0, 0xa28: 0x00c0, + 0xa2a: 0x00c0, 0xa2b: 0x00c0, 0xa2c: 0x00c0, 0xa2d: 0x00c0, 0xa2e: 0x00c0, 0xa2f: 0x00c0, + 0xa30: 0x00c0, 0xa32: 0x00c0, 0xa33: 0x00c0, 0xa35: 0x00c0, + 0xa36: 0x00c0, 0xa37: 0x00c0, 0xa38: 0x00c0, 0xa39: 0x00c0, + 0xa3c: 0x00c3, 0xa3d: 0x00c0, 0xa3e: 0x00c0, 0xa3f: 0x00c3, + // Block 0x29, offset 0xa40 + 0xa40: 0x00c0, 0xa41: 0x00c3, 0xa42: 0x00c3, 0xa43: 0x00c3, 0xa44: 0x00c3, + 0xa47: 0x00c0, 0xa48: 0x00c0, 0xa4b: 0x00c0, + 0xa4c: 0x00c0, 0xa4d: 0x00c6, + 0xa56: 0x00c3, 0xa57: 0x00c0, + 0xa5c: 0x0080, 0xa5d: 0x0080, + 0xa5f: 0x00c0, 0xa60: 0x00c0, 0xa61: 0x00c0, 0xa62: 0x00c3, 0xa63: 0x00c3, + 0xa66: 0x00c0, 0xa67: 0x00c0, 0xa68: 0x00c0, 0xa69: 0x00c0, + 0xa6a: 0x00c0, 0xa6b: 0x00c0, 0xa6c: 0x00c0, 0xa6d: 0x00c0, 0xa6e: 0x00c0, 0xa6f: 0x00c0, + 0xa70: 0x0080, 0xa71: 0x00c0, 0xa72: 0x0080, 0xa73: 0x0080, 0xa74: 0x0080, 0xa75: 0x0080, + 0xa76: 0x0080, 0xa77: 0x0080, + // Block 0x2a, offset 0xa80 + 0xa82: 0x00c3, 0xa83: 0x00c0, 0xa85: 0x00c0, + 0xa86: 0x00c0, 0xa87: 0x00c0, 0xa88: 0x00c0, 0xa89: 0x00c0, 0xa8a: 0x00c0, + 0xa8e: 0x00c0, 0xa8f: 0x00c0, 0xa90: 0x00c0, + 0xa92: 0x00c0, 0xa93: 0x00c0, 0xa94: 0x00c0, 0xa95: 0x00c0, + 0xa99: 0x00c0, 0xa9a: 0x00c0, 0xa9c: 0x00c0, + 0xa9e: 0x00c0, 0xa9f: 0x00c0, 0xaa3: 0x00c0, + 0xaa4: 0x00c0, 0xaa8: 0x00c0, 0xaa9: 0x00c0, + 0xaaa: 0x00c0, 0xaae: 0x00c0, 0xaaf: 0x00c0, + 0xab0: 0x00c0, 0xab1: 0x00c0, 0xab2: 0x00c0, 0xab3: 0x00c0, 0xab4: 0x00c0, 0xab5: 0x00c0, + 0xab6: 0x00c0, 0xab7: 0x00c0, 0xab8: 0x00c0, 0xab9: 0x00c0, + 0xabe: 0x00c0, 0xabf: 0x00c0, + // Block 0x2b, offset 0xac0 + 0xac0: 0x00c3, 0xac1: 0x00c0, 0xac2: 0x00c0, + 0xac6: 0x00c0, 0xac7: 0x00c0, 0xac8: 0x00c0, 0xaca: 0x00c0, 0xacb: 0x00c0, + 0xacc: 0x00c0, 0xacd: 0x00c6, 0xad0: 0x00c0, + 0xad7: 0x00c0, + 0xae6: 0x00c0, 0xae7: 0x00c0, 0xae8: 0x00c0, 0xae9: 0x00c0, + 0xaea: 0x00c0, 0xaeb: 0x00c0, 0xaec: 0x00c0, 0xaed: 0x00c0, 0xaee: 0x00c0, 0xaef: 0x00c0, + 0xaf0: 0x0080, 0xaf1: 0x0080, 0xaf2: 0x0080, 0xaf3: 0x0080, 0xaf4: 0x0080, 0xaf5: 0x0080, + 0xaf6: 0x0080, 0xaf7: 0x0080, 0xaf8: 0x0080, 0xaf9: 0x0080, 0xafa: 0x0080, + // Block 0x2c, offset 0xb00 + 0xb00: 0x00c3, 0xb01: 0x00c0, 0xb02: 0x00c0, 0xb03: 0x00c0, 0xb04: 0x00c3, 0xb05: 0x00c0, + 0xb06: 0x00c0, 0xb07: 0x00c0, 0xb08: 0x00c0, 0xb09: 0x00c0, 0xb0a: 0x00c0, 0xb0b: 0x00c0, + 0xb0c: 0x00c0, 0xb0e: 0x00c0, 0xb0f: 0x00c0, 0xb10: 0x00c0, + 0xb12: 0x00c0, 0xb13: 0x00c0, 0xb14: 0x00c0, 0xb15: 0x00c0, 0xb16: 0x00c0, 0xb17: 0x00c0, + 0xb18: 0x00c0, 0xb19: 0x00c0, 0xb1a: 0x00c0, 0xb1b: 0x00c0, 0xb1c: 0x00c0, 0xb1d: 0x00c0, + 0xb1e: 0x00c0, 0xb1f: 0x00c0, 0xb20: 0x00c0, 0xb21: 0x00c0, 0xb22: 0x00c0, 0xb23: 0x00c0, + 0xb24: 0x00c0, 0xb25: 0x00c0, 0xb26: 0x00c0, 0xb27: 0x00c0, 0xb28: 0x00c0, + 0xb2a: 0x00c0, 0xb2b: 0x00c0, 0xb2c: 0x00c0, 0xb2d: 0x00c0, 0xb2e: 0x00c0, 0xb2f: 0x00c0, + 0xb30: 0x00c0, 0xb31: 0x00c0, 0xb32: 0x00c0, 0xb33: 0x00c0, 0xb34: 0x00c0, 0xb35: 0x00c0, + 0xb36: 0x00c0, 0xb37: 0x00c0, 0xb38: 0x00c0, 0xb39: 0x00c0, + 0xb3d: 0x00c0, 0xb3e: 0x00c3, 0xb3f: 0x00c3, + // Block 0x2d, offset 0xb40 + 0xb40: 0x00c3, 0xb41: 0x00c0, 0xb42: 0x00c0, 0xb43: 0x00c0, 0xb44: 0x00c0, + 0xb46: 0x00c3, 0xb47: 0x00c3, 0xb48: 0x00c3, 0xb4a: 0x00c3, 0xb4b: 0x00c3, + 0xb4c: 0x00c3, 0xb4d: 0x00c6, + 0xb55: 0x00c3, 0xb56: 0x00c3, + 0xb58: 0x00c0, 0xb59: 0x00c0, 0xb5a: 0x00c0, + 0xb60: 0x00c0, 0xb61: 0x00c0, 0xb62: 0x00c3, 0xb63: 0x00c3, + 0xb66: 0x00c0, 0xb67: 0x00c0, 0xb68: 0x00c0, 0xb69: 0x00c0, + 0xb6a: 0x00c0, 0xb6b: 0x00c0, 0xb6c: 0x00c0, 0xb6d: 0x00c0, 0xb6e: 0x00c0, 0xb6f: 0x00c0, + 0xb78: 0x0080, 0xb79: 0x0080, 0xb7a: 0x0080, 0xb7b: 0x0080, + 0xb7c: 0x0080, 0xb7d: 0x0080, 0xb7e: 0x0080, 0xb7f: 0x0080, + // Block 0x2e, offset 0xb80 + 0xb80: 0x00c0, 0xb81: 0x00c3, 0xb82: 0x00c0, 0xb83: 0x00c0, 0xb84: 0x0080, 0xb85: 0x00c0, + 0xb86: 0x00c0, 0xb87: 0x00c0, 0xb88: 0x00c0, 0xb89: 0x00c0, 0xb8a: 0x00c0, 0xb8b: 0x00c0, + 0xb8c: 0x00c0, 0xb8e: 0x00c0, 0xb8f: 0x00c0, 0xb90: 0x00c0, + 0xb92: 0x00c0, 0xb93: 0x00c0, 0xb94: 0x00c0, 0xb95: 0x00c0, 0xb96: 0x00c0, 0xb97: 0x00c0, + 0xb98: 0x00c0, 0xb99: 0x00c0, 0xb9a: 0x00c0, 0xb9b: 0x00c0, 0xb9c: 0x00c0, 0xb9d: 0x00c0, + 0xb9e: 0x00c0, 0xb9f: 0x00c0, 0xba0: 0x00c0, 0xba1: 0x00c0, 0xba2: 0x00c0, 0xba3: 0x00c0, + 0xba4: 0x00c0, 0xba5: 0x00c0, 0xba6: 0x00c0, 0xba7: 0x00c0, 0xba8: 0x00c0, + 0xbaa: 0x00c0, 0xbab: 0x00c0, 0xbac: 0x00c0, 0xbad: 0x00c0, 0xbae: 0x00c0, 0xbaf: 0x00c0, + 0xbb0: 0x00c0, 0xbb1: 0x00c0, 0xbb2: 0x00c0, 0xbb3: 0x00c0, 0xbb5: 0x00c0, + 0xbb6: 0x00c0, 0xbb7: 0x00c0, 0xbb8: 0x00c0, 0xbb9: 0x00c0, + 0xbbc: 0x00c3, 0xbbd: 0x00c0, 0xbbe: 0x00c0, 0xbbf: 0x00c3, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x00c0, 0xbc1: 0x00c0, 0xbc2: 0x00c0, 0xbc3: 0x00c0, 0xbc4: 0x00c0, + 0xbc6: 0x00c3, 0xbc7: 0x00c0, 0xbc8: 0x00c0, 0xbca: 0x00c0, 0xbcb: 0x00c0, + 0xbcc: 0x00c3, 0xbcd: 0x00c6, + 0xbd5: 0x00c0, 0xbd6: 0x00c0, + 0xbde: 0x00c0, 0xbe0: 0x00c0, 0xbe1: 0x00c0, 0xbe2: 0x00c3, 0xbe3: 0x00c3, + 0xbe6: 0x00c0, 0xbe7: 0x00c0, 0xbe8: 0x00c0, 0xbe9: 0x00c0, + 0xbea: 0x00c0, 0xbeb: 0x00c0, 0xbec: 0x00c0, 0xbed: 0x00c0, 0xbee: 0x00c0, 0xbef: 0x00c0, + 0xbf1: 0x00c0, 0xbf2: 0x00c0, + // Block 0x30, offset 0xc00 + 0xc00: 0x00c3, 0xc01: 0x00c3, 0xc02: 0x00c0, 0xc03: 0x00c0, 0xc05: 0x00c0, + 0xc06: 0x00c0, 0xc07: 0x00c0, 0xc08: 0x00c0, 0xc09: 0x00c0, 0xc0a: 0x00c0, 0xc0b: 0x00c0, + 0xc0c: 0x00c0, 0xc0e: 0x00c0, 0xc0f: 0x00c0, 0xc10: 0x00c0, + 0xc12: 0x00c0, 0xc13: 0x00c0, 0xc14: 0x00c0, 0xc15: 0x00c0, 0xc16: 0x00c0, 0xc17: 0x00c0, + 0xc18: 0x00c0, 0xc19: 0x00c0, 0xc1a: 0x00c0, 0xc1b: 0x00c0, 0xc1c: 0x00c0, 0xc1d: 0x00c0, + 0xc1e: 0x00c0, 0xc1f: 0x00c0, 0xc20: 0x00c0, 0xc21: 0x00c0, 0xc22: 0x00c0, 0xc23: 0x00c0, + 0xc24: 0x00c0, 0xc25: 0x00c0, 0xc26: 0x00c0, 0xc27: 0x00c0, 0xc28: 0x00c0, 0xc29: 0x00c0, + 0xc2a: 0x00c0, 0xc2b: 0x00c0, 0xc2c: 0x00c0, 0xc2d: 0x00c0, 0xc2e: 0x00c0, 0xc2f: 0x00c0, + 0xc30: 0x00c0, 0xc31: 0x00c0, 0xc32: 0x00c0, 0xc33: 0x00c0, 0xc34: 0x00c0, 0xc35: 0x00c0, + 0xc36: 0x00c0, 0xc37: 0x00c0, 0xc38: 0x00c0, 0xc39: 0x00c0, 0xc3a: 0x00c0, 0xc3b: 0x00c6, + 0xc3c: 0x00c6, 0xc3d: 0x00c0, 0xc3e: 0x00c0, 0xc3f: 0x00c0, + // Block 0x31, offset 0xc40 + 0xc40: 0x00c0, 0xc41: 0x00c3, 0xc42: 0x00c3, 0xc43: 0x00c3, 0xc44: 0x00c3, + 0xc46: 0x00c0, 0xc47: 0x00c0, 0xc48: 0x00c0, 0xc4a: 0x00c0, 0xc4b: 0x00c0, + 0xc4c: 0x00c0, 0xc4d: 0x00c6, 0xc4e: 0x00c0, 0xc4f: 0x0080, + 0xc54: 0x00c0, 0xc55: 0x00c0, 0xc56: 0x00c0, 0xc57: 0x00c0, + 0xc58: 0x0080, 0xc59: 0x0080, 0xc5a: 0x0080, 0xc5b: 0x0080, 0xc5c: 0x0080, 0xc5d: 0x0080, + 0xc5e: 0x0080, 0xc5f: 0x00c0, 0xc60: 0x00c0, 0xc61: 0x00c0, 0xc62: 0x00c3, 0xc63: 0x00c3, + 0xc66: 0x00c0, 0xc67: 0x00c0, 0xc68: 0x00c0, 0xc69: 0x00c0, + 0xc6a: 0x00c0, 0xc6b: 0x00c0, 0xc6c: 0x00c0, 0xc6d: 0x00c0, 0xc6e: 0x00c0, 0xc6f: 0x00c0, + 0xc70: 0x0080, 0xc71: 0x0080, 0xc72: 0x0080, 0xc73: 0x0080, 0xc74: 0x0080, 0xc75: 0x0080, + 0xc76: 0x0080, 0xc77: 0x0080, 0xc78: 0x0080, 0xc79: 0x0080, 0xc7a: 0x00c0, 0xc7b: 0x00c0, + 0xc7c: 0x00c0, 0xc7d: 0x00c0, 0xc7e: 0x00c0, 0xc7f: 0x00c0, + // Block 0x32, offset 0xc80 + 0xc82: 0x00c0, 0xc83: 0x00c0, 0xc85: 0x00c0, + 0xc86: 0x00c0, 0xc87: 0x00c0, 0xc88: 0x00c0, 0xc89: 0x00c0, 0xc8a: 0x00c0, 0xc8b: 0x00c0, + 0xc8c: 0x00c0, 0xc8d: 0x00c0, 0xc8e: 0x00c0, 0xc8f: 0x00c0, 0xc90: 0x00c0, 0xc91: 0x00c0, + 0xc92: 0x00c0, 0xc93: 0x00c0, 0xc94: 0x00c0, 0xc95: 0x00c0, 0xc96: 0x00c0, + 0xc9a: 0x00c0, 0xc9b: 0x00c0, 0xc9c: 0x00c0, 0xc9d: 0x00c0, + 0xc9e: 0x00c0, 0xc9f: 0x00c0, 0xca0: 0x00c0, 0xca1: 0x00c0, 0xca2: 0x00c0, 0xca3: 0x00c0, + 0xca4: 0x00c0, 0xca5: 0x00c0, 0xca6: 0x00c0, 0xca7: 0x00c0, 0xca8: 0x00c0, 0xca9: 0x00c0, + 0xcaa: 0x00c0, 0xcab: 0x00c0, 0xcac: 0x00c0, 0xcad: 0x00c0, 0xcae: 0x00c0, 0xcaf: 0x00c0, + 0xcb0: 0x00c0, 0xcb1: 0x00c0, 0xcb3: 0x00c0, 0xcb4: 0x00c0, 0xcb5: 0x00c0, + 0xcb6: 0x00c0, 0xcb7: 0x00c0, 0xcb8: 0x00c0, 0xcb9: 0x00c0, 0xcba: 0x00c0, 0xcbb: 0x00c0, + 0xcbd: 0x00c0, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x00c0, 0xcc1: 0x00c0, 0xcc2: 0x00c0, 0xcc3: 0x00c0, 0xcc4: 0x00c0, 0xcc5: 0x00c0, + 0xcc6: 0x00c0, 0xcca: 0x00c6, + 0xccf: 0x00c0, 0xcd0: 0x00c0, 0xcd1: 0x00c0, + 0xcd2: 0x00c3, 0xcd3: 0x00c3, 0xcd4: 0x00c3, 0xcd6: 0x00c3, + 0xcd8: 0x00c0, 0xcd9: 0x00c0, 0xcda: 0x00c0, 0xcdb: 0x00c0, 0xcdc: 0x00c0, 0xcdd: 0x00c0, + 0xcde: 0x00c0, 0xcdf: 0x00c0, + 0xce6: 0x00c0, 0xce7: 0x00c0, 0xce8: 0x00c0, 0xce9: 0x00c0, + 0xcea: 0x00c0, 0xceb: 0x00c0, 0xcec: 0x00c0, 0xced: 0x00c0, 0xcee: 0x00c0, 0xcef: 0x00c0, + 0xcf2: 0x00c0, 0xcf3: 0x00c0, 0xcf4: 0x0080, + // Block 0x34, offset 0xd00 + 0xd01: 0x00c0, 0xd02: 0x00c0, 0xd03: 0x00c0, 0xd04: 0x00c0, 0xd05: 0x00c0, + 0xd06: 0x00c0, 0xd07: 0x00c0, 0xd08: 0x00c0, 0xd09: 0x00c0, 0xd0a: 0x00c0, 0xd0b: 0x00c0, + 0xd0c: 0x00c0, 0xd0d: 0x00c0, 0xd0e: 0x00c0, 0xd0f: 0x00c0, 0xd10: 0x00c0, 0xd11: 0x00c0, + 0xd12: 0x00c0, 0xd13: 0x00c0, 0xd14: 0x00c0, 0xd15: 0x00c0, 0xd16: 0x00c0, 0xd17: 0x00c0, + 0xd18: 0x00c0, 0xd19: 0x00c0, 0xd1a: 0x00c0, 0xd1b: 0x00c0, 0xd1c: 0x00c0, 0xd1d: 0x00c0, + 0xd1e: 0x00c0, 0xd1f: 0x00c0, 0xd20: 0x00c0, 0xd21: 0x00c0, 0xd22: 0x00c0, 0xd23: 0x00c0, + 0xd24: 0x00c0, 0xd25: 0x00c0, 0xd26: 0x00c0, 0xd27: 0x00c0, 0xd28: 0x00c0, 0xd29: 0x00c0, + 0xd2a: 0x00c0, 0xd2b: 0x00c0, 0xd2c: 0x00c0, 0xd2d: 0x00c0, 0xd2e: 0x00c0, 0xd2f: 0x00c0, + 0xd30: 0x00c0, 0xd31: 0x00c3, 0xd32: 0x00c0, 0xd33: 0x0080, 0xd34: 0x00c3, 0xd35: 0x00c3, + 0xd36: 0x00c3, 0xd37: 0x00c3, 0xd38: 0x00c3, 0xd39: 0x00c3, 0xd3a: 0x00c6, + 0xd3f: 0x0080, + // Block 0x35, offset 0xd40 + 0xd40: 0x00c0, 0xd41: 0x00c0, 0xd42: 0x00c0, 0xd43: 0x00c0, 0xd44: 0x00c0, 0xd45: 0x00c0, + 0xd46: 0x00c0, 0xd47: 0x00c3, 0xd48: 0x00c3, 0xd49: 0x00c3, 0xd4a: 0x00c3, 0xd4b: 0x00c3, + 0xd4c: 0x00c3, 0xd4d: 0x00c3, 0xd4e: 0x00c3, 0xd4f: 0x0080, 0xd50: 0x00c0, 0xd51: 0x00c0, + 0xd52: 0x00c0, 0xd53: 0x00c0, 0xd54: 0x00c0, 0xd55: 0x00c0, 0xd56: 0x00c0, 0xd57: 0x00c0, + 0xd58: 0x00c0, 0xd59: 0x00c0, 0xd5a: 0x0080, 0xd5b: 0x0080, + // Block 0x36, offset 0xd80 + 0xd81: 0x00c0, 0xd82: 0x00c0, 0xd84: 0x00c0, + 0xd87: 0x00c0, 0xd88: 0x00c0, 0xd8a: 0x00c0, + 0xd8d: 0x00c0, + 0xd94: 0x00c0, 0xd95: 0x00c0, 0xd96: 0x00c0, 0xd97: 0x00c0, + 0xd99: 0x00c0, 0xd9a: 0x00c0, 0xd9b: 0x00c0, 0xd9c: 0x00c0, 0xd9d: 0x00c0, + 0xd9e: 0x00c0, 0xd9f: 0x00c0, 0xda1: 0x00c0, 0xda2: 0x00c0, 0xda3: 0x00c0, + 0xda5: 0x00c0, 0xda7: 0x00c0, + 0xdaa: 0x00c0, 0xdab: 0x00c0, 0xdad: 0x00c0, 0xdae: 0x00c0, 0xdaf: 0x00c0, + 0xdb0: 0x00c0, 0xdb1: 0x00c3, 0xdb2: 0x00c0, 0xdb3: 0x0080, 0xdb4: 0x00c3, 0xdb5: 0x00c3, + 0xdb6: 0x00c3, 0xdb7: 0x00c3, 0xdb8: 0x00c3, 0xdb9: 0x00c3, 0xdbb: 0x00c3, + 0xdbc: 0x00c3, 0xdbd: 0x00c0, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x00c0, 0xdc1: 0x00c0, 0xdc2: 0x00c0, 0xdc3: 0x00c0, 0xdc4: 0x00c0, + 0xdc6: 0x00c0, 0xdc8: 0x00c3, 0xdc9: 0x00c3, 0xdca: 0x00c3, 0xdcb: 0x00c3, + 0xdcc: 0x00c3, 0xdcd: 0x00c3, 0xdd0: 0x00c0, 0xdd1: 0x00c0, + 0xdd2: 0x00c0, 0xdd3: 0x00c0, 0xdd4: 0x00c0, 0xdd5: 0x00c0, 0xdd6: 0x00c0, 0xdd7: 0x00c0, + 0xdd8: 0x00c0, 0xdd9: 0x00c0, 0xddc: 0x0080, 0xddd: 0x0080, + 0xdde: 0x00c0, 0xddf: 0x00c0, + // Block 0x38, offset 0xe00 + 0xe00: 0x00c0, 0xe01: 0x0080, 0xe02: 0x0080, 0xe03: 0x0080, 0xe04: 0x0080, 0xe05: 0x0080, + 0xe06: 0x0080, 0xe07: 0x0080, 0xe08: 0x0080, 0xe09: 0x0080, 0xe0a: 0x0080, 0xe0b: 0x00c0, + 0xe0c: 0x0080, 0xe0d: 0x0080, 0xe0e: 0x0080, 0xe0f: 0x0080, 0xe10: 0x0080, 0xe11: 0x0080, + 0xe12: 0x0080, 0xe13: 0x0080, 0xe14: 0x0080, 0xe15: 0x0080, 0xe16: 0x0080, 0xe17: 0x0080, + 0xe18: 0x00c3, 0xe19: 0x00c3, 0xe1a: 0x0080, 0xe1b: 0x0080, 0xe1c: 0x0080, 0xe1d: 0x0080, + 0xe1e: 0x0080, 0xe1f: 0x0080, 0xe20: 0x00c0, 0xe21: 0x00c0, 0xe22: 0x00c0, 0xe23: 0x00c0, + 0xe24: 0x00c0, 0xe25: 0x00c0, 0xe26: 0x00c0, 0xe27: 0x00c0, 0xe28: 0x00c0, 0xe29: 0x00c0, + 0xe2a: 0x0080, 0xe2b: 0x0080, 0xe2c: 0x0080, 0xe2d: 0x0080, 0xe2e: 0x0080, 0xe2f: 0x0080, + 0xe30: 0x0080, 0xe31: 0x0080, 0xe32: 0x0080, 0xe33: 0x0080, 0xe34: 0x0080, 0xe35: 0x00c3, + 0xe36: 0x0080, 0xe37: 0x00c3, 0xe38: 0x0080, 0xe39: 0x00c3, 0xe3a: 0x0080, 0xe3b: 0x0080, + 0xe3c: 0x0080, 0xe3d: 0x0080, 0xe3e: 0x00c0, 0xe3f: 0x00c0, + // Block 0x39, offset 0xe40 + 0xe40: 0x00c0, 0xe41: 0x00c0, 0xe42: 0x00c0, 0xe43: 0x0080, 0xe44: 0x00c0, 0xe45: 0x00c0, + 0xe46: 0x00c0, 0xe47: 0x00c0, 0xe49: 0x00c0, 0xe4a: 0x00c0, 0xe4b: 0x00c0, + 0xe4c: 0x00c0, 0xe4d: 0x0080, 0xe4e: 0x00c0, 0xe4f: 0x00c0, 0xe50: 0x00c0, 0xe51: 0x00c0, + 0xe52: 0x0080, 0xe53: 0x00c0, 0xe54: 0x00c0, 0xe55: 0x00c0, 0xe56: 0x00c0, 0xe57: 0x0080, + 0xe58: 0x00c0, 0xe59: 0x00c0, 0xe5a: 0x00c0, 0xe5b: 0x00c0, 0xe5c: 0x0080, 0xe5d: 0x00c0, + 0xe5e: 0x00c0, 0xe5f: 0x00c0, 0xe60: 0x00c0, 0xe61: 0x00c0, 0xe62: 0x00c0, 0xe63: 0x00c0, + 0xe64: 0x00c0, 0xe65: 0x00c0, 0xe66: 0x00c0, 0xe67: 0x00c0, 0xe68: 0x00c0, 0xe69: 0x0080, + 0xe6a: 0x00c0, 0xe6b: 0x00c0, 0xe6c: 0x00c0, + 0xe71: 0x00c3, 0xe72: 0x00c3, 0xe73: 0x0083, 0xe74: 0x00c3, 0xe75: 0x0083, + 0xe76: 0x0083, 0xe77: 0x0083, 0xe78: 0x0083, 0xe79: 0x0083, 0xe7a: 0x00c3, 0xe7b: 0x00c3, + 0xe7c: 0x00c3, 0xe7d: 0x00c3, 0xe7e: 0x00c3, 0xe7f: 0x00c0, + // Block 0x3a, offset 0xe80 + 0xe80: 0x00c3, 0xe81: 0x0083, 0xe82: 0x00c3, 0xe83: 0x00c3, 0xe84: 0x00c6, 0xe85: 0x0080, + 0xe86: 0x00c3, 0xe87: 0x00c3, 0xe88: 0x00c0, 0xe89: 0x00c0, 0xe8a: 0x00c0, 0xe8b: 0x00c0, + 0xe8c: 0x00c0, 0xe8d: 0x00c3, 0xe8e: 0x00c3, 0xe8f: 0x00c3, 0xe90: 0x00c3, 0xe91: 0x00c3, + 0xe92: 0x00c3, 0xe93: 0x0083, 0xe94: 0x00c3, 0xe95: 0x00c3, 0xe96: 0x00c3, 0xe97: 0x00c3, + 0xe99: 0x00c3, 0xe9a: 0x00c3, 0xe9b: 0x00c3, 0xe9c: 0x00c3, 0xe9d: 0x0083, + 0xe9e: 0x00c3, 0xe9f: 0x00c3, 0xea0: 0x00c3, 0xea1: 0x00c3, 0xea2: 0x0083, 0xea3: 0x00c3, + 0xea4: 0x00c3, 0xea5: 0x00c3, 0xea6: 0x00c3, 0xea7: 0x0083, 0xea8: 0x00c3, 0xea9: 0x00c3, + 0xeaa: 0x00c3, 0xeab: 0x00c3, 0xeac: 0x0083, 0xead: 0x00c3, 0xeae: 0x00c3, 0xeaf: 0x00c3, + 0xeb0: 0x00c3, 0xeb1: 0x00c3, 0xeb2: 0x00c3, 0xeb3: 0x00c3, 0xeb4: 0x00c3, 0xeb5: 0x00c3, + 0xeb6: 0x00c3, 0xeb7: 0x00c3, 0xeb8: 0x00c3, 0xeb9: 0x0083, 0xeba: 0x00c3, 0xebb: 0x00c3, + 0xebc: 0x00c3, 0xebe: 0x0080, 0xebf: 0x0080, + // Block 0x3b, offset 0xec0 + 0xec0: 0x0080, 0xec1: 0x0080, 0xec2: 0x0080, 0xec3: 0x0080, 0xec4: 0x0080, 0xec5: 0x0080, + 0xec6: 0x00c3, 0xec7: 0x0080, 0xec8: 0x0080, 0xec9: 0x0080, 0xeca: 0x0080, 0xecb: 0x0080, + 0xecc: 0x0080, 0xece: 0x0080, 0xecf: 0x0080, 0xed0: 0x0080, 0xed1: 0x0080, + 0xed2: 0x0080, 0xed3: 0x0080, 0xed4: 0x0080, 0xed5: 0x0080, 0xed6: 0x0080, 0xed7: 0x0080, + 0xed8: 0x0080, 0xed9: 0x0080, 0xeda: 0x0080, + // Block 0x3c, offset 0xf00 + 0xf00: 0x00c0, 0xf01: 0x00c0, 0xf02: 0x00c0, 0xf03: 0x00c0, 0xf04: 0x00c0, 0xf05: 0x00c0, + 0xf06: 0x00c0, 0xf07: 0x00c0, 0xf08: 0x00c0, 0xf09: 0x00c0, 0xf0a: 0x00c0, 0xf0b: 0x00c0, + 0xf0c: 0x00c0, 0xf0d: 0x00c0, 0xf0e: 0x00c0, 0xf0f: 0x00c0, 0xf10: 0x00c0, 0xf11: 0x00c0, + 0xf12: 0x00c0, 0xf13: 0x00c0, 0xf14: 0x00c0, 0xf15: 0x00c0, 0xf16: 0x00c0, 0xf17: 0x00c0, + 0xf18: 0x00c0, 0xf19: 0x00c0, 0xf1a: 0x00c0, 0xf1b: 0x00c0, 0xf1c: 0x00c0, 0xf1d: 0x00c0, + 0xf1e: 0x00c0, 0xf1f: 0x00c0, 0xf20: 0x00c0, 0xf21: 0x00c0, 0xf22: 0x00c0, 0xf23: 0x00c0, + 0xf24: 0x00c0, 0xf25: 0x00c0, 0xf26: 0x00c0, 0xf27: 0x00c0, 0xf28: 0x00c0, 0xf29: 0x00c0, + 0xf2a: 0x00c0, 0xf2b: 0x00c0, 0xf2c: 0x00c0, 0xf2d: 0x00c3, 0xf2e: 0x00c3, 0xf2f: 0x00c3, + 0xf30: 0x00c3, 0xf31: 0x00c0, 0xf32: 0x00c3, 0xf33: 0x00c3, 0xf34: 0x00c3, 0xf35: 0x00c3, + 0xf36: 0x00c3, 0xf37: 0x00c3, 0xf38: 0x00c0, 0xf39: 0x00c6, 0xf3a: 0x00c6, 0xf3b: 0x00c0, + 0xf3c: 0x00c0, 0xf3d: 0x00c3, 0xf3e: 0x00c3, 0xf3f: 0x00c0, + // Block 0x3d, offset 0xf40 + 0xf40: 0x00c0, 0xf41: 0x00c0, 0xf42: 0x00c0, 0xf43: 0x00c0, 0xf44: 0x00c0, 0xf45: 0x00c0, + 0xf46: 0x00c0, 0xf47: 0x00c0, 0xf48: 0x00c0, 0xf49: 0x00c0, 0xf4a: 0x0080, 0xf4b: 0x0080, + 0xf4c: 0x0080, 0xf4d: 0x0080, 0xf4e: 0x0080, 0xf4f: 0x0080, 0xf50: 0x00c0, 0xf51: 0x00c0, + 0xf52: 0x00c0, 0xf53: 0x00c0, 0xf54: 0x00c0, 0xf55: 0x00c0, 0xf56: 0x00c0, 0xf57: 0x00c0, + 0xf58: 0x00c3, 0xf59: 0x00c3, 0xf5a: 0x00c0, 0xf5b: 0x00c0, 0xf5c: 0x00c0, 0xf5d: 0x00c0, + 0xf5e: 0x00c3, 0xf5f: 0x00c3, 0xf60: 0x00c3, 0xf61: 0x00c0, 0xf62: 0x00c0, 0xf63: 0x00c0, + 0xf64: 0x00c0, 0xf65: 0x00c0, 0xf66: 0x00c0, 0xf67: 0x00c0, 0xf68: 0x00c0, 0xf69: 0x00c0, + 0xf6a: 0x00c0, 0xf6b: 0x00c0, 0xf6c: 0x00c0, 0xf6d: 0x00c0, 0xf6e: 0x00c0, 0xf6f: 0x00c0, + 0xf70: 0x00c0, 0xf71: 0x00c3, 0xf72: 0x00c3, 0xf73: 0x00c3, 0xf74: 0x00c3, 0xf75: 0x00c0, + 0xf76: 0x00c0, 0xf77: 0x00c0, 0xf78: 0x00c0, 0xf79: 0x00c0, 0xf7a: 0x00c0, 0xf7b: 0x00c0, + 0xf7c: 0x00c0, 0xf7d: 0x00c0, 0xf7e: 0x00c0, 0xf7f: 0x00c0, + // Block 0x3e, offset 0xf80 + 0xf80: 0x00c0, 0xf81: 0x00c0, 0xf82: 0x00c3, 0xf83: 0x00c0, 0xf84: 0x00c0, 0xf85: 0x00c3, + 0xf86: 0x00c3, 0xf87: 0x00c0, 0xf88: 0x00c0, 0xf89: 0x00c0, 0xf8a: 0x00c0, 0xf8b: 0x00c0, + 0xf8c: 0x00c0, 0xf8d: 0x00c3, 0xf8e: 0x00c0, 0xf8f: 0x00c0, 0xf90: 0x00c0, 0xf91: 0x00c0, + 0xf92: 0x00c0, 0xf93: 0x00c0, 0xf94: 0x00c0, 0xf95: 0x00c0, 0xf96: 0x00c0, 0xf97: 0x00c0, + 0xf98: 0x00c0, 0xf99: 0x00c0, 0xf9a: 0x00c0, 0xf9b: 0x00c0, 0xf9c: 0x00c0, 0xf9d: 0x00c3, + 0xf9e: 0x0080, 0xf9f: 0x0080, 0xfa0: 0x00c0, 0xfa1: 0x00c0, 0xfa2: 0x00c0, 0xfa3: 0x00c0, + 0xfa4: 0x00c0, 0xfa5: 0x00c0, 0xfa6: 0x00c0, 0xfa7: 0x00c0, 0xfa8: 0x00c0, 0xfa9: 0x00c0, + 0xfaa: 0x00c0, 0xfab: 0x00c0, 0xfac: 0x00c0, 0xfad: 0x00c0, 0xfae: 0x00c0, 0xfaf: 0x00c0, + 0xfb0: 0x00c0, 0xfb1: 0x00c0, 0xfb2: 0x00c0, 0xfb3: 0x00c0, 0xfb4: 0x00c0, 0xfb5: 0x00c0, + 0xfb6: 0x00c0, 0xfb7: 0x00c0, 0xfb8: 0x00c0, 0xfb9: 0x00c0, 0xfba: 0x00c0, 0xfbb: 0x00c0, + 0xfbc: 0x00c0, 0xfbd: 0x00c0, 0xfbe: 0x00c0, 0xfbf: 0x00c0, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x00c0, 0xfc1: 0x00c0, 0xfc2: 0x00c0, 0xfc3: 0x00c0, 0xfc4: 0x00c0, 0xfc5: 0x00c0, + 0xfc7: 0x00c0, + 0xfcd: 0x00c0, 0xfd0: 0x00c0, 0xfd1: 0x00c0, + 0xfd2: 0x00c0, 0xfd3: 0x00c0, 0xfd4: 0x00c0, 0xfd5: 0x00c0, 0xfd6: 0x00c0, 0xfd7: 0x00c0, + 0xfd8: 0x00c0, 0xfd9: 0x00c0, 0xfda: 0x00c0, 0xfdb: 0x00c0, 0xfdc: 0x00c0, 0xfdd: 0x00c0, + 0xfde: 0x00c0, 0xfdf: 0x00c0, 0xfe0: 0x00c0, 0xfe1: 0x00c0, 0xfe2: 0x00c0, 0xfe3: 0x00c0, + 0xfe4: 0x00c0, 0xfe5: 0x00c0, 0xfe6: 0x00c0, 0xfe7: 0x00c0, 0xfe8: 0x00c0, 0xfe9: 0x00c0, + 0xfea: 0x00c0, 0xfeb: 0x00c0, 0xfec: 0x00c0, 0xfed: 0x00c0, 0xfee: 0x00c0, 0xfef: 0x00c0, + 0xff0: 0x00c0, 0xff1: 0x00c0, 0xff2: 0x00c0, 0xff3: 0x00c0, 0xff4: 0x00c0, 0xff5: 0x00c0, + 0xff6: 0x00c0, 0xff7: 0x00c0, 0xff8: 0x00c0, 0xff9: 0x00c0, 0xffa: 0x00c0, 0xffb: 0x0080, + 0xffc: 0x0080, 0xffd: 0x00c0, 0xffe: 0x00c0, 0xfff: 0x00c0, + // Block 0x40, offset 0x1000 + 0x1000: 0x0040, 0x1001: 0x0040, 0x1002: 0x0040, 0x1003: 0x0040, 0x1004: 0x0040, 0x1005: 0x0040, + 0x1006: 0x0040, 0x1007: 0x0040, 0x1008: 0x0040, 0x1009: 0x0040, 0x100a: 0x0040, 0x100b: 0x0040, + 0x100c: 0x0040, 0x100d: 0x0040, 0x100e: 0x0040, 0x100f: 0x0040, 0x1010: 0x0040, 0x1011: 0x0040, + 0x1012: 0x0040, 0x1013: 0x0040, 0x1014: 0x0040, 0x1015: 0x0040, 0x1016: 0x0040, 0x1017: 0x0040, + 0x1018: 0x0040, 0x1019: 0x0040, 0x101a: 0x0040, 0x101b: 0x0040, 0x101c: 0x0040, 0x101d: 0x0040, + 0x101e: 0x0040, 0x101f: 0x0040, 0x1020: 0x0040, 0x1021: 0x0040, 0x1022: 0x0040, 0x1023: 0x0040, + 0x1024: 0x0040, 0x1025: 0x0040, 0x1026: 0x0040, 0x1027: 0x0040, 0x1028: 0x0040, 0x1029: 0x0040, + 0x102a: 0x0040, 0x102b: 0x0040, 0x102c: 0x0040, 0x102d: 0x0040, 0x102e: 0x0040, 0x102f: 0x0040, + 0x1030: 0x0040, 0x1031: 0x0040, 0x1032: 0x0040, 0x1033: 0x0040, 0x1034: 0x0040, 0x1035: 0x0040, + 0x1036: 0x0040, 0x1037: 0x0040, 0x1038: 0x0040, 0x1039: 0x0040, 0x103a: 0x0040, 0x103b: 0x0040, + 0x103c: 0x0040, 0x103d: 0x0040, 0x103e: 0x0040, 0x103f: 0x0040, + // Block 0x41, offset 0x1040 + 0x1040: 0x00c0, 0x1041: 0x00c0, 0x1042: 0x00c0, 0x1043: 0x00c0, 0x1044: 0x00c0, 0x1045: 0x00c0, + 0x1046: 0x00c0, 0x1047: 0x00c0, 0x1048: 0x00c0, 0x104a: 0x00c0, 0x104b: 0x00c0, + 0x104c: 0x00c0, 0x104d: 0x00c0, 0x1050: 0x00c0, 0x1051: 0x00c0, + 0x1052: 0x00c0, 0x1053: 0x00c0, 0x1054: 0x00c0, 0x1055: 0x00c0, 0x1056: 0x00c0, + 0x1058: 0x00c0, 0x105a: 0x00c0, 0x105b: 0x00c0, 0x105c: 0x00c0, 0x105d: 0x00c0, + 0x1060: 0x00c0, 0x1061: 0x00c0, 0x1062: 0x00c0, 0x1063: 0x00c0, + 0x1064: 0x00c0, 0x1065: 0x00c0, 0x1066: 0x00c0, 0x1067: 0x00c0, 0x1068: 0x00c0, 0x1069: 0x00c0, + 0x106a: 0x00c0, 0x106b: 0x00c0, 0x106c: 0x00c0, 0x106d: 0x00c0, 0x106e: 0x00c0, 0x106f: 0x00c0, + 0x1070: 0x00c0, 0x1071: 0x00c0, 0x1072: 0x00c0, 0x1073: 0x00c0, 0x1074: 0x00c0, 0x1075: 0x00c0, + 0x1076: 0x00c0, 0x1077: 0x00c0, 0x1078: 0x00c0, 0x1079: 0x00c0, 0x107a: 0x00c0, 0x107b: 0x00c0, + 0x107c: 0x00c0, 0x107d: 0x00c0, 0x107e: 0x00c0, 0x107f: 0x00c0, + // Block 0x42, offset 0x1080 + 0x1080: 0x00c0, 0x1081: 0x00c0, 0x1082: 0x00c0, 0x1083: 0x00c0, 0x1084: 0x00c0, 0x1085: 0x00c0, + 0x1086: 0x00c0, 0x1087: 0x00c0, 0x1088: 0x00c0, 0x108a: 0x00c0, 0x108b: 0x00c0, + 0x108c: 0x00c0, 0x108d: 0x00c0, 0x1090: 0x00c0, 0x1091: 0x00c0, + 0x1092: 0x00c0, 0x1093: 0x00c0, 0x1094: 0x00c0, 0x1095: 0x00c0, 0x1096: 0x00c0, 0x1097: 0x00c0, + 0x1098: 0x00c0, 0x1099: 0x00c0, 0x109a: 0x00c0, 0x109b: 0x00c0, 0x109c: 0x00c0, 0x109d: 0x00c0, + 0x109e: 0x00c0, 0x109f: 0x00c0, 0x10a0: 0x00c0, 0x10a1: 0x00c0, 0x10a2: 0x00c0, 0x10a3: 0x00c0, + 0x10a4: 0x00c0, 0x10a5: 0x00c0, 0x10a6: 0x00c0, 0x10a7: 0x00c0, 0x10a8: 0x00c0, 0x10a9: 0x00c0, + 0x10aa: 0x00c0, 0x10ab: 0x00c0, 0x10ac: 0x00c0, 0x10ad: 0x00c0, 0x10ae: 0x00c0, 0x10af: 0x00c0, + 0x10b0: 0x00c0, 0x10b2: 0x00c0, 0x10b3: 0x00c0, 0x10b4: 0x00c0, 0x10b5: 0x00c0, + 0x10b8: 0x00c0, 0x10b9: 0x00c0, 0x10ba: 0x00c0, 0x10bb: 0x00c0, + 0x10bc: 0x00c0, 0x10bd: 0x00c0, 0x10be: 0x00c0, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x00c0, 0x10c2: 0x00c0, 0x10c3: 0x00c0, 0x10c4: 0x00c0, 0x10c5: 0x00c0, + 0x10c8: 0x00c0, 0x10c9: 0x00c0, 0x10ca: 0x00c0, 0x10cb: 0x00c0, + 0x10cc: 0x00c0, 0x10cd: 0x00c0, 0x10ce: 0x00c0, 0x10cf: 0x00c0, 0x10d0: 0x00c0, 0x10d1: 0x00c0, + 0x10d2: 0x00c0, 0x10d3: 0x00c0, 0x10d4: 0x00c0, 0x10d5: 0x00c0, 0x10d6: 0x00c0, + 0x10d8: 0x00c0, 0x10d9: 0x00c0, 0x10da: 0x00c0, 0x10db: 0x00c0, 0x10dc: 0x00c0, 0x10dd: 0x00c0, + 0x10de: 0x00c0, 0x10df: 0x00c0, 0x10e0: 0x00c0, 0x10e1: 0x00c0, 0x10e2: 0x00c0, 0x10e3: 0x00c0, + 0x10e4: 0x00c0, 0x10e5: 0x00c0, 0x10e6: 0x00c0, 0x10e7: 0x00c0, 0x10e8: 0x00c0, 0x10e9: 0x00c0, + 0x10ea: 0x00c0, 0x10eb: 0x00c0, 0x10ec: 0x00c0, 0x10ed: 0x00c0, 0x10ee: 0x00c0, 0x10ef: 0x00c0, + 0x10f0: 0x00c0, 0x10f1: 0x00c0, 0x10f2: 0x00c0, 0x10f3: 0x00c0, 0x10f4: 0x00c0, 0x10f5: 0x00c0, + 0x10f6: 0x00c0, 0x10f7: 0x00c0, 0x10f8: 0x00c0, 0x10f9: 0x00c0, 0x10fa: 0x00c0, 0x10fb: 0x00c0, + 0x10fc: 0x00c0, 0x10fd: 0x00c0, 0x10fe: 0x00c0, 0x10ff: 0x00c0, + // Block 0x44, offset 0x1100 + 0x1100: 0x00c0, 0x1101: 0x00c0, 0x1102: 0x00c0, 0x1103: 0x00c0, 0x1104: 0x00c0, 0x1105: 0x00c0, + 0x1106: 0x00c0, 0x1107: 0x00c0, 0x1108: 0x00c0, 0x1109: 0x00c0, 0x110a: 0x00c0, 0x110b: 0x00c0, + 0x110c: 0x00c0, 0x110d: 0x00c0, 0x110e: 0x00c0, 0x110f: 0x00c0, 0x1110: 0x00c0, + 0x1112: 0x00c0, 0x1113: 0x00c0, 0x1114: 0x00c0, 0x1115: 0x00c0, + 0x1118: 0x00c0, 0x1119: 0x00c0, 0x111a: 0x00c0, 0x111b: 0x00c0, 0x111c: 0x00c0, 0x111d: 0x00c0, + 0x111e: 0x00c0, 0x111f: 0x00c0, 0x1120: 0x00c0, 0x1121: 0x00c0, 0x1122: 0x00c0, 0x1123: 0x00c0, + 0x1124: 0x00c0, 0x1125: 0x00c0, 0x1126: 0x00c0, 0x1127: 0x00c0, 0x1128: 0x00c0, 0x1129: 0x00c0, + 0x112a: 0x00c0, 0x112b: 0x00c0, 0x112c: 0x00c0, 0x112d: 0x00c0, 0x112e: 0x00c0, 0x112f: 0x00c0, + 0x1130: 0x00c0, 0x1131: 0x00c0, 0x1132: 0x00c0, 0x1133: 0x00c0, 0x1134: 0x00c0, 0x1135: 0x00c0, + 0x1136: 0x00c0, 0x1137: 0x00c0, 0x1138: 0x00c0, 0x1139: 0x00c0, 0x113a: 0x00c0, 0x113b: 0x00c0, + 0x113c: 0x00c0, 0x113d: 0x00c0, 0x113e: 0x00c0, 0x113f: 0x00c0, + // Block 0x45, offset 0x1140 + 0x1140: 0x00c0, 0x1141: 0x00c0, 0x1142: 0x00c0, 0x1143: 0x00c0, 0x1144: 0x00c0, 0x1145: 0x00c0, + 0x1146: 0x00c0, 0x1147: 0x00c0, 0x1148: 0x00c0, 0x1149: 0x00c0, 0x114a: 0x00c0, 0x114b: 0x00c0, + 0x114c: 0x00c0, 0x114d: 0x00c0, 0x114e: 0x00c0, 0x114f: 0x00c0, 0x1150: 0x00c0, 0x1151: 0x00c0, + 0x1152: 0x00c0, 0x1153: 0x00c0, 0x1154: 0x00c0, 0x1155: 0x00c0, 0x1156: 0x00c0, 0x1157: 0x00c0, + 0x1158: 0x00c0, 0x1159: 0x00c0, 0x115a: 0x00c0, 0x115d: 0x00c3, + 0x115e: 0x00c3, 0x115f: 0x00c3, 0x1160: 0x0080, 0x1161: 0x0080, 0x1162: 0x0080, 0x1163: 0x0080, + 0x1164: 0x0080, 0x1165: 0x0080, 0x1166: 0x0080, 0x1167: 0x0080, 0x1168: 0x0080, 0x1169: 0x0080, + 0x116a: 0x0080, 0x116b: 0x0080, 0x116c: 0x0080, 0x116d: 0x0080, 0x116e: 0x0080, 0x116f: 0x0080, + 0x1170: 0x0080, 0x1171: 0x0080, 0x1172: 0x0080, 0x1173: 0x0080, 0x1174: 0x0080, 0x1175: 0x0080, + 0x1176: 0x0080, 0x1177: 0x0080, 0x1178: 0x0080, 0x1179: 0x0080, 0x117a: 0x0080, 0x117b: 0x0080, + 0x117c: 0x0080, + // Block 0x46, offset 0x1180 + 0x1180: 0x00c0, 0x1181: 0x00c0, 0x1182: 0x00c0, 0x1183: 0x00c0, 0x1184: 0x00c0, 0x1185: 0x00c0, + 0x1186: 0x00c0, 0x1187: 0x00c0, 0x1188: 0x00c0, 0x1189: 0x00c0, 0x118a: 0x00c0, 0x118b: 0x00c0, + 0x118c: 0x00c0, 0x118d: 0x00c0, 0x118e: 0x00c0, 0x118f: 0x00c0, 0x1190: 0x0080, 0x1191: 0x0080, + 0x1192: 0x0080, 0x1193: 0x0080, 0x1194: 0x0080, 0x1195: 0x0080, 0x1196: 0x0080, 0x1197: 0x0080, + 0x1198: 0x0080, 0x1199: 0x0080, + 0x11a0: 0x00c0, 0x11a1: 0x00c0, 0x11a2: 0x00c0, 0x11a3: 0x00c0, + 0x11a4: 0x00c0, 0x11a5: 0x00c0, 0x11a6: 0x00c0, 0x11a7: 0x00c0, 0x11a8: 0x00c0, 0x11a9: 0x00c0, + 0x11aa: 0x00c0, 0x11ab: 0x00c0, 0x11ac: 0x00c0, 0x11ad: 0x00c0, 0x11ae: 0x00c0, 0x11af: 0x00c0, + 0x11b0: 0x00c0, 0x11b1: 0x00c0, 0x11b2: 0x00c0, 0x11b3: 0x00c0, 0x11b4: 0x00c0, 0x11b5: 0x00c0, + 0x11b6: 0x00c0, 0x11b7: 0x00c0, 0x11b8: 0x00c0, 0x11b9: 0x00c0, 0x11ba: 0x00c0, 0x11bb: 0x00c0, + 0x11bc: 0x00c0, 0x11bd: 0x00c0, 0x11be: 0x00c0, 0x11bf: 0x00c0, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x00c0, 0x11c1: 0x00c0, 0x11c2: 0x00c0, 0x11c3: 0x00c0, 0x11c4: 0x00c0, 0x11c5: 0x00c0, + 0x11c6: 0x00c0, 0x11c7: 0x00c0, 0x11c8: 0x00c0, 0x11c9: 0x00c0, 0x11ca: 0x00c0, 0x11cb: 0x00c0, + 0x11cc: 0x00c0, 0x11cd: 0x00c0, 0x11ce: 0x00c0, 0x11cf: 0x00c0, 0x11d0: 0x00c0, 0x11d1: 0x00c0, + 0x11d2: 0x00c0, 0x11d3: 0x00c0, 0x11d4: 0x00c0, 0x11d5: 0x00c0, 0x11d6: 0x00c0, 0x11d7: 0x00c0, + 0x11d8: 0x00c0, 0x11d9: 0x00c0, 0x11da: 0x00c0, 0x11db: 0x00c0, 0x11dc: 0x00c0, 0x11dd: 0x00c0, + 0x11de: 0x00c0, 0x11df: 0x00c0, 0x11e0: 0x00c0, 0x11e1: 0x00c0, 0x11e2: 0x00c0, 0x11e3: 0x00c0, + 0x11e4: 0x00c0, 0x11e5: 0x00c0, 0x11e6: 0x00c0, 0x11e7: 0x00c0, 0x11e8: 0x00c0, 0x11e9: 0x00c0, + 0x11ea: 0x00c0, 0x11eb: 0x00c0, 0x11ec: 0x00c0, 0x11ed: 0x00c0, 0x11ee: 0x00c0, 0x11ef: 0x00c0, + 0x11f0: 0x00c0, 0x11f1: 0x00c0, 0x11f2: 0x00c0, 0x11f3: 0x00c0, 0x11f4: 0x00c0, 0x11f5: 0x00c0, + 0x11f8: 0x00c0, 0x11f9: 0x00c0, 0x11fa: 0x00c0, 0x11fb: 0x00c0, + 0x11fc: 0x00c0, 0x11fd: 0x00c0, + // Block 0x48, offset 0x1200 + 0x1200: 0x0080, 0x1201: 0x00c0, 0x1202: 0x00c0, 0x1203: 0x00c0, 0x1204: 0x00c0, 0x1205: 0x00c0, + 0x1206: 0x00c0, 0x1207: 0x00c0, 0x1208: 0x00c0, 0x1209: 0x00c0, 0x120a: 0x00c0, 0x120b: 0x00c0, + 0x120c: 0x00c0, 0x120d: 0x00c0, 0x120e: 0x00c0, 0x120f: 0x00c0, 0x1210: 0x00c0, 0x1211: 0x00c0, + 0x1212: 0x00c0, 0x1213: 0x00c0, 0x1214: 0x00c0, 0x1215: 0x00c0, 0x1216: 0x00c0, 0x1217: 0x00c0, + 0x1218: 0x00c0, 0x1219: 0x00c0, 0x121a: 0x00c0, 0x121b: 0x00c0, 0x121c: 0x00c0, 0x121d: 0x00c0, + 0x121e: 0x00c0, 0x121f: 0x00c0, 0x1220: 0x00c0, 0x1221: 0x00c0, 0x1222: 0x00c0, 0x1223: 0x00c0, + 0x1224: 0x00c0, 0x1225: 0x00c0, 0x1226: 0x00c0, 0x1227: 0x00c0, 0x1228: 0x00c0, 0x1229: 0x00c0, + 0x122a: 0x00c0, 0x122b: 0x00c0, 0x122c: 0x00c0, 0x122d: 0x00c0, 0x122e: 0x00c0, 0x122f: 0x00c0, + 0x1230: 0x00c0, 0x1231: 0x00c0, 0x1232: 0x00c0, 0x1233: 0x00c0, 0x1234: 0x00c0, 0x1235: 0x00c0, + 0x1236: 0x00c0, 0x1237: 0x00c0, 0x1238: 0x00c0, 0x1239: 0x00c0, 0x123a: 0x00c0, 0x123b: 0x00c0, + 0x123c: 0x00c0, 0x123d: 0x00c0, 0x123e: 0x00c0, 0x123f: 0x00c0, + // Block 0x49, offset 0x1240 + 0x1240: 0x00c0, 0x1241: 0x00c0, 0x1242: 0x00c0, 0x1243: 0x00c0, 0x1244: 0x00c0, 0x1245: 0x00c0, + 0x1246: 0x00c0, 0x1247: 0x00c0, 0x1248: 0x00c0, 0x1249: 0x00c0, 0x124a: 0x00c0, 0x124b: 0x00c0, + 0x124c: 0x00c0, 0x124d: 0x00c0, 0x124e: 0x00c0, 0x124f: 0x00c0, 0x1250: 0x00c0, 0x1251: 0x00c0, + 0x1252: 0x00c0, 0x1253: 0x00c0, 0x1254: 0x00c0, 0x1255: 0x00c0, 0x1256: 0x00c0, 0x1257: 0x00c0, + 0x1258: 0x00c0, 0x1259: 0x00c0, 0x125a: 0x00c0, 0x125b: 0x00c0, 0x125c: 0x00c0, 0x125d: 0x00c0, + 0x125e: 0x00c0, 0x125f: 0x00c0, 0x1260: 0x00c0, 0x1261: 0x00c0, 0x1262: 0x00c0, 0x1263: 0x00c0, + 0x1264: 0x00c0, 0x1265: 0x00c0, 0x1266: 0x00c0, 0x1267: 0x00c0, 0x1268: 0x00c0, 0x1269: 0x00c0, + 0x126a: 0x00c0, 0x126b: 0x00c0, 0x126c: 0x00c0, 0x126d: 0x0080, 0x126e: 0x0080, 0x126f: 0x00c0, + 0x1270: 0x00c0, 0x1271: 0x00c0, 0x1272: 0x00c0, 0x1273: 0x00c0, 0x1274: 0x00c0, 0x1275: 0x00c0, + 0x1276: 0x00c0, 0x1277: 0x00c0, 0x1278: 0x00c0, 0x1279: 0x00c0, 0x127a: 0x00c0, 0x127b: 0x00c0, + 0x127c: 0x00c0, 0x127d: 0x00c0, 0x127e: 0x00c0, 0x127f: 0x00c0, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0080, 0x1281: 0x00c0, 0x1282: 0x00c0, 0x1283: 0x00c0, 0x1284: 0x00c0, 0x1285: 0x00c0, + 0x1286: 0x00c0, 0x1287: 0x00c0, 0x1288: 0x00c0, 0x1289: 0x00c0, 0x128a: 0x00c0, 0x128b: 0x00c0, + 0x128c: 0x00c0, 0x128d: 0x00c0, 0x128e: 0x00c0, 0x128f: 0x00c0, 0x1290: 0x00c0, 0x1291: 0x00c0, + 0x1292: 0x00c0, 0x1293: 0x00c0, 0x1294: 0x00c0, 0x1295: 0x00c0, 0x1296: 0x00c0, 0x1297: 0x00c0, + 0x1298: 0x00c0, 0x1299: 0x00c0, 0x129a: 0x00c0, 0x129b: 0x0080, 0x129c: 0x0080, + 0x12a0: 0x00c0, 0x12a1: 0x00c0, 0x12a2: 0x00c0, 0x12a3: 0x00c0, + 0x12a4: 0x00c0, 0x12a5: 0x00c0, 0x12a6: 0x00c0, 0x12a7: 0x00c0, 0x12a8: 0x00c0, 0x12a9: 0x00c0, + 0x12aa: 0x00c0, 0x12ab: 0x00c0, 0x12ac: 0x00c0, 0x12ad: 0x00c0, 0x12ae: 0x00c0, 0x12af: 0x00c0, + 0x12b0: 0x00c0, 0x12b1: 0x00c0, 0x12b2: 0x00c0, 0x12b3: 0x00c0, 0x12b4: 0x00c0, 0x12b5: 0x00c0, + 0x12b6: 0x00c0, 0x12b7: 0x00c0, 0x12b8: 0x00c0, 0x12b9: 0x00c0, 0x12ba: 0x00c0, 0x12bb: 0x00c0, + 0x12bc: 0x00c0, 0x12bd: 0x00c0, 0x12be: 0x00c0, 0x12bf: 0x00c0, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x00c0, 0x12c1: 0x00c0, 0x12c2: 0x00c0, 0x12c3: 0x00c0, 0x12c4: 0x00c0, 0x12c5: 0x00c0, + 0x12c6: 0x00c0, 0x12c7: 0x00c0, 0x12c8: 0x00c0, 0x12c9: 0x00c0, 0x12ca: 0x00c0, 0x12cb: 0x00c0, + 0x12cc: 0x00c0, 0x12cd: 0x00c0, 0x12ce: 0x00c0, 0x12cf: 0x00c0, 0x12d0: 0x00c0, 0x12d1: 0x00c0, + 0x12d2: 0x00c0, 0x12d3: 0x00c0, 0x12d4: 0x00c0, 0x12d5: 0x00c0, 0x12d6: 0x00c0, 0x12d7: 0x00c0, + 0x12d8: 0x00c0, 0x12d9: 0x00c0, 0x12da: 0x00c0, 0x12db: 0x00c0, 0x12dc: 0x00c0, 0x12dd: 0x00c0, + 0x12de: 0x00c0, 0x12df: 0x00c0, 0x12e0: 0x00c0, 0x12e1: 0x00c0, 0x12e2: 0x00c0, 0x12e3: 0x00c0, + 0x12e4: 0x00c0, 0x12e5: 0x00c0, 0x12e6: 0x00c0, 0x12e7: 0x00c0, 0x12e8: 0x00c0, 0x12e9: 0x00c0, + 0x12ea: 0x00c0, 0x12eb: 0x0080, 0x12ec: 0x0080, 0x12ed: 0x0080, 0x12ee: 0x0080, 0x12ef: 0x0080, + 0x12f0: 0x0080, 0x12f1: 0x00c0, 0x12f2: 0x00c0, 0x12f3: 0x00c0, 0x12f4: 0x00c0, 0x12f5: 0x00c0, + 0x12f6: 0x00c0, 0x12f7: 0x00c0, 0x12f8: 0x00c0, + // Block 0x4c, offset 0x1300 + 0x1300: 0x00c0, 0x1301: 0x00c0, 0x1302: 0x00c0, 0x1303: 0x00c0, 0x1304: 0x00c0, 0x1305: 0x00c0, + 0x1306: 0x00c0, 0x1307: 0x00c0, 0x1308: 0x00c0, 0x1309: 0x00c0, 0x130a: 0x00c0, 0x130b: 0x00c0, + 0x130c: 0x00c0, 0x130e: 0x00c0, 0x130f: 0x00c0, 0x1310: 0x00c0, 0x1311: 0x00c0, + 0x1312: 0x00c3, 0x1313: 0x00c3, 0x1314: 0x00c6, + 0x1320: 0x00c0, 0x1321: 0x00c0, 0x1322: 0x00c0, 0x1323: 0x00c0, + 0x1324: 0x00c0, 0x1325: 0x00c0, 0x1326: 0x00c0, 0x1327: 0x00c0, 0x1328: 0x00c0, 0x1329: 0x00c0, + 0x132a: 0x00c0, 0x132b: 0x00c0, 0x132c: 0x00c0, 0x132d: 0x00c0, 0x132e: 0x00c0, 0x132f: 0x00c0, + 0x1330: 0x00c0, 0x1331: 0x00c0, 0x1332: 0x00c3, 0x1333: 0x00c3, 0x1334: 0x00c6, 0x1335: 0x0080, + 0x1336: 0x0080, + // Block 0x4d, offset 0x1340 + 0x1340: 0x00c0, 0x1341: 0x00c0, 0x1342: 0x00c0, 0x1343: 0x00c0, 0x1344: 0x00c0, 0x1345: 0x00c0, + 0x1346: 0x00c0, 0x1347: 0x00c0, 0x1348: 0x00c0, 0x1349: 0x00c0, 0x134a: 0x00c0, 0x134b: 0x00c0, + 0x134c: 0x00c0, 0x134d: 0x00c0, 0x134e: 0x00c0, 0x134f: 0x00c0, 0x1350: 0x00c0, 0x1351: 0x00c0, + 0x1352: 0x00c3, 0x1353: 0x00c3, + 0x1360: 0x00c0, 0x1361: 0x00c0, 0x1362: 0x00c0, 0x1363: 0x00c0, + 0x1364: 0x00c0, 0x1365: 0x00c0, 0x1366: 0x00c0, 0x1367: 0x00c0, 0x1368: 0x00c0, 0x1369: 0x00c0, + 0x136a: 0x00c0, 0x136b: 0x00c0, 0x136c: 0x00c0, 0x136e: 0x00c0, 0x136f: 0x00c0, + 0x1370: 0x00c0, 0x1372: 0x00c3, 0x1373: 0x00c3, + // Block 0x4e, offset 0x1380 + 0x1380: 0x00c0, 0x1381: 0x00c0, 0x1382: 0x00c0, 0x1383: 0x00c0, 0x1384: 0x00c0, 0x1385: 0x00c0, + 0x1386: 0x00c0, 0x1387: 0x00c0, 0x1388: 0x00c0, 0x1389: 0x00c0, 0x138a: 0x00c0, 0x138b: 0x00c0, + 0x138c: 0x00c0, 0x138d: 0x00c0, 0x138e: 0x00c0, 0x138f: 0x00c0, 0x1390: 0x00c0, 0x1391: 0x00c0, + 0x1392: 0x00c0, 0x1393: 0x00c0, 0x1394: 0x00c0, 0x1395: 0x00c0, 0x1396: 0x00c0, 0x1397: 0x00c0, + 0x1398: 0x00c0, 0x1399: 0x00c0, 0x139a: 0x00c0, 0x139b: 0x00c0, 0x139c: 0x00c0, 0x139d: 0x00c0, + 0x139e: 0x00c0, 0x139f: 0x00c0, 0x13a0: 0x00c0, 0x13a1: 0x00c0, 0x13a2: 0x00c0, 0x13a3: 0x00c0, + 0x13a4: 0x00c0, 0x13a5: 0x00c0, 0x13a6: 0x00c0, 0x13a7: 0x00c0, 0x13a8: 0x00c0, 0x13a9: 0x00c0, + 0x13aa: 0x00c0, 0x13ab: 0x00c0, 0x13ac: 0x00c0, 0x13ad: 0x00c0, 0x13ae: 0x00c0, 0x13af: 0x00c0, + 0x13b0: 0x00c0, 0x13b1: 0x00c0, 0x13b2: 0x00c0, 0x13b3: 0x00c0, 0x13b4: 0x0040, 0x13b5: 0x0040, + 0x13b6: 0x00c0, 0x13b7: 0x00c3, 0x13b8: 0x00c3, 0x13b9: 0x00c3, 0x13ba: 0x00c3, 0x13bb: 0x00c3, + 0x13bc: 0x00c3, 0x13bd: 0x00c3, 0x13be: 0x00c0, 0x13bf: 0x00c0, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x00c0, 0x13c1: 0x00c0, 0x13c2: 0x00c0, 0x13c3: 0x00c0, 0x13c4: 0x00c0, 0x13c5: 0x00c0, + 0x13c6: 0x00c3, 0x13c7: 0x00c0, 0x13c8: 0x00c0, 0x13c9: 0x00c3, 0x13ca: 0x00c3, 0x13cb: 0x00c3, + 0x13cc: 0x00c3, 0x13cd: 0x00c3, 0x13ce: 0x00c3, 0x13cf: 0x00c3, 0x13d0: 0x00c3, 0x13d1: 0x00c3, + 0x13d2: 0x00c6, 0x13d3: 0x00c3, 0x13d4: 0x0080, 0x13d5: 0x0080, 0x13d6: 0x0080, 0x13d7: 0x00c0, + 0x13d8: 0x0080, 0x13d9: 0x0080, 0x13da: 0x0080, 0x13db: 0x0080, 0x13dc: 0x00c0, 0x13dd: 0x00c3, + 0x13e0: 0x00c0, 0x13e1: 0x00c0, 0x13e2: 0x00c0, 0x13e3: 0x00c0, + 0x13e4: 0x00c0, 0x13e5: 0x00c0, 0x13e6: 0x00c0, 0x13e7: 0x00c0, 0x13e8: 0x00c0, 0x13e9: 0x00c0, + 0x13f0: 0x0080, 0x13f1: 0x0080, 0x13f2: 0x0080, 0x13f3: 0x0080, 0x13f4: 0x0080, 0x13f5: 0x0080, + 0x13f6: 0x0080, 0x13f7: 0x0080, 0x13f8: 0x0080, 0x13f9: 0x0080, + // Block 0x50, offset 0x1400 + 0x1400: 0x0080, 0x1401: 0x0080, 0x1402: 0x0080, 0x1403: 0x0080, 0x1404: 0x0080, 0x1405: 0x0080, + 0x1406: 0x0080, 0x1407: 0x0082, 0x1408: 0x0080, 0x1409: 0x0080, 0x140a: 0x0080, 0x140b: 0x0040, + 0x140c: 0x0040, 0x140d: 0x0040, 0x140e: 0x0040, 0x1410: 0x00c0, 0x1411: 0x00c0, + 0x1412: 0x00c0, 0x1413: 0x00c0, 0x1414: 0x00c0, 0x1415: 0x00c0, 0x1416: 0x00c0, 0x1417: 0x00c0, + 0x1418: 0x00c0, 0x1419: 0x00c0, + 0x1420: 0x00c2, 0x1421: 0x00c2, 0x1422: 0x00c2, 0x1423: 0x00c2, + 0x1424: 0x00c2, 0x1425: 0x00c2, 0x1426: 0x00c2, 0x1427: 0x00c2, 0x1428: 0x00c2, 0x1429: 0x00c2, + 0x142a: 0x00c2, 0x142b: 0x00c2, 0x142c: 0x00c2, 0x142d: 0x00c2, 0x142e: 0x00c2, 0x142f: 0x00c2, + 0x1430: 0x00c2, 0x1431: 0x00c2, 0x1432: 0x00c2, 0x1433: 0x00c2, 0x1434: 0x00c2, 0x1435: 0x00c2, + 0x1436: 0x00c2, 0x1437: 0x00c2, 0x1438: 0x00c2, 0x1439: 0x00c2, 0x143a: 0x00c2, 0x143b: 0x00c2, + 0x143c: 0x00c2, 0x143d: 0x00c2, 0x143e: 0x00c2, 0x143f: 0x00c2, + // Block 0x51, offset 0x1440 + 0x1440: 0x00c2, 0x1441: 0x00c2, 0x1442: 0x00c2, 0x1443: 0x00c2, 0x1444: 0x00c2, 0x1445: 0x00c2, + 0x1446: 0x00c2, 0x1447: 0x00c2, 0x1448: 0x00c2, 0x1449: 0x00c2, 0x144a: 0x00c2, 0x144b: 0x00c2, + 0x144c: 0x00c2, 0x144d: 0x00c2, 0x144e: 0x00c2, 0x144f: 0x00c2, 0x1450: 0x00c2, 0x1451: 0x00c2, + 0x1452: 0x00c2, 0x1453: 0x00c2, 0x1454: 0x00c2, 0x1455: 0x00c2, 0x1456: 0x00c2, 0x1457: 0x00c2, + 0x1458: 0x00c2, 0x1459: 0x00c2, 0x145a: 0x00c2, 0x145b: 0x00c2, 0x145c: 0x00c2, 0x145d: 0x00c2, + 0x145e: 0x00c2, 0x145f: 0x00c2, 0x1460: 0x00c2, 0x1461: 0x00c2, 0x1462: 0x00c2, 0x1463: 0x00c2, + 0x1464: 0x00c2, 0x1465: 0x00c2, 0x1466: 0x00c2, 0x1467: 0x00c2, 0x1468: 0x00c2, 0x1469: 0x00c2, + 0x146a: 0x00c2, 0x146b: 0x00c2, 0x146c: 0x00c2, 0x146d: 0x00c2, 0x146e: 0x00c2, 0x146f: 0x00c2, + 0x1470: 0x00c2, 0x1471: 0x00c2, 0x1472: 0x00c2, 0x1473: 0x00c2, 0x1474: 0x00c2, 0x1475: 0x00c2, + 0x1476: 0x00c2, 0x1477: 0x00c2, 0x1478: 0x00c2, + // Block 0x52, offset 0x1480 + 0x1480: 0x00c0, 0x1481: 0x00c0, 0x1482: 0x00c0, 0x1483: 0x00c0, 0x1484: 0x00c0, 0x1485: 0x00c3, + 0x1486: 0x00c3, 0x1487: 0x00c2, 0x1488: 0x00c2, 0x1489: 0x00c2, 0x148a: 0x00c2, 0x148b: 0x00c2, + 0x148c: 0x00c2, 0x148d: 0x00c2, 0x148e: 0x00c2, 0x148f: 0x00c2, 0x1490: 0x00c2, 0x1491: 0x00c2, + 0x1492: 0x00c2, 0x1493: 0x00c2, 0x1494: 0x00c2, 0x1495: 0x00c2, 0x1496: 0x00c2, 0x1497: 0x00c2, + 0x1498: 0x00c2, 0x1499: 0x00c2, 0x149a: 0x00c2, 0x149b: 0x00c2, 0x149c: 0x00c2, 0x149d: 0x00c2, + 0x149e: 0x00c2, 0x149f: 0x00c2, 0x14a0: 0x00c2, 0x14a1: 0x00c2, 0x14a2: 0x00c2, 0x14a3: 0x00c2, + 0x14a4: 0x00c2, 0x14a5: 0x00c2, 0x14a6: 0x00c2, 0x14a7: 0x00c2, 0x14a8: 0x00c2, 0x14a9: 0x00c3, + 0x14aa: 0x00c2, + 0x14b0: 0x00c0, 0x14b1: 0x00c0, 0x14b2: 0x00c0, 0x14b3: 0x00c0, 0x14b4: 0x00c0, 0x14b5: 0x00c0, + 0x14b6: 0x00c0, 0x14b7: 0x00c0, 0x14b8: 0x00c0, 0x14b9: 0x00c0, 0x14ba: 0x00c0, 0x14bb: 0x00c0, + 0x14bc: 0x00c0, 0x14bd: 0x00c0, 0x14be: 0x00c0, 0x14bf: 0x00c0, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x00c0, 0x14c1: 0x00c0, 0x14c2: 0x00c0, 0x14c3: 0x00c0, 0x14c4: 0x00c0, 0x14c5: 0x00c0, + 0x14c6: 0x00c0, 0x14c7: 0x00c0, 0x14c8: 0x00c0, 0x14c9: 0x00c0, 0x14ca: 0x00c0, 0x14cb: 0x00c0, + 0x14cc: 0x00c0, 0x14cd: 0x00c0, 0x14ce: 0x00c0, 0x14cf: 0x00c0, 0x14d0: 0x00c0, 0x14d1: 0x00c0, + 0x14d2: 0x00c0, 0x14d3: 0x00c0, 0x14d4: 0x00c0, 0x14d5: 0x00c0, 0x14d6: 0x00c0, 0x14d7: 0x00c0, + 0x14d8: 0x00c0, 0x14d9: 0x00c0, 0x14da: 0x00c0, 0x14db: 0x00c0, 0x14dc: 0x00c0, 0x14dd: 0x00c0, + 0x14de: 0x00c0, 0x14df: 0x00c0, 0x14e0: 0x00c0, 0x14e1: 0x00c0, 0x14e2: 0x00c0, 0x14e3: 0x00c0, + 0x14e4: 0x00c0, 0x14e5: 0x00c0, 0x14e6: 0x00c0, 0x14e7: 0x00c0, 0x14e8: 0x00c0, 0x14e9: 0x00c0, + 0x14ea: 0x00c0, 0x14eb: 0x00c0, 0x14ec: 0x00c0, 0x14ed: 0x00c0, 0x14ee: 0x00c0, 0x14ef: 0x00c0, + 0x14f0: 0x00c0, 0x14f1: 0x00c0, 0x14f2: 0x00c0, 0x14f3: 0x00c0, 0x14f4: 0x00c0, 0x14f5: 0x00c0, + // Block 0x54, offset 0x1500 + 0x1500: 0x00c0, 0x1501: 0x00c0, 0x1502: 0x00c0, 0x1503: 0x00c0, 0x1504: 0x00c0, 0x1505: 0x00c0, + 0x1506: 0x00c0, 0x1507: 0x00c0, 0x1508: 0x00c0, 0x1509: 0x00c0, 0x150a: 0x00c0, 0x150b: 0x00c0, + 0x150c: 0x00c0, 0x150d: 0x00c0, 0x150e: 0x00c0, 0x150f: 0x00c0, 0x1510: 0x00c0, 0x1511: 0x00c0, + 0x1512: 0x00c0, 0x1513: 0x00c0, 0x1514: 0x00c0, 0x1515: 0x00c0, 0x1516: 0x00c0, 0x1517: 0x00c0, + 0x1518: 0x00c0, 0x1519: 0x00c0, 0x151a: 0x00c0, 0x151b: 0x00c0, 0x151c: 0x00c0, 0x151d: 0x00c0, + 0x151e: 0x00c0, 0x1520: 0x00c3, 0x1521: 0x00c3, 0x1522: 0x00c3, 0x1523: 0x00c0, + 0x1524: 0x00c0, 0x1525: 0x00c0, 0x1526: 0x00c0, 0x1527: 0x00c3, 0x1528: 0x00c3, 0x1529: 0x00c0, + 0x152a: 0x00c0, 0x152b: 0x00c0, + 0x1530: 0x00c0, 0x1531: 0x00c0, 0x1532: 0x00c3, 0x1533: 0x00c0, 0x1534: 0x00c0, 0x1535: 0x00c0, + 0x1536: 0x00c0, 0x1537: 0x00c0, 0x1538: 0x00c0, 0x1539: 0x00c3, 0x153a: 0x00c3, 0x153b: 0x00c3, + // Block 0x55, offset 0x1540 + 0x1540: 0x0080, 0x1544: 0x0080, 0x1545: 0x0080, + 0x1546: 0x00c0, 0x1547: 0x00c0, 0x1548: 0x00c0, 0x1549: 0x00c0, 0x154a: 0x00c0, 0x154b: 0x00c0, + 0x154c: 0x00c0, 0x154d: 0x00c0, 0x154e: 0x00c0, 0x154f: 0x00c0, 0x1550: 0x00c0, 0x1551: 0x00c0, + 0x1552: 0x00c0, 0x1553: 0x00c0, 0x1554: 0x00c0, 0x1555: 0x00c0, 0x1556: 0x00c0, 0x1557: 0x00c0, + 0x1558: 0x00c0, 0x1559: 0x00c0, 0x155a: 0x00c0, 0x155b: 0x00c0, 0x155c: 0x00c0, 0x155d: 0x00c0, + 0x155e: 0x00c0, 0x155f: 0x00c0, 0x1560: 0x00c0, 0x1561: 0x00c0, 0x1562: 0x00c0, 0x1563: 0x00c0, + 0x1564: 0x00c0, 0x1565: 0x00c0, 0x1566: 0x00c0, 0x1567: 0x00c0, 0x1568: 0x00c0, 0x1569: 0x00c0, + 0x156a: 0x00c0, 0x156b: 0x00c0, 0x156c: 0x00c0, 0x156d: 0x00c0, + 0x1570: 0x00c0, 0x1571: 0x00c0, 0x1572: 0x00c0, 0x1573: 0x00c0, 0x1574: 0x00c0, + // Block 0x56, offset 0x1580 + 0x1580: 0x00c0, 0x1581: 0x00c0, 0x1582: 0x00c0, 0x1583: 0x00c0, 0x1584: 0x00c0, 0x1585: 0x00c0, + 0x1586: 0x00c0, 0x1587: 0x00c0, 0x1588: 0x00c0, 0x1589: 0x00c0, 0x158a: 0x00c0, 0x158b: 0x00c0, + 0x158c: 0x00c0, 0x158d: 0x00c0, 0x158e: 0x00c0, 0x158f: 0x00c0, 0x1590: 0x00c0, 0x1591: 0x00c0, + 0x1592: 0x00c0, 0x1593: 0x00c0, 0x1594: 0x00c0, 0x1595: 0x00c0, 0x1596: 0x00c0, 0x1597: 0x00c0, + 0x1598: 0x00c0, 0x1599: 0x00c0, 0x159a: 0x00c0, 0x159b: 0x00c0, 0x159c: 0x00c0, 0x159d: 0x00c0, + 0x159e: 0x00c0, 0x159f: 0x00c0, 0x15a0: 0x00c0, 0x15a1: 0x00c0, 0x15a2: 0x00c0, 0x15a3: 0x00c0, + 0x15a4: 0x00c0, 0x15a5: 0x00c0, 0x15a6: 0x00c0, 0x15a7: 0x00c0, 0x15a8: 0x00c0, 0x15a9: 0x00c0, + 0x15aa: 0x00c0, 0x15ab: 0x00c0, + 0x15b0: 0x00c0, 0x15b1: 0x00c0, 0x15b2: 0x00c0, 0x15b3: 0x00c0, 0x15b4: 0x00c0, 0x15b5: 0x00c0, + 0x15b6: 0x00c0, 0x15b7: 0x00c0, 0x15b8: 0x00c0, 0x15b9: 0x00c0, 0x15ba: 0x00c0, 0x15bb: 0x00c0, + 0x15bc: 0x00c0, 0x15bd: 0x00c0, 0x15be: 0x00c0, 0x15bf: 0x00c0, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x00c0, 0x15c1: 0x00c0, 0x15c2: 0x00c0, 0x15c3: 0x00c0, 0x15c4: 0x00c0, 0x15c5: 0x00c0, + 0x15c6: 0x00c0, 0x15c7: 0x00c0, 0x15c8: 0x00c0, 0x15c9: 0x00c0, + 0x15d0: 0x00c0, 0x15d1: 0x00c0, + 0x15d2: 0x00c0, 0x15d3: 0x00c0, 0x15d4: 0x00c0, 0x15d5: 0x00c0, 0x15d6: 0x00c0, 0x15d7: 0x00c0, + 0x15d8: 0x00c0, 0x15d9: 0x00c0, 0x15da: 0x0080, + 0x15de: 0x0080, 0x15df: 0x0080, 0x15e0: 0x0080, 0x15e1: 0x0080, 0x15e2: 0x0080, 0x15e3: 0x0080, + 0x15e4: 0x0080, 0x15e5: 0x0080, 0x15e6: 0x0080, 0x15e7: 0x0080, 0x15e8: 0x0080, 0x15e9: 0x0080, + 0x15ea: 0x0080, 0x15eb: 0x0080, 0x15ec: 0x0080, 0x15ed: 0x0080, 0x15ee: 0x0080, 0x15ef: 0x0080, + 0x15f0: 0x0080, 0x15f1: 0x0080, 0x15f2: 0x0080, 0x15f3: 0x0080, 0x15f4: 0x0080, 0x15f5: 0x0080, + 0x15f6: 0x0080, 0x15f7: 0x0080, 0x15f8: 0x0080, 0x15f9: 0x0080, 0x15fa: 0x0080, 0x15fb: 0x0080, + 0x15fc: 0x0080, 0x15fd: 0x0080, 0x15fe: 0x0080, 0x15ff: 0x0080, + // Block 0x58, offset 0x1600 + 0x1600: 0x00c0, 0x1601: 0x00c0, 0x1602: 0x00c0, 0x1603: 0x00c0, 0x1604: 0x00c0, 0x1605: 0x00c0, + 0x1606: 0x00c0, 0x1607: 0x00c0, 0x1608: 0x00c0, 0x1609: 0x00c0, 0x160a: 0x00c0, 0x160b: 0x00c0, + 0x160c: 0x00c0, 0x160d: 0x00c0, 0x160e: 0x00c0, 0x160f: 0x00c0, 0x1610: 0x00c0, 0x1611: 0x00c0, + 0x1612: 0x00c0, 0x1613: 0x00c0, 0x1614: 0x00c0, 0x1615: 0x00c0, 0x1616: 0x00c0, 0x1617: 0x00c3, + 0x1618: 0x00c3, 0x1619: 0x00c0, 0x161a: 0x00c0, 0x161b: 0x00c3, + 0x161e: 0x0080, 0x161f: 0x0080, 0x1620: 0x00c0, 0x1621: 0x00c0, 0x1622: 0x00c0, 0x1623: 0x00c0, + 0x1624: 0x00c0, 0x1625: 0x00c0, 0x1626: 0x00c0, 0x1627: 0x00c0, 0x1628: 0x00c0, 0x1629: 0x00c0, + 0x162a: 0x00c0, 0x162b: 0x00c0, 0x162c: 0x00c0, 0x162d: 0x00c0, 0x162e: 0x00c0, 0x162f: 0x00c0, + 0x1630: 0x00c0, 0x1631: 0x00c0, 0x1632: 0x00c0, 0x1633: 0x00c0, 0x1634: 0x00c0, 0x1635: 0x00c0, + 0x1636: 0x00c0, 0x1637: 0x00c0, 0x1638: 0x00c0, 0x1639: 0x00c0, 0x163a: 0x00c0, 0x163b: 0x00c0, + 0x163c: 0x00c0, 0x163d: 0x00c0, 0x163e: 0x00c0, 0x163f: 0x00c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x00c0, 0x1641: 0x00c0, 0x1642: 0x00c0, 0x1643: 0x00c0, 0x1644: 0x00c0, 0x1645: 0x00c0, + 0x1646: 0x00c0, 0x1647: 0x00c0, 0x1648: 0x00c0, 0x1649: 0x00c0, 0x164a: 0x00c0, 0x164b: 0x00c0, + 0x164c: 0x00c0, 0x164d: 0x00c0, 0x164e: 0x00c0, 0x164f: 0x00c0, 0x1650: 0x00c0, 0x1651: 0x00c0, + 0x1652: 0x00c0, 0x1653: 0x00c0, 0x1654: 0x00c0, 0x1655: 0x00c0, 0x1656: 0x00c3, 0x1657: 0x00c0, + 0x1658: 0x00c3, 0x1659: 0x00c3, 0x165a: 0x00c3, 0x165b: 0x00c3, 0x165c: 0x00c3, 0x165d: 0x00c3, + 0x165e: 0x00c3, 0x1660: 0x00c6, 0x1661: 0x00c0, 0x1662: 0x00c3, 0x1663: 0x00c0, + 0x1664: 0x00c0, 0x1665: 0x00c3, 0x1666: 0x00c3, 0x1667: 0x00c3, 0x1668: 0x00c3, 0x1669: 0x00c3, + 0x166a: 0x00c3, 0x166b: 0x00c3, 0x166c: 0x00c3, 0x166d: 0x00c0, 0x166e: 0x00c0, 0x166f: 0x00c0, + 0x1670: 0x00c0, 0x1671: 0x00c0, 0x1672: 0x00c0, 0x1673: 0x00c3, 0x1674: 0x00c3, 0x1675: 0x00c3, + 0x1676: 0x00c3, 0x1677: 0x00c3, 0x1678: 0x00c3, 0x1679: 0x00c3, 0x167a: 0x00c3, 0x167b: 0x00c3, + 0x167c: 0x00c3, 0x167f: 0x00c3, + // Block 0x5a, offset 0x1680 + 0x1680: 0x00c0, 0x1681: 0x00c0, 0x1682: 0x00c0, 0x1683: 0x00c0, 0x1684: 0x00c0, 0x1685: 0x00c0, + 0x1686: 0x00c0, 0x1687: 0x00c0, 0x1688: 0x00c0, 0x1689: 0x00c0, + 0x1690: 0x00c0, 0x1691: 0x00c0, + 0x1692: 0x00c0, 0x1693: 0x00c0, 0x1694: 0x00c0, 0x1695: 0x00c0, 0x1696: 0x00c0, 0x1697: 0x00c0, + 0x1698: 0x00c0, 0x1699: 0x00c0, + 0x16a0: 0x0080, 0x16a1: 0x0080, 0x16a2: 0x0080, 0x16a3: 0x0080, + 0x16a4: 0x0080, 0x16a5: 0x0080, 0x16a6: 0x0080, 0x16a7: 0x00c0, 0x16a8: 0x0080, 0x16a9: 0x0080, + 0x16aa: 0x0080, 0x16ab: 0x0080, 0x16ac: 0x0080, 0x16ad: 0x0080, + 0x16b0: 0x00c3, 0x16b1: 0x00c3, 0x16b2: 0x00c3, 0x16b3: 0x00c3, 0x16b4: 0x00c3, 0x16b5: 0x00c3, + 0x16b6: 0x00c3, 0x16b7: 0x00c3, 0x16b8: 0x00c3, 0x16b9: 0x00c3, 0x16ba: 0x00c3, 0x16bb: 0x00c3, + 0x16bc: 0x00c3, 0x16bd: 0x00c3, 0x16be: 0x0083, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x00c3, 0x16c1: 0x00c3, 0x16c2: 0x00c3, 0x16c3: 0x00c3, 0x16c4: 0x00c0, 0x16c5: 0x00c0, + 0x16c6: 0x00c0, 0x16c7: 0x00c0, 0x16c8: 0x00c0, 0x16c9: 0x00c0, 0x16ca: 0x00c0, 0x16cb: 0x00c0, + 0x16cc: 0x00c0, 0x16cd: 0x00c0, 0x16ce: 0x00c0, 0x16cf: 0x00c0, 0x16d0: 0x00c0, 0x16d1: 0x00c0, + 0x16d2: 0x00c0, 0x16d3: 0x00c0, 0x16d4: 0x00c0, 0x16d5: 0x00c0, 0x16d6: 0x00c0, 0x16d7: 0x00c0, + 0x16d8: 0x00c0, 0x16d9: 0x00c0, 0x16da: 0x00c0, 0x16db: 0x00c0, 0x16dc: 0x00c0, 0x16dd: 0x00c0, + 0x16de: 0x00c0, 0x16df: 0x00c0, 0x16e0: 0x00c0, 0x16e1: 0x00c0, 0x16e2: 0x00c0, 0x16e3: 0x00c0, + 0x16e4: 0x00c0, 0x16e5: 0x00c0, 0x16e6: 0x00c0, 0x16e7: 0x00c0, 0x16e8: 0x00c0, 0x16e9: 0x00c0, + 0x16ea: 0x00c0, 0x16eb: 0x00c0, 0x16ec: 0x00c0, 0x16ed: 0x00c0, 0x16ee: 0x00c0, 0x16ef: 0x00c0, + 0x16f0: 0x00c0, 0x16f1: 0x00c0, 0x16f2: 0x00c0, 0x16f3: 0x00c0, 0x16f4: 0x00c3, 0x16f5: 0x00c0, + 0x16f6: 0x00c3, 0x16f7: 0x00c3, 0x16f8: 0x00c3, 0x16f9: 0x00c3, 0x16fa: 0x00c3, 0x16fb: 0x00c0, + 0x16fc: 0x00c3, 0x16fd: 0x00c0, 0x16fe: 0x00c0, 0x16ff: 0x00c0, + // Block 0x5c, offset 0x1700 + 0x1700: 0x00c0, 0x1701: 0x00c0, 0x1702: 0x00c3, 0x1703: 0x00c0, 0x1704: 0x00c5, 0x1705: 0x00c0, + 0x1706: 0x00c0, 0x1707: 0x00c0, 0x1708: 0x00c0, 0x1709: 0x00c0, 0x170a: 0x00c0, 0x170b: 0x00c0, + 0x1710: 0x00c0, 0x1711: 0x00c0, + 0x1712: 0x00c0, 0x1713: 0x00c0, 0x1714: 0x00c0, 0x1715: 0x00c0, 0x1716: 0x00c0, 0x1717: 0x00c0, + 0x1718: 0x00c0, 0x1719: 0x00c0, 0x171a: 0x0080, 0x171b: 0x0080, 0x171c: 0x0080, 0x171d: 0x0080, + 0x171e: 0x0080, 0x171f: 0x0080, 0x1720: 0x0080, 0x1721: 0x0080, 0x1722: 0x0080, 0x1723: 0x0080, + 0x1724: 0x0080, 0x1725: 0x0080, 0x1726: 0x0080, 0x1727: 0x0080, 0x1728: 0x0080, 0x1729: 0x0080, + 0x172a: 0x0080, 0x172b: 0x00c3, 0x172c: 0x00c3, 0x172d: 0x00c3, 0x172e: 0x00c3, 0x172f: 0x00c3, + 0x1730: 0x00c3, 0x1731: 0x00c3, 0x1732: 0x00c3, 0x1733: 0x00c3, 0x1734: 0x0080, 0x1735: 0x0080, + 0x1736: 0x0080, 0x1737: 0x0080, 0x1738: 0x0080, 0x1739: 0x0080, 0x173a: 0x0080, 0x173b: 0x0080, + 0x173c: 0x0080, + // Block 0x5d, offset 0x1740 + 0x1740: 0x00c3, 0x1741: 0x00c3, 0x1742: 0x00c0, 0x1743: 0x00c0, 0x1744: 0x00c0, 0x1745: 0x00c0, + 0x1746: 0x00c0, 0x1747: 0x00c0, 0x1748: 0x00c0, 0x1749: 0x00c0, 0x174a: 0x00c0, 0x174b: 0x00c0, + 0x174c: 0x00c0, 0x174d: 0x00c0, 0x174e: 0x00c0, 0x174f: 0x00c0, 0x1750: 0x00c0, 0x1751: 0x00c0, + 0x1752: 0x00c0, 0x1753: 0x00c0, 0x1754: 0x00c0, 0x1755: 0x00c0, 0x1756: 0x00c0, 0x1757: 0x00c0, + 0x1758: 0x00c0, 0x1759: 0x00c0, 0x175a: 0x00c0, 0x175b: 0x00c0, 0x175c: 0x00c0, 0x175d: 0x00c0, + 0x175e: 0x00c0, 0x175f: 0x00c0, 0x1760: 0x00c0, 0x1761: 0x00c0, 0x1762: 0x00c3, 0x1763: 0x00c3, + 0x1764: 0x00c3, 0x1765: 0x00c3, 0x1766: 0x00c0, 0x1767: 0x00c0, 0x1768: 0x00c3, 0x1769: 0x00c3, + 0x176a: 0x00c5, 0x176b: 0x00c6, 0x176c: 0x00c3, 0x176d: 0x00c3, 0x176e: 0x00c0, 0x176f: 0x00c0, + 0x1770: 0x00c0, 0x1771: 0x00c0, 0x1772: 0x00c0, 0x1773: 0x00c0, 0x1774: 0x00c0, 0x1775: 0x00c0, + 0x1776: 0x00c0, 0x1777: 0x00c0, 0x1778: 0x00c0, 0x1779: 0x00c0, 0x177a: 0x00c0, 0x177b: 0x00c0, + 0x177c: 0x00c0, 0x177d: 0x00c0, 0x177e: 0x00c0, 0x177f: 0x00c0, + // Block 0x5e, offset 0x1780 + 0x1780: 0x00c0, 0x1781: 0x00c0, 0x1782: 0x00c0, 0x1783: 0x00c0, 0x1784: 0x00c0, 0x1785: 0x00c0, + 0x1786: 0x00c0, 0x1787: 0x00c0, 0x1788: 0x00c0, 0x1789: 0x00c0, 0x178a: 0x00c0, 0x178b: 0x00c0, + 0x178c: 0x00c0, 0x178d: 0x00c0, 0x178e: 0x00c0, 0x178f: 0x00c0, 0x1790: 0x00c0, 0x1791: 0x00c0, + 0x1792: 0x00c0, 0x1793: 0x00c0, 0x1794: 0x00c0, 0x1795: 0x00c0, 0x1796: 0x00c0, 0x1797: 0x00c0, + 0x1798: 0x00c0, 0x1799: 0x00c0, 0x179a: 0x00c0, 0x179b: 0x00c0, 0x179c: 0x00c0, 0x179d: 0x00c0, + 0x179e: 0x00c0, 0x179f: 0x00c0, 0x17a0: 0x00c0, 0x17a1: 0x00c0, 0x17a2: 0x00c0, 0x17a3: 0x00c0, + 0x17a4: 0x00c0, 0x17a5: 0x00c0, 0x17a6: 0x00c3, 0x17a7: 0x00c0, 0x17a8: 0x00c3, 0x17a9: 0x00c3, + 0x17aa: 0x00c0, 0x17ab: 0x00c0, 0x17ac: 0x00c0, 0x17ad: 0x00c3, 0x17ae: 0x00c0, 0x17af: 0x00c3, + 0x17b0: 0x00c3, 0x17b1: 0x00c3, 0x17b2: 0x00c5, 0x17b3: 0x00c5, + 0x17bc: 0x0080, 0x17bd: 0x0080, 0x17be: 0x0080, 0x17bf: 0x0080, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x00c0, 0x17c1: 0x00c0, 0x17c2: 0x00c0, 0x17c3: 0x00c0, 0x17c4: 0x00c0, 0x17c5: 0x00c0, + 0x17c6: 0x00c0, 0x17c7: 0x00c0, 0x17c8: 0x00c0, 0x17c9: 0x00c0, 0x17ca: 0x00c0, 0x17cb: 0x00c0, + 0x17cc: 0x00c0, 0x17cd: 0x00c0, 0x17ce: 0x00c0, 0x17cf: 0x00c0, 0x17d0: 0x00c0, 0x17d1: 0x00c0, + 0x17d2: 0x00c0, 0x17d3: 0x00c0, 0x17d4: 0x00c0, 0x17d5: 0x00c0, 0x17d6: 0x00c0, 0x17d7: 0x00c0, + 0x17d8: 0x00c0, 0x17d9: 0x00c0, 0x17da: 0x00c0, 0x17db: 0x00c0, 0x17dc: 0x00c0, 0x17dd: 0x00c0, + 0x17de: 0x00c0, 0x17df: 0x00c0, 0x17e0: 0x00c0, 0x17e1: 0x00c0, 0x17e2: 0x00c0, 0x17e3: 0x00c0, + 0x17e4: 0x00c0, 0x17e5: 0x00c0, 0x17e6: 0x00c0, 0x17e7: 0x00c0, 0x17e8: 0x00c0, 0x17e9: 0x00c0, + 0x17ea: 0x00c0, 0x17eb: 0x00c0, 0x17ec: 0x00c3, 0x17ed: 0x00c3, 0x17ee: 0x00c3, 0x17ef: 0x00c3, + 0x17f0: 0x00c3, 0x17f1: 0x00c3, 0x17f2: 0x00c3, 0x17f3: 0x00c3, 0x17f4: 0x00c0, 0x17f5: 0x00c0, + 0x17f6: 0x00c3, 0x17f7: 0x00c3, 0x17fb: 0x0080, + 0x17fc: 0x0080, 0x17fd: 0x0080, 0x17fe: 0x0080, 0x17ff: 0x0080, + // Block 0x60, offset 0x1800 + 0x1800: 0x00c0, 0x1801: 0x00c0, 0x1802: 0x00c0, 0x1803: 0x00c0, 0x1804: 0x00c0, 0x1805: 0x00c0, + 0x1806: 0x00c0, 0x1807: 0x00c0, 0x1808: 0x00c0, 0x1809: 0x00c0, + 0x180d: 0x00c0, 0x180e: 0x00c0, 0x180f: 0x00c0, 0x1810: 0x00c0, 0x1811: 0x00c0, + 0x1812: 0x00c0, 0x1813: 0x00c0, 0x1814: 0x00c0, 0x1815: 0x00c0, 0x1816: 0x00c0, 0x1817: 0x00c0, + 0x1818: 0x00c0, 0x1819: 0x00c0, 0x181a: 0x00c0, 0x181b: 0x00c0, 0x181c: 0x00c0, 0x181d: 0x00c0, + 0x181e: 0x00c0, 0x181f: 0x00c0, 0x1820: 0x00c0, 0x1821: 0x00c0, 0x1822: 0x00c0, 0x1823: 0x00c0, + 0x1824: 0x00c0, 0x1825: 0x00c0, 0x1826: 0x00c0, 0x1827: 0x00c0, 0x1828: 0x00c0, 0x1829: 0x00c0, + 0x182a: 0x00c0, 0x182b: 0x00c0, 0x182c: 0x00c0, 0x182d: 0x00c0, 0x182e: 0x00c0, 0x182f: 0x00c0, + 0x1830: 0x00c0, 0x1831: 0x00c0, 0x1832: 0x00c0, 0x1833: 0x00c0, 0x1834: 0x00c0, 0x1835: 0x00c0, + 0x1836: 0x00c0, 0x1837: 0x00c0, 0x1838: 0x00c0, 0x1839: 0x00c0, 0x183a: 0x00c0, 0x183b: 0x00c0, + 0x183c: 0x00c0, 0x183d: 0x00c0, 0x183e: 0x0080, 0x183f: 0x0080, + // Block 0x61, offset 0x1840 + 0x1840: 0x00c0, 0x1841: 0x00c0, 0x1842: 0x00c0, 0x1843: 0x00c0, 0x1844: 0x00c0, 0x1845: 0x00c0, + 0x1846: 0x00c0, 0x1847: 0x00c0, 0x1848: 0x00c0, + 0x1850: 0x00c0, 0x1851: 0x00c0, + 0x1852: 0x00c0, 0x1853: 0x00c0, 0x1854: 0x00c0, 0x1855: 0x00c0, 0x1856: 0x00c0, 0x1857: 0x00c0, + 0x1858: 0x00c0, 0x1859: 0x00c0, 0x185a: 0x00c0, 0x185b: 0x00c0, 0x185c: 0x00c0, 0x185d: 0x00c0, + 0x185e: 0x00c0, 0x185f: 0x00c0, 0x1860: 0x00c0, 0x1861: 0x00c0, 0x1862: 0x00c0, 0x1863: 0x00c0, + 0x1864: 0x00c0, 0x1865: 0x00c0, 0x1866: 0x00c0, 0x1867: 0x00c0, 0x1868: 0x00c0, 0x1869: 0x00c0, + 0x186a: 0x00c0, 0x186b: 0x00c0, 0x186c: 0x00c0, 0x186d: 0x00c0, 0x186e: 0x00c0, 0x186f: 0x00c0, + 0x1870: 0x00c0, 0x1871: 0x00c0, 0x1872: 0x00c0, 0x1873: 0x00c0, 0x1874: 0x00c0, 0x1875: 0x00c0, + 0x1876: 0x00c0, 0x1877: 0x00c0, 0x1878: 0x00c0, 0x1879: 0x00c0, 0x187a: 0x00c0, + 0x187d: 0x00c0, 0x187e: 0x00c0, 0x187f: 0x00c0, + // Block 0x62, offset 0x1880 + 0x1880: 0x0080, 0x1881: 0x0080, 0x1882: 0x0080, 0x1883: 0x0080, 0x1884: 0x0080, 0x1885: 0x0080, + 0x1886: 0x0080, 0x1887: 0x0080, + 0x1890: 0x00c3, 0x1891: 0x00c3, + 0x1892: 0x00c3, 0x1893: 0x0080, 0x1894: 0x00c3, 0x1895: 0x00c3, 0x1896: 0x00c3, 0x1897: 0x00c3, + 0x1898: 0x00c3, 0x1899: 0x00c3, 0x189a: 0x00c3, 0x189b: 0x00c3, 0x189c: 0x00c3, 0x189d: 0x00c3, + 0x189e: 0x00c3, 0x189f: 0x00c3, 0x18a0: 0x00c3, 0x18a1: 0x00c0, 0x18a2: 0x00c3, 0x18a3: 0x00c3, + 0x18a4: 0x00c3, 0x18a5: 0x00c3, 0x18a6: 0x00c3, 0x18a7: 0x00c3, 0x18a8: 0x00c3, 0x18a9: 0x00c0, + 0x18aa: 0x00c0, 0x18ab: 0x00c0, 0x18ac: 0x00c0, 0x18ad: 0x00c3, 0x18ae: 0x00c0, 0x18af: 0x00c0, + 0x18b0: 0x00c0, 0x18b1: 0x00c0, 0x18b2: 0x00c0, 0x18b3: 0x00c0, 0x18b4: 0x00c3, 0x18b5: 0x00c0, + 0x18b6: 0x00c0, 0x18b7: 0x00c0, 0x18b8: 0x00c3, 0x18b9: 0x00c3, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x00c0, 0x18c1: 0x00c0, 0x18c2: 0x00c0, 0x18c3: 0x00c0, 0x18c4: 0x00c0, 0x18c5: 0x00c0, + 0x18c6: 0x00c0, 0x18c7: 0x00c0, 0x18c8: 0x00c0, 0x18c9: 0x00c0, 0x18ca: 0x00c0, 0x18cb: 0x00c0, + 0x18cc: 0x00c0, 0x18cd: 0x00c0, 0x18ce: 0x00c0, 0x18cf: 0x00c0, 0x18d0: 0x00c0, 0x18d1: 0x00c0, + 0x18d2: 0x00c0, 0x18d3: 0x00c0, 0x18d4: 0x00c0, 0x18d5: 0x00c0, 0x18d6: 0x00c0, 0x18d7: 0x00c0, + 0x18d8: 0x00c0, 0x18d9: 0x00c0, 0x18da: 0x00c0, 0x18db: 0x00c0, 0x18dc: 0x00c0, 0x18dd: 0x00c0, + 0x18de: 0x00c0, 0x18df: 0x00c0, 0x18e0: 0x00c0, 0x18e1: 0x00c0, 0x18e2: 0x00c0, 0x18e3: 0x00c0, + 0x18e4: 0x00c0, 0x18e5: 0x00c0, 0x18e6: 0x00c8, 0x18e7: 0x00c8, 0x18e8: 0x00c8, 0x18e9: 0x00c8, + 0x18ea: 0x00c8, 0x18eb: 0x00c0, 0x18ec: 0x0080, 0x18ed: 0x0080, 0x18ee: 0x0080, 0x18ef: 0x00c0, + 0x18f0: 0x0080, 0x18f1: 0x0080, 0x18f2: 0x0080, 0x18f3: 0x0080, 0x18f4: 0x0080, 0x18f5: 0x0080, + 0x18f6: 0x0080, 0x18f7: 0x0080, 0x18f8: 0x0080, 0x18f9: 0x0080, 0x18fa: 0x0080, 0x18fb: 0x00c0, + 0x18fc: 0x0080, 0x18fd: 0x0080, 0x18fe: 0x0080, 0x18ff: 0x0080, + // Block 0x64, offset 0x1900 + 0x1900: 0x0080, 0x1901: 0x0080, 0x1902: 0x0080, 0x1903: 0x0080, 0x1904: 0x0080, 0x1905: 0x0080, + 0x1906: 0x0080, 0x1907: 0x0080, 0x1908: 0x0080, 0x1909: 0x0080, 0x190a: 0x0080, 0x190b: 0x0080, + 0x190c: 0x0080, 0x190d: 0x0080, 0x190e: 0x00c0, 0x190f: 0x0080, 0x1910: 0x0080, 0x1911: 0x0080, + 0x1912: 0x0080, 0x1913: 0x0080, 0x1914: 0x0080, 0x1915: 0x0080, 0x1916: 0x0080, 0x1917: 0x0080, + 0x1918: 0x0080, 0x1919: 0x0080, 0x191a: 0x0080, 0x191b: 0x0080, 0x191c: 0x0080, 0x191d: 0x0088, + 0x191e: 0x0088, 0x191f: 0x0088, 0x1920: 0x0088, 0x1921: 0x0088, 0x1922: 0x0080, 0x1923: 0x0080, + 0x1924: 0x0080, 0x1925: 0x0080, 0x1926: 0x0088, 0x1927: 0x0088, 0x1928: 0x0088, 0x1929: 0x0088, + 0x192a: 0x0088, 0x192b: 0x00c0, 0x192c: 0x00c0, 0x192d: 0x00c0, 0x192e: 0x00c0, 0x192f: 0x00c0, + 0x1930: 0x00c0, 0x1931: 0x00c0, 0x1932: 0x00c0, 0x1933: 0x00c0, 0x1934: 0x00c0, 0x1935: 0x00c0, + 0x1936: 0x00c0, 0x1937: 0x00c0, 0x1938: 0x0080, 0x1939: 0x00c0, 0x193a: 0x00c0, 0x193b: 0x00c0, + 0x193c: 0x00c0, 0x193d: 0x00c0, 0x193e: 0x00c0, 0x193f: 0x00c0, + // Block 0x65, offset 0x1940 + 0x1940: 0x00c0, 0x1941: 0x00c0, 0x1942: 0x00c0, 0x1943: 0x00c0, 0x1944: 0x00c0, 0x1945: 0x00c0, + 0x1946: 0x00c0, 0x1947: 0x00c0, 0x1948: 0x00c0, 0x1949: 0x00c0, 0x194a: 0x00c0, 0x194b: 0x00c0, + 0x194c: 0x00c0, 0x194d: 0x00c0, 0x194e: 0x00c0, 0x194f: 0x00c0, 0x1950: 0x00c0, 0x1951: 0x00c0, + 0x1952: 0x00c0, 0x1953: 0x00c0, 0x1954: 0x00c0, 0x1955: 0x00c0, 0x1956: 0x00c0, 0x1957: 0x00c0, + 0x1958: 0x00c0, 0x1959: 0x00c0, 0x195a: 0x00c0, 0x195b: 0x0080, 0x195c: 0x0080, 0x195d: 0x0080, + 0x195e: 0x0080, 0x195f: 0x0080, 0x1960: 0x0080, 0x1961: 0x0080, 0x1962: 0x0080, 0x1963: 0x0080, + 0x1964: 0x0080, 0x1965: 0x0080, 0x1966: 0x0080, 0x1967: 0x0080, 0x1968: 0x0080, 0x1969: 0x0080, + 0x196a: 0x0080, 0x196b: 0x0080, 0x196c: 0x0080, 0x196d: 0x0080, 0x196e: 0x0080, 0x196f: 0x0080, + 0x1970: 0x0080, 0x1971: 0x0080, 0x1972: 0x0080, 0x1973: 0x0080, 0x1974: 0x0080, 0x1975: 0x0080, + 0x1976: 0x0080, 0x1977: 0x0080, 0x1978: 0x0080, 0x1979: 0x0080, 0x197a: 0x0080, 0x197b: 0x0080, + 0x197c: 0x0080, 0x197d: 0x0080, 0x197e: 0x0080, 0x197f: 0x0088, + // Block 0x66, offset 0x1980 + 0x1980: 0x00c3, 0x1981: 0x00c3, 0x1982: 0x00c3, 0x1983: 0x00c3, 0x1984: 0x00c3, 0x1985: 0x00c3, + 0x1986: 0x00c3, 0x1987: 0x00c3, 0x1988: 0x00c3, 0x1989: 0x00c3, 0x198a: 0x00c3, 0x198b: 0x00c3, + 0x198c: 0x00c3, 0x198d: 0x00c3, 0x198e: 0x00c3, 0x198f: 0x00c3, 0x1990: 0x00c3, 0x1991: 0x00c3, + 0x1992: 0x00c3, 0x1993: 0x00c3, 0x1994: 0x00c3, 0x1995: 0x00c3, 0x1996: 0x00c3, 0x1997: 0x00c3, + 0x1998: 0x00c3, 0x1999: 0x00c3, 0x199a: 0x00c3, 0x199b: 0x00c3, 0x199c: 0x00c3, 0x199d: 0x00c3, + 0x199e: 0x00c3, 0x199f: 0x00c3, 0x19a0: 0x00c3, 0x19a1: 0x00c3, 0x19a2: 0x00c3, 0x19a3: 0x00c3, + 0x19a4: 0x00c3, 0x19a5: 0x00c3, 0x19a6: 0x00c3, 0x19a7: 0x00c3, 0x19a8: 0x00c3, 0x19a9: 0x00c3, + 0x19aa: 0x00c3, 0x19ab: 0x00c3, 0x19ac: 0x00c3, 0x19ad: 0x00c3, 0x19ae: 0x00c3, 0x19af: 0x00c3, + 0x19b0: 0x00c3, 0x19b1: 0x00c3, 0x19b2: 0x00c3, 0x19b3: 0x00c3, 0x19b4: 0x00c3, 0x19b5: 0x00c3, + 0x19b6: 0x00c3, 0x19b7: 0x00c3, 0x19b8: 0x00c3, 0x19b9: 0x00c3, 0x19bb: 0x00c3, + 0x19bc: 0x00c3, 0x19bd: 0x00c3, 0x19be: 0x00c3, 0x19bf: 0x00c3, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x00c0, 0x19c1: 0x00c0, 0x19c2: 0x00c0, 0x19c3: 0x00c0, 0x19c4: 0x00c0, 0x19c5: 0x00c0, + 0x19c6: 0x00c0, 0x19c7: 0x00c0, 0x19c8: 0x00c0, 0x19c9: 0x00c0, 0x19ca: 0x00c0, 0x19cb: 0x00c0, + 0x19cc: 0x00c0, 0x19cd: 0x00c0, 0x19ce: 0x00c0, 0x19cf: 0x00c0, 0x19d0: 0x00c0, 0x19d1: 0x00c0, + 0x19d2: 0x00c0, 0x19d3: 0x00c0, 0x19d4: 0x00c0, 0x19d5: 0x00c0, 0x19d6: 0x00c0, 0x19d7: 0x00c0, + 0x19d8: 0x00c0, 0x19d9: 0x00c0, 0x19da: 0x0080, 0x19db: 0x0080, 0x19dc: 0x00c0, 0x19dd: 0x00c0, + 0x19de: 0x00c0, 0x19df: 0x00c0, 0x19e0: 0x00c0, 0x19e1: 0x00c0, 0x19e2: 0x00c0, 0x19e3: 0x00c0, + 0x19e4: 0x00c0, 0x19e5: 0x00c0, 0x19e6: 0x00c0, 0x19e7: 0x00c0, 0x19e8: 0x00c0, 0x19e9: 0x00c0, + 0x19ea: 0x00c0, 0x19eb: 0x00c0, 0x19ec: 0x00c0, 0x19ed: 0x00c0, 0x19ee: 0x00c0, 0x19ef: 0x00c0, + 0x19f0: 0x00c0, 0x19f1: 0x00c0, 0x19f2: 0x00c0, 0x19f3: 0x00c0, 0x19f4: 0x00c0, 0x19f5: 0x00c0, + 0x19f6: 0x00c0, 0x19f7: 0x00c0, 0x19f8: 0x00c0, 0x19f9: 0x00c0, 0x19fa: 0x00c0, 0x19fb: 0x00c0, + 0x19fc: 0x00c0, 0x19fd: 0x00c0, 0x19fe: 0x00c0, 0x19ff: 0x00c0, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x00c8, 0x1a01: 0x00c8, 0x1a02: 0x00c8, 0x1a03: 0x00c8, 0x1a04: 0x00c8, 0x1a05: 0x00c8, + 0x1a06: 0x00c8, 0x1a07: 0x00c8, 0x1a08: 0x00c8, 0x1a09: 0x00c8, 0x1a0a: 0x00c8, 0x1a0b: 0x00c8, + 0x1a0c: 0x00c8, 0x1a0d: 0x00c8, 0x1a0e: 0x00c8, 0x1a0f: 0x00c8, 0x1a10: 0x00c8, 0x1a11: 0x00c8, + 0x1a12: 0x00c8, 0x1a13: 0x00c8, 0x1a14: 0x00c8, 0x1a15: 0x00c8, + 0x1a18: 0x00c8, 0x1a19: 0x00c8, 0x1a1a: 0x00c8, 0x1a1b: 0x00c8, 0x1a1c: 0x00c8, 0x1a1d: 0x00c8, + 0x1a20: 0x00c8, 0x1a21: 0x00c8, 0x1a22: 0x00c8, 0x1a23: 0x00c8, + 0x1a24: 0x00c8, 0x1a25: 0x00c8, 0x1a26: 0x00c8, 0x1a27: 0x00c8, 0x1a28: 0x00c8, 0x1a29: 0x00c8, + 0x1a2a: 0x00c8, 0x1a2b: 0x00c8, 0x1a2c: 0x00c8, 0x1a2d: 0x00c8, 0x1a2e: 0x00c8, 0x1a2f: 0x00c8, + 0x1a30: 0x00c8, 0x1a31: 0x00c8, 0x1a32: 0x00c8, 0x1a33: 0x00c8, 0x1a34: 0x00c8, 0x1a35: 0x00c8, + 0x1a36: 0x00c8, 0x1a37: 0x00c8, 0x1a38: 0x00c8, 0x1a39: 0x00c8, 0x1a3a: 0x00c8, 0x1a3b: 0x00c8, + 0x1a3c: 0x00c8, 0x1a3d: 0x00c8, 0x1a3e: 0x00c8, 0x1a3f: 0x00c8, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x00c8, 0x1a41: 0x00c8, 0x1a42: 0x00c8, 0x1a43: 0x00c8, 0x1a44: 0x00c8, 0x1a45: 0x00c8, + 0x1a48: 0x00c8, 0x1a49: 0x00c8, 0x1a4a: 0x00c8, 0x1a4b: 0x00c8, + 0x1a4c: 0x00c8, 0x1a4d: 0x00c8, 0x1a50: 0x00c8, 0x1a51: 0x00c8, + 0x1a52: 0x00c8, 0x1a53: 0x00c8, 0x1a54: 0x00c8, 0x1a55: 0x00c8, 0x1a56: 0x00c8, 0x1a57: 0x00c8, + 0x1a59: 0x00c8, 0x1a5b: 0x00c8, 0x1a5d: 0x00c8, + 0x1a5f: 0x00c8, 0x1a60: 0x00c8, 0x1a61: 0x00c8, 0x1a62: 0x00c8, 0x1a63: 0x00c8, + 0x1a64: 0x00c8, 0x1a65: 0x00c8, 0x1a66: 0x00c8, 0x1a67: 0x00c8, 0x1a68: 0x00c8, 0x1a69: 0x00c8, + 0x1a6a: 0x00c8, 0x1a6b: 0x00c8, 0x1a6c: 0x00c8, 0x1a6d: 0x00c8, 0x1a6e: 0x00c8, 0x1a6f: 0x00c8, + 0x1a70: 0x00c8, 0x1a71: 0x0088, 0x1a72: 0x00c8, 0x1a73: 0x0088, 0x1a74: 0x00c8, 0x1a75: 0x0088, + 0x1a76: 0x00c8, 0x1a77: 0x0088, 0x1a78: 0x00c8, 0x1a79: 0x0088, 0x1a7a: 0x00c8, 0x1a7b: 0x0088, + 0x1a7c: 0x00c8, 0x1a7d: 0x0088, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x00c8, 0x1a81: 0x00c8, 0x1a82: 0x00c8, 0x1a83: 0x00c8, 0x1a84: 0x00c8, 0x1a85: 0x00c8, + 0x1a86: 0x00c8, 0x1a87: 0x00c8, 0x1a88: 0x0088, 0x1a89: 0x0088, 0x1a8a: 0x0088, 0x1a8b: 0x0088, + 0x1a8c: 0x0088, 0x1a8d: 0x0088, 0x1a8e: 0x0088, 0x1a8f: 0x0088, 0x1a90: 0x00c8, 0x1a91: 0x00c8, + 0x1a92: 0x00c8, 0x1a93: 0x00c8, 0x1a94: 0x00c8, 0x1a95: 0x00c8, 0x1a96: 0x00c8, 0x1a97: 0x00c8, + 0x1a98: 0x0088, 0x1a99: 0x0088, 0x1a9a: 0x0088, 0x1a9b: 0x0088, 0x1a9c: 0x0088, 0x1a9d: 0x0088, + 0x1a9e: 0x0088, 0x1a9f: 0x0088, 0x1aa0: 0x00c8, 0x1aa1: 0x00c8, 0x1aa2: 0x00c8, 0x1aa3: 0x00c8, + 0x1aa4: 0x00c8, 0x1aa5: 0x00c8, 0x1aa6: 0x00c8, 0x1aa7: 0x00c8, 0x1aa8: 0x0088, 0x1aa9: 0x0088, + 0x1aaa: 0x0088, 0x1aab: 0x0088, 0x1aac: 0x0088, 0x1aad: 0x0088, 0x1aae: 0x0088, 0x1aaf: 0x0088, + 0x1ab0: 0x00c8, 0x1ab1: 0x00c8, 0x1ab2: 0x00c8, 0x1ab3: 0x00c8, 0x1ab4: 0x00c8, + 0x1ab6: 0x00c8, 0x1ab7: 0x00c8, 0x1ab8: 0x00c8, 0x1ab9: 0x00c8, 0x1aba: 0x00c8, 0x1abb: 0x0088, + 0x1abc: 0x0088, 0x1abd: 0x0088, 0x1abe: 0x0088, 0x1abf: 0x0088, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x0088, 0x1ac1: 0x0088, 0x1ac2: 0x00c8, 0x1ac3: 0x00c8, 0x1ac4: 0x00c8, + 0x1ac6: 0x00c8, 0x1ac7: 0x00c8, 0x1ac8: 0x00c8, 0x1ac9: 0x0088, 0x1aca: 0x00c8, 0x1acb: 0x0088, + 0x1acc: 0x0088, 0x1acd: 0x0088, 0x1ace: 0x0088, 0x1acf: 0x0088, 0x1ad0: 0x00c8, 0x1ad1: 0x00c8, + 0x1ad2: 0x00c8, 0x1ad3: 0x0088, 0x1ad6: 0x00c8, 0x1ad7: 0x00c8, + 0x1ad8: 0x00c8, 0x1ad9: 0x00c8, 0x1ada: 0x00c8, 0x1adb: 0x0088, 0x1add: 0x0088, + 0x1ade: 0x0088, 0x1adf: 0x0088, 0x1ae0: 0x00c8, 0x1ae1: 0x00c8, 0x1ae2: 0x00c8, 0x1ae3: 0x0088, + 0x1ae4: 0x00c8, 0x1ae5: 0x00c8, 0x1ae6: 0x00c8, 0x1ae7: 0x00c8, 0x1ae8: 0x00c8, 0x1ae9: 0x00c8, + 0x1aea: 0x00c8, 0x1aeb: 0x0088, 0x1aec: 0x00c8, 0x1aed: 0x0088, 0x1aee: 0x0088, 0x1aef: 0x0088, + 0x1af2: 0x00c8, 0x1af3: 0x00c8, 0x1af4: 0x00c8, + 0x1af6: 0x00c8, 0x1af7: 0x00c8, 0x1af8: 0x00c8, 0x1af9: 0x0088, 0x1afa: 0x00c8, 0x1afb: 0x0088, + 0x1afc: 0x0088, 0x1afd: 0x0088, 0x1afe: 0x0088, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x0080, 0x1b01: 0x0080, 0x1b02: 0x0080, 0x1b03: 0x0080, 0x1b04: 0x0080, 0x1b05: 0x0080, + 0x1b06: 0x0080, 0x1b07: 0x0080, 0x1b08: 0x0080, 0x1b09: 0x0080, 0x1b0a: 0x0080, 0x1b0b: 0x0040, + 0x1b0c: 0x004d, 0x1b0d: 0x004e, 0x1b0e: 0x0040, 0x1b0f: 0x0040, 0x1b10: 0x0080, 0x1b11: 0x0080, + 0x1b12: 0x0080, 0x1b13: 0x0080, 0x1b14: 0x0080, 0x1b15: 0x0080, 0x1b16: 0x0080, 0x1b17: 0x0080, + 0x1b18: 0x0080, 0x1b19: 0x0080, 0x1b1a: 0x0080, 0x1b1b: 0x0080, 0x1b1c: 0x0080, 0x1b1d: 0x0080, + 0x1b1e: 0x0080, 0x1b1f: 0x0080, 0x1b20: 0x0080, 0x1b21: 0x0080, 0x1b22: 0x0080, 0x1b23: 0x0080, + 0x1b24: 0x0080, 0x1b25: 0x0080, 0x1b26: 0x0080, 0x1b27: 0x0080, 0x1b28: 0x0040, 0x1b29: 0x0040, + 0x1b2a: 0x0040, 0x1b2b: 0x0040, 0x1b2c: 0x0040, 0x1b2d: 0x0040, 0x1b2e: 0x0040, 0x1b2f: 0x0080, + 0x1b30: 0x0080, 0x1b31: 0x0080, 0x1b32: 0x0080, 0x1b33: 0x0080, 0x1b34: 0x0080, 0x1b35: 0x0080, + 0x1b36: 0x0080, 0x1b37: 0x0080, 0x1b38: 0x0080, 0x1b39: 0x0080, 0x1b3a: 0x0080, 0x1b3b: 0x0080, + 0x1b3c: 0x0080, 0x1b3d: 0x0080, 0x1b3e: 0x0080, 0x1b3f: 0x0080, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x0080, 0x1b41: 0x0080, 0x1b42: 0x0080, 0x1b43: 0x0080, 0x1b44: 0x0080, 0x1b45: 0x0080, + 0x1b46: 0x0080, 0x1b47: 0x0080, 0x1b48: 0x0080, 0x1b49: 0x0080, 0x1b4a: 0x0080, 0x1b4b: 0x0080, + 0x1b4c: 0x0080, 0x1b4d: 0x0080, 0x1b4e: 0x0080, 0x1b4f: 0x0080, 0x1b50: 0x0080, 0x1b51: 0x0080, + 0x1b52: 0x0080, 0x1b53: 0x0080, 0x1b54: 0x0080, 0x1b55: 0x0080, 0x1b56: 0x0080, 0x1b57: 0x0080, + 0x1b58: 0x0080, 0x1b59: 0x0080, 0x1b5a: 0x0080, 0x1b5b: 0x0080, 0x1b5c: 0x0080, 0x1b5d: 0x0080, + 0x1b5e: 0x0080, 0x1b5f: 0x0080, 0x1b60: 0x0040, 0x1b61: 0x0040, 0x1b62: 0x0040, 0x1b63: 0x0040, + 0x1b64: 0x0040, 0x1b66: 0x0040, 0x1b67: 0x0040, 0x1b68: 0x0040, 0x1b69: 0x0040, + 0x1b6a: 0x0040, 0x1b6b: 0x0040, 0x1b6c: 0x0040, 0x1b6d: 0x0040, 0x1b6e: 0x0040, 0x1b6f: 0x0040, + 0x1b70: 0x0080, 0x1b71: 0x0080, 0x1b74: 0x0080, 0x1b75: 0x0080, + 0x1b76: 0x0080, 0x1b77: 0x0080, 0x1b78: 0x0080, 0x1b79: 0x0080, 0x1b7a: 0x0080, 0x1b7b: 0x0080, + 0x1b7c: 0x0080, 0x1b7d: 0x0080, 0x1b7e: 0x0080, 0x1b7f: 0x0080, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x0080, 0x1b81: 0x0080, 0x1b82: 0x0080, 0x1b83: 0x0080, 0x1b84: 0x0080, 0x1b85: 0x0080, + 0x1b86: 0x0080, 0x1b87: 0x0080, 0x1b88: 0x0080, 0x1b89: 0x0080, 0x1b8a: 0x0080, 0x1b8b: 0x0080, + 0x1b8c: 0x0080, 0x1b8d: 0x0080, 0x1b8e: 0x0080, 0x1b90: 0x0080, 0x1b91: 0x0080, + 0x1b92: 0x0080, 0x1b93: 0x0080, 0x1b94: 0x0080, 0x1b95: 0x0080, 0x1b96: 0x0080, 0x1b97: 0x0080, + 0x1b98: 0x0080, 0x1b99: 0x0080, 0x1b9a: 0x0080, 0x1b9b: 0x0080, 0x1b9c: 0x0080, + 0x1ba0: 0x0080, 0x1ba1: 0x0080, 0x1ba2: 0x0080, 0x1ba3: 0x0080, + 0x1ba4: 0x0080, 0x1ba5: 0x0080, 0x1ba6: 0x0080, 0x1ba7: 0x0080, 0x1ba8: 0x0080, 0x1ba9: 0x0080, + 0x1baa: 0x0080, 0x1bab: 0x0080, 0x1bac: 0x0080, 0x1bad: 0x0080, 0x1bae: 0x0080, 0x1baf: 0x0080, + 0x1bb0: 0x0080, 0x1bb1: 0x0080, 0x1bb2: 0x0080, 0x1bb3: 0x0080, 0x1bb4: 0x0080, 0x1bb5: 0x0080, + 0x1bb6: 0x0080, 0x1bb7: 0x0080, 0x1bb8: 0x0080, 0x1bb9: 0x0080, 0x1bba: 0x0080, 0x1bbb: 0x0080, + 0x1bbc: 0x0080, 0x1bbd: 0x0080, 0x1bbe: 0x0080, 0x1bbf: 0x0080, + // Block 0x6f, offset 0x1bc0 + 0x1bd0: 0x00c3, 0x1bd1: 0x00c3, + 0x1bd2: 0x00c3, 0x1bd3: 0x00c3, 0x1bd4: 0x00c3, 0x1bd5: 0x00c3, 0x1bd6: 0x00c3, 0x1bd7: 0x00c3, + 0x1bd8: 0x00c3, 0x1bd9: 0x00c3, 0x1bda: 0x00c3, 0x1bdb: 0x00c3, 0x1bdc: 0x00c3, 0x1bdd: 0x0083, + 0x1bde: 0x0083, 0x1bdf: 0x0083, 0x1be0: 0x0083, 0x1be1: 0x00c3, 0x1be2: 0x0083, 0x1be3: 0x0083, + 0x1be4: 0x0083, 0x1be5: 0x00c3, 0x1be6: 0x00c3, 0x1be7: 0x00c3, 0x1be8: 0x00c3, 0x1be9: 0x00c3, + 0x1bea: 0x00c3, 0x1beb: 0x00c3, 0x1bec: 0x00c3, 0x1bed: 0x00c3, 0x1bee: 0x00c3, 0x1bef: 0x00c3, + 0x1bf0: 0x00c3, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x0080, 0x1c01: 0x0080, 0x1c02: 0x0080, 0x1c03: 0x0080, 0x1c04: 0x0080, 0x1c05: 0x0080, + 0x1c06: 0x0080, 0x1c07: 0x0080, 0x1c08: 0x0080, 0x1c09: 0x0080, 0x1c0a: 0x0080, 0x1c0b: 0x0080, + 0x1c0c: 0x0080, 0x1c0d: 0x0080, 0x1c0e: 0x0080, 0x1c0f: 0x0080, 0x1c10: 0x0080, 0x1c11: 0x0080, + 0x1c12: 0x0080, 0x1c13: 0x0080, 0x1c14: 0x0080, 0x1c15: 0x0080, 0x1c16: 0x0080, 0x1c17: 0x0080, + 0x1c18: 0x0080, 0x1c19: 0x0080, 0x1c1a: 0x0080, 0x1c1b: 0x0080, 0x1c1c: 0x0080, 0x1c1d: 0x0080, + 0x1c1e: 0x0080, 0x1c1f: 0x0080, 0x1c20: 0x0080, 0x1c21: 0x0080, 0x1c22: 0x0080, 0x1c23: 0x0080, + 0x1c24: 0x0080, 0x1c25: 0x0080, 0x1c26: 0x0088, 0x1c27: 0x0080, 0x1c28: 0x0080, 0x1c29: 0x0080, + 0x1c2a: 0x0080, 0x1c2b: 0x0080, 0x1c2c: 0x0080, 0x1c2d: 0x0080, 0x1c2e: 0x0080, 0x1c2f: 0x0080, + 0x1c30: 0x0080, 0x1c31: 0x0080, 0x1c32: 0x00c0, 0x1c33: 0x0080, 0x1c34: 0x0080, 0x1c35: 0x0080, + 0x1c36: 0x0080, 0x1c37: 0x0080, 0x1c38: 0x0080, 0x1c39: 0x0080, 0x1c3a: 0x0080, 0x1c3b: 0x0080, + 0x1c3c: 0x0080, 0x1c3d: 0x0080, 0x1c3e: 0x0080, 0x1c3f: 0x0080, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x0080, 0x1c41: 0x0080, 0x1c42: 0x0080, 0x1c43: 0x0080, 0x1c44: 0x0080, 0x1c45: 0x0080, + 0x1c46: 0x0080, 0x1c47: 0x0080, 0x1c48: 0x0080, 0x1c49: 0x0080, 0x1c4a: 0x0080, 0x1c4b: 0x0080, + 0x1c4c: 0x0080, 0x1c4d: 0x0080, 0x1c4e: 0x00c0, 0x1c4f: 0x0080, 0x1c50: 0x0080, 0x1c51: 0x0080, + 0x1c52: 0x0080, 0x1c53: 0x0080, 0x1c54: 0x0080, 0x1c55: 0x0080, 0x1c56: 0x0080, 0x1c57: 0x0080, + 0x1c58: 0x0080, 0x1c59: 0x0080, 0x1c5a: 0x0080, 0x1c5b: 0x0080, 0x1c5c: 0x0080, 0x1c5d: 0x0080, + 0x1c5e: 0x0080, 0x1c5f: 0x0080, 0x1c60: 0x0080, 0x1c61: 0x0080, 0x1c62: 0x0080, 0x1c63: 0x0080, + 0x1c64: 0x0080, 0x1c65: 0x0080, 0x1c66: 0x0080, 0x1c67: 0x0080, 0x1c68: 0x0080, 0x1c69: 0x0080, + 0x1c6a: 0x0080, 0x1c6b: 0x0080, 0x1c6c: 0x0080, 0x1c6d: 0x0080, 0x1c6e: 0x0080, 0x1c6f: 0x0080, + 0x1c70: 0x0080, 0x1c71: 0x0080, 0x1c72: 0x0080, 0x1c73: 0x0080, 0x1c74: 0x0080, 0x1c75: 0x0080, + 0x1c76: 0x0080, 0x1c77: 0x0080, 0x1c78: 0x0080, 0x1c79: 0x0080, 0x1c7a: 0x0080, 0x1c7b: 0x0080, + 0x1c7c: 0x0080, 0x1c7d: 0x0080, 0x1c7e: 0x0080, 0x1c7f: 0x0080, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x0080, 0x1c81: 0x0080, 0x1c82: 0x0080, 0x1c83: 0x00c0, 0x1c84: 0x00c0, 0x1c85: 0x0080, + 0x1c86: 0x0080, 0x1c87: 0x0080, 0x1c88: 0x0080, 0x1c89: 0x0080, 0x1c8a: 0x0080, 0x1c8b: 0x0080, + 0x1c90: 0x0080, 0x1c91: 0x0080, + 0x1c92: 0x0080, 0x1c93: 0x0080, 0x1c94: 0x0080, 0x1c95: 0x0080, 0x1c96: 0x0080, 0x1c97: 0x0080, + 0x1c98: 0x0080, 0x1c99: 0x0080, 0x1c9a: 0x0080, 0x1c9b: 0x0080, 0x1c9c: 0x0080, 0x1c9d: 0x0080, + 0x1c9e: 0x0080, 0x1c9f: 0x0080, 0x1ca0: 0x0080, 0x1ca1: 0x0080, 0x1ca2: 0x0080, 0x1ca3: 0x0080, + 0x1ca4: 0x0080, 0x1ca5: 0x0080, 0x1ca6: 0x0080, 0x1ca7: 0x0080, 0x1ca8: 0x0080, 0x1ca9: 0x0080, + 0x1caa: 0x0080, 0x1cab: 0x0080, 0x1cac: 0x0080, 0x1cad: 0x0080, 0x1cae: 0x0080, 0x1caf: 0x0080, + 0x1cb0: 0x0080, 0x1cb1: 0x0080, 0x1cb2: 0x0080, 0x1cb3: 0x0080, 0x1cb4: 0x0080, 0x1cb5: 0x0080, + 0x1cb6: 0x0080, 0x1cb7: 0x0080, 0x1cb8: 0x0080, 0x1cb9: 0x0080, 0x1cba: 0x0080, 0x1cbb: 0x0080, + 0x1cbc: 0x0080, 0x1cbd: 0x0080, 0x1cbe: 0x0080, 0x1cbf: 0x0080, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0080, 0x1cc1: 0x0080, 0x1cc2: 0x0080, 0x1cc3: 0x0080, 0x1cc4: 0x0080, 0x1cc5: 0x0080, + 0x1cc6: 0x0080, 0x1cc7: 0x0080, 0x1cc8: 0x0080, 0x1cc9: 0x0080, 0x1cca: 0x0080, 0x1ccb: 0x0080, + 0x1ccc: 0x0080, 0x1ccd: 0x0080, 0x1cce: 0x0080, 0x1ccf: 0x0080, 0x1cd0: 0x0080, 0x1cd1: 0x0080, + 0x1cd2: 0x0080, 0x1cd3: 0x0080, 0x1cd4: 0x0080, 0x1cd5: 0x0080, 0x1cd6: 0x0080, 0x1cd7: 0x0080, + 0x1cd8: 0x0080, 0x1cd9: 0x0080, 0x1cda: 0x0080, 0x1cdb: 0x0080, 0x1cdc: 0x0080, 0x1cdd: 0x0080, + 0x1cde: 0x0080, 0x1cdf: 0x0080, 0x1ce0: 0x0080, 0x1ce1: 0x0080, 0x1ce2: 0x0080, 0x1ce3: 0x0080, + 0x1ce4: 0x0080, 0x1ce5: 0x0080, 0x1ce6: 0x0080, 0x1ce7: 0x0080, 0x1ce8: 0x0080, 0x1ce9: 0x0080, + 0x1cea: 0x0080, 0x1ceb: 0x0080, 0x1cec: 0x0080, 0x1ced: 0x0080, 0x1cee: 0x0080, 0x1cef: 0x0080, + 0x1cf0: 0x0080, 0x1cf1: 0x0080, 0x1cf2: 0x0080, 0x1cf3: 0x0080, 0x1cf4: 0x0080, 0x1cf5: 0x0080, + 0x1cf6: 0x0080, 0x1cf7: 0x0080, 0x1cf8: 0x0080, 0x1cf9: 0x0080, 0x1cfa: 0x0080, 0x1cfb: 0x0080, + 0x1cfc: 0x0080, 0x1cfd: 0x0080, 0x1cfe: 0x0080, 0x1cff: 0x0080, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0080, 0x1d01: 0x0080, 0x1d02: 0x0080, 0x1d03: 0x0080, 0x1d04: 0x0080, 0x1d05: 0x0080, + 0x1d06: 0x0080, 0x1d07: 0x0080, 0x1d08: 0x0080, 0x1d09: 0x0080, 0x1d0a: 0x0080, 0x1d0b: 0x0080, + 0x1d0c: 0x0080, 0x1d0d: 0x0080, 0x1d0e: 0x0080, 0x1d0f: 0x0080, 0x1d10: 0x0080, 0x1d11: 0x0080, + 0x1d12: 0x0080, 0x1d13: 0x0080, 0x1d14: 0x0080, 0x1d15: 0x0080, 0x1d16: 0x0080, 0x1d17: 0x0080, + 0x1d18: 0x0080, 0x1d19: 0x0080, 0x1d1a: 0x0080, 0x1d1b: 0x0080, 0x1d1c: 0x0080, 0x1d1d: 0x0080, + 0x1d1e: 0x0080, 0x1d1f: 0x0080, 0x1d20: 0x0080, 0x1d21: 0x0080, 0x1d22: 0x0080, 0x1d23: 0x0080, + 0x1d24: 0x0080, 0x1d25: 0x0080, 0x1d26: 0x0080, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0080, 0x1d41: 0x0080, 0x1d42: 0x0080, 0x1d43: 0x0080, 0x1d44: 0x0080, 0x1d45: 0x0080, + 0x1d46: 0x0080, 0x1d47: 0x0080, 0x1d48: 0x0080, 0x1d49: 0x0080, 0x1d4a: 0x0080, + 0x1d60: 0x0080, 0x1d61: 0x0080, 0x1d62: 0x0080, 0x1d63: 0x0080, + 0x1d64: 0x0080, 0x1d65: 0x0080, 0x1d66: 0x0080, 0x1d67: 0x0080, 0x1d68: 0x0080, 0x1d69: 0x0080, + 0x1d6a: 0x0080, 0x1d6b: 0x0080, 0x1d6c: 0x0080, 0x1d6d: 0x0080, 0x1d6e: 0x0080, 0x1d6f: 0x0080, + 0x1d70: 0x0080, 0x1d71: 0x0080, 0x1d72: 0x0080, 0x1d73: 0x0080, 0x1d74: 0x0080, 0x1d75: 0x0080, + 0x1d76: 0x0080, 0x1d77: 0x0080, 0x1d78: 0x0080, 0x1d79: 0x0080, 0x1d7a: 0x0080, 0x1d7b: 0x0080, + 0x1d7c: 0x0080, 0x1d7d: 0x0080, 0x1d7e: 0x0080, 0x1d7f: 0x0080, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x0080, 0x1d81: 0x0080, 0x1d82: 0x0080, 0x1d83: 0x0080, 0x1d84: 0x0080, 0x1d85: 0x0080, + 0x1d86: 0x0080, 0x1d87: 0x0080, 0x1d88: 0x0080, 0x1d89: 0x0080, 0x1d8a: 0x0080, 0x1d8b: 0x0080, + 0x1d8c: 0x0080, 0x1d8d: 0x0080, 0x1d8e: 0x0080, 0x1d8f: 0x0080, 0x1d90: 0x0080, 0x1d91: 0x0080, + 0x1d92: 0x0080, 0x1d93: 0x0080, 0x1d94: 0x0080, 0x1d95: 0x0080, 0x1d96: 0x0080, 0x1d97: 0x0080, + 0x1d98: 0x0080, 0x1d99: 0x0080, 0x1d9a: 0x0080, 0x1d9b: 0x0080, 0x1d9c: 0x0080, 0x1d9d: 0x0080, + 0x1d9e: 0x0080, 0x1d9f: 0x0080, 0x1da0: 0x0080, 0x1da1: 0x0080, 0x1da2: 0x0080, 0x1da3: 0x0080, + 0x1da4: 0x0080, 0x1da5: 0x0080, 0x1da6: 0x0080, 0x1da7: 0x0080, 0x1da8: 0x0080, 0x1da9: 0x0080, + 0x1daa: 0x0080, 0x1dab: 0x0080, 0x1dac: 0x0080, 0x1dad: 0x0080, 0x1dae: 0x0080, 0x1daf: 0x0080, + 0x1db0: 0x0080, 0x1db1: 0x0080, 0x1db2: 0x0080, 0x1db3: 0x0080, + 0x1db6: 0x0080, 0x1db7: 0x0080, 0x1db8: 0x0080, 0x1db9: 0x0080, 0x1dba: 0x0080, 0x1dbb: 0x0080, + 0x1dbc: 0x0080, 0x1dbd: 0x0080, 0x1dbe: 0x0080, 0x1dbf: 0x0080, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x0080, 0x1dc1: 0x0080, 0x1dc2: 0x0080, 0x1dc3: 0x0080, 0x1dc4: 0x0080, 0x1dc5: 0x0080, + 0x1dc6: 0x0080, 0x1dc7: 0x0080, 0x1dc8: 0x0080, 0x1dc9: 0x0080, 0x1dca: 0x0080, 0x1dcb: 0x0080, + 0x1dcc: 0x0080, 0x1dcd: 0x0080, 0x1dce: 0x0080, 0x1dcf: 0x0080, 0x1dd0: 0x0080, 0x1dd1: 0x0080, + 0x1dd2: 0x0080, 0x1dd3: 0x0080, 0x1dd4: 0x0080, 0x1dd5: 0x0080, + 0x1dd8: 0x0080, 0x1dd9: 0x0080, 0x1dda: 0x0080, 0x1ddb: 0x0080, 0x1ddc: 0x0080, 0x1ddd: 0x0080, + 0x1dde: 0x0080, 0x1ddf: 0x0080, 0x1de0: 0x0080, 0x1de1: 0x0080, 0x1de2: 0x0080, 0x1de3: 0x0080, + 0x1de4: 0x0080, 0x1de5: 0x0080, 0x1de6: 0x0080, 0x1de7: 0x0080, 0x1de8: 0x0080, 0x1de9: 0x0080, + 0x1dea: 0x0080, 0x1deb: 0x0080, 0x1dec: 0x0080, 0x1ded: 0x0080, 0x1dee: 0x0080, 0x1def: 0x0080, + 0x1df0: 0x0080, 0x1df1: 0x0080, 0x1df2: 0x0080, 0x1df3: 0x0080, 0x1df4: 0x0080, 0x1df5: 0x0080, + 0x1df6: 0x0080, 0x1df7: 0x0080, 0x1df8: 0x0080, 0x1df9: 0x0080, 0x1dfa: 0x0080, 0x1dfb: 0x0080, + 0x1dfc: 0x0080, 0x1dfd: 0x0080, 0x1dfe: 0x0080, 0x1dff: 0x0080, + // Block 0x78, offset 0x1e00 + 0x1e00: 0x0080, 0x1e01: 0x0080, 0x1e02: 0x0080, 0x1e03: 0x0080, 0x1e04: 0x0080, 0x1e05: 0x0080, + 0x1e06: 0x0080, 0x1e07: 0x0080, 0x1e08: 0x0080, 0x1e0a: 0x0080, 0x1e0b: 0x0080, + 0x1e0c: 0x0080, 0x1e0d: 0x0080, 0x1e0e: 0x0080, 0x1e0f: 0x0080, 0x1e10: 0x0080, 0x1e11: 0x0080, + 0x1e12: 0x0080, 0x1e13: 0x0080, 0x1e14: 0x0080, 0x1e15: 0x0080, 0x1e16: 0x0080, 0x1e17: 0x0080, + 0x1e18: 0x0080, 0x1e19: 0x0080, 0x1e1a: 0x0080, 0x1e1b: 0x0080, 0x1e1c: 0x0080, 0x1e1d: 0x0080, + 0x1e1e: 0x0080, 0x1e1f: 0x0080, 0x1e20: 0x0080, 0x1e21: 0x0080, 0x1e22: 0x0080, 0x1e23: 0x0080, + 0x1e24: 0x0080, 0x1e25: 0x0080, 0x1e26: 0x0080, 0x1e27: 0x0080, 0x1e28: 0x0080, 0x1e29: 0x0080, + 0x1e2a: 0x0080, 0x1e2b: 0x0080, 0x1e2c: 0x0080, 0x1e2d: 0x0080, 0x1e2e: 0x0080, 0x1e2f: 0x0080, + 0x1e30: 0x0080, 0x1e31: 0x0080, 0x1e32: 0x0080, 0x1e33: 0x0080, 0x1e34: 0x0080, 0x1e35: 0x0080, + 0x1e36: 0x0080, 0x1e37: 0x0080, 0x1e38: 0x0080, 0x1e39: 0x0080, 0x1e3a: 0x0080, 0x1e3b: 0x0080, + 0x1e3c: 0x0080, 0x1e3d: 0x0080, 0x1e3e: 0x0080, + // Block 0x79, offset 0x1e40 + 0x1e40: 0x00c0, 0x1e41: 0x00c0, 0x1e42: 0x00c0, 0x1e43: 0x00c0, 0x1e44: 0x00c0, 0x1e45: 0x00c0, + 0x1e46: 0x00c0, 0x1e47: 0x00c0, 0x1e48: 0x00c0, 0x1e49: 0x00c0, 0x1e4a: 0x00c0, 0x1e4b: 0x00c0, + 0x1e4c: 0x00c0, 0x1e4d: 0x00c0, 0x1e4e: 0x00c0, 0x1e4f: 0x00c0, 0x1e50: 0x00c0, 0x1e51: 0x00c0, + 0x1e52: 0x00c0, 0x1e53: 0x00c0, 0x1e54: 0x00c0, 0x1e55: 0x00c0, 0x1e56: 0x00c0, 0x1e57: 0x00c0, + 0x1e58: 0x00c0, 0x1e59: 0x00c0, 0x1e5a: 0x00c0, 0x1e5b: 0x00c0, 0x1e5c: 0x00c0, 0x1e5d: 0x00c0, + 0x1e5e: 0x00c0, 0x1e5f: 0x00c0, 0x1e60: 0x00c0, 0x1e61: 0x00c0, 0x1e62: 0x00c0, 0x1e63: 0x00c0, + 0x1e64: 0x00c0, 0x1e65: 0x00c0, 0x1e66: 0x00c0, 0x1e67: 0x00c0, 0x1e68: 0x00c0, 0x1e69: 0x00c0, + 0x1e6a: 0x00c0, 0x1e6b: 0x00c0, 0x1e6c: 0x00c0, 0x1e6d: 0x00c0, 0x1e6e: 0x00c0, + 0x1e70: 0x00c0, 0x1e71: 0x00c0, 0x1e72: 0x00c0, 0x1e73: 0x00c0, 0x1e74: 0x00c0, 0x1e75: 0x00c0, + 0x1e76: 0x00c0, 0x1e77: 0x00c0, 0x1e78: 0x00c0, 0x1e79: 0x00c0, 0x1e7a: 0x00c0, 0x1e7b: 0x00c0, + 0x1e7c: 0x00c0, 0x1e7d: 0x00c0, 0x1e7e: 0x00c0, 0x1e7f: 0x00c0, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x00c0, 0x1e81: 0x00c0, 0x1e82: 0x00c0, 0x1e83: 0x00c0, 0x1e84: 0x00c0, 0x1e85: 0x00c0, + 0x1e86: 0x00c0, 0x1e87: 0x00c0, 0x1e88: 0x00c0, 0x1e89: 0x00c0, 0x1e8a: 0x00c0, 0x1e8b: 0x00c0, + 0x1e8c: 0x00c0, 0x1e8d: 0x00c0, 0x1e8e: 0x00c0, 0x1e8f: 0x00c0, 0x1e90: 0x00c0, 0x1e91: 0x00c0, + 0x1e92: 0x00c0, 0x1e93: 0x00c0, 0x1e94: 0x00c0, 0x1e95: 0x00c0, 0x1e96: 0x00c0, 0x1e97: 0x00c0, + 0x1e98: 0x00c0, 0x1e99: 0x00c0, 0x1e9a: 0x00c0, 0x1e9b: 0x00c0, 0x1e9c: 0x00c0, 0x1e9d: 0x00c0, + 0x1e9e: 0x00c0, 0x1ea0: 0x00c0, 0x1ea1: 0x00c0, 0x1ea2: 0x00c0, 0x1ea3: 0x00c0, + 0x1ea4: 0x00c0, 0x1ea5: 0x00c0, 0x1ea6: 0x00c0, 0x1ea7: 0x00c0, 0x1ea8: 0x00c0, 0x1ea9: 0x00c0, + 0x1eaa: 0x00c0, 0x1eab: 0x00c0, 0x1eac: 0x00c0, 0x1ead: 0x00c0, 0x1eae: 0x00c0, 0x1eaf: 0x00c0, + 0x1eb0: 0x00c0, 0x1eb1: 0x00c0, 0x1eb2: 0x00c0, 0x1eb3: 0x00c0, 0x1eb4: 0x00c0, 0x1eb5: 0x00c0, + 0x1eb6: 0x00c0, 0x1eb7: 0x00c0, 0x1eb8: 0x00c0, 0x1eb9: 0x00c0, 0x1eba: 0x00c0, 0x1ebb: 0x00c0, + 0x1ebc: 0x0080, 0x1ebd: 0x0080, 0x1ebe: 0x00c0, 0x1ebf: 0x00c0, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x00c0, 0x1ec1: 0x00c0, 0x1ec2: 0x00c0, 0x1ec3: 0x00c0, 0x1ec4: 0x00c0, 0x1ec5: 0x00c0, + 0x1ec6: 0x00c0, 0x1ec7: 0x00c0, 0x1ec8: 0x00c0, 0x1ec9: 0x00c0, 0x1eca: 0x00c0, 0x1ecb: 0x00c0, + 0x1ecc: 0x00c0, 0x1ecd: 0x00c0, 0x1ece: 0x00c0, 0x1ecf: 0x00c0, 0x1ed0: 0x00c0, 0x1ed1: 0x00c0, + 0x1ed2: 0x00c0, 0x1ed3: 0x00c0, 0x1ed4: 0x00c0, 0x1ed5: 0x00c0, 0x1ed6: 0x00c0, 0x1ed7: 0x00c0, + 0x1ed8: 0x00c0, 0x1ed9: 0x00c0, 0x1eda: 0x00c0, 0x1edb: 0x00c0, 0x1edc: 0x00c0, 0x1edd: 0x00c0, + 0x1ede: 0x00c0, 0x1edf: 0x00c0, 0x1ee0: 0x00c0, 0x1ee1: 0x00c0, 0x1ee2: 0x00c0, 0x1ee3: 0x00c0, + 0x1ee4: 0x00c0, 0x1ee5: 0x0080, 0x1ee6: 0x0080, 0x1ee7: 0x0080, 0x1ee8: 0x0080, 0x1ee9: 0x0080, + 0x1eea: 0x0080, 0x1eeb: 0x00c0, 0x1eec: 0x00c0, 0x1eed: 0x00c0, 0x1eee: 0x00c0, 0x1eef: 0x00c3, + 0x1ef0: 0x00c3, 0x1ef1: 0x00c3, 0x1ef2: 0x00c0, 0x1ef3: 0x00c0, + 0x1ef9: 0x0080, 0x1efa: 0x0080, 0x1efb: 0x0080, + 0x1efc: 0x0080, 0x1efd: 0x0080, 0x1efe: 0x0080, 0x1eff: 0x0080, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0x00c0, 0x1f01: 0x00c0, 0x1f02: 0x00c0, 0x1f03: 0x00c0, 0x1f04: 0x00c0, 0x1f05: 0x00c0, + 0x1f06: 0x00c0, 0x1f07: 0x00c0, 0x1f08: 0x00c0, 0x1f09: 0x00c0, 0x1f0a: 0x00c0, 0x1f0b: 0x00c0, + 0x1f0c: 0x00c0, 0x1f0d: 0x00c0, 0x1f0e: 0x00c0, 0x1f0f: 0x00c0, 0x1f10: 0x00c0, 0x1f11: 0x00c0, + 0x1f12: 0x00c0, 0x1f13: 0x00c0, 0x1f14: 0x00c0, 0x1f15: 0x00c0, 0x1f16: 0x00c0, 0x1f17: 0x00c0, + 0x1f18: 0x00c0, 0x1f19: 0x00c0, 0x1f1a: 0x00c0, 0x1f1b: 0x00c0, 0x1f1c: 0x00c0, 0x1f1d: 0x00c0, + 0x1f1e: 0x00c0, 0x1f1f: 0x00c0, 0x1f20: 0x00c0, 0x1f21: 0x00c0, 0x1f22: 0x00c0, 0x1f23: 0x00c0, + 0x1f24: 0x00c0, 0x1f25: 0x00c0, 0x1f27: 0x00c0, + 0x1f2d: 0x00c0, + 0x1f30: 0x00c0, 0x1f31: 0x00c0, 0x1f32: 0x00c0, 0x1f33: 0x00c0, 0x1f34: 0x00c0, 0x1f35: 0x00c0, + 0x1f36: 0x00c0, 0x1f37: 0x00c0, 0x1f38: 0x00c0, 0x1f39: 0x00c0, 0x1f3a: 0x00c0, 0x1f3b: 0x00c0, + 0x1f3c: 0x00c0, 0x1f3d: 0x00c0, 0x1f3e: 0x00c0, 0x1f3f: 0x00c0, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0x00c0, 0x1f41: 0x00c0, 0x1f42: 0x00c0, 0x1f43: 0x00c0, 0x1f44: 0x00c0, 0x1f45: 0x00c0, + 0x1f46: 0x00c0, 0x1f47: 0x00c0, 0x1f48: 0x00c0, 0x1f49: 0x00c0, 0x1f4a: 0x00c0, 0x1f4b: 0x00c0, + 0x1f4c: 0x00c0, 0x1f4d: 0x00c0, 0x1f4e: 0x00c0, 0x1f4f: 0x00c0, 0x1f50: 0x00c0, 0x1f51: 0x00c0, + 0x1f52: 0x00c0, 0x1f53: 0x00c0, 0x1f54: 0x00c0, 0x1f55: 0x00c0, 0x1f56: 0x00c0, 0x1f57: 0x00c0, + 0x1f58: 0x00c0, 0x1f59: 0x00c0, 0x1f5a: 0x00c0, 0x1f5b: 0x00c0, 0x1f5c: 0x00c0, 0x1f5d: 0x00c0, + 0x1f5e: 0x00c0, 0x1f5f: 0x00c0, 0x1f60: 0x00c0, 0x1f61: 0x00c0, 0x1f62: 0x00c0, 0x1f63: 0x00c0, + 0x1f64: 0x00c0, 0x1f65: 0x00c0, 0x1f66: 0x00c0, 0x1f67: 0x00c0, + 0x1f6f: 0x0080, + 0x1f70: 0x0080, + 0x1f7f: 0x00c6, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0x00c0, 0x1f81: 0x00c0, 0x1f82: 0x00c0, 0x1f83: 0x00c0, 0x1f84: 0x00c0, 0x1f85: 0x00c0, + 0x1f86: 0x00c0, 0x1f87: 0x00c0, 0x1f88: 0x00c0, 0x1f89: 0x00c0, 0x1f8a: 0x00c0, 0x1f8b: 0x00c0, + 0x1f8c: 0x00c0, 0x1f8d: 0x00c0, 0x1f8e: 0x00c0, 0x1f8f: 0x00c0, 0x1f90: 0x00c0, 0x1f91: 0x00c0, + 0x1f92: 0x00c0, 0x1f93: 0x00c0, 0x1f94: 0x00c0, 0x1f95: 0x00c0, 0x1f96: 0x00c0, + 0x1fa0: 0x00c0, 0x1fa1: 0x00c0, 0x1fa2: 0x00c0, 0x1fa3: 0x00c0, + 0x1fa4: 0x00c0, 0x1fa5: 0x00c0, 0x1fa6: 0x00c0, 0x1fa8: 0x00c0, 0x1fa9: 0x00c0, + 0x1faa: 0x00c0, 0x1fab: 0x00c0, 0x1fac: 0x00c0, 0x1fad: 0x00c0, 0x1fae: 0x00c0, + 0x1fb0: 0x00c0, 0x1fb1: 0x00c0, 0x1fb2: 0x00c0, 0x1fb3: 0x00c0, 0x1fb4: 0x00c0, 0x1fb5: 0x00c0, + 0x1fb6: 0x00c0, 0x1fb8: 0x00c0, 0x1fb9: 0x00c0, 0x1fba: 0x00c0, 0x1fbb: 0x00c0, + 0x1fbc: 0x00c0, 0x1fbd: 0x00c0, 0x1fbe: 0x00c0, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x00c0, 0x1fc1: 0x00c0, 0x1fc2: 0x00c0, 0x1fc3: 0x00c0, 0x1fc4: 0x00c0, 0x1fc5: 0x00c0, + 0x1fc6: 0x00c0, 0x1fc8: 0x00c0, 0x1fc9: 0x00c0, 0x1fca: 0x00c0, 0x1fcb: 0x00c0, + 0x1fcc: 0x00c0, 0x1fcd: 0x00c0, 0x1fce: 0x00c0, 0x1fd0: 0x00c0, 0x1fd1: 0x00c0, + 0x1fd2: 0x00c0, 0x1fd3: 0x00c0, 0x1fd4: 0x00c0, 0x1fd5: 0x00c0, 0x1fd6: 0x00c0, + 0x1fd8: 0x00c0, 0x1fd9: 0x00c0, 0x1fda: 0x00c0, 0x1fdb: 0x00c0, 0x1fdc: 0x00c0, 0x1fdd: 0x00c0, + 0x1fde: 0x00c0, 0x1fe0: 0x00c3, 0x1fe1: 0x00c3, 0x1fe2: 0x00c3, 0x1fe3: 0x00c3, + 0x1fe4: 0x00c3, 0x1fe5: 0x00c3, 0x1fe6: 0x00c3, 0x1fe7: 0x00c3, 0x1fe8: 0x00c3, 0x1fe9: 0x00c3, + 0x1fea: 0x00c3, 0x1feb: 0x00c3, 0x1fec: 0x00c3, 0x1fed: 0x00c3, 0x1fee: 0x00c3, 0x1fef: 0x00c3, + 0x1ff0: 0x00c3, 0x1ff1: 0x00c3, 0x1ff2: 0x00c3, 0x1ff3: 0x00c3, 0x1ff4: 0x00c3, 0x1ff5: 0x00c3, + 0x1ff6: 0x00c3, 0x1ff7: 0x00c3, 0x1ff8: 0x00c3, 0x1ff9: 0x00c3, 0x1ffa: 0x00c3, 0x1ffb: 0x00c3, + 0x1ffc: 0x00c3, 0x1ffd: 0x00c3, 0x1ffe: 0x00c3, 0x1fff: 0x00c3, + // Block 0x80, offset 0x2000 + 0x2000: 0x0080, 0x2001: 0x0080, 0x2002: 0x0080, 0x2003: 0x0080, 0x2004: 0x0080, 0x2005: 0x0080, + 0x2006: 0x0080, 0x2007: 0x0080, 0x2008: 0x0080, 0x2009: 0x0080, 0x200a: 0x0080, 0x200b: 0x0080, + 0x200c: 0x0080, 0x200d: 0x0080, 0x200e: 0x0080, 0x200f: 0x0080, 0x2010: 0x0080, 0x2011: 0x0080, + 0x2012: 0x0080, 0x2013: 0x0080, 0x2014: 0x0080, 0x2015: 0x0080, 0x2016: 0x0080, 0x2017: 0x0080, + 0x2018: 0x0080, 0x2019: 0x0080, 0x201a: 0x0080, 0x201b: 0x0080, 0x201c: 0x0080, 0x201d: 0x0080, + 0x201e: 0x0080, 0x201f: 0x0080, 0x2020: 0x0080, 0x2021: 0x0080, 0x2022: 0x0080, 0x2023: 0x0080, + 0x2024: 0x0080, 0x2025: 0x0080, 0x2026: 0x0080, 0x2027: 0x0080, 0x2028: 0x0080, 0x2029: 0x0080, + 0x202a: 0x0080, 0x202b: 0x0080, 0x202c: 0x0080, 0x202d: 0x0080, 0x202e: 0x0080, 0x202f: 0x00c0, + 0x2030: 0x0080, 0x2031: 0x0080, 0x2032: 0x0080, 0x2033: 0x0080, 0x2034: 0x0080, 0x2035: 0x0080, + 0x2036: 0x0080, 0x2037: 0x0080, 0x2038: 0x0080, 0x2039: 0x0080, 0x203a: 0x0080, 0x203b: 0x0080, + 0x203c: 0x0080, 0x203d: 0x0080, 0x203e: 0x0080, 0x203f: 0x0080, + // Block 0x81, offset 0x2040 + 0x2040: 0x0080, 0x2041: 0x0080, 0x2042: 0x0080, 0x2043: 0x0080, 0x2044: 0x0080, 0x2045: 0x0080, + 0x2046: 0x0080, 0x2047: 0x0080, 0x2048: 0x0080, 0x2049: 0x0080, 0x204a: 0x0080, 0x204b: 0x0080, + 0x204c: 0x0080, 0x204d: 0x0080, 0x204e: 0x0080, + // Block 0x82, offset 0x2080 + 0x2080: 0x008c, 0x2081: 0x008c, 0x2082: 0x008c, 0x2083: 0x008c, 0x2084: 0x008c, 0x2085: 0x008c, + 0x2086: 0x008c, 0x2087: 0x008c, 0x2088: 0x008c, 0x2089: 0x008c, 0x208a: 0x008c, 0x208b: 0x008c, + 0x208c: 0x008c, 0x208d: 0x008c, 0x208e: 0x008c, 0x208f: 0x008c, 0x2090: 0x008c, 0x2091: 0x008c, + 0x2092: 0x008c, 0x2093: 0x008c, 0x2094: 0x008c, 0x2095: 0x008c, 0x2096: 0x008c, 0x2097: 0x008c, + 0x2098: 0x008c, 0x2099: 0x008c, 0x209b: 0x008c, 0x209c: 0x008c, 0x209d: 0x008c, + 0x209e: 0x008c, 0x209f: 0x008c, 0x20a0: 0x008c, 0x20a1: 0x008c, 0x20a2: 0x008c, 0x20a3: 0x008c, + 0x20a4: 0x008c, 0x20a5: 0x008c, 0x20a6: 0x008c, 0x20a7: 0x008c, 0x20a8: 0x008c, 0x20a9: 0x008c, + 0x20aa: 0x008c, 0x20ab: 0x008c, 0x20ac: 0x008c, 0x20ad: 0x008c, 0x20ae: 0x008c, 0x20af: 0x008c, + 0x20b0: 0x008c, 0x20b1: 0x008c, 0x20b2: 0x008c, 0x20b3: 0x008c, 0x20b4: 0x008c, 0x20b5: 0x008c, + 0x20b6: 0x008c, 0x20b7: 0x008c, 0x20b8: 0x008c, 0x20b9: 0x008c, 0x20ba: 0x008c, 0x20bb: 0x008c, + 0x20bc: 0x008c, 0x20bd: 0x008c, 0x20be: 0x008c, 0x20bf: 0x008c, + // Block 0x83, offset 0x20c0 + 0x20c0: 0x008c, 0x20c1: 0x008c, 0x20c2: 0x008c, 0x20c3: 0x008c, 0x20c4: 0x008c, 0x20c5: 0x008c, + 0x20c6: 0x008c, 0x20c7: 0x008c, 0x20c8: 0x008c, 0x20c9: 0x008c, 0x20ca: 0x008c, 0x20cb: 0x008c, + 0x20cc: 0x008c, 0x20cd: 0x008c, 0x20ce: 0x008c, 0x20cf: 0x008c, 0x20d0: 0x008c, 0x20d1: 0x008c, + 0x20d2: 0x008c, 0x20d3: 0x008c, 0x20d4: 0x008c, 0x20d5: 0x008c, 0x20d6: 0x008c, 0x20d7: 0x008c, + 0x20d8: 0x008c, 0x20d9: 0x008c, 0x20da: 0x008c, 0x20db: 0x008c, 0x20dc: 0x008c, 0x20dd: 0x008c, + 0x20de: 0x008c, 0x20df: 0x008c, 0x20e0: 0x008c, 0x20e1: 0x008c, 0x20e2: 0x008c, 0x20e3: 0x008c, + 0x20e4: 0x008c, 0x20e5: 0x008c, 0x20e6: 0x008c, 0x20e7: 0x008c, 0x20e8: 0x008c, 0x20e9: 0x008c, + 0x20ea: 0x008c, 0x20eb: 0x008c, 0x20ec: 0x008c, 0x20ed: 0x008c, 0x20ee: 0x008c, 0x20ef: 0x008c, + 0x20f0: 0x008c, 0x20f1: 0x008c, 0x20f2: 0x008c, 0x20f3: 0x008c, + // Block 0x84, offset 0x2100 + 0x2100: 0x008c, 0x2101: 0x008c, 0x2102: 0x008c, 0x2103: 0x008c, 0x2104: 0x008c, 0x2105: 0x008c, + 0x2106: 0x008c, 0x2107: 0x008c, 0x2108: 0x008c, 0x2109: 0x008c, 0x210a: 0x008c, 0x210b: 0x008c, + 0x210c: 0x008c, 0x210d: 0x008c, 0x210e: 0x008c, 0x210f: 0x008c, 0x2110: 0x008c, 0x2111: 0x008c, + 0x2112: 0x008c, 0x2113: 0x008c, 0x2114: 0x008c, 0x2115: 0x008c, 0x2116: 0x008c, 0x2117: 0x008c, + 0x2118: 0x008c, 0x2119: 0x008c, 0x211a: 0x008c, 0x211b: 0x008c, 0x211c: 0x008c, 0x211d: 0x008c, + 0x211e: 0x008c, 0x211f: 0x008c, 0x2120: 0x008c, 0x2121: 0x008c, 0x2122: 0x008c, 0x2123: 0x008c, + 0x2124: 0x008c, 0x2125: 0x008c, 0x2126: 0x008c, 0x2127: 0x008c, 0x2128: 0x008c, 0x2129: 0x008c, + 0x212a: 0x008c, 0x212b: 0x008c, 0x212c: 0x008c, 0x212d: 0x008c, 0x212e: 0x008c, 0x212f: 0x008c, + 0x2130: 0x008c, 0x2131: 0x008c, 0x2132: 0x008c, 0x2133: 0x008c, 0x2134: 0x008c, 0x2135: 0x008c, + 0x2136: 0x008c, 0x2137: 0x008c, 0x2138: 0x008c, 0x2139: 0x008c, 0x213a: 0x008c, 0x213b: 0x008c, + 0x213c: 0x008c, 0x213d: 0x008c, 0x213e: 0x008c, 0x213f: 0x008c, + // Block 0x85, offset 0x2140 + 0x2140: 0x008c, 0x2141: 0x008c, 0x2142: 0x008c, 0x2143: 0x008c, 0x2144: 0x008c, 0x2145: 0x008c, + 0x2146: 0x008c, 0x2147: 0x008c, 0x2148: 0x008c, 0x2149: 0x008c, 0x214a: 0x008c, 0x214b: 0x008c, + 0x214c: 0x008c, 0x214d: 0x008c, 0x214e: 0x008c, 0x214f: 0x008c, 0x2150: 0x008c, 0x2151: 0x008c, + 0x2152: 0x008c, 0x2153: 0x008c, 0x2154: 0x008c, 0x2155: 0x008c, + 0x2170: 0x0080, 0x2171: 0x0080, 0x2172: 0x0080, 0x2173: 0x0080, 0x2174: 0x0080, 0x2175: 0x0080, + 0x2176: 0x0080, 0x2177: 0x0080, 0x2178: 0x0080, 0x2179: 0x0080, 0x217a: 0x0080, 0x217b: 0x0080, + // Block 0x86, offset 0x2180 + 0x2180: 0x0080, 0x2181: 0x0080, 0x2182: 0x0080, 0x2183: 0x0080, 0x2184: 0x0080, 0x2185: 0x00cc, + 0x2186: 0x00c0, 0x2187: 0x00cc, 0x2188: 0x0080, 0x2189: 0x0080, 0x218a: 0x0080, 0x218b: 0x0080, + 0x218c: 0x0080, 0x218d: 0x0080, 0x218e: 0x0080, 0x218f: 0x0080, 0x2190: 0x0080, 0x2191: 0x0080, + 0x2192: 0x0080, 0x2193: 0x0080, 0x2194: 0x0080, 0x2195: 0x0080, 0x2196: 0x0080, 0x2197: 0x0080, + 0x2198: 0x0080, 0x2199: 0x0080, 0x219a: 0x0080, 0x219b: 0x0080, 0x219c: 0x0080, 0x219d: 0x0080, + 0x219e: 0x0080, 0x219f: 0x0080, 0x21a0: 0x0080, 0x21a1: 0x008c, 0x21a2: 0x008c, 0x21a3: 0x008c, + 0x21a4: 0x008c, 0x21a5: 0x008c, 0x21a6: 0x008c, 0x21a7: 0x008c, 0x21a8: 0x008c, 0x21a9: 0x008c, + 0x21aa: 0x00c3, 0x21ab: 0x00c3, 0x21ac: 0x00c3, 0x21ad: 0x00c3, 0x21ae: 0x0040, 0x21af: 0x0040, + 0x21b0: 0x0080, 0x21b1: 0x0040, 0x21b2: 0x0040, 0x21b3: 0x0040, 0x21b4: 0x0040, 0x21b5: 0x0040, + 0x21b6: 0x0080, 0x21b7: 0x0080, 0x21b8: 0x008c, 0x21b9: 0x008c, 0x21ba: 0x008c, 0x21bb: 0x0040, + 0x21bc: 0x00c0, 0x21bd: 0x0080, 0x21be: 0x0080, 0x21bf: 0x0080, + // Block 0x87, offset 0x21c0 + 0x21c1: 0x00cc, 0x21c2: 0x00cc, 0x21c3: 0x00cc, 0x21c4: 0x00cc, 0x21c5: 0x00cc, + 0x21c6: 0x00cc, 0x21c7: 0x00cc, 0x21c8: 0x00cc, 0x21c9: 0x00cc, 0x21ca: 0x00cc, 0x21cb: 0x00cc, + 0x21cc: 0x00cc, 0x21cd: 0x00cc, 0x21ce: 0x00cc, 0x21cf: 0x00cc, 0x21d0: 0x00cc, 0x21d1: 0x00cc, + 0x21d2: 0x00cc, 0x21d3: 0x00cc, 0x21d4: 0x00cc, 0x21d5: 0x00cc, 0x21d6: 0x00cc, 0x21d7: 0x00cc, + 0x21d8: 0x00cc, 0x21d9: 0x00cc, 0x21da: 0x00cc, 0x21db: 0x00cc, 0x21dc: 0x00cc, 0x21dd: 0x00cc, + 0x21de: 0x00cc, 0x21df: 0x00cc, 0x21e0: 0x00cc, 0x21e1: 0x00cc, 0x21e2: 0x00cc, 0x21e3: 0x00cc, + 0x21e4: 0x00cc, 0x21e5: 0x00cc, 0x21e6: 0x00cc, 0x21e7: 0x00cc, 0x21e8: 0x00cc, 0x21e9: 0x00cc, + 0x21ea: 0x00cc, 0x21eb: 0x00cc, 0x21ec: 0x00cc, 0x21ed: 0x00cc, 0x21ee: 0x00cc, 0x21ef: 0x00cc, + 0x21f0: 0x00cc, 0x21f1: 0x00cc, 0x21f2: 0x00cc, 0x21f3: 0x00cc, 0x21f4: 0x00cc, 0x21f5: 0x00cc, + 0x21f6: 0x00cc, 0x21f7: 0x00cc, 0x21f8: 0x00cc, 0x21f9: 0x00cc, 0x21fa: 0x00cc, 0x21fb: 0x00cc, + 0x21fc: 0x00cc, 0x21fd: 0x00cc, 0x21fe: 0x00cc, 0x21ff: 0x00cc, + // Block 0x88, offset 0x2200 + 0x2200: 0x00cc, 0x2201: 0x00cc, 0x2202: 0x00cc, 0x2203: 0x00cc, 0x2204: 0x00cc, 0x2205: 0x00cc, + 0x2206: 0x00cc, 0x2207: 0x00cc, 0x2208: 0x00cc, 0x2209: 0x00cc, 0x220a: 0x00cc, 0x220b: 0x00cc, + 0x220c: 0x00cc, 0x220d: 0x00cc, 0x220e: 0x00cc, 0x220f: 0x00cc, 0x2210: 0x00cc, 0x2211: 0x00cc, + 0x2212: 0x00cc, 0x2213: 0x00cc, 0x2214: 0x00cc, 0x2215: 0x00cc, 0x2216: 0x00cc, + 0x2219: 0x00c3, 0x221a: 0x00c3, 0x221b: 0x0080, 0x221c: 0x0080, 0x221d: 0x00cc, + 0x221e: 0x00cc, 0x221f: 0x008c, 0x2220: 0x0080, 0x2221: 0x00cc, 0x2222: 0x00cc, 0x2223: 0x00cc, + 0x2224: 0x00cc, 0x2225: 0x00cc, 0x2226: 0x00cc, 0x2227: 0x00cc, 0x2228: 0x00cc, 0x2229: 0x00cc, + 0x222a: 0x00cc, 0x222b: 0x00cc, 0x222c: 0x00cc, 0x222d: 0x00cc, 0x222e: 0x00cc, 0x222f: 0x00cc, + 0x2230: 0x00cc, 0x2231: 0x00cc, 0x2232: 0x00cc, 0x2233: 0x00cc, 0x2234: 0x00cc, 0x2235: 0x00cc, + 0x2236: 0x00cc, 0x2237: 0x00cc, 0x2238: 0x00cc, 0x2239: 0x00cc, 0x223a: 0x00cc, 0x223b: 0x00cc, + 0x223c: 0x00cc, 0x223d: 0x00cc, 0x223e: 0x00cc, 0x223f: 0x00cc, + // Block 0x89, offset 0x2240 + 0x2240: 0x00cc, 0x2241: 0x00cc, 0x2242: 0x00cc, 0x2243: 0x00cc, 0x2244: 0x00cc, 0x2245: 0x00cc, + 0x2246: 0x00cc, 0x2247: 0x00cc, 0x2248: 0x00cc, 0x2249: 0x00cc, 0x224a: 0x00cc, 0x224b: 0x00cc, + 0x224c: 0x00cc, 0x224d: 0x00cc, 0x224e: 0x00cc, 0x224f: 0x00cc, 0x2250: 0x00cc, 0x2251: 0x00cc, + 0x2252: 0x00cc, 0x2253: 0x00cc, 0x2254: 0x00cc, 0x2255: 0x00cc, 0x2256: 0x00cc, 0x2257: 0x00cc, + 0x2258: 0x00cc, 0x2259: 0x00cc, 0x225a: 0x00cc, 0x225b: 0x00cc, 0x225c: 0x00cc, 0x225d: 0x00cc, + 0x225e: 0x00cc, 0x225f: 0x00cc, 0x2260: 0x00cc, 0x2261: 0x00cc, 0x2262: 0x00cc, 0x2263: 0x00cc, + 0x2264: 0x00cc, 0x2265: 0x00cc, 0x2266: 0x00cc, 0x2267: 0x00cc, 0x2268: 0x00cc, 0x2269: 0x00cc, + 0x226a: 0x00cc, 0x226b: 0x00cc, 0x226c: 0x00cc, 0x226d: 0x00cc, 0x226e: 0x00cc, 0x226f: 0x00cc, + 0x2270: 0x00cc, 0x2271: 0x00cc, 0x2272: 0x00cc, 0x2273: 0x00cc, 0x2274: 0x00cc, 0x2275: 0x00cc, + 0x2276: 0x00cc, 0x2277: 0x00cc, 0x2278: 0x00cc, 0x2279: 0x00cc, 0x227a: 0x00cc, 0x227b: 0x00d2, + 0x227c: 0x00c0, 0x227d: 0x00cc, 0x227e: 0x00cc, 0x227f: 0x008c, + // Block 0x8a, offset 0x2280 + 0x2285: 0x00c0, + 0x2286: 0x00c0, 0x2287: 0x00c0, 0x2288: 0x00c0, 0x2289: 0x00c0, 0x228a: 0x00c0, 0x228b: 0x00c0, + 0x228c: 0x00c0, 0x228d: 0x00c0, 0x228e: 0x00c0, 0x228f: 0x00c0, 0x2290: 0x00c0, 0x2291: 0x00c0, + 0x2292: 0x00c0, 0x2293: 0x00c0, 0x2294: 0x00c0, 0x2295: 0x00c0, 0x2296: 0x00c0, 0x2297: 0x00c0, + 0x2298: 0x00c0, 0x2299: 0x00c0, 0x229a: 0x00c0, 0x229b: 0x00c0, 0x229c: 0x00c0, 0x229d: 0x00c0, + 0x229e: 0x00c0, 0x229f: 0x00c0, 0x22a0: 0x00c0, 0x22a1: 0x00c0, 0x22a2: 0x00c0, 0x22a3: 0x00c0, + 0x22a4: 0x00c0, 0x22a5: 0x00c0, 0x22a6: 0x00c0, 0x22a7: 0x00c0, 0x22a8: 0x00c0, 0x22a9: 0x00c0, + 0x22aa: 0x00c0, 0x22ab: 0x00c0, 0x22ac: 0x00c0, 0x22ad: 0x00c0, 0x22ae: 0x00c0, 0x22af: 0x00c0, + 0x22b1: 0x0080, 0x22b2: 0x0080, 0x22b3: 0x0080, 0x22b4: 0x0080, 0x22b5: 0x0080, + 0x22b6: 0x0080, 0x22b7: 0x0080, 0x22b8: 0x0080, 0x22b9: 0x0080, 0x22ba: 0x0080, 0x22bb: 0x0080, + 0x22bc: 0x0080, 0x22bd: 0x0080, 0x22be: 0x0080, 0x22bf: 0x0080, + // Block 0x8b, offset 0x22c0 + 0x22c0: 0x0080, 0x22c1: 0x0080, 0x22c2: 0x0080, 0x22c3: 0x0080, 0x22c4: 0x0080, 0x22c5: 0x0080, + 0x22c6: 0x0080, 0x22c7: 0x0080, 0x22c8: 0x0080, 0x22c9: 0x0080, 0x22ca: 0x0080, 0x22cb: 0x0080, + 0x22cc: 0x0080, 0x22cd: 0x0080, 0x22ce: 0x0080, 0x22cf: 0x0080, 0x22d0: 0x0080, 0x22d1: 0x0080, + 0x22d2: 0x0080, 0x22d3: 0x0080, 0x22d4: 0x0080, 0x22d5: 0x0080, 0x22d6: 0x0080, 0x22d7: 0x0080, + 0x22d8: 0x0080, 0x22d9: 0x0080, 0x22da: 0x0080, 0x22db: 0x0080, 0x22dc: 0x0080, 0x22dd: 0x0080, + 0x22de: 0x0080, 0x22df: 0x0080, 0x22e0: 0x0080, 0x22e1: 0x0080, 0x22e2: 0x0080, 0x22e3: 0x0080, + 0x22e4: 0x0040, 0x22e5: 0x0080, 0x22e6: 0x0080, 0x22e7: 0x0080, 0x22e8: 0x0080, 0x22e9: 0x0080, + 0x22ea: 0x0080, 0x22eb: 0x0080, 0x22ec: 0x0080, 0x22ed: 0x0080, 0x22ee: 0x0080, 0x22ef: 0x0080, + 0x22f0: 0x0080, 0x22f1: 0x0080, 0x22f2: 0x0080, 0x22f3: 0x0080, 0x22f4: 0x0080, 0x22f5: 0x0080, + 0x22f6: 0x0080, 0x22f7: 0x0080, 0x22f8: 0x0080, 0x22f9: 0x0080, 0x22fa: 0x0080, 0x22fb: 0x0080, + 0x22fc: 0x0080, 0x22fd: 0x0080, 0x22fe: 0x0080, 0x22ff: 0x0080, + // Block 0x8c, offset 0x2300 + 0x2300: 0x0080, 0x2301: 0x0080, 0x2302: 0x0080, 0x2303: 0x0080, 0x2304: 0x0080, 0x2305: 0x0080, + 0x2306: 0x0080, 0x2307: 0x0080, 0x2308: 0x0080, 0x2309: 0x0080, 0x230a: 0x0080, 0x230b: 0x0080, + 0x230c: 0x0080, 0x230d: 0x0080, 0x230e: 0x0080, 0x2310: 0x0080, 0x2311: 0x0080, + 0x2312: 0x0080, 0x2313: 0x0080, 0x2314: 0x0080, 0x2315: 0x0080, 0x2316: 0x0080, 0x2317: 0x0080, + 0x2318: 0x0080, 0x2319: 0x0080, 0x231a: 0x0080, 0x231b: 0x0080, 0x231c: 0x0080, 0x231d: 0x0080, + 0x231e: 0x0080, 0x231f: 0x0080, 0x2320: 0x00c0, 0x2321: 0x00c0, 0x2322: 0x00c0, 0x2323: 0x00c0, + 0x2324: 0x00c0, 0x2325: 0x00c0, 0x2326: 0x00c0, 0x2327: 0x00c0, 0x2328: 0x00c0, 0x2329: 0x00c0, + 0x232a: 0x00c0, 0x232b: 0x00c0, 0x232c: 0x00c0, 0x232d: 0x00c0, 0x232e: 0x00c0, 0x232f: 0x00c0, + 0x2330: 0x00c0, 0x2331: 0x00c0, 0x2332: 0x00c0, 0x2333: 0x00c0, 0x2334: 0x00c0, 0x2335: 0x00c0, + 0x2336: 0x00c0, 0x2337: 0x00c0, 0x2338: 0x00c0, 0x2339: 0x00c0, 0x233a: 0x00c0, + // Block 0x8d, offset 0x2340 + 0x2340: 0x0080, 0x2341: 0x0080, 0x2342: 0x0080, 0x2343: 0x0080, 0x2344: 0x0080, 0x2345: 0x0080, + 0x2346: 0x0080, 0x2347: 0x0080, 0x2348: 0x0080, 0x2349: 0x0080, 0x234a: 0x0080, 0x234b: 0x0080, + 0x234c: 0x0080, 0x234d: 0x0080, 0x234e: 0x0080, 0x234f: 0x0080, 0x2350: 0x0080, 0x2351: 0x0080, + 0x2352: 0x0080, 0x2353: 0x0080, 0x2354: 0x0080, 0x2355: 0x0080, 0x2356: 0x0080, 0x2357: 0x0080, + 0x2358: 0x0080, 0x2359: 0x0080, 0x235a: 0x0080, 0x235b: 0x0080, 0x235c: 0x0080, 0x235d: 0x0080, + 0x235e: 0x0080, 0x235f: 0x0080, 0x2360: 0x0080, 0x2361: 0x0080, 0x2362: 0x0080, 0x2363: 0x0080, + 0x2370: 0x00cc, 0x2371: 0x00cc, 0x2372: 0x00cc, 0x2373: 0x00cc, 0x2374: 0x00cc, 0x2375: 0x00cc, + 0x2376: 0x00cc, 0x2377: 0x00cc, 0x2378: 0x00cc, 0x2379: 0x00cc, 0x237a: 0x00cc, 0x237b: 0x00cc, + 0x237c: 0x00cc, 0x237d: 0x00cc, 0x237e: 0x00cc, 0x237f: 0x00cc, + // Block 0x8e, offset 0x2380 + 0x2380: 0x0080, 0x2381: 0x0080, 0x2382: 0x0080, 0x2383: 0x0080, 0x2384: 0x0080, 0x2385: 0x0080, + 0x2386: 0x0080, 0x2387: 0x0080, 0x2388: 0x0080, 0x2389: 0x0080, 0x238a: 0x0080, 0x238b: 0x0080, + 0x238c: 0x0080, 0x238d: 0x0080, 0x238e: 0x0080, 0x238f: 0x0080, 0x2390: 0x0080, 0x2391: 0x0080, + 0x2392: 0x0080, 0x2393: 0x0080, 0x2394: 0x0080, 0x2395: 0x0080, 0x2396: 0x0080, 0x2397: 0x0080, + 0x2398: 0x0080, 0x2399: 0x0080, 0x239a: 0x0080, 0x239b: 0x0080, 0x239c: 0x0080, 0x239d: 0x0080, + 0x239e: 0x0080, 0x23a0: 0x0080, 0x23a1: 0x0080, 0x23a2: 0x0080, 0x23a3: 0x0080, + 0x23a4: 0x0080, 0x23a5: 0x0080, 0x23a6: 0x0080, 0x23a7: 0x0080, 0x23a8: 0x0080, 0x23a9: 0x0080, + 0x23aa: 0x0080, 0x23ab: 0x0080, 0x23ac: 0x0080, 0x23ad: 0x0080, 0x23ae: 0x0080, 0x23af: 0x0080, + 0x23b0: 0x0080, 0x23b1: 0x0080, 0x23b2: 0x0080, 0x23b3: 0x0080, 0x23b4: 0x0080, 0x23b5: 0x0080, + 0x23b6: 0x0080, 0x23b7: 0x0080, 0x23b8: 0x0080, 0x23b9: 0x0080, 0x23ba: 0x0080, 0x23bb: 0x0080, + 0x23bc: 0x0080, 0x23bd: 0x0080, 0x23be: 0x0080, 0x23bf: 0x0080, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x0080, 0x23c1: 0x0080, 0x23c2: 0x0080, 0x23c3: 0x0080, 0x23c4: 0x0080, 0x23c5: 0x0080, + 0x23c6: 0x0080, 0x23c7: 0x0080, 0x23c8: 0x0080, 0x23c9: 0x0080, 0x23ca: 0x0080, 0x23cb: 0x0080, + 0x23cc: 0x0080, 0x23cd: 0x0080, 0x23ce: 0x0080, 0x23cf: 0x0080, 0x23d0: 0x008c, 0x23d1: 0x008c, + 0x23d2: 0x008c, 0x23d3: 0x008c, 0x23d4: 0x008c, 0x23d5: 0x008c, 0x23d6: 0x008c, 0x23d7: 0x008c, + 0x23d8: 0x008c, 0x23d9: 0x008c, 0x23da: 0x008c, 0x23db: 0x008c, 0x23dc: 0x008c, 0x23dd: 0x008c, + 0x23de: 0x008c, 0x23df: 0x008c, 0x23e0: 0x008c, 0x23e1: 0x008c, 0x23e2: 0x008c, 0x23e3: 0x008c, + 0x23e4: 0x008c, 0x23e5: 0x008c, 0x23e6: 0x008c, 0x23e7: 0x008c, 0x23e8: 0x008c, 0x23e9: 0x008c, + 0x23ea: 0x008c, 0x23eb: 0x008c, 0x23ec: 0x008c, 0x23ed: 0x008c, 0x23ee: 0x008c, 0x23ef: 0x008c, + 0x23f0: 0x008c, 0x23f1: 0x008c, 0x23f2: 0x008c, 0x23f3: 0x008c, 0x23f4: 0x008c, 0x23f5: 0x008c, + 0x23f6: 0x008c, 0x23f7: 0x008c, 0x23f8: 0x008c, 0x23f9: 0x008c, 0x23fa: 0x008c, 0x23fb: 0x008c, + 0x23fc: 0x008c, 0x23fd: 0x008c, 0x23fe: 0x008c, + // Block 0x90, offset 0x2400 + 0x2400: 0x008c, 0x2401: 0x008c, 0x2402: 0x008c, 0x2403: 0x008c, 0x2404: 0x008c, 0x2405: 0x008c, + 0x2406: 0x008c, 0x2407: 0x008c, 0x2408: 0x008c, 0x2409: 0x008c, 0x240a: 0x008c, 0x240b: 0x008c, + 0x240c: 0x008c, 0x240d: 0x008c, 0x240e: 0x008c, 0x240f: 0x008c, 0x2410: 0x008c, 0x2411: 0x008c, + 0x2412: 0x008c, 0x2413: 0x008c, 0x2414: 0x008c, 0x2415: 0x008c, 0x2416: 0x008c, 0x2417: 0x008c, + 0x2418: 0x0080, 0x2419: 0x0080, 0x241a: 0x0080, 0x241b: 0x0080, 0x241c: 0x0080, 0x241d: 0x0080, + 0x241e: 0x0080, 0x241f: 0x0080, 0x2420: 0x0080, 0x2421: 0x0080, 0x2422: 0x0080, 0x2423: 0x0080, + 0x2424: 0x0080, 0x2425: 0x0080, 0x2426: 0x0080, 0x2427: 0x0080, 0x2428: 0x0080, 0x2429: 0x0080, + 0x242a: 0x0080, 0x242b: 0x0080, 0x242c: 0x0080, 0x242d: 0x0080, 0x242e: 0x0080, 0x242f: 0x0080, + 0x2430: 0x0080, 0x2431: 0x0080, 0x2432: 0x0080, 0x2433: 0x0080, 0x2434: 0x0080, 0x2435: 0x0080, + 0x2436: 0x0080, 0x2437: 0x0080, 0x2438: 0x0080, 0x2439: 0x0080, 0x243a: 0x0080, 0x243b: 0x0080, + 0x243c: 0x0080, 0x243d: 0x0080, 0x243e: 0x0080, 0x243f: 0x0080, + // Block 0x91, offset 0x2440 + 0x2440: 0x00cc, 0x2441: 0x00cc, 0x2442: 0x00cc, 0x2443: 0x00cc, 0x2444: 0x00cc, 0x2445: 0x00cc, + 0x2446: 0x00cc, 0x2447: 0x00cc, 0x2448: 0x00cc, 0x2449: 0x00cc, 0x244a: 0x00cc, 0x244b: 0x00cc, + 0x244c: 0x00cc, 0x244d: 0x00cc, 0x244e: 0x00cc, 0x244f: 0x00cc, 0x2450: 0x00cc, 0x2451: 0x00cc, + 0x2452: 0x00cc, 0x2453: 0x00cc, 0x2454: 0x00cc, 0x2455: 0x00cc, 0x2456: 0x00cc, 0x2457: 0x00cc, + 0x2458: 0x00cc, 0x2459: 0x00cc, 0x245a: 0x00cc, 0x245b: 0x00cc, 0x245c: 0x00cc, 0x245d: 0x00cc, + 0x245e: 0x00cc, 0x245f: 0x00cc, 0x2460: 0x00cc, 0x2461: 0x00cc, 0x2462: 0x00cc, 0x2463: 0x00cc, + 0x2464: 0x00cc, 0x2465: 0x00cc, 0x2466: 0x00cc, 0x2467: 0x00cc, 0x2468: 0x00cc, 0x2469: 0x00cc, + 0x246a: 0x00cc, 0x246b: 0x00cc, 0x246c: 0x00cc, 0x246d: 0x00cc, 0x246e: 0x00cc, 0x246f: 0x00cc, + 0x2470: 0x00cc, 0x2471: 0x00cc, 0x2472: 0x00cc, 0x2473: 0x00cc, 0x2474: 0x00cc, 0x2475: 0x00cc, + 0x2476: 0x00cc, 0x2477: 0x00cc, 0x2478: 0x00cc, 0x2479: 0x00cc, 0x247a: 0x00cc, 0x247b: 0x00cc, + 0x247c: 0x00cc, 0x247d: 0x00cc, 0x247e: 0x00cc, 0x247f: 0x00cc, + // Block 0x92, offset 0x2480 + 0x2480: 0x00cc, 0x2481: 0x00cc, 0x2482: 0x00cc, 0x2483: 0x00cc, 0x2484: 0x00cc, 0x2485: 0x00cc, + 0x2486: 0x00cc, 0x2487: 0x00cc, 0x2488: 0x00cc, 0x2489: 0x00cc, 0x248a: 0x00cc, 0x248b: 0x00cc, + 0x248c: 0x00cc, 0x248d: 0x00cc, 0x248e: 0x00cc, 0x248f: 0x00cc, 0x2490: 0x00cc, 0x2491: 0x00cc, + 0x2492: 0x00cc, 0x2493: 0x00cc, 0x2494: 0x00cc, 0x2495: 0x00cc, 0x2496: 0x00cc, 0x2497: 0x00cc, + 0x2498: 0x00cc, 0x2499: 0x00cc, 0x249a: 0x00cc, 0x249b: 0x00cc, 0x249c: 0x00cc, 0x249d: 0x00cc, + 0x249e: 0x00cc, 0x249f: 0x00cc, 0x24a0: 0x00cc, 0x24a1: 0x00cc, 0x24a2: 0x00cc, 0x24a3: 0x00cc, + 0x24a4: 0x00cc, 0x24a5: 0x00cc, 0x24a6: 0x00cc, 0x24a7: 0x00cc, 0x24a8: 0x00cc, 0x24a9: 0x00cc, + 0x24aa: 0x00cc, 0x24ab: 0x00cc, 0x24ac: 0x00cc, 0x24ad: 0x00cc, 0x24ae: 0x00cc, 0x24af: 0x00cc, + 0x24b0: 0x00cc, 0x24b1: 0x00cc, 0x24b2: 0x00cc, 0x24b3: 0x00cc, 0x24b4: 0x00cc, 0x24b5: 0x00cc, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x00cc, 0x24c1: 0x00cc, 0x24c2: 0x00cc, 0x24c3: 0x00cc, 0x24c4: 0x00cc, 0x24c5: 0x00cc, + 0x24c6: 0x00cc, 0x24c7: 0x00cc, 0x24c8: 0x00cc, 0x24c9: 0x00cc, 0x24ca: 0x00cc, 0x24cb: 0x00cc, + 0x24cc: 0x00cc, 0x24cd: 0x00cc, 0x24ce: 0x00cc, 0x24cf: 0x00cc, 0x24d0: 0x00cc, 0x24d1: 0x00cc, + 0x24d2: 0x00cc, 0x24d3: 0x00cc, 0x24d4: 0x00cc, 0x24d5: 0x00cc, 0x24d6: 0x00cc, 0x24d7: 0x00cc, + 0x24d8: 0x00cc, 0x24d9: 0x00cc, 0x24da: 0x00cc, 0x24db: 0x00cc, 0x24dc: 0x00cc, 0x24dd: 0x00cc, + 0x24de: 0x00cc, 0x24df: 0x00cc, 0x24e0: 0x00cc, 0x24e1: 0x00cc, 0x24e2: 0x00cc, 0x24e3: 0x00cc, + 0x24e4: 0x00cc, 0x24e5: 0x00cc, 0x24e6: 0x00cc, 0x24e7: 0x00cc, 0x24e8: 0x00cc, 0x24e9: 0x00cc, + 0x24ea: 0x00cc, 0x24eb: 0x00cc, 0x24ec: 0x00cc, 0x24ed: 0x00cc, 0x24ee: 0x00cc, 0x24ef: 0x00cc, + // Block 0x94, offset 0x2500 + 0x2500: 0x00c0, 0x2501: 0x00c0, 0x2502: 0x00c0, 0x2503: 0x00c0, 0x2504: 0x00c0, 0x2505: 0x00c0, + 0x2506: 0x00c0, 0x2507: 0x00c0, 0x2508: 0x00c0, 0x2509: 0x00c0, 0x250a: 0x00c0, 0x250b: 0x00c0, + 0x250c: 0x00c0, 0x2510: 0x0080, 0x2511: 0x0080, + 0x2512: 0x0080, 0x2513: 0x0080, 0x2514: 0x0080, 0x2515: 0x0080, 0x2516: 0x0080, 0x2517: 0x0080, + 0x2518: 0x0080, 0x2519: 0x0080, 0x251a: 0x0080, 0x251b: 0x0080, 0x251c: 0x0080, 0x251d: 0x0080, + 0x251e: 0x0080, 0x251f: 0x0080, 0x2520: 0x0080, 0x2521: 0x0080, 0x2522: 0x0080, 0x2523: 0x0080, + 0x2524: 0x0080, 0x2525: 0x0080, 0x2526: 0x0080, 0x2527: 0x0080, 0x2528: 0x0080, 0x2529: 0x0080, + 0x252a: 0x0080, 0x252b: 0x0080, 0x252c: 0x0080, 0x252d: 0x0080, 0x252e: 0x0080, 0x252f: 0x0080, + 0x2530: 0x0080, 0x2531: 0x0080, 0x2532: 0x0080, 0x2533: 0x0080, 0x2534: 0x0080, 0x2535: 0x0080, + 0x2536: 0x0080, 0x2537: 0x0080, 0x2538: 0x0080, 0x2539: 0x0080, 0x253a: 0x0080, 0x253b: 0x0080, + 0x253c: 0x0080, 0x253d: 0x0080, 0x253e: 0x0080, 0x253f: 0x0080, + // Block 0x95, offset 0x2540 + 0x2540: 0x0080, 0x2541: 0x0080, 0x2542: 0x0080, 0x2543: 0x0080, 0x2544: 0x0080, 0x2545: 0x0080, + 0x2546: 0x0080, + 0x2550: 0x00c0, 0x2551: 0x00c0, + 0x2552: 0x00c0, 0x2553: 0x00c0, 0x2554: 0x00c0, 0x2555: 0x00c0, 0x2556: 0x00c0, 0x2557: 0x00c0, + 0x2558: 0x00c0, 0x2559: 0x00c0, 0x255a: 0x00c0, 0x255b: 0x00c0, 0x255c: 0x00c0, 0x255d: 0x00c0, + 0x255e: 0x00c0, 0x255f: 0x00c0, 0x2560: 0x00c0, 0x2561: 0x00c0, 0x2562: 0x00c0, 0x2563: 0x00c0, + 0x2564: 0x00c0, 0x2565: 0x00c0, 0x2566: 0x00c0, 0x2567: 0x00c0, 0x2568: 0x00c0, 0x2569: 0x00c0, + 0x256a: 0x00c0, 0x256b: 0x00c0, 0x256c: 0x00c0, 0x256d: 0x00c0, 0x256e: 0x00c0, 0x256f: 0x00c0, + 0x2570: 0x00c0, 0x2571: 0x00c0, 0x2572: 0x00c0, 0x2573: 0x00c0, 0x2574: 0x00c0, 0x2575: 0x00c0, + 0x2576: 0x00c0, 0x2577: 0x00c0, 0x2578: 0x00c0, 0x2579: 0x00c0, 0x257a: 0x00c0, 0x257b: 0x00c0, + 0x257c: 0x00c0, 0x257d: 0x00c0, 0x257e: 0x0080, 0x257f: 0x0080, + // Block 0x96, offset 0x2580 + 0x2580: 0x00c0, 0x2581: 0x00c0, 0x2582: 0x00c0, 0x2583: 0x00c0, 0x2584: 0x00c0, 0x2585: 0x00c0, + 0x2586: 0x00c0, 0x2587: 0x00c0, 0x2588: 0x00c0, 0x2589: 0x00c0, 0x258a: 0x00c0, 0x258b: 0x00c0, + 0x258c: 0x00c0, 0x258d: 0x0080, 0x258e: 0x0080, 0x258f: 0x0080, 0x2590: 0x00c0, 0x2591: 0x00c0, + 0x2592: 0x00c0, 0x2593: 0x00c0, 0x2594: 0x00c0, 0x2595: 0x00c0, 0x2596: 0x00c0, 0x2597: 0x00c0, + 0x2598: 0x00c0, 0x2599: 0x00c0, 0x259a: 0x00c0, 0x259b: 0x00c0, 0x259c: 0x00c0, 0x259d: 0x00c0, + 0x259e: 0x00c0, 0x259f: 0x00c0, 0x25a0: 0x00c0, 0x25a1: 0x00c0, 0x25a2: 0x00c0, 0x25a3: 0x00c0, + 0x25a4: 0x00c0, 0x25a5: 0x00c0, 0x25a6: 0x00c0, 0x25a7: 0x00c0, 0x25a8: 0x00c0, 0x25a9: 0x00c0, + 0x25aa: 0x00c0, 0x25ab: 0x00c0, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x00c0, 0x25c1: 0x00c0, 0x25c2: 0x00c0, 0x25c3: 0x00c0, 0x25c4: 0x00c0, 0x25c5: 0x00c0, + 0x25c6: 0x00c0, 0x25c7: 0x00c0, 0x25c8: 0x00c0, 0x25c9: 0x00c0, 0x25ca: 0x00c0, 0x25cb: 0x00c0, + 0x25cc: 0x00c0, 0x25cd: 0x00c0, 0x25ce: 0x00c0, 0x25cf: 0x00c0, 0x25d0: 0x00c0, 0x25d1: 0x00c0, + 0x25d2: 0x00c0, 0x25d3: 0x00c0, 0x25d4: 0x00c0, 0x25d5: 0x00c0, 0x25d6: 0x00c0, 0x25d7: 0x00c0, + 0x25d8: 0x00c0, 0x25d9: 0x00c0, 0x25da: 0x00c0, 0x25db: 0x00c0, 0x25dc: 0x00c0, 0x25dd: 0x00c0, + 0x25de: 0x00c0, 0x25df: 0x00c0, 0x25e0: 0x00c0, 0x25e1: 0x00c0, 0x25e2: 0x00c0, 0x25e3: 0x00c0, + 0x25e4: 0x00c0, 0x25e5: 0x00c0, 0x25e6: 0x00c0, 0x25e7: 0x00c0, 0x25e8: 0x00c0, 0x25e9: 0x00c0, + 0x25ea: 0x00c0, 0x25eb: 0x00c0, 0x25ec: 0x00c0, 0x25ed: 0x00c0, 0x25ee: 0x00c0, 0x25ef: 0x00c3, + 0x25f0: 0x0083, 0x25f1: 0x0083, 0x25f2: 0x0083, 0x25f3: 0x0080, 0x25f4: 0x00c3, 0x25f5: 0x00c3, + 0x25f6: 0x00c3, 0x25f7: 0x00c3, 0x25f8: 0x00c3, 0x25f9: 0x00c3, 0x25fa: 0x00c3, 0x25fb: 0x00c3, + 0x25fc: 0x00c3, 0x25fd: 0x00c3, 0x25fe: 0x0080, 0x25ff: 0x00c0, + // Block 0x98, offset 0x2600 + 0x2600: 0x00c0, 0x2601: 0x00c0, 0x2602: 0x00c0, 0x2603: 0x00c0, 0x2604: 0x00c0, 0x2605: 0x00c0, + 0x2606: 0x00c0, 0x2607: 0x00c0, 0x2608: 0x00c0, 0x2609: 0x00c0, 0x260a: 0x00c0, 0x260b: 0x00c0, + 0x260c: 0x00c0, 0x260d: 0x00c0, 0x260e: 0x00c0, 0x260f: 0x00c0, 0x2610: 0x00c0, 0x2611: 0x00c0, + 0x2612: 0x00c0, 0x2613: 0x00c0, 0x2614: 0x00c0, 0x2615: 0x00c0, 0x2616: 0x00c0, 0x2617: 0x00c0, + 0x2618: 0x00c0, 0x2619: 0x00c0, 0x261a: 0x00c0, 0x261b: 0x00c0, 0x261c: 0x0080, 0x261d: 0x0080, + 0x261e: 0x00c3, 0x261f: 0x00c3, 0x2620: 0x00c0, 0x2621: 0x00c0, 0x2622: 0x00c0, 0x2623: 0x00c0, + 0x2624: 0x00c0, 0x2625: 0x00c0, 0x2626: 0x00c0, 0x2627: 0x00c0, 0x2628: 0x00c0, 0x2629: 0x00c0, + 0x262a: 0x00c0, 0x262b: 0x00c0, 0x262c: 0x00c0, 0x262d: 0x00c0, 0x262e: 0x00c0, 0x262f: 0x00c0, + 0x2630: 0x00c0, 0x2631: 0x00c0, 0x2632: 0x00c0, 0x2633: 0x00c0, 0x2634: 0x00c0, 0x2635: 0x00c0, + 0x2636: 0x00c0, 0x2637: 0x00c0, 0x2638: 0x00c0, 0x2639: 0x00c0, 0x263a: 0x00c0, 0x263b: 0x00c0, + 0x263c: 0x00c0, 0x263d: 0x00c0, 0x263e: 0x00c0, 0x263f: 0x00c0, + // Block 0x99, offset 0x2640 + 0x2640: 0x00c0, 0x2641: 0x00c0, 0x2642: 0x00c0, 0x2643: 0x00c0, 0x2644: 0x00c0, 0x2645: 0x00c0, + 0x2646: 0x00c0, 0x2647: 0x00c0, 0x2648: 0x00c0, 0x2649: 0x00c0, 0x264a: 0x00c0, 0x264b: 0x00c0, + 0x264c: 0x00c0, 0x264d: 0x00c0, 0x264e: 0x00c0, 0x264f: 0x00c0, 0x2650: 0x00c0, 0x2651: 0x00c0, + 0x2652: 0x00c0, 0x2653: 0x00c0, 0x2654: 0x00c0, 0x2655: 0x00c0, 0x2656: 0x00c0, 0x2657: 0x00c0, + 0x2658: 0x00c0, 0x2659: 0x00c0, 0x265a: 0x00c0, 0x265b: 0x00c0, 0x265c: 0x00c0, 0x265d: 0x00c0, + 0x265e: 0x00c0, 0x265f: 0x00c0, 0x2660: 0x00c0, 0x2661: 0x00c0, 0x2662: 0x00c0, 0x2663: 0x00c0, + 0x2664: 0x00c0, 0x2665: 0x00c0, 0x2666: 0x0080, 0x2667: 0x0080, 0x2668: 0x0080, 0x2669: 0x0080, + 0x266a: 0x0080, 0x266b: 0x0080, 0x266c: 0x0080, 0x266d: 0x0080, 0x266e: 0x0080, 0x266f: 0x0080, + 0x2670: 0x00c3, 0x2671: 0x00c3, 0x2672: 0x0080, 0x2673: 0x0080, 0x2674: 0x0080, 0x2675: 0x0080, + 0x2676: 0x0080, 0x2677: 0x0080, + // Block 0x9a, offset 0x2680 + 0x2680: 0x0080, 0x2681: 0x0080, 0x2682: 0x0080, 0x2683: 0x0080, 0x2684: 0x0080, 0x2685: 0x0080, + 0x2686: 0x0080, 0x2687: 0x0080, 0x2688: 0x0080, 0x2689: 0x0080, 0x268a: 0x0080, 0x268b: 0x0080, + 0x268c: 0x0080, 0x268d: 0x0080, 0x268e: 0x0080, 0x268f: 0x0080, 0x2690: 0x0080, 0x2691: 0x0080, + 0x2692: 0x0080, 0x2693: 0x0080, 0x2694: 0x0080, 0x2695: 0x0080, 0x2696: 0x0080, 0x2697: 0x00c0, + 0x2698: 0x00c0, 0x2699: 0x00c0, 0x269a: 0x00c0, 0x269b: 0x00c0, 0x269c: 0x00c0, 0x269d: 0x00c0, + 0x269e: 0x00c0, 0x269f: 0x00c0, 0x26a0: 0x0080, 0x26a1: 0x0080, 0x26a2: 0x00c0, 0x26a3: 0x00c0, + 0x26a4: 0x00c0, 0x26a5: 0x00c0, 0x26a6: 0x00c0, 0x26a7: 0x00c0, 0x26a8: 0x00c0, 0x26a9: 0x00c0, + 0x26aa: 0x00c0, 0x26ab: 0x00c0, 0x26ac: 0x00c0, 0x26ad: 0x00c0, 0x26ae: 0x00c0, 0x26af: 0x00c0, + 0x26b0: 0x00c0, 0x26b1: 0x00c0, 0x26b2: 0x00c0, 0x26b3: 0x00c0, 0x26b4: 0x00c0, 0x26b5: 0x00c0, + 0x26b6: 0x00c0, 0x26b7: 0x00c0, 0x26b8: 0x00c0, 0x26b9: 0x00c0, 0x26ba: 0x00c0, 0x26bb: 0x00c0, + 0x26bc: 0x00c0, 0x26bd: 0x00c0, 0x26be: 0x00c0, 0x26bf: 0x00c0, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x00c0, 0x26c1: 0x00c0, 0x26c2: 0x00c0, 0x26c3: 0x00c0, 0x26c4: 0x00c0, 0x26c5: 0x00c0, + 0x26c6: 0x00c0, 0x26c7: 0x00c0, 0x26c8: 0x00c0, 0x26c9: 0x00c0, 0x26ca: 0x00c0, 0x26cb: 0x00c0, + 0x26cc: 0x00c0, 0x26cd: 0x00c0, 0x26ce: 0x00c0, 0x26cf: 0x00c0, 0x26d0: 0x00c0, 0x26d1: 0x00c0, + 0x26d2: 0x00c0, 0x26d3: 0x00c0, 0x26d4: 0x00c0, 0x26d5: 0x00c0, 0x26d6: 0x00c0, 0x26d7: 0x00c0, + 0x26d8: 0x00c0, 0x26d9: 0x00c0, 0x26da: 0x00c0, 0x26db: 0x00c0, 0x26dc: 0x00c0, 0x26dd: 0x00c0, + 0x26de: 0x00c0, 0x26df: 0x00c0, 0x26e0: 0x00c0, 0x26e1: 0x00c0, 0x26e2: 0x00c0, 0x26e3: 0x00c0, + 0x26e4: 0x00c0, 0x26e5: 0x00c0, 0x26e6: 0x00c0, 0x26e7: 0x00c0, 0x26e8: 0x00c0, 0x26e9: 0x00c0, + 0x26ea: 0x00c0, 0x26eb: 0x00c0, 0x26ec: 0x00c0, 0x26ed: 0x00c0, 0x26ee: 0x00c0, 0x26ef: 0x00c0, + 0x26f0: 0x0080, 0x26f1: 0x00c0, 0x26f2: 0x00c0, 0x26f3: 0x00c0, 0x26f4: 0x00c0, 0x26f5: 0x00c0, + 0x26f6: 0x00c0, 0x26f7: 0x00c0, 0x26f8: 0x00c0, 0x26f9: 0x00c0, 0x26fa: 0x00c0, 0x26fb: 0x00c0, + 0x26fc: 0x00c0, 0x26fd: 0x00c0, 0x26fe: 0x00c0, 0x26ff: 0x00c0, + // Block 0x9c, offset 0x2700 + 0x2700: 0x00c0, 0x2701: 0x00c0, 0x2702: 0x00c0, 0x2703: 0x00c0, 0x2704: 0x00c0, 0x2705: 0x00c0, + 0x2706: 0x00c0, 0x2707: 0x00c0, 0x2708: 0x00c0, 0x2709: 0x0080, 0x270a: 0x0080, 0x270b: 0x00c0, + 0x270c: 0x00c0, 0x270d: 0x00c0, 0x270e: 0x00c0, 0x270f: 0x00c0, 0x2710: 0x00c0, 0x2711: 0x00c0, + 0x2712: 0x00c0, 0x2713: 0x00c0, 0x2714: 0x00c0, 0x2715: 0x00c0, 0x2716: 0x00c0, 0x2717: 0x00c0, + 0x2718: 0x00c0, 0x2719: 0x00c0, 0x271a: 0x00c0, 0x271b: 0x00c0, 0x271c: 0x00c0, 0x271d: 0x00c0, + 0x271e: 0x00c0, 0x271f: 0x00c0, 0x2720: 0x00c0, 0x2721: 0x00c0, 0x2722: 0x00c0, 0x2723: 0x00c0, + 0x2724: 0x00c0, 0x2725: 0x00c0, 0x2726: 0x00c0, 0x2727: 0x00c0, 0x2728: 0x00c0, 0x2729: 0x00c0, + 0x272a: 0x00c0, 0x272b: 0x00c0, 0x272c: 0x00c0, 0x272d: 0x00c0, 0x272e: 0x00c0, 0x272f: 0x00c0, + 0x2730: 0x00c0, 0x2731: 0x00c0, 0x2732: 0x00c0, 0x2733: 0x00c0, 0x2734: 0x00c0, 0x2735: 0x00c0, + 0x2736: 0x00c0, 0x2737: 0x00c0, 0x2738: 0x00c0, 0x2739: 0x00c0, + // Block 0x9d, offset 0x2740 + 0x2777: 0x00c0, 0x2778: 0x0080, 0x2779: 0x0080, 0x277a: 0x00c0, 0x277b: 0x00c0, + 0x277c: 0x00c0, 0x277d: 0x00c0, 0x277e: 0x00c0, 0x277f: 0x00c0, + // Block 0x9e, offset 0x2780 + 0x2780: 0x00c0, 0x2781: 0x00c0, 0x2782: 0x00c3, 0x2783: 0x00c0, 0x2784: 0x00c0, 0x2785: 0x00c0, + 0x2786: 0x00c6, 0x2787: 0x00c0, 0x2788: 0x00c0, 0x2789: 0x00c0, 0x278a: 0x00c0, 0x278b: 0x00c3, + 0x278c: 0x00c0, 0x278d: 0x00c0, 0x278e: 0x00c0, 0x278f: 0x00c0, 0x2790: 0x00c0, 0x2791: 0x00c0, + 0x2792: 0x00c0, 0x2793: 0x00c0, 0x2794: 0x00c0, 0x2795: 0x00c0, 0x2796: 0x00c0, 0x2797: 0x00c0, + 0x2798: 0x00c0, 0x2799: 0x00c0, 0x279a: 0x00c0, 0x279b: 0x00c0, 0x279c: 0x00c0, 0x279d: 0x00c0, + 0x279e: 0x00c0, 0x279f: 0x00c0, 0x27a0: 0x00c0, 0x27a1: 0x00c0, 0x27a2: 0x00c0, 0x27a3: 0x00c0, + 0x27a4: 0x00c0, 0x27a5: 0x00c3, 0x27a6: 0x00c3, 0x27a7: 0x00c0, 0x27a8: 0x0080, 0x27a9: 0x0080, + 0x27aa: 0x0080, 0x27ab: 0x0080, + 0x27b0: 0x0080, 0x27b1: 0x0080, 0x27b2: 0x0080, 0x27b3: 0x0080, 0x27b4: 0x0080, 0x27b5: 0x0080, + 0x27b6: 0x0080, 0x27b7: 0x0080, 0x27b8: 0x0080, 0x27b9: 0x0080, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x00c2, 0x27c1: 0x00c2, 0x27c2: 0x00c2, 0x27c3: 0x00c2, 0x27c4: 0x00c2, 0x27c5: 0x00c2, + 0x27c6: 0x00c2, 0x27c7: 0x00c2, 0x27c8: 0x00c2, 0x27c9: 0x00c2, 0x27ca: 0x00c2, 0x27cb: 0x00c2, + 0x27cc: 0x00c2, 0x27cd: 0x00c2, 0x27ce: 0x00c2, 0x27cf: 0x00c2, 0x27d0: 0x00c2, 0x27d1: 0x00c2, + 0x27d2: 0x00c2, 0x27d3: 0x00c2, 0x27d4: 0x00c2, 0x27d5: 0x00c2, 0x27d6: 0x00c2, 0x27d7: 0x00c2, + 0x27d8: 0x00c2, 0x27d9: 0x00c2, 0x27da: 0x00c2, 0x27db: 0x00c2, 0x27dc: 0x00c2, 0x27dd: 0x00c2, + 0x27de: 0x00c2, 0x27df: 0x00c2, 0x27e0: 0x00c2, 0x27e1: 0x00c2, 0x27e2: 0x00c2, 0x27e3: 0x00c2, + 0x27e4: 0x00c2, 0x27e5: 0x00c2, 0x27e6: 0x00c2, 0x27e7: 0x00c2, 0x27e8: 0x00c2, 0x27e9: 0x00c2, + 0x27ea: 0x00c2, 0x27eb: 0x00c2, 0x27ec: 0x00c2, 0x27ed: 0x00c2, 0x27ee: 0x00c2, 0x27ef: 0x00c2, + 0x27f0: 0x00c2, 0x27f1: 0x00c2, 0x27f2: 0x00c1, 0x27f3: 0x00c0, 0x27f4: 0x0080, 0x27f5: 0x0080, + 0x27f6: 0x0080, 0x27f7: 0x0080, + // Block 0xa0, offset 0x2800 + 0x2800: 0x00c0, 0x2801: 0x00c0, 0x2802: 0x00c0, 0x2803: 0x00c0, 0x2804: 0x00c6, 0x2805: 0x00c3, + 0x280e: 0x0080, 0x280f: 0x0080, 0x2810: 0x00c0, 0x2811: 0x00c0, + 0x2812: 0x00c0, 0x2813: 0x00c0, 0x2814: 0x00c0, 0x2815: 0x00c0, 0x2816: 0x00c0, 0x2817: 0x00c0, + 0x2818: 0x00c0, 0x2819: 0x00c0, + 0x2820: 0x00c3, 0x2821: 0x00c3, 0x2822: 0x00c3, 0x2823: 0x00c3, + 0x2824: 0x00c3, 0x2825: 0x00c3, 0x2826: 0x00c3, 0x2827: 0x00c3, 0x2828: 0x00c3, 0x2829: 0x00c3, + 0x282a: 0x00c3, 0x282b: 0x00c3, 0x282c: 0x00c3, 0x282d: 0x00c3, 0x282e: 0x00c3, 0x282f: 0x00c3, + 0x2830: 0x00c3, 0x2831: 0x00c3, 0x2832: 0x00c0, 0x2833: 0x00c0, 0x2834: 0x00c0, 0x2835: 0x00c0, + 0x2836: 0x00c0, 0x2837: 0x00c0, 0x2838: 0x0080, 0x2839: 0x0080, 0x283a: 0x0080, 0x283b: 0x00c0, + 0x283c: 0x0080, 0x283d: 0x00c0, 0x283e: 0x00c0, 0x283f: 0x00c3, + // Block 0xa1, offset 0x2840 + 0x2840: 0x00c0, 0x2841: 0x00c0, 0x2842: 0x00c0, 0x2843: 0x00c0, 0x2844: 0x00c0, 0x2845: 0x00c0, + 0x2846: 0x00c0, 0x2847: 0x00c0, 0x2848: 0x00c0, 0x2849: 0x00c0, 0x284a: 0x00c0, 0x284b: 0x00c0, + 0x284c: 0x00c0, 0x284d: 0x00c0, 0x284e: 0x00c0, 0x284f: 0x00c0, 0x2850: 0x00c0, 0x2851: 0x00c0, + 0x2852: 0x00c0, 0x2853: 0x00c0, 0x2854: 0x00c0, 0x2855: 0x00c0, 0x2856: 0x00c0, 0x2857: 0x00c0, + 0x2858: 0x00c0, 0x2859: 0x00c0, 0x285a: 0x00c0, 0x285b: 0x00c0, 0x285c: 0x00c0, 0x285d: 0x00c0, + 0x285e: 0x00c0, 0x285f: 0x00c0, 0x2860: 0x00c0, 0x2861: 0x00c0, 0x2862: 0x00c0, 0x2863: 0x00c0, + 0x2864: 0x00c0, 0x2865: 0x00c0, 0x2866: 0x00c3, 0x2867: 0x00c3, 0x2868: 0x00c3, 0x2869: 0x00c3, + 0x286a: 0x00c3, 0x286b: 0x00c3, 0x286c: 0x00c3, 0x286d: 0x00c3, 0x286e: 0x0080, 0x286f: 0x0080, + 0x2870: 0x00c0, 0x2871: 0x00c0, 0x2872: 0x00c0, 0x2873: 0x00c0, 0x2874: 0x00c0, 0x2875: 0x00c0, + 0x2876: 0x00c0, 0x2877: 0x00c0, 0x2878: 0x00c0, 0x2879: 0x00c0, 0x287a: 0x00c0, 0x287b: 0x00c0, + 0x287c: 0x00c0, 0x287d: 0x00c0, 0x287e: 0x00c0, 0x287f: 0x00c0, + // Block 0xa2, offset 0x2880 + 0x2880: 0x00c0, 0x2881: 0x00c0, 0x2882: 0x00c0, 0x2883: 0x00c0, 0x2884: 0x00c0, 0x2885: 0x00c0, + 0x2886: 0x00c0, 0x2887: 0x00c3, 0x2888: 0x00c3, 0x2889: 0x00c3, 0x288a: 0x00c3, 0x288b: 0x00c3, + 0x288c: 0x00c3, 0x288d: 0x00c3, 0x288e: 0x00c3, 0x288f: 0x00c3, 0x2890: 0x00c3, 0x2891: 0x00c3, + 0x2892: 0x00c0, 0x2893: 0x00c5, + 0x289f: 0x0080, 0x28a0: 0x0040, 0x28a1: 0x0040, 0x28a2: 0x0040, 0x28a3: 0x0040, + 0x28a4: 0x0040, 0x28a5: 0x0040, 0x28a6: 0x0040, 0x28a7: 0x0040, 0x28a8: 0x0040, 0x28a9: 0x0040, + 0x28aa: 0x0040, 0x28ab: 0x0040, 0x28ac: 0x0040, 0x28ad: 0x0040, 0x28ae: 0x0040, 0x28af: 0x0040, + 0x28b0: 0x0040, 0x28b1: 0x0040, 0x28b2: 0x0040, 0x28b3: 0x0040, 0x28b4: 0x0040, 0x28b5: 0x0040, + 0x28b6: 0x0040, 0x28b7: 0x0040, 0x28b8: 0x0040, 0x28b9: 0x0040, 0x28ba: 0x0040, 0x28bb: 0x0040, + 0x28bc: 0x0040, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x00c3, 0x28c1: 0x00c3, 0x28c2: 0x00c3, 0x28c3: 0x00c0, 0x28c4: 0x00c0, 0x28c5: 0x00c0, + 0x28c6: 0x00c0, 0x28c7: 0x00c0, 0x28c8: 0x00c0, 0x28c9: 0x00c0, 0x28ca: 0x00c0, 0x28cb: 0x00c0, + 0x28cc: 0x00c0, 0x28cd: 0x00c0, 0x28ce: 0x00c0, 0x28cf: 0x00c0, 0x28d0: 0x00c0, 0x28d1: 0x00c0, + 0x28d2: 0x00c0, 0x28d3: 0x00c0, 0x28d4: 0x00c0, 0x28d5: 0x00c0, 0x28d6: 0x00c0, 0x28d7: 0x00c0, + 0x28d8: 0x00c0, 0x28d9: 0x00c0, 0x28da: 0x00c0, 0x28db: 0x00c0, 0x28dc: 0x00c0, 0x28dd: 0x00c0, + 0x28de: 0x00c0, 0x28df: 0x00c0, 0x28e0: 0x00c0, 0x28e1: 0x00c0, 0x28e2: 0x00c0, 0x28e3: 0x00c0, + 0x28e4: 0x00c0, 0x28e5: 0x00c0, 0x28e6: 0x00c0, 0x28e7: 0x00c0, 0x28e8: 0x00c0, 0x28e9: 0x00c0, + 0x28ea: 0x00c0, 0x28eb: 0x00c0, 0x28ec: 0x00c0, 0x28ed: 0x00c0, 0x28ee: 0x00c0, 0x28ef: 0x00c0, + 0x28f0: 0x00c0, 0x28f1: 0x00c0, 0x28f2: 0x00c0, 0x28f3: 0x00c3, 0x28f4: 0x00c0, 0x28f5: 0x00c0, + 0x28f6: 0x00c3, 0x28f7: 0x00c3, 0x28f8: 0x00c3, 0x28f9: 0x00c3, 0x28fa: 0x00c0, 0x28fb: 0x00c0, + 0x28fc: 0x00c3, 0x28fd: 0x00c0, 0x28fe: 0x00c0, 0x28ff: 0x00c0, + // Block 0xa4, offset 0x2900 + 0x2900: 0x00c5, 0x2901: 0x0080, 0x2902: 0x0080, 0x2903: 0x0080, 0x2904: 0x0080, 0x2905: 0x0080, + 0x2906: 0x0080, 0x2907: 0x0080, 0x2908: 0x0080, 0x2909: 0x0080, 0x290a: 0x0080, 0x290b: 0x0080, + 0x290c: 0x0080, 0x290d: 0x0080, 0x290f: 0x00c0, 0x2910: 0x00c0, 0x2911: 0x00c0, + 0x2912: 0x00c0, 0x2913: 0x00c0, 0x2914: 0x00c0, 0x2915: 0x00c0, 0x2916: 0x00c0, 0x2917: 0x00c0, + 0x2918: 0x00c0, 0x2919: 0x00c0, + 0x291e: 0x0080, 0x291f: 0x0080, 0x2920: 0x00c0, 0x2921: 0x00c0, 0x2922: 0x00c0, 0x2923: 0x00c0, + 0x2924: 0x00c0, 0x2925: 0x00c3, 0x2926: 0x00c0, 0x2927: 0x00c0, 0x2928: 0x00c0, 0x2929: 0x00c0, + 0x292a: 0x00c0, 0x292b: 0x00c0, 0x292c: 0x00c0, 0x292d: 0x00c0, 0x292e: 0x00c0, 0x292f: 0x00c0, + 0x2930: 0x00c0, 0x2931: 0x00c0, 0x2932: 0x00c0, 0x2933: 0x00c0, 0x2934: 0x00c0, 0x2935: 0x00c0, + 0x2936: 0x00c0, 0x2937: 0x00c0, 0x2938: 0x00c0, 0x2939: 0x00c0, 0x293a: 0x00c0, 0x293b: 0x00c0, + 0x293c: 0x00c0, 0x293d: 0x00c0, 0x293e: 0x00c0, + // Block 0xa5, offset 0x2940 + 0x2940: 0x00c0, 0x2941: 0x00c0, 0x2942: 0x00c0, 0x2943: 0x00c0, 0x2944: 0x00c0, 0x2945: 0x00c0, + 0x2946: 0x00c0, 0x2947: 0x00c0, 0x2948: 0x00c0, 0x2949: 0x00c0, 0x294a: 0x00c0, 0x294b: 0x00c0, + 0x294c: 0x00c0, 0x294d: 0x00c0, 0x294e: 0x00c0, 0x294f: 0x00c0, 0x2950: 0x00c0, 0x2951: 0x00c0, + 0x2952: 0x00c0, 0x2953: 0x00c0, 0x2954: 0x00c0, 0x2955: 0x00c0, 0x2956: 0x00c0, 0x2957: 0x00c0, + 0x2958: 0x00c0, 0x2959: 0x00c0, 0x295a: 0x00c0, 0x295b: 0x00c0, 0x295c: 0x00c0, 0x295d: 0x00c0, + 0x295e: 0x00c0, 0x295f: 0x00c0, 0x2960: 0x00c0, 0x2961: 0x00c0, 0x2962: 0x00c0, 0x2963: 0x00c0, + 0x2964: 0x00c0, 0x2965: 0x00c0, 0x2966: 0x00c0, 0x2967: 0x00c0, 0x2968: 0x00c0, 0x2969: 0x00c3, + 0x296a: 0x00c3, 0x296b: 0x00c3, 0x296c: 0x00c3, 0x296d: 0x00c3, 0x296e: 0x00c3, 0x296f: 0x00c0, + 0x2970: 0x00c0, 0x2971: 0x00c3, 0x2972: 0x00c3, 0x2973: 0x00c0, 0x2974: 0x00c0, 0x2975: 0x00c3, + 0x2976: 0x00c3, + // Block 0xa6, offset 0x2980 + 0x2980: 0x00c0, 0x2981: 0x00c0, 0x2982: 0x00c0, 0x2983: 0x00c3, 0x2984: 0x00c0, 0x2985: 0x00c0, + 0x2986: 0x00c0, 0x2987: 0x00c0, 0x2988: 0x00c0, 0x2989: 0x00c0, 0x298a: 0x00c0, 0x298b: 0x00c0, + 0x298c: 0x00c3, 0x298d: 0x00c0, 0x2990: 0x00c0, 0x2991: 0x00c0, + 0x2992: 0x00c0, 0x2993: 0x00c0, 0x2994: 0x00c0, 0x2995: 0x00c0, 0x2996: 0x00c0, 0x2997: 0x00c0, + 0x2998: 0x00c0, 0x2999: 0x00c0, 0x299c: 0x0080, 0x299d: 0x0080, + 0x299e: 0x0080, 0x299f: 0x0080, 0x29a0: 0x00c0, 0x29a1: 0x00c0, 0x29a2: 0x00c0, 0x29a3: 0x00c0, + 0x29a4: 0x00c0, 0x29a5: 0x00c0, 0x29a6: 0x00c0, 0x29a7: 0x00c0, 0x29a8: 0x00c0, 0x29a9: 0x00c0, + 0x29aa: 0x00c0, 0x29ab: 0x00c0, 0x29ac: 0x00c0, 0x29ad: 0x00c0, 0x29ae: 0x00c0, 0x29af: 0x00c0, + 0x29b0: 0x00c0, 0x29b1: 0x00c0, 0x29b2: 0x00c0, 0x29b3: 0x00c0, 0x29b4: 0x00c0, 0x29b5: 0x00c0, + 0x29b6: 0x00c0, 0x29b7: 0x0080, 0x29b8: 0x0080, 0x29b9: 0x0080, 0x29ba: 0x00c0, 0x29bb: 0x00c0, + 0x29bc: 0x00c3, 0x29bd: 0x00c0, 0x29be: 0x00c0, 0x29bf: 0x00c0, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x00c0, 0x29c1: 0x00c0, 0x29c2: 0x00c0, 0x29c3: 0x00c0, 0x29c4: 0x00c0, 0x29c5: 0x00c0, + 0x29c6: 0x00c0, 0x29c7: 0x00c0, 0x29c8: 0x00c0, 0x29c9: 0x00c0, 0x29ca: 0x00c0, 0x29cb: 0x00c0, + 0x29cc: 0x00c0, 0x29cd: 0x00c0, 0x29ce: 0x00c0, 0x29cf: 0x00c0, 0x29d0: 0x00c0, 0x29d1: 0x00c0, + 0x29d2: 0x00c0, 0x29d3: 0x00c0, 0x29d4: 0x00c0, 0x29d5: 0x00c0, 0x29d6: 0x00c0, 0x29d7: 0x00c0, + 0x29d8: 0x00c0, 0x29d9: 0x00c0, 0x29da: 0x00c0, 0x29db: 0x00c0, 0x29dc: 0x00c0, 0x29dd: 0x00c0, + 0x29de: 0x00c0, 0x29df: 0x00c0, 0x29e0: 0x00c0, 0x29e1: 0x00c0, 0x29e2: 0x00c0, 0x29e3: 0x00c0, + 0x29e4: 0x00c0, 0x29e5: 0x00c0, 0x29e6: 0x00c0, 0x29e7: 0x00c0, 0x29e8: 0x00c0, 0x29e9: 0x00c0, + 0x29ea: 0x00c0, 0x29eb: 0x00c0, 0x29ec: 0x00c0, 0x29ed: 0x00c0, 0x29ee: 0x00c0, 0x29ef: 0x00c0, + 0x29f0: 0x00c3, 0x29f1: 0x00c0, 0x29f2: 0x00c3, 0x29f3: 0x00c3, 0x29f4: 0x00c3, 0x29f5: 0x00c0, + 0x29f6: 0x00c0, 0x29f7: 0x00c3, 0x29f8: 0x00c3, 0x29f9: 0x00c0, 0x29fa: 0x00c0, 0x29fb: 0x00c0, + 0x29fc: 0x00c0, 0x29fd: 0x00c0, 0x29fe: 0x00c3, 0x29ff: 0x00c3, + // Block 0xa8, offset 0x2a00 + 0x2a00: 0x00c0, 0x2a01: 0x00c3, 0x2a02: 0x00c0, + 0x2a1b: 0x00c0, 0x2a1c: 0x00c0, 0x2a1d: 0x00c0, + 0x2a1e: 0x0080, 0x2a1f: 0x0080, 0x2a20: 0x00c0, 0x2a21: 0x00c0, 0x2a22: 0x00c0, 0x2a23: 0x00c0, + 0x2a24: 0x00c0, 0x2a25: 0x00c0, 0x2a26: 0x00c0, 0x2a27: 0x00c0, 0x2a28: 0x00c0, 0x2a29: 0x00c0, + 0x2a2a: 0x00c0, 0x2a2b: 0x00c0, 0x2a2c: 0x00c3, 0x2a2d: 0x00c3, 0x2a2e: 0x00c0, 0x2a2f: 0x00c0, + 0x2a30: 0x0080, 0x2a31: 0x0080, 0x2a32: 0x00c0, 0x2a33: 0x00c0, 0x2a34: 0x00c0, 0x2a35: 0x00c0, + 0x2a36: 0x00c6, + // Block 0xa9, offset 0x2a40 + 0x2a41: 0x00c0, 0x2a42: 0x00c0, 0x2a43: 0x00c0, 0x2a44: 0x00c0, 0x2a45: 0x00c0, + 0x2a46: 0x00c0, 0x2a49: 0x00c0, 0x2a4a: 0x00c0, 0x2a4b: 0x00c0, + 0x2a4c: 0x00c0, 0x2a4d: 0x00c0, 0x2a4e: 0x00c0, 0x2a51: 0x00c0, + 0x2a52: 0x00c0, 0x2a53: 0x00c0, 0x2a54: 0x00c0, 0x2a55: 0x00c0, 0x2a56: 0x00c0, + 0x2a60: 0x00c0, 0x2a61: 0x00c0, 0x2a62: 0x00c0, 0x2a63: 0x00c0, + 0x2a64: 0x00c0, 0x2a65: 0x00c0, 0x2a66: 0x00c0, 0x2a68: 0x00c0, 0x2a69: 0x00c0, + 0x2a6a: 0x00c0, 0x2a6b: 0x00c0, 0x2a6c: 0x00c0, 0x2a6d: 0x00c0, 0x2a6e: 0x00c0, + 0x2a70: 0x00c0, 0x2a71: 0x00c0, 0x2a72: 0x00c0, 0x2a73: 0x00c0, 0x2a74: 0x00c0, 0x2a75: 0x00c0, + 0x2a76: 0x00c0, 0x2a77: 0x00c0, 0x2a78: 0x00c0, 0x2a79: 0x00c0, 0x2a7a: 0x00c0, 0x2a7b: 0x00c0, + 0x2a7c: 0x00c0, 0x2a7d: 0x00c0, 0x2a7e: 0x00c0, 0x2a7f: 0x00c0, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x00c0, 0x2a81: 0x00c0, 0x2a82: 0x00c0, 0x2a83: 0x00c0, 0x2a84: 0x00c0, 0x2a85: 0x00c0, + 0x2a86: 0x00c0, 0x2a87: 0x00c0, 0x2a88: 0x00c0, 0x2a89: 0x00c0, 0x2a8a: 0x00c0, 0x2a8b: 0x00c0, + 0x2a8c: 0x00c0, 0x2a8d: 0x00c0, 0x2a8e: 0x00c0, 0x2a8f: 0x00c0, 0x2a90: 0x00c0, 0x2a91: 0x00c0, + 0x2a92: 0x00c0, 0x2a93: 0x00c0, 0x2a94: 0x00c0, 0x2a95: 0x00c0, 0x2a96: 0x00c0, 0x2a97: 0x00c0, + 0x2a98: 0x00c0, 0x2a99: 0x00c0, 0x2a9a: 0x00c0, 0x2a9b: 0x0080, 0x2a9c: 0x0080, 0x2a9d: 0x0080, + 0x2a9e: 0x0080, 0x2a9f: 0x0080, 0x2aa0: 0x00c0, 0x2aa1: 0x00c0, 0x2aa2: 0x00c0, 0x2aa3: 0x00c0, + 0x2aa4: 0x00c0, 0x2aa5: 0x00c8, + 0x2ab0: 0x00c0, 0x2ab1: 0x00c0, 0x2ab2: 0x00c0, 0x2ab3: 0x00c0, 0x2ab4: 0x00c0, 0x2ab5: 0x00c0, + 0x2ab6: 0x00c0, 0x2ab7: 0x00c0, 0x2ab8: 0x00c0, 0x2ab9: 0x00c0, 0x2aba: 0x00c0, 0x2abb: 0x00c0, + 0x2abc: 0x00c0, 0x2abd: 0x00c0, 0x2abe: 0x00c0, 0x2abf: 0x00c0, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x00c0, 0x2ac1: 0x00c0, 0x2ac2: 0x00c0, 0x2ac3: 0x00c0, 0x2ac4: 0x00c0, 0x2ac5: 0x00c0, + 0x2ac6: 0x00c0, 0x2ac7: 0x00c0, 0x2ac8: 0x00c0, 0x2ac9: 0x00c0, 0x2aca: 0x00c0, 0x2acb: 0x00c0, + 0x2acc: 0x00c0, 0x2acd: 0x00c0, 0x2ace: 0x00c0, 0x2acf: 0x00c0, 0x2ad0: 0x00c0, 0x2ad1: 0x00c0, + 0x2ad2: 0x00c0, 0x2ad3: 0x00c0, 0x2ad4: 0x00c0, 0x2ad5: 0x00c0, 0x2ad6: 0x00c0, 0x2ad7: 0x00c0, + 0x2ad8: 0x00c0, 0x2ad9: 0x00c0, 0x2ada: 0x00c0, 0x2adb: 0x00c0, 0x2adc: 0x00c0, 0x2add: 0x00c0, + 0x2ade: 0x00c0, 0x2adf: 0x00c0, 0x2ae0: 0x00c0, 0x2ae1: 0x00c0, 0x2ae2: 0x00c0, 0x2ae3: 0x00c0, + 0x2ae4: 0x00c0, 0x2ae5: 0x00c3, 0x2ae6: 0x00c0, 0x2ae7: 0x00c0, 0x2ae8: 0x00c3, 0x2ae9: 0x00c0, + 0x2aea: 0x00c0, 0x2aeb: 0x0080, 0x2aec: 0x00c0, 0x2aed: 0x00c6, + 0x2af0: 0x00c0, 0x2af1: 0x00c0, 0x2af2: 0x00c0, 0x2af3: 0x00c0, 0x2af4: 0x00c0, 0x2af5: 0x00c0, + 0x2af6: 0x00c0, 0x2af7: 0x00c0, 0x2af8: 0x00c0, 0x2af9: 0x00c0, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x00c0, 0x2b01: 0x00c0, 0x2b02: 0x00c0, 0x2b03: 0x00c0, 0x2b04: 0x00c0, 0x2b05: 0x00c0, + 0x2b06: 0x00c0, 0x2b07: 0x00c0, 0x2b08: 0x00c0, 0x2b09: 0x00c0, 0x2b0a: 0x00c0, 0x2b0b: 0x00c0, + 0x2b0c: 0x00c0, 0x2b0d: 0x00c0, 0x2b0e: 0x00c0, 0x2b0f: 0x00c0, 0x2b10: 0x00c0, 0x2b11: 0x00c0, + 0x2b12: 0x00c0, 0x2b13: 0x00c0, 0x2b14: 0x00c0, 0x2b15: 0x00c0, 0x2b16: 0x00c0, 0x2b17: 0x00c0, + 0x2b18: 0x00c0, 0x2b19: 0x00c0, 0x2b1a: 0x00c0, 0x2b1b: 0x00c0, 0x2b1c: 0x00c0, 0x2b1d: 0x00c0, + 0x2b1e: 0x00c0, 0x2b1f: 0x00c0, 0x2b20: 0x00c0, 0x2b21: 0x00c0, 0x2b22: 0x00c0, 0x2b23: 0x00c0, + 0x2b30: 0x0040, 0x2b31: 0x0040, 0x2b32: 0x0040, 0x2b33: 0x0040, 0x2b34: 0x0040, 0x2b35: 0x0040, + 0x2b36: 0x0040, 0x2b37: 0x0040, 0x2b38: 0x0040, 0x2b39: 0x0040, 0x2b3a: 0x0040, 0x2b3b: 0x0040, + 0x2b3c: 0x0040, 0x2b3d: 0x0040, 0x2b3e: 0x0040, 0x2b3f: 0x0040, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x0040, 0x2b41: 0x0040, 0x2b42: 0x0040, 0x2b43: 0x0040, 0x2b44: 0x0040, 0x2b45: 0x0040, + 0x2b46: 0x0040, 0x2b4b: 0x0040, + 0x2b4c: 0x0040, 0x2b4d: 0x0040, 0x2b4e: 0x0040, 0x2b4f: 0x0040, 0x2b50: 0x0040, 0x2b51: 0x0040, + 0x2b52: 0x0040, 0x2b53: 0x0040, 0x2b54: 0x0040, 0x2b55: 0x0040, 0x2b56: 0x0040, 0x2b57: 0x0040, + 0x2b58: 0x0040, 0x2b59: 0x0040, 0x2b5a: 0x0040, 0x2b5b: 0x0040, 0x2b5c: 0x0040, 0x2b5d: 0x0040, + 0x2b5e: 0x0040, 0x2b5f: 0x0040, 0x2b60: 0x0040, 0x2b61: 0x0040, 0x2b62: 0x0040, 0x2b63: 0x0040, + 0x2b64: 0x0040, 0x2b65: 0x0040, 0x2b66: 0x0040, 0x2b67: 0x0040, 0x2b68: 0x0040, 0x2b69: 0x0040, + 0x2b6a: 0x0040, 0x2b6b: 0x0040, 0x2b6c: 0x0040, 0x2b6d: 0x0040, 0x2b6e: 0x0040, 0x2b6f: 0x0040, + 0x2b70: 0x0040, 0x2b71: 0x0040, 0x2b72: 0x0040, 0x2b73: 0x0040, 0x2b74: 0x0040, 0x2b75: 0x0040, + 0x2b76: 0x0040, 0x2b77: 0x0040, 0x2b78: 0x0040, 0x2b79: 0x0040, 0x2b7a: 0x0040, 0x2b7b: 0x0040, + // Block 0xae, offset 0x2b80 + 0x2b80: 0x008c, 0x2b81: 0x008c, 0x2b82: 0x008c, 0x2b83: 0x008c, 0x2b84: 0x008c, 0x2b85: 0x008c, + 0x2b86: 0x008c, 0x2b87: 0x008c, 0x2b88: 0x008c, 0x2b89: 0x008c, 0x2b8a: 0x008c, 0x2b8b: 0x008c, + 0x2b8c: 0x008c, 0x2b8d: 0x008c, 0x2b8e: 0x00cc, 0x2b8f: 0x00cc, 0x2b90: 0x008c, 0x2b91: 0x00cc, + 0x2b92: 0x008c, 0x2b93: 0x00cc, 0x2b94: 0x00cc, 0x2b95: 0x008c, 0x2b96: 0x008c, 0x2b97: 0x008c, + 0x2b98: 0x008c, 0x2b99: 0x008c, 0x2b9a: 0x008c, 0x2b9b: 0x008c, 0x2b9c: 0x008c, 0x2b9d: 0x008c, + 0x2b9e: 0x008c, 0x2b9f: 0x00cc, 0x2ba0: 0x008c, 0x2ba1: 0x00cc, 0x2ba2: 0x008c, 0x2ba3: 0x00cc, + 0x2ba4: 0x00cc, 0x2ba5: 0x008c, 0x2ba6: 0x008c, 0x2ba7: 0x00cc, 0x2ba8: 0x00cc, 0x2ba9: 0x00cc, + 0x2baa: 0x008c, 0x2bab: 0x008c, 0x2bac: 0x008c, 0x2bad: 0x008c, 0x2bae: 0x008c, 0x2baf: 0x008c, + 0x2bb0: 0x008c, 0x2bb1: 0x008c, 0x2bb2: 0x008c, 0x2bb3: 0x008c, 0x2bb4: 0x008c, 0x2bb5: 0x008c, + 0x2bb6: 0x008c, 0x2bb7: 0x008c, 0x2bb8: 0x008c, 0x2bb9: 0x008c, 0x2bba: 0x008c, 0x2bbb: 0x008c, + 0x2bbc: 0x008c, 0x2bbd: 0x008c, 0x2bbe: 0x008c, 0x2bbf: 0x008c, + // Block 0xaf, offset 0x2bc0 + 0x2bc0: 0x008c, 0x2bc1: 0x008c, 0x2bc2: 0x008c, 0x2bc3: 0x008c, 0x2bc4: 0x008c, 0x2bc5: 0x008c, + 0x2bc6: 0x008c, 0x2bc7: 0x008c, 0x2bc8: 0x008c, 0x2bc9: 0x008c, 0x2bca: 0x008c, 0x2bcb: 0x008c, + 0x2bcc: 0x008c, 0x2bcd: 0x008c, 0x2bce: 0x008c, 0x2bcf: 0x008c, 0x2bd0: 0x008c, 0x2bd1: 0x008c, + 0x2bd2: 0x008c, 0x2bd3: 0x008c, 0x2bd4: 0x008c, 0x2bd5: 0x008c, 0x2bd6: 0x008c, 0x2bd7: 0x008c, + 0x2bd8: 0x008c, 0x2bd9: 0x008c, 0x2bda: 0x008c, 0x2bdb: 0x008c, 0x2bdc: 0x008c, 0x2bdd: 0x008c, + 0x2bde: 0x008c, 0x2bdf: 0x008c, 0x2be0: 0x008c, 0x2be1: 0x008c, 0x2be2: 0x008c, 0x2be3: 0x008c, + 0x2be4: 0x008c, 0x2be5: 0x008c, 0x2be6: 0x008c, 0x2be7: 0x008c, 0x2be8: 0x008c, 0x2be9: 0x008c, + 0x2bea: 0x008c, 0x2beb: 0x008c, 0x2bec: 0x008c, 0x2bed: 0x008c, + 0x2bf0: 0x008c, 0x2bf1: 0x008c, 0x2bf2: 0x008c, 0x2bf3: 0x008c, 0x2bf4: 0x008c, 0x2bf5: 0x008c, + 0x2bf6: 0x008c, 0x2bf7: 0x008c, 0x2bf8: 0x008c, 0x2bf9: 0x008c, 0x2bfa: 0x008c, 0x2bfb: 0x008c, + 0x2bfc: 0x008c, 0x2bfd: 0x008c, 0x2bfe: 0x008c, 0x2bff: 0x008c, + // Block 0xb0, offset 0x2c00 + 0x2c00: 0x008c, 0x2c01: 0x008c, 0x2c02: 0x008c, 0x2c03: 0x008c, 0x2c04: 0x008c, 0x2c05: 0x008c, + 0x2c06: 0x008c, 0x2c07: 0x008c, 0x2c08: 0x008c, 0x2c09: 0x008c, 0x2c0a: 0x008c, 0x2c0b: 0x008c, + 0x2c0c: 0x008c, 0x2c0d: 0x008c, 0x2c0e: 0x008c, 0x2c0f: 0x008c, 0x2c10: 0x008c, 0x2c11: 0x008c, + 0x2c12: 0x008c, 0x2c13: 0x008c, 0x2c14: 0x008c, 0x2c15: 0x008c, 0x2c16: 0x008c, 0x2c17: 0x008c, + 0x2c18: 0x008c, 0x2c19: 0x008c, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x0080, 0x2c41: 0x0080, 0x2c42: 0x0080, 0x2c43: 0x0080, 0x2c44: 0x0080, 0x2c45: 0x0080, + 0x2c46: 0x0080, + 0x2c53: 0x0080, 0x2c54: 0x0080, 0x2c55: 0x0080, 0x2c56: 0x0080, 0x2c57: 0x0080, + 0x2c5d: 0x008a, + 0x2c5e: 0x00cb, 0x2c5f: 0x008a, 0x2c60: 0x008a, 0x2c61: 0x008a, 0x2c62: 0x008a, 0x2c63: 0x008a, + 0x2c64: 0x008a, 0x2c65: 0x008a, 0x2c66: 0x008a, 0x2c67: 0x008a, 0x2c68: 0x008a, 0x2c69: 0x008a, + 0x2c6a: 0x008a, 0x2c6b: 0x008a, 0x2c6c: 0x008a, 0x2c6d: 0x008a, 0x2c6e: 0x008a, 0x2c6f: 0x008a, + 0x2c70: 0x008a, 0x2c71: 0x008a, 0x2c72: 0x008a, 0x2c73: 0x008a, 0x2c74: 0x008a, 0x2c75: 0x008a, + 0x2c76: 0x008a, 0x2c78: 0x008a, 0x2c79: 0x008a, 0x2c7a: 0x008a, 0x2c7b: 0x008a, + 0x2c7c: 0x008a, 0x2c7e: 0x008a, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0x008a, 0x2c81: 0x008a, 0x2c83: 0x008a, 0x2c84: 0x008a, + 0x2c86: 0x008a, 0x2c87: 0x008a, 0x2c88: 0x008a, 0x2c89: 0x008a, 0x2c8a: 0x008a, 0x2c8b: 0x008a, + 0x2c8c: 0x008a, 0x2c8d: 0x008a, 0x2c8e: 0x008a, 0x2c8f: 0x008a, 0x2c90: 0x0080, 0x2c91: 0x0080, + 0x2c92: 0x0080, 0x2c93: 0x0080, 0x2c94: 0x0080, 0x2c95: 0x0080, 0x2c96: 0x0080, 0x2c97: 0x0080, + 0x2c98: 0x0080, 0x2c99: 0x0080, 0x2c9a: 0x0080, 0x2c9b: 0x0080, 0x2c9c: 0x0080, 0x2c9d: 0x0080, + 0x2c9e: 0x0080, 0x2c9f: 0x0080, 0x2ca0: 0x0080, 0x2ca1: 0x0080, 0x2ca2: 0x0080, 0x2ca3: 0x0080, + 0x2ca4: 0x0080, 0x2ca5: 0x0080, 0x2ca6: 0x0080, 0x2ca7: 0x0080, 0x2ca8: 0x0080, 0x2ca9: 0x0080, + 0x2caa: 0x0080, 0x2cab: 0x0080, 0x2cac: 0x0080, 0x2cad: 0x0080, 0x2cae: 0x0080, 0x2caf: 0x0080, + 0x2cb0: 0x0080, 0x2cb1: 0x0080, 0x2cb2: 0x0080, 0x2cb3: 0x0080, 0x2cb4: 0x0080, 0x2cb5: 0x0080, + 0x2cb6: 0x0080, 0x2cb7: 0x0080, 0x2cb8: 0x0080, 0x2cb9: 0x0080, 0x2cba: 0x0080, 0x2cbb: 0x0080, + 0x2cbc: 0x0080, 0x2cbd: 0x0080, 0x2cbe: 0x0080, 0x2cbf: 0x0080, + // Block 0xb3, offset 0x2cc0 + 0x2cc0: 0x0080, 0x2cc1: 0x0080, + 0x2cd3: 0x0080, 0x2cd4: 0x0080, 0x2cd5: 0x0080, 0x2cd6: 0x0080, 0x2cd7: 0x0080, + 0x2cd8: 0x0080, 0x2cd9: 0x0080, 0x2cda: 0x0080, 0x2cdb: 0x0080, 0x2cdc: 0x0080, 0x2cdd: 0x0080, + 0x2cde: 0x0080, 0x2cdf: 0x0080, 0x2ce0: 0x0080, 0x2ce1: 0x0080, 0x2ce2: 0x0080, 0x2ce3: 0x0080, + 0x2ce4: 0x0080, 0x2ce5: 0x0080, 0x2ce6: 0x0080, 0x2ce7: 0x0080, 0x2ce8: 0x0080, 0x2ce9: 0x0080, + 0x2cea: 0x0080, 0x2ceb: 0x0080, 0x2cec: 0x0080, 0x2ced: 0x0080, 0x2cee: 0x0080, 0x2cef: 0x0080, + 0x2cf0: 0x0080, 0x2cf1: 0x0080, 0x2cf2: 0x0080, 0x2cf3: 0x0080, 0x2cf4: 0x0080, 0x2cf5: 0x0080, + 0x2cf6: 0x0080, 0x2cf7: 0x0080, 0x2cf8: 0x0080, 0x2cf9: 0x0080, 0x2cfa: 0x0080, 0x2cfb: 0x0080, + 0x2cfc: 0x0080, 0x2cfd: 0x0080, 0x2cfe: 0x0080, 0x2cff: 0x0080, + // Block 0xb4, offset 0x2d00 + 0x2d10: 0x0080, 0x2d11: 0x0080, + 0x2d12: 0x0080, 0x2d13: 0x0080, 0x2d14: 0x0080, 0x2d15: 0x0080, 0x2d16: 0x0080, 0x2d17: 0x0080, + 0x2d18: 0x0080, 0x2d19: 0x0080, 0x2d1a: 0x0080, 0x2d1b: 0x0080, 0x2d1c: 0x0080, 0x2d1d: 0x0080, + 0x2d1e: 0x0080, 0x2d1f: 0x0080, 0x2d20: 0x0080, 0x2d21: 0x0080, 0x2d22: 0x0080, 0x2d23: 0x0080, + 0x2d24: 0x0080, 0x2d25: 0x0080, 0x2d26: 0x0080, 0x2d27: 0x0080, 0x2d28: 0x0080, 0x2d29: 0x0080, + 0x2d2a: 0x0080, 0x2d2b: 0x0080, 0x2d2c: 0x0080, 0x2d2d: 0x0080, 0x2d2e: 0x0080, 0x2d2f: 0x0080, + 0x2d30: 0x0080, 0x2d31: 0x0080, 0x2d32: 0x0080, 0x2d33: 0x0080, 0x2d34: 0x0080, 0x2d35: 0x0080, + 0x2d36: 0x0080, 0x2d37: 0x0080, 0x2d38: 0x0080, 0x2d39: 0x0080, 0x2d3a: 0x0080, 0x2d3b: 0x0080, + 0x2d3c: 0x0080, 0x2d3d: 0x0080, 0x2d3e: 0x0080, 0x2d3f: 0x0080, + // Block 0xb5, offset 0x2d40 + 0x2d40: 0x0080, 0x2d41: 0x0080, 0x2d42: 0x0080, 0x2d43: 0x0080, 0x2d44: 0x0080, 0x2d45: 0x0080, + 0x2d46: 0x0080, 0x2d47: 0x0080, 0x2d48: 0x0080, 0x2d49: 0x0080, 0x2d4a: 0x0080, 0x2d4b: 0x0080, + 0x2d4c: 0x0080, 0x2d4d: 0x0080, 0x2d4e: 0x0080, 0x2d4f: 0x0080, + 0x2d52: 0x0080, 0x2d53: 0x0080, 0x2d54: 0x0080, 0x2d55: 0x0080, 0x2d56: 0x0080, 0x2d57: 0x0080, + 0x2d58: 0x0080, 0x2d59: 0x0080, 0x2d5a: 0x0080, 0x2d5b: 0x0080, 0x2d5c: 0x0080, 0x2d5d: 0x0080, + 0x2d5e: 0x0080, 0x2d5f: 0x0080, 0x2d60: 0x0080, 0x2d61: 0x0080, 0x2d62: 0x0080, 0x2d63: 0x0080, + 0x2d64: 0x0080, 0x2d65: 0x0080, 0x2d66: 0x0080, 0x2d67: 0x0080, 0x2d68: 0x0080, 0x2d69: 0x0080, + 0x2d6a: 0x0080, 0x2d6b: 0x0080, 0x2d6c: 0x0080, 0x2d6d: 0x0080, 0x2d6e: 0x0080, 0x2d6f: 0x0080, + 0x2d70: 0x0080, 0x2d71: 0x0080, 0x2d72: 0x0080, 0x2d73: 0x0080, 0x2d74: 0x0080, 0x2d75: 0x0080, + 0x2d76: 0x0080, 0x2d77: 0x0080, 0x2d78: 0x0080, 0x2d79: 0x0080, 0x2d7a: 0x0080, 0x2d7b: 0x0080, + 0x2d7c: 0x0080, 0x2d7d: 0x0080, 0x2d7e: 0x0080, 0x2d7f: 0x0080, + // Block 0xb6, offset 0x2d80 + 0x2d80: 0x0080, 0x2d81: 0x0080, 0x2d82: 0x0080, 0x2d83: 0x0080, 0x2d84: 0x0080, 0x2d85: 0x0080, + 0x2d86: 0x0080, 0x2d87: 0x0080, + 0x2db0: 0x0080, 0x2db1: 0x0080, 0x2db2: 0x0080, 0x2db3: 0x0080, 0x2db4: 0x0080, 0x2db5: 0x0080, + 0x2db6: 0x0080, 0x2db7: 0x0080, 0x2db8: 0x0080, 0x2db9: 0x0080, 0x2dba: 0x0080, 0x2dbb: 0x0080, + 0x2dbc: 0x0080, 0x2dbd: 0x0080, + // Block 0xb7, offset 0x2dc0 + 0x2dc0: 0x0040, 0x2dc1: 0x0040, 0x2dc2: 0x0040, 0x2dc3: 0x0040, 0x2dc4: 0x0040, 0x2dc5: 0x0040, + 0x2dc6: 0x0040, 0x2dc7: 0x0040, 0x2dc8: 0x0040, 0x2dc9: 0x0040, 0x2dca: 0x0040, 0x2dcb: 0x0040, + 0x2dcc: 0x0040, 0x2dcd: 0x0040, 0x2dce: 0x0040, 0x2dcf: 0x0040, 0x2dd0: 0x0080, 0x2dd1: 0x0080, + 0x2dd2: 0x0080, 0x2dd3: 0x0080, 0x2dd4: 0x0080, 0x2dd5: 0x0080, 0x2dd6: 0x0080, 0x2dd7: 0x0080, + 0x2dd8: 0x0080, 0x2dd9: 0x0080, + 0x2de0: 0x00c3, 0x2de1: 0x00c3, 0x2de2: 0x00c3, 0x2de3: 0x00c3, + 0x2de4: 0x00c3, 0x2de5: 0x00c3, 0x2de6: 0x00c3, 0x2de7: 0x00c3, 0x2de8: 0x00c3, 0x2de9: 0x00c3, + 0x2dea: 0x00c3, 0x2deb: 0x00c3, 0x2dec: 0x00c3, 0x2ded: 0x00c3, 0x2dee: 0x00c3, 0x2def: 0x00c3, + 0x2df0: 0x0080, 0x2df1: 0x0080, 0x2df2: 0x0080, 0x2df3: 0x0080, 0x2df4: 0x0080, 0x2df5: 0x0080, + 0x2df6: 0x0080, 0x2df7: 0x0080, 0x2df8: 0x0080, 0x2df9: 0x0080, 0x2dfa: 0x0080, 0x2dfb: 0x0080, + 0x2dfc: 0x0080, 0x2dfd: 0x0080, 0x2dfe: 0x0080, 0x2dff: 0x0080, + // Block 0xb8, offset 0x2e00 + 0x2e00: 0x0080, 0x2e01: 0x0080, 0x2e02: 0x0080, 0x2e03: 0x0080, 0x2e04: 0x0080, 0x2e05: 0x0080, + 0x2e06: 0x0080, 0x2e07: 0x0080, 0x2e08: 0x0080, 0x2e09: 0x0080, 0x2e0a: 0x0080, 0x2e0b: 0x0080, + 0x2e0c: 0x0080, 0x2e0d: 0x0080, 0x2e0e: 0x0080, 0x2e0f: 0x0080, 0x2e10: 0x0080, 0x2e11: 0x0080, + 0x2e12: 0x0080, 0x2e14: 0x0080, 0x2e15: 0x0080, 0x2e16: 0x0080, 0x2e17: 0x0080, + 0x2e18: 0x0080, 0x2e19: 0x0080, 0x2e1a: 0x0080, 0x2e1b: 0x0080, 0x2e1c: 0x0080, 0x2e1d: 0x0080, + 0x2e1e: 0x0080, 0x2e1f: 0x0080, 0x2e20: 0x0080, 0x2e21: 0x0080, 0x2e22: 0x0080, 0x2e23: 0x0080, + 0x2e24: 0x0080, 0x2e25: 0x0080, 0x2e26: 0x0080, 0x2e28: 0x0080, 0x2e29: 0x0080, + 0x2e2a: 0x0080, 0x2e2b: 0x0080, + 0x2e30: 0x0080, 0x2e31: 0x0080, 0x2e32: 0x0080, 0x2e33: 0x00c0, 0x2e34: 0x0080, + 0x2e36: 0x0080, 0x2e37: 0x0080, 0x2e38: 0x0080, 0x2e39: 0x0080, 0x2e3a: 0x0080, 0x2e3b: 0x0080, + 0x2e3c: 0x0080, 0x2e3d: 0x0080, 0x2e3e: 0x0080, 0x2e3f: 0x0080, + // Block 0xb9, offset 0x2e40 + 0x2e40: 0x0080, 0x2e41: 0x0080, 0x2e42: 0x0080, 0x2e43: 0x0080, 0x2e44: 0x0080, 0x2e45: 0x0080, + 0x2e46: 0x0080, 0x2e47: 0x0080, 0x2e48: 0x0080, 0x2e49: 0x0080, 0x2e4a: 0x0080, 0x2e4b: 0x0080, + 0x2e4c: 0x0080, 0x2e4d: 0x0080, 0x2e4e: 0x0080, 0x2e4f: 0x0080, 0x2e50: 0x0080, 0x2e51: 0x0080, + 0x2e52: 0x0080, 0x2e53: 0x0080, 0x2e54: 0x0080, 0x2e55: 0x0080, 0x2e56: 0x0080, 0x2e57: 0x0080, + 0x2e58: 0x0080, 0x2e59: 0x0080, 0x2e5a: 0x0080, 0x2e5b: 0x0080, 0x2e5c: 0x0080, 0x2e5d: 0x0080, + 0x2e5e: 0x0080, 0x2e5f: 0x0080, 0x2e60: 0x0080, 0x2e61: 0x0080, 0x2e62: 0x0080, 0x2e63: 0x0080, + 0x2e64: 0x0080, 0x2e65: 0x0080, 0x2e66: 0x0080, 0x2e67: 0x0080, 0x2e68: 0x0080, 0x2e69: 0x0080, + 0x2e6a: 0x0080, 0x2e6b: 0x0080, 0x2e6c: 0x0080, 0x2e6d: 0x0080, 0x2e6e: 0x0080, 0x2e6f: 0x0080, + 0x2e70: 0x0080, 0x2e71: 0x0080, 0x2e72: 0x0080, 0x2e73: 0x0080, 0x2e74: 0x0080, 0x2e75: 0x0080, + 0x2e76: 0x0080, 0x2e77: 0x0080, 0x2e78: 0x0080, 0x2e79: 0x0080, 0x2e7a: 0x0080, 0x2e7b: 0x0080, + 0x2e7c: 0x0080, 0x2e7f: 0x0040, + // Block 0xba, offset 0x2e80 + 0x2e81: 0x0080, 0x2e82: 0x0080, 0x2e83: 0x0080, 0x2e84: 0x0080, 0x2e85: 0x0080, + 0x2e86: 0x0080, 0x2e87: 0x0080, 0x2e88: 0x0080, 0x2e89: 0x0080, 0x2e8a: 0x0080, 0x2e8b: 0x0080, + 0x2e8c: 0x0080, 0x2e8d: 0x0080, 0x2e8e: 0x0080, 0x2e8f: 0x0080, 0x2e90: 0x0080, 0x2e91: 0x0080, + 0x2e92: 0x0080, 0x2e93: 0x0080, 0x2e94: 0x0080, 0x2e95: 0x0080, 0x2e96: 0x0080, 0x2e97: 0x0080, + 0x2e98: 0x0080, 0x2e99: 0x0080, 0x2e9a: 0x0080, 0x2e9b: 0x0080, 0x2e9c: 0x0080, 0x2e9d: 0x0080, + 0x2e9e: 0x0080, 0x2e9f: 0x0080, 0x2ea0: 0x0080, 0x2ea1: 0x0080, 0x2ea2: 0x0080, 0x2ea3: 0x0080, + 0x2ea4: 0x0080, 0x2ea5: 0x0080, 0x2ea6: 0x0080, 0x2ea7: 0x0080, 0x2ea8: 0x0080, 0x2ea9: 0x0080, + 0x2eaa: 0x0080, 0x2eab: 0x0080, 0x2eac: 0x0080, 0x2ead: 0x0080, 0x2eae: 0x0080, 0x2eaf: 0x0080, + 0x2eb0: 0x0080, 0x2eb1: 0x0080, 0x2eb2: 0x0080, 0x2eb3: 0x0080, 0x2eb4: 0x0080, 0x2eb5: 0x0080, + 0x2eb6: 0x0080, 0x2eb7: 0x0080, 0x2eb8: 0x0080, 0x2eb9: 0x0080, 0x2eba: 0x0080, 0x2ebb: 0x0080, + 0x2ebc: 0x0080, 0x2ebd: 0x0080, 0x2ebe: 0x0080, 0x2ebf: 0x0080, + // Block 0xbb, offset 0x2ec0 + 0x2ec0: 0x0080, 0x2ec1: 0x0080, 0x2ec2: 0x0080, 0x2ec3: 0x0080, 0x2ec4: 0x0080, 0x2ec5: 0x0080, + 0x2ec6: 0x0080, 0x2ec7: 0x0080, 0x2ec8: 0x0080, 0x2ec9: 0x0080, 0x2eca: 0x0080, 0x2ecb: 0x0080, + 0x2ecc: 0x0080, 0x2ecd: 0x0080, 0x2ece: 0x0080, 0x2ecf: 0x0080, 0x2ed0: 0x0080, 0x2ed1: 0x0080, + 0x2ed2: 0x0080, 0x2ed3: 0x0080, 0x2ed4: 0x0080, 0x2ed5: 0x0080, 0x2ed6: 0x0080, 0x2ed7: 0x0080, + 0x2ed8: 0x0080, 0x2ed9: 0x0080, 0x2eda: 0x0080, 0x2edb: 0x0080, 0x2edc: 0x0080, 0x2edd: 0x0080, + 0x2ede: 0x0080, 0x2edf: 0x0080, 0x2ee0: 0x0080, 0x2ee1: 0x0080, 0x2ee2: 0x0080, 0x2ee3: 0x0080, + 0x2ee4: 0x0080, 0x2ee5: 0x0080, 0x2ee6: 0x008c, 0x2ee7: 0x008c, 0x2ee8: 0x008c, 0x2ee9: 0x008c, + 0x2eea: 0x008c, 0x2eeb: 0x008c, 0x2eec: 0x008c, 0x2eed: 0x008c, 0x2eee: 0x008c, 0x2eef: 0x008c, + 0x2ef0: 0x0080, 0x2ef1: 0x008c, 0x2ef2: 0x008c, 0x2ef3: 0x008c, 0x2ef4: 0x008c, 0x2ef5: 0x008c, + 0x2ef6: 0x008c, 0x2ef7: 0x008c, 0x2ef8: 0x008c, 0x2ef9: 0x008c, 0x2efa: 0x008c, 0x2efb: 0x008c, + 0x2efc: 0x008c, 0x2efd: 0x008c, 0x2efe: 0x008c, 0x2eff: 0x008c, + // Block 0xbc, offset 0x2f00 + 0x2f00: 0x008c, 0x2f01: 0x008c, 0x2f02: 0x008c, 0x2f03: 0x008c, 0x2f04: 0x008c, 0x2f05: 0x008c, + 0x2f06: 0x008c, 0x2f07: 0x008c, 0x2f08: 0x008c, 0x2f09: 0x008c, 0x2f0a: 0x008c, 0x2f0b: 0x008c, + 0x2f0c: 0x008c, 0x2f0d: 0x008c, 0x2f0e: 0x008c, 0x2f0f: 0x008c, 0x2f10: 0x008c, 0x2f11: 0x008c, + 0x2f12: 0x008c, 0x2f13: 0x008c, 0x2f14: 0x008c, 0x2f15: 0x008c, 0x2f16: 0x008c, 0x2f17: 0x008c, + 0x2f18: 0x008c, 0x2f19: 0x008c, 0x2f1a: 0x008c, 0x2f1b: 0x008c, 0x2f1c: 0x008c, 0x2f1d: 0x008c, + 0x2f1e: 0x0080, 0x2f1f: 0x0080, 0x2f20: 0x0040, 0x2f21: 0x0080, 0x2f22: 0x0080, 0x2f23: 0x0080, + 0x2f24: 0x0080, 0x2f25: 0x0080, 0x2f26: 0x0080, 0x2f27: 0x0080, 0x2f28: 0x0080, 0x2f29: 0x0080, + 0x2f2a: 0x0080, 0x2f2b: 0x0080, 0x2f2c: 0x0080, 0x2f2d: 0x0080, 0x2f2e: 0x0080, 0x2f2f: 0x0080, + 0x2f30: 0x0080, 0x2f31: 0x0080, 0x2f32: 0x0080, 0x2f33: 0x0080, 0x2f34: 0x0080, 0x2f35: 0x0080, + 0x2f36: 0x0080, 0x2f37: 0x0080, 0x2f38: 0x0080, 0x2f39: 0x0080, 0x2f3a: 0x0080, 0x2f3b: 0x0080, + 0x2f3c: 0x0080, 0x2f3d: 0x0080, 0x2f3e: 0x0080, + // Block 0xbd, offset 0x2f40 + 0x2f42: 0x0080, 0x2f43: 0x0080, 0x2f44: 0x0080, 0x2f45: 0x0080, + 0x2f46: 0x0080, 0x2f47: 0x0080, 0x2f4a: 0x0080, 0x2f4b: 0x0080, + 0x2f4c: 0x0080, 0x2f4d: 0x0080, 0x2f4e: 0x0080, 0x2f4f: 0x0080, + 0x2f52: 0x0080, 0x2f53: 0x0080, 0x2f54: 0x0080, 0x2f55: 0x0080, 0x2f56: 0x0080, 0x2f57: 0x0080, + 0x2f5a: 0x0080, 0x2f5b: 0x0080, 0x2f5c: 0x0080, + 0x2f60: 0x0080, 0x2f61: 0x0080, 0x2f62: 0x0080, 0x2f63: 0x0080, + 0x2f64: 0x0080, 0x2f65: 0x0080, 0x2f66: 0x0080, 0x2f68: 0x0080, 0x2f69: 0x0080, + 0x2f6a: 0x0080, 0x2f6b: 0x0080, 0x2f6c: 0x0080, 0x2f6d: 0x0080, 0x2f6e: 0x0080, + 0x2f79: 0x0040, 0x2f7a: 0x0040, 0x2f7b: 0x0040, + 0x2f7c: 0x0080, 0x2f7d: 0x0080, + // Block 0xbe, offset 0x2f80 + 0x2f80: 0x00c0, 0x2f81: 0x00c0, 0x2f82: 0x00c0, 0x2f83: 0x00c0, 0x2f84: 0x00c0, 0x2f85: 0x00c0, + 0x2f86: 0x00c0, 0x2f87: 0x00c0, 0x2f88: 0x00c0, 0x2f89: 0x00c0, 0x2f8a: 0x00c0, 0x2f8b: 0x00c0, + 0x2f8d: 0x00c0, 0x2f8e: 0x00c0, 0x2f8f: 0x00c0, 0x2f90: 0x00c0, 0x2f91: 0x00c0, + 0x2f92: 0x00c0, 0x2f93: 0x00c0, 0x2f94: 0x00c0, 0x2f95: 0x00c0, 0x2f96: 0x00c0, 0x2f97: 0x00c0, + 0x2f98: 0x00c0, 0x2f99: 0x00c0, 0x2f9a: 0x00c0, 0x2f9b: 0x00c0, 0x2f9c: 0x00c0, 0x2f9d: 0x00c0, + 0x2f9e: 0x00c0, 0x2f9f: 0x00c0, 0x2fa0: 0x00c0, 0x2fa1: 0x00c0, 0x2fa2: 0x00c0, 0x2fa3: 0x00c0, + 0x2fa4: 0x00c0, 0x2fa5: 0x00c0, 0x2fa6: 0x00c0, 0x2fa8: 0x00c0, 0x2fa9: 0x00c0, + 0x2faa: 0x00c0, 0x2fab: 0x00c0, 0x2fac: 0x00c0, 0x2fad: 0x00c0, 0x2fae: 0x00c0, 0x2faf: 0x00c0, + 0x2fb0: 0x00c0, 0x2fb1: 0x00c0, 0x2fb2: 0x00c0, 0x2fb3: 0x00c0, 0x2fb4: 0x00c0, 0x2fb5: 0x00c0, + 0x2fb6: 0x00c0, 0x2fb7: 0x00c0, 0x2fb8: 0x00c0, 0x2fb9: 0x00c0, 0x2fba: 0x00c0, + 0x2fbc: 0x00c0, 0x2fbd: 0x00c0, 0x2fbf: 0x00c0, + // Block 0xbf, offset 0x2fc0 + 0x2fc0: 0x00c0, 0x2fc1: 0x00c0, 0x2fc2: 0x00c0, 0x2fc3: 0x00c0, 0x2fc4: 0x00c0, 0x2fc5: 0x00c0, + 0x2fc6: 0x00c0, 0x2fc7: 0x00c0, 0x2fc8: 0x00c0, 0x2fc9: 0x00c0, 0x2fca: 0x00c0, 0x2fcb: 0x00c0, + 0x2fcc: 0x00c0, 0x2fcd: 0x00c0, 0x2fd0: 0x00c0, 0x2fd1: 0x00c0, + 0x2fd2: 0x00c0, 0x2fd3: 0x00c0, 0x2fd4: 0x00c0, 0x2fd5: 0x00c0, 0x2fd6: 0x00c0, 0x2fd7: 0x00c0, + 0x2fd8: 0x00c0, 0x2fd9: 0x00c0, 0x2fda: 0x00c0, 0x2fdb: 0x00c0, 0x2fdc: 0x00c0, 0x2fdd: 0x00c0, + // Block 0xc0, offset 0x3000 + 0x3000: 0x00c0, 0x3001: 0x00c0, 0x3002: 0x00c0, 0x3003: 0x00c0, 0x3004: 0x00c0, 0x3005: 0x00c0, + 0x3006: 0x00c0, 0x3007: 0x00c0, 0x3008: 0x00c0, 0x3009: 0x00c0, 0x300a: 0x00c0, 0x300b: 0x00c0, + 0x300c: 0x00c0, 0x300d: 0x00c0, 0x300e: 0x00c0, 0x300f: 0x00c0, 0x3010: 0x00c0, 0x3011: 0x00c0, + 0x3012: 0x00c0, 0x3013: 0x00c0, 0x3014: 0x00c0, 0x3015: 0x00c0, 0x3016: 0x00c0, 0x3017: 0x00c0, + 0x3018: 0x00c0, 0x3019: 0x00c0, 0x301a: 0x00c0, 0x301b: 0x00c0, 0x301c: 0x00c0, 0x301d: 0x00c0, + 0x301e: 0x00c0, 0x301f: 0x00c0, 0x3020: 0x00c0, 0x3021: 0x00c0, 0x3022: 0x00c0, 0x3023: 0x00c0, + 0x3024: 0x00c0, 0x3025: 0x00c0, 0x3026: 0x00c0, 0x3027: 0x00c0, 0x3028: 0x00c0, 0x3029: 0x00c0, + 0x302a: 0x00c0, 0x302b: 0x00c0, 0x302c: 0x00c0, 0x302d: 0x00c0, 0x302e: 0x00c0, 0x302f: 0x00c0, + 0x3030: 0x00c0, 0x3031: 0x00c0, 0x3032: 0x00c0, 0x3033: 0x00c0, 0x3034: 0x00c0, 0x3035: 0x00c0, + 0x3036: 0x00c0, 0x3037: 0x00c0, 0x3038: 0x00c0, 0x3039: 0x00c0, 0x303a: 0x00c0, + // Block 0xc1, offset 0x3040 + 0x3040: 0x0080, 0x3041: 0x0080, 0x3042: 0x0080, + 0x3047: 0x0080, 0x3048: 0x0080, 0x3049: 0x0080, 0x304a: 0x0080, 0x304b: 0x0080, + 0x304c: 0x0080, 0x304d: 0x0080, 0x304e: 0x0080, 0x304f: 0x0080, 0x3050: 0x0080, 0x3051: 0x0080, + 0x3052: 0x0080, 0x3053: 0x0080, 0x3054: 0x0080, 0x3055: 0x0080, 0x3056: 0x0080, 0x3057: 0x0080, + 0x3058: 0x0080, 0x3059: 0x0080, 0x305a: 0x0080, 0x305b: 0x0080, 0x305c: 0x0080, 0x305d: 0x0080, + 0x305e: 0x0080, 0x305f: 0x0080, 0x3060: 0x0080, 0x3061: 0x0080, 0x3062: 0x0080, 0x3063: 0x0080, + 0x3064: 0x0080, 0x3065: 0x0080, 0x3066: 0x0080, 0x3067: 0x0080, 0x3068: 0x0080, 0x3069: 0x0080, + 0x306a: 0x0080, 0x306b: 0x0080, 0x306c: 0x0080, 0x306d: 0x0080, 0x306e: 0x0080, 0x306f: 0x0080, + 0x3070: 0x0080, 0x3071: 0x0080, 0x3072: 0x0080, 0x3073: 0x0080, + 0x3077: 0x0080, 0x3078: 0x0080, 0x3079: 0x0080, 0x307a: 0x0080, 0x307b: 0x0080, + 0x307c: 0x0080, 0x307d: 0x0080, 0x307e: 0x0080, 0x307f: 0x0080, + // Block 0xc2, offset 0x3080 + 0x3080: 0x0088, 0x3081: 0x0088, 0x3082: 0x0088, 0x3083: 0x0088, 0x3084: 0x0088, 0x3085: 0x0088, + 0x3086: 0x0088, 0x3087: 0x0088, 0x3088: 0x0088, 0x3089: 0x0088, 0x308a: 0x0088, 0x308b: 0x0088, + 0x308c: 0x0088, 0x308d: 0x0088, 0x308e: 0x0088, 0x308f: 0x0088, 0x3090: 0x0088, 0x3091: 0x0088, + 0x3092: 0x0088, 0x3093: 0x0088, 0x3094: 0x0088, 0x3095: 0x0088, 0x3096: 0x0088, 0x3097: 0x0088, + 0x3098: 0x0088, 0x3099: 0x0088, 0x309a: 0x0088, 0x309b: 0x0088, 0x309c: 0x0088, 0x309d: 0x0088, + 0x309e: 0x0088, 0x309f: 0x0088, 0x30a0: 0x0088, 0x30a1: 0x0088, 0x30a2: 0x0088, 0x30a3: 0x0088, + 0x30a4: 0x0088, 0x30a5: 0x0088, 0x30a6: 0x0088, 0x30a7: 0x0088, 0x30a8: 0x0088, 0x30a9: 0x0088, + 0x30aa: 0x0088, 0x30ab: 0x0088, 0x30ac: 0x0088, 0x30ad: 0x0088, 0x30ae: 0x0088, 0x30af: 0x0088, + 0x30b0: 0x0088, 0x30b1: 0x0088, 0x30b2: 0x0088, 0x30b3: 0x0088, 0x30b4: 0x0088, 0x30b5: 0x0088, + 0x30b6: 0x0088, 0x30b7: 0x0088, 0x30b8: 0x0088, 0x30b9: 0x0088, 0x30ba: 0x0088, 0x30bb: 0x0088, + 0x30bc: 0x0088, 0x30bd: 0x0088, 0x30be: 0x0088, 0x30bf: 0x0088, + // Block 0xc3, offset 0x30c0 + 0x30c0: 0x0088, 0x30c1: 0x0088, 0x30c2: 0x0088, 0x30c3: 0x0088, 0x30c4: 0x0088, 0x30c5: 0x0088, + 0x30c6: 0x0088, 0x30c7: 0x0088, 0x30c8: 0x0088, 0x30c9: 0x0088, 0x30ca: 0x0088, 0x30cb: 0x0088, + 0x30cc: 0x0088, 0x30cd: 0x0088, 0x30ce: 0x0088, 0x30d0: 0x0080, 0x30d1: 0x0080, + 0x30d2: 0x0080, 0x30d3: 0x0080, 0x30d4: 0x0080, 0x30d5: 0x0080, 0x30d6: 0x0080, 0x30d7: 0x0080, + 0x30d8: 0x0080, 0x30d9: 0x0080, 0x30da: 0x0080, 0x30db: 0x0080, + 0x30e0: 0x0088, + // Block 0xc4, offset 0x3100 + 0x3110: 0x0080, 0x3111: 0x0080, + 0x3112: 0x0080, 0x3113: 0x0080, 0x3114: 0x0080, 0x3115: 0x0080, 0x3116: 0x0080, 0x3117: 0x0080, + 0x3118: 0x0080, 0x3119: 0x0080, 0x311a: 0x0080, 0x311b: 0x0080, 0x311c: 0x0080, 0x311d: 0x0080, + 0x311e: 0x0080, 0x311f: 0x0080, 0x3120: 0x0080, 0x3121: 0x0080, 0x3122: 0x0080, 0x3123: 0x0080, + 0x3124: 0x0080, 0x3125: 0x0080, 0x3126: 0x0080, 0x3127: 0x0080, 0x3128: 0x0080, 0x3129: 0x0080, + 0x312a: 0x0080, 0x312b: 0x0080, 0x312c: 0x0080, 0x312d: 0x0080, 0x312e: 0x0080, 0x312f: 0x0080, + 0x3130: 0x0080, 0x3131: 0x0080, 0x3132: 0x0080, 0x3133: 0x0080, 0x3134: 0x0080, 0x3135: 0x0080, + 0x3136: 0x0080, 0x3137: 0x0080, 0x3138: 0x0080, 0x3139: 0x0080, 0x313a: 0x0080, 0x313b: 0x0080, + 0x313c: 0x0080, 0x313d: 0x00c3, + // Block 0xc5, offset 0x3140 + 0x3140: 0x00c0, 0x3141: 0x00c0, 0x3142: 0x00c0, 0x3143: 0x00c0, 0x3144: 0x00c0, 0x3145: 0x00c0, + 0x3146: 0x00c0, 0x3147: 0x00c0, 0x3148: 0x00c0, 0x3149: 0x00c0, 0x314a: 0x00c0, 0x314b: 0x00c0, + 0x314c: 0x00c0, 0x314d: 0x00c0, 0x314e: 0x00c0, 0x314f: 0x00c0, 0x3150: 0x00c0, 0x3151: 0x00c0, + 0x3152: 0x00c0, 0x3153: 0x00c0, 0x3154: 0x00c0, 0x3155: 0x00c0, 0x3156: 0x00c0, 0x3157: 0x00c0, + 0x3158: 0x00c0, 0x3159: 0x00c0, 0x315a: 0x00c0, 0x315b: 0x00c0, 0x315c: 0x00c0, + 0x3160: 0x00c0, 0x3161: 0x00c0, 0x3162: 0x00c0, 0x3163: 0x00c0, + 0x3164: 0x00c0, 0x3165: 0x00c0, 0x3166: 0x00c0, 0x3167: 0x00c0, 0x3168: 0x00c0, 0x3169: 0x00c0, + 0x316a: 0x00c0, 0x316b: 0x00c0, 0x316c: 0x00c0, 0x316d: 0x00c0, 0x316e: 0x00c0, 0x316f: 0x00c0, + 0x3170: 0x00c0, 0x3171: 0x00c0, 0x3172: 0x00c0, 0x3173: 0x00c0, 0x3174: 0x00c0, 0x3175: 0x00c0, + 0x3176: 0x00c0, 0x3177: 0x00c0, 0x3178: 0x00c0, 0x3179: 0x00c0, 0x317a: 0x00c0, 0x317b: 0x00c0, + 0x317c: 0x00c0, 0x317d: 0x00c0, 0x317e: 0x00c0, 0x317f: 0x00c0, + // Block 0xc6, offset 0x3180 + 0x3180: 0x00c0, 0x3181: 0x00c0, 0x3182: 0x00c0, 0x3183: 0x00c0, 0x3184: 0x00c0, 0x3185: 0x00c0, + 0x3186: 0x00c0, 0x3187: 0x00c0, 0x3188: 0x00c0, 0x3189: 0x00c0, 0x318a: 0x00c0, 0x318b: 0x00c0, + 0x318c: 0x00c0, 0x318d: 0x00c0, 0x318e: 0x00c0, 0x318f: 0x00c0, 0x3190: 0x00c0, + 0x31a0: 0x00c3, 0x31a1: 0x0080, 0x31a2: 0x0080, 0x31a3: 0x0080, + 0x31a4: 0x0080, 0x31a5: 0x0080, 0x31a6: 0x0080, 0x31a7: 0x0080, 0x31a8: 0x0080, 0x31a9: 0x0080, + 0x31aa: 0x0080, 0x31ab: 0x0080, 0x31ac: 0x0080, 0x31ad: 0x0080, 0x31ae: 0x0080, 0x31af: 0x0080, + 0x31b0: 0x0080, 0x31b1: 0x0080, 0x31b2: 0x0080, 0x31b3: 0x0080, 0x31b4: 0x0080, 0x31b5: 0x0080, + 0x31b6: 0x0080, 0x31b7: 0x0080, 0x31b8: 0x0080, 0x31b9: 0x0080, 0x31ba: 0x0080, 0x31bb: 0x0080, + // Block 0xc7, offset 0x31c0 + 0x31c0: 0x00c0, 0x31c1: 0x00c0, 0x31c2: 0x00c0, 0x31c3: 0x00c0, 0x31c4: 0x00c0, 0x31c5: 0x00c0, + 0x31c6: 0x00c0, 0x31c7: 0x00c0, 0x31c8: 0x00c0, 0x31c9: 0x00c0, 0x31ca: 0x00c0, 0x31cb: 0x00c0, + 0x31cc: 0x00c0, 0x31cd: 0x00c0, 0x31ce: 0x00c0, 0x31cf: 0x00c0, 0x31d0: 0x00c0, 0x31d1: 0x00c0, + 0x31d2: 0x00c0, 0x31d3: 0x00c0, 0x31d4: 0x00c0, 0x31d5: 0x00c0, 0x31d6: 0x00c0, 0x31d7: 0x00c0, + 0x31d8: 0x00c0, 0x31d9: 0x00c0, 0x31da: 0x00c0, 0x31db: 0x00c0, 0x31dc: 0x00c0, 0x31dd: 0x00c0, + 0x31de: 0x00c0, 0x31df: 0x00c0, 0x31e0: 0x0080, 0x31e1: 0x0080, 0x31e2: 0x0080, 0x31e3: 0x0080, + 0x31ed: 0x00c0, 0x31ee: 0x00c0, 0x31ef: 0x00c0, + 0x31f0: 0x00c0, 0x31f1: 0x00c0, 0x31f2: 0x00c0, 0x31f3: 0x00c0, 0x31f4: 0x00c0, 0x31f5: 0x00c0, + 0x31f6: 0x00c0, 0x31f7: 0x00c0, 0x31f8: 0x00c0, 0x31f9: 0x00c0, 0x31fa: 0x00c0, 0x31fb: 0x00c0, + 0x31fc: 0x00c0, 0x31fd: 0x00c0, 0x31fe: 0x00c0, 0x31ff: 0x00c0, + // Block 0xc8, offset 0x3200 + 0x3200: 0x00c0, 0x3201: 0x0080, 0x3202: 0x00c0, 0x3203: 0x00c0, 0x3204: 0x00c0, 0x3205: 0x00c0, + 0x3206: 0x00c0, 0x3207: 0x00c0, 0x3208: 0x00c0, 0x3209: 0x00c0, 0x320a: 0x0080, + 0x3210: 0x00c0, 0x3211: 0x00c0, + 0x3212: 0x00c0, 0x3213: 0x00c0, 0x3214: 0x00c0, 0x3215: 0x00c0, 0x3216: 0x00c0, 0x3217: 0x00c0, + 0x3218: 0x00c0, 0x3219: 0x00c0, 0x321a: 0x00c0, 0x321b: 0x00c0, 0x321c: 0x00c0, 0x321d: 0x00c0, + 0x321e: 0x00c0, 0x321f: 0x00c0, 0x3220: 0x00c0, 0x3221: 0x00c0, 0x3222: 0x00c0, 0x3223: 0x00c0, + 0x3224: 0x00c0, 0x3225: 0x00c0, 0x3226: 0x00c0, 0x3227: 0x00c0, 0x3228: 0x00c0, 0x3229: 0x00c0, + 0x322a: 0x00c0, 0x322b: 0x00c0, 0x322c: 0x00c0, 0x322d: 0x00c0, 0x322e: 0x00c0, 0x322f: 0x00c0, + 0x3230: 0x00c0, 0x3231: 0x00c0, 0x3232: 0x00c0, 0x3233: 0x00c0, 0x3234: 0x00c0, 0x3235: 0x00c0, + 0x3236: 0x00c3, 0x3237: 0x00c3, 0x3238: 0x00c3, 0x3239: 0x00c3, 0x323a: 0x00c3, + // Block 0xc9, offset 0x3240 + 0x3240: 0x00c0, 0x3241: 0x00c0, 0x3242: 0x00c0, 0x3243: 0x00c0, 0x3244: 0x00c0, 0x3245: 0x00c0, + 0x3246: 0x00c0, 0x3247: 0x00c0, 0x3248: 0x00c0, 0x3249: 0x00c0, 0x324a: 0x00c0, 0x324b: 0x00c0, + 0x324c: 0x00c0, 0x324d: 0x00c0, 0x324e: 0x00c0, 0x324f: 0x00c0, 0x3250: 0x00c0, 0x3251: 0x00c0, + 0x3252: 0x00c0, 0x3253: 0x00c0, 0x3254: 0x00c0, 0x3255: 0x00c0, 0x3256: 0x00c0, 0x3257: 0x00c0, + 0x3258: 0x00c0, 0x3259: 0x00c0, 0x325a: 0x00c0, 0x325b: 0x00c0, 0x325c: 0x00c0, 0x325d: 0x00c0, + 0x325f: 0x0080, 0x3260: 0x00c0, 0x3261: 0x00c0, 0x3262: 0x00c0, 0x3263: 0x00c0, + 0x3264: 0x00c0, 0x3265: 0x00c0, 0x3266: 0x00c0, 0x3267: 0x00c0, 0x3268: 0x00c0, 0x3269: 0x00c0, + 0x326a: 0x00c0, 0x326b: 0x00c0, 0x326c: 0x00c0, 0x326d: 0x00c0, 0x326e: 0x00c0, 0x326f: 0x00c0, + 0x3270: 0x00c0, 0x3271: 0x00c0, 0x3272: 0x00c0, 0x3273: 0x00c0, 0x3274: 0x00c0, 0x3275: 0x00c0, + 0x3276: 0x00c0, 0x3277: 0x00c0, 0x3278: 0x00c0, 0x3279: 0x00c0, 0x327a: 0x00c0, 0x327b: 0x00c0, + 0x327c: 0x00c0, 0x327d: 0x00c0, 0x327e: 0x00c0, 0x327f: 0x00c0, + // Block 0xca, offset 0x3280 + 0x3280: 0x00c0, 0x3281: 0x00c0, 0x3282: 0x00c0, 0x3283: 0x00c0, + 0x3288: 0x00c0, 0x3289: 0x00c0, 0x328a: 0x00c0, 0x328b: 0x00c0, + 0x328c: 0x00c0, 0x328d: 0x00c0, 0x328e: 0x00c0, 0x328f: 0x00c0, 0x3290: 0x0080, 0x3291: 0x0080, + 0x3292: 0x0080, 0x3293: 0x0080, 0x3294: 0x0080, 0x3295: 0x0080, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x00c0, 0x32c1: 0x00c0, 0x32c2: 0x00c0, 0x32c3: 0x00c0, 0x32c4: 0x00c0, 0x32c5: 0x00c0, + 0x32c6: 0x00c0, 0x32c7: 0x00c0, 0x32c8: 0x00c0, 0x32c9: 0x00c0, 0x32ca: 0x00c0, 0x32cb: 0x00c0, + 0x32cc: 0x00c0, 0x32cd: 0x00c0, 0x32ce: 0x00c0, 0x32cf: 0x00c0, 0x32d0: 0x00c0, 0x32d1: 0x00c0, + 0x32d2: 0x00c0, 0x32d3: 0x00c0, 0x32d4: 0x00c0, 0x32d5: 0x00c0, 0x32d6: 0x00c0, 0x32d7: 0x00c0, + 0x32d8: 0x00c0, 0x32d9: 0x00c0, 0x32da: 0x00c0, 0x32db: 0x00c0, 0x32dc: 0x00c0, 0x32dd: 0x00c0, + 0x32e0: 0x00c0, 0x32e1: 0x00c0, 0x32e2: 0x00c0, 0x32e3: 0x00c0, + 0x32e4: 0x00c0, 0x32e5: 0x00c0, 0x32e6: 0x00c0, 0x32e7: 0x00c0, 0x32e8: 0x00c0, 0x32e9: 0x00c0, + 0x32f0: 0x00c0, 0x32f1: 0x00c0, 0x32f2: 0x00c0, 0x32f3: 0x00c0, 0x32f4: 0x00c0, 0x32f5: 0x00c0, + 0x32f6: 0x00c0, 0x32f7: 0x00c0, 0x32f8: 0x00c0, 0x32f9: 0x00c0, 0x32fa: 0x00c0, 0x32fb: 0x00c0, + 0x32fc: 0x00c0, 0x32fd: 0x00c0, 0x32fe: 0x00c0, 0x32ff: 0x00c0, + // Block 0xcc, offset 0x3300 + 0x3300: 0x00c0, 0x3301: 0x00c0, 0x3302: 0x00c0, 0x3303: 0x00c0, 0x3304: 0x00c0, 0x3305: 0x00c0, + 0x3306: 0x00c0, 0x3307: 0x00c0, 0x3308: 0x00c0, 0x3309: 0x00c0, 0x330a: 0x00c0, 0x330b: 0x00c0, + 0x330c: 0x00c0, 0x330d: 0x00c0, 0x330e: 0x00c0, 0x330f: 0x00c0, 0x3310: 0x00c0, 0x3311: 0x00c0, + 0x3312: 0x00c0, 0x3313: 0x00c0, + 0x3318: 0x00c0, 0x3319: 0x00c0, 0x331a: 0x00c0, 0x331b: 0x00c0, 0x331c: 0x00c0, 0x331d: 0x00c0, + 0x331e: 0x00c0, 0x331f: 0x00c0, 0x3320: 0x00c0, 0x3321: 0x00c0, 0x3322: 0x00c0, 0x3323: 0x00c0, + 0x3324: 0x00c0, 0x3325: 0x00c0, 0x3326: 0x00c0, 0x3327: 0x00c0, 0x3328: 0x00c0, 0x3329: 0x00c0, + 0x332a: 0x00c0, 0x332b: 0x00c0, 0x332c: 0x00c0, 0x332d: 0x00c0, 0x332e: 0x00c0, 0x332f: 0x00c0, + 0x3330: 0x00c0, 0x3331: 0x00c0, 0x3332: 0x00c0, 0x3333: 0x00c0, 0x3334: 0x00c0, 0x3335: 0x00c0, + 0x3336: 0x00c0, 0x3337: 0x00c0, 0x3338: 0x00c0, 0x3339: 0x00c0, 0x333a: 0x00c0, 0x333b: 0x00c0, + // Block 0xcd, offset 0x3340 + 0x3340: 0x00c0, 0x3341: 0x00c0, 0x3342: 0x00c0, 0x3343: 0x00c0, 0x3344: 0x00c0, 0x3345: 0x00c0, + 0x3346: 0x00c0, 0x3347: 0x00c0, 0x3348: 0x00c0, 0x3349: 0x00c0, 0x334a: 0x00c0, 0x334b: 0x00c0, + 0x334c: 0x00c0, 0x334d: 0x00c0, 0x334e: 0x00c0, 0x334f: 0x00c0, 0x3350: 0x00c0, 0x3351: 0x00c0, + 0x3352: 0x00c0, 0x3353: 0x00c0, 0x3354: 0x00c0, 0x3355: 0x00c0, 0x3356: 0x00c0, 0x3357: 0x00c0, + 0x3358: 0x00c0, 0x3359: 0x00c0, 0x335a: 0x00c0, 0x335b: 0x00c0, 0x335c: 0x00c0, 0x335d: 0x00c0, + 0x335e: 0x00c0, 0x335f: 0x00c0, 0x3360: 0x00c0, 0x3361: 0x00c0, 0x3362: 0x00c0, 0x3363: 0x00c0, + 0x3364: 0x00c0, 0x3365: 0x00c0, 0x3366: 0x00c0, 0x3367: 0x00c0, + 0x3370: 0x00c0, 0x3371: 0x00c0, 0x3372: 0x00c0, 0x3373: 0x00c0, 0x3374: 0x00c0, 0x3375: 0x00c0, + 0x3376: 0x00c0, 0x3377: 0x00c0, 0x3378: 0x00c0, 0x3379: 0x00c0, 0x337a: 0x00c0, 0x337b: 0x00c0, + 0x337c: 0x00c0, 0x337d: 0x00c0, 0x337e: 0x00c0, 0x337f: 0x00c0, + // Block 0xce, offset 0x3380 + 0x3380: 0x00c0, 0x3381: 0x00c0, 0x3382: 0x00c0, 0x3383: 0x00c0, 0x3384: 0x00c0, 0x3385: 0x00c0, + 0x3386: 0x00c0, 0x3387: 0x00c0, 0x3388: 0x00c0, 0x3389: 0x00c0, 0x338a: 0x00c0, 0x338b: 0x00c0, + 0x338c: 0x00c0, 0x338d: 0x00c0, 0x338e: 0x00c0, 0x338f: 0x00c0, 0x3390: 0x00c0, 0x3391: 0x00c0, + 0x3392: 0x00c0, 0x3393: 0x00c0, 0x3394: 0x00c0, 0x3395: 0x00c0, 0x3396: 0x00c0, 0x3397: 0x00c0, + 0x3398: 0x00c0, 0x3399: 0x00c0, 0x339a: 0x00c0, 0x339b: 0x00c0, 0x339c: 0x00c0, 0x339d: 0x00c0, + 0x339e: 0x00c0, 0x339f: 0x00c0, 0x33a0: 0x00c0, 0x33a1: 0x00c0, 0x33a2: 0x00c0, 0x33a3: 0x00c0, + 0x33af: 0x0080, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x00c0, 0x33c1: 0x00c0, 0x33c2: 0x00c0, 0x33c3: 0x00c0, 0x33c4: 0x00c0, 0x33c5: 0x00c0, + 0x33c6: 0x00c0, 0x33c7: 0x00c0, 0x33c8: 0x00c0, 0x33c9: 0x00c0, 0x33ca: 0x00c0, 0x33cb: 0x00c0, + 0x33cc: 0x00c0, 0x33cd: 0x00c0, 0x33ce: 0x00c0, 0x33cf: 0x00c0, 0x33d0: 0x00c0, 0x33d1: 0x00c0, + 0x33d2: 0x00c0, 0x33d3: 0x00c0, 0x33d4: 0x00c0, 0x33d5: 0x00c0, 0x33d6: 0x00c0, 0x33d7: 0x00c0, + 0x33d8: 0x00c0, 0x33d9: 0x00c0, 0x33da: 0x00c0, 0x33db: 0x00c0, 0x33dc: 0x00c0, 0x33dd: 0x00c0, + 0x33de: 0x00c0, 0x33df: 0x00c0, 0x33e0: 0x00c0, 0x33e1: 0x00c0, 0x33e2: 0x00c0, 0x33e3: 0x00c0, + 0x33e4: 0x00c0, 0x33e5: 0x00c0, 0x33e6: 0x00c0, 0x33e7: 0x00c0, 0x33e8: 0x00c0, 0x33e9: 0x00c0, + 0x33ea: 0x00c0, 0x33eb: 0x00c0, 0x33ec: 0x00c0, 0x33ed: 0x00c0, 0x33ee: 0x00c0, 0x33ef: 0x00c0, + 0x33f0: 0x00c0, 0x33f1: 0x00c0, 0x33f2: 0x00c0, 0x33f3: 0x00c0, 0x33f4: 0x00c0, 0x33f5: 0x00c0, + 0x33f6: 0x00c0, + // Block 0xd0, offset 0x3400 + 0x3400: 0x00c0, 0x3401: 0x00c0, 0x3402: 0x00c0, 0x3403: 0x00c0, 0x3404: 0x00c0, 0x3405: 0x00c0, + 0x3406: 0x00c0, 0x3407: 0x00c0, 0x3408: 0x00c0, 0x3409: 0x00c0, 0x340a: 0x00c0, 0x340b: 0x00c0, + 0x340c: 0x00c0, 0x340d: 0x00c0, 0x340e: 0x00c0, 0x340f: 0x00c0, 0x3410: 0x00c0, 0x3411: 0x00c0, + 0x3412: 0x00c0, 0x3413: 0x00c0, 0x3414: 0x00c0, 0x3415: 0x00c0, + 0x3420: 0x00c0, 0x3421: 0x00c0, 0x3422: 0x00c0, 0x3423: 0x00c0, + 0x3424: 0x00c0, 0x3425: 0x00c0, 0x3426: 0x00c0, 0x3427: 0x00c0, + // Block 0xd1, offset 0x3440 + 0x3440: 0x00c0, 0x3441: 0x00c0, 0x3442: 0x00c0, 0x3443: 0x00c0, 0x3444: 0x00c0, 0x3445: 0x00c0, + 0x3448: 0x00c0, 0x344a: 0x00c0, 0x344b: 0x00c0, + 0x344c: 0x00c0, 0x344d: 0x00c0, 0x344e: 0x00c0, 0x344f: 0x00c0, 0x3450: 0x00c0, 0x3451: 0x00c0, + 0x3452: 0x00c0, 0x3453: 0x00c0, 0x3454: 0x00c0, 0x3455: 0x00c0, 0x3456: 0x00c0, 0x3457: 0x00c0, + 0x3458: 0x00c0, 0x3459: 0x00c0, 0x345a: 0x00c0, 0x345b: 0x00c0, 0x345c: 0x00c0, 0x345d: 0x00c0, + 0x345e: 0x00c0, 0x345f: 0x00c0, 0x3460: 0x00c0, 0x3461: 0x00c0, 0x3462: 0x00c0, 0x3463: 0x00c0, + 0x3464: 0x00c0, 0x3465: 0x00c0, 0x3466: 0x00c0, 0x3467: 0x00c0, 0x3468: 0x00c0, 0x3469: 0x00c0, + 0x346a: 0x00c0, 0x346b: 0x00c0, 0x346c: 0x00c0, 0x346d: 0x00c0, 0x346e: 0x00c0, 0x346f: 0x00c0, + 0x3470: 0x00c0, 0x3471: 0x00c0, 0x3472: 0x00c0, 0x3473: 0x00c0, 0x3474: 0x00c0, 0x3475: 0x00c0, + 0x3477: 0x00c0, 0x3478: 0x00c0, + 0x347c: 0x00c0, 0x347f: 0x00c0, + // Block 0xd2, offset 0x3480 + 0x3480: 0x00c0, 0x3481: 0x00c0, 0x3482: 0x00c0, 0x3483: 0x00c0, 0x3484: 0x00c0, 0x3485: 0x00c0, + 0x3486: 0x00c0, 0x3487: 0x00c0, 0x3488: 0x00c0, 0x3489: 0x00c0, 0x348a: 0x00c0, 0x348b: 0x00c0, + 0x348c: 0x00c0, 0x348d: 0x00c0, 0x348e: 0x00c0, 0x348f: 0x00c0, 0x3490: 0x00c0, 0x3491: 0x00c0, + 0x3492: 0x00c0, 0x3493: 0x00c0, 0x3494: 0x00c0, 0x3495: 0x00c0, 0x3497: 0x0080, + 0x3498: 0x0080, 0x3499: 0x0080, 0x349a: 0x0080, 0x349b: 0x0080, 0x349c: 0x0080, 0x349d: 0x0080, + 0x349e: 0x0080, 0x349f: 0x0080, 0x34a0: 0x00c0, 0x34a1: 0x00c0, 0x34a2: 0x00c0, 0x34a3: 0x00c0, + 0x34a4: 0x00c0, 0x34a5: 0x00c0, 0x34a6: 0x00c0, 0x34a7: 0x00c0, 0x34a8: 0x00c0, 0x34a9: 0x00c0, + 0x34aa: 0x00c0, 0x34ab: 0x00c0, 0x34ac: 0x00c0, 0x34ad: 0x00c0, 0x34ae: 0x00c0, 0x34af: 0x00c0, + 0x34b0: 0x00c0, 0x34b1: 0x00c0, 0x34b2: 0x00c0, 0x34b3: 0x00c0, 0x34b4: 0x00c0, 0x34b5: 0x00c0, + 0x34b6: 0x00c0, 0x34b7: 0x0080, 0x34b8: 0x0080, 0x34b9: 0x0080, 0x34ba: 0x0080, 0x34bb: 0x0080, + 0x34bc: 0x0080, 0x34bd: 0x0080, 0x34be: 0x0080, 0x34bf: 0x0080, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x00c0, 0x34c1: 0x00c0, 0x34c2: 0x00c0, 0x34c3: 0x00c0, 0x34c4: 0x00c0, 0x34c5: 0x00c0, + 0x34c6: 0x00c0, 0x34c7: 0x00c0, 0x34c8: 0x00c0, 0x34c9: 0x00c0, 0x34ca: 0x00c0, 0x34cb: 0x00c0, + 0x34cc: 0x00c0, 0x34cd: 0x00c0, 0x34ce: 0x00c0, 0x34cf: 0x00c0, 0x34d0: 0x00c0, 0x34d1: 0x00c0, + 0x34d2: 0x00c0, 0x34d3: 0x00c0, 0x34d4: 0x00c0, 0x34d5: 0x00c0, 0x34d6: 0x00c0, 0x34d7: 0x00c0, + 0x34d8: 0x00c0, 0x34d9: 0x00c0, 0x34da: 0x00c0, 0x34db: 0x00c0, 0x34dc: 0x00c0, 0x34dd: 0x00c0, + 0x34de: 0x00c0, + 0x34e7: 0x0080, 0x34e8: 0x0080, 0x34e9: 0x0080, + 0x34ea: 0x0080, 0x34eb: 0x0080, 0x34ec: 0x0080, 0x34ed: 0x0080, 0x34ee: 0x0080, 0x34ef: 0x0080, + // Block 0xd4, offset 0x3500 + 0x3520: 0x00c0, 0x3521: 0x00c0, 0x3522: 0x00c0, 0x3523: 0x00c0, + 0x3524: 0x00c0, 0x3525: 0x00c0, 0x3526: 0x00c0, 0x3527: 0x00c0, 0x3528: 0x00c0, 0x3529: 0x00c0, + 0x352a: 0x00c0, 0x352b: 0x00c0, 0x352c: 0x00c0, 0x352d: 0x00c0, 0x352e: 0x00c0, 0x352f: 0x00c0, + 0x3530: 0x00c0, 0x3531: 0x00c0, 0x3532: 0x00c0, 0x3534: 0x00c0, 0x3535: 0x00c0, + 0x353b: 0x0080, + 0x353c: 0x0080, 0x353d: 0x0080, 0x353e: 0x0080, 0x353f: 0x0080, + // Block 0xd5, offset 0x3540 + 0x3540: 0x00c0, 0x3541: 0x00c0, 0x3542: 0x00c0, 0x3543: 0x00c0, 0x3544: 0x00c0, 0x3545: 0x00c0, + 0x3546: 0x00c0, 0x3547: 0x00c0, 0x3548: 0x00c0, 0x3549: 0x00c0, 0x354a: 0x00c0, 0x354b: 0x00c0, + 0x354c: 0x00c0, 0x354d: 0x00c0, 0x354e: 0x00c0, 0x354f: 0x00c0, 0x3550: 0x00c0, 0x3551: 0x00c0, + 0x3552: 0x00c0, 0x3553: 0x00c0, 0x3554: 0x00c0, 0x3555: 0x00c0, 0x3556: 0x0080, 0x3557: 0x0080, + 0x3558: 0x0080, 0x3559: 0x0080, 0x355a: 0x0080, 0x355b: 0x0080, + 0x355f: 0x0080, 0x3560: 0x00c0, 0x3561: 0x00c0, 0x3562: 0x00c0, 0x3563: 0x00c0, + 0x3564: 0x00c0, 0x3565: 0x00c0, 0x3566: 0x00c0, 0x3567: 0x00c0, 0x3568: 0x00c0, 0x3569: 0x00c0, + 0x356a: 0x00c0, 0x356b: 0x00c0, 0x356c: 0x00c0, 0x356d: 0x00c0, 0x356e: 0x00c0, 0x356f: 0x00c0, + 0x3570: 0x00c0, 0x3571: 0x00c0, 0x3572: 0x00c0, 0x3573: 0x00c0, 0x3574: 0x00c0, 0x3575: 0x00c0, + 0x3576: 0x00c0, 0x3577: 0x00c0, 0x3578: 0x00c0, 0x3579: 0x00c0, + 0x357f: 0x0080, + // Block 0xd6, offset 0x3580 + 0x3580: 0x00c0, 0x3581: 0x00c0, 0x3582: 0x00c0, 0x3583: 0x00c0, 0x3584: 0x00c0, 0x3585: 0x00c0, + 0x3586: 0x00c0, 0x3587: 0x00c0, 0x3588: 0x00c0, 0x3589: 0x00c0, 0x358a: 0x00c0, 0x358b: 0x00c0, + 0x358c: 0x00c0, 0x358d: 0x00c0, 0x358e: 0x00c0, 0x358f: 0x00c0, 0x3590: 0x00c0, 0x3591: 0x00c0, + 0x3592: 0x00c0, 0x3593: 0x00c0, 0x3594: 0x00c0, 0x3595: 0x00c0, 0x3596: 0x00c0, 0x3597: 0x00c0, + 0x3598: 0x00c0, 0x3599: 0x00c0, 0x359a: 0x00c0, 0x359b: 0x00c0, 0x359c: 0x00c0, 0x359d: 0x00c0, + 0x359e: 0x00c0, 0x359f: 0x00c0, 0x35a0: 0x00c0, 0x35a1: 0x00c0, 0x35a2: 0x00c0, 0x35a3: 0x00c0, + 0x35a4: 0x00c0, 0x35a5: 0x00c0, 0x35a6: 0x00c0, 0x35a7: 0x00c0, 0x35a8: 0x00c0, 0x35a9: 0x00c0, + 0x35aa: 0x00c0, 0x35ab: 0x00c0, 0x35ac: 0x00c0, 0x35ad: 0x00c0, 0x35ae: 0x00c0, 0x35af: 0x00c0, + 0x35b0: 0x00c0, 0x35b1: 0x00c0, 0x35b2: 0x00c0, 0x35b3: 0x00c0, 0x35b4: 0x00c0, 0x35b5: 0x00c0, + 0x35b6: 0x00c0, 0x35b7: 0x00c0, + 0x35bc: 0x0080, 0x35bd: 0x0080, 0x35be: 0x00c0, 0x35bf: 0x00c0, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x00c0, 0x35c1: 0x00c3, 0x35c2: 0x00c3, 0x35c3: 0x00c3, 0x35c5: 0x00c3, + 0x35c6: 0x00c3, + 0x35cc: 0x00c3, 0x35cd: 0x00c3, 0x35ce: 0x00c3, 0x35cf: 0x00c3, 0x35d0: 0x00c0, 0x35d1: 0x00c0, + 0x35d2: 0x00c0, 0x35d3: 0x00c0, 0x35d5: 0x00c0, 0x35d6: 0x00c0, 0x35d7: 0x00c0, + 0x35d9: 0x00c0, 0x35da: 0x00c0, 0x35db: 0x00c0, 0x35dc: 0x00c0, 0x35dd: 0x00c0, + 0x35de: 0x00c0, 0x35df: 0x00c0, 0x35e0: 0x00c0, 0x35e1: 0x00c0, 0x35e2: 0x00c0, 0x35e3: 0x00c0, + 0x35e4: 0x00c0, 0x35e5: 0x00c0, 0x35e6: 0x00c0, 0x35e7: 0x00c0, 0x35e8: 0x00c0, 0x35e9: 0x00c0, + 0x35ea: 0x00c0, 0x35eb: 0x00c0, 0x35ec: 0x00c0, 0x35ed: 0x00c0, 0x35ee: 0x00c0, 0x35ef: 0x00c0, + 0x35f0: 0x00c0, 0x35f1: 0x00c0, 0x35f2: 0x00c0, 0x35f3: 0x00c0, 0x35f4: 0x00c0, 0x35f5: 0x00c0, + 0x35f8: 0x00c3, 0x35f9: 0x00c3, 0x35fa: 0x00c3, + 0x35ff: 0x00c6, + // Block 0xd8, offset 0x3600 + 0x3600: 0x0080, 0x3601: 0x0080, 0x3602: 0x0080, 0x3603: 0x0080, 0x3604: 0x0080, 0x3605: 0x0080, + 0x3606: 0x0080, 0x3607: 0x0080, 0x3608: 0x0080, + 0x3610: 0x0080, 0x3611: 0x0080, + 0x3612: 0x0080, 0x3613: 0x0080, 0x3614: 0x0080, 0x3615: 0x0080, 0x3616: 0x0080, 0x3617: 0x0080, + 0x3618: 0x0080, + 0x3620: 0x00c0, 0x3621: 0x00c0, 0x3622: 0x00c0, 0x3623: 0x00c0, + 0x3624: 0x00c0, 0x3625: 0x00c0, 0x3626: 0x00c0, 0x3627: 0x00c0, 0x3628: 0x00c0, 0x3629: 0x00c0, + 0x362a: 0x00c0, 0x362b: 0x00c0, 0x362c: 0x00c0, 0x362d: 0x00c0, 0x362e: 0x00c0, 0x362f: 0x00c0, + 0x3630: 0x00c0, 0x3631: 0x00c0, 0x3632: 0x00c0, 0x3633: 0x00c0, 0x3634: 0x00c0, 0x3635: 0x00c0, + 0x3636: 0x00c0, 0x3637: 0x00c0, 0x3638: 0x00c0, 0x3639: 0x00c0, 0x363a: 0x00c0, 0x363b: 0x00c0, + 0x363c: 0x00c0, 0x363d: 0x0080, 0x363e: 0x0080, 0x363f: 0x0080, + // Block 0xd9, offset 0x3640 + 0x3640: 0x00c0, 0x3641: 0x00c0, 0x3642: 0x00c0, 0x3643: 0x00c0, 0x3644: 0x00c0, 0x3645: 0x00c0, + 0x3646: 0x00c0, 0x3647: 0x00c0, 0x3648: 0x00c0, 0x3649: 0x00c0, 0x364a: 0x00c0, 0x364b: 0x00c0, + 0x364c: 0x00c0, 0x364d: 0x00c0, 0x364e: 0x00c0, 0x364f: 0x00c0, 0x3650: 0x00c0, 0x3651: 0x00c0, + 0x3652: 0x00c0, 0x3653: 0x00c0, 0x3654: 0x00c0, 0x3655: 0x00c0, 0x3656: 0x00c0, 0x3657: 0x00c0, + 0x3658: 0x00c0, 0x3659: 0x00c0, 0x365a: 0x00c0, 0x365b: 0x00c0, 0x365c: 0x00c0, 0x365d: 0x0080, + 0x365e: 0x0080, 0x365f: 0x0080, + // Block 0xda, offset 0x3680 + 0x3680: 0x00c2, 0x3681: 0x00c2, 0x3682: 0x00c2, 0x3683: 0x00c2, 0x3684: 0x00c2, 0x3685: 0x00c4, + 0x3686: 0x00c0, 0x3687: 0x00c4, 0x3688: 0x0080, 0x3689: 0x00c4, 0x368a: 0x00c4, 0x368b: 0x00c0, + 0x368c: 0x00c0, 0x368d: 0x00c1, 0x368e: 0x00c4, 0x368f: 0x00c4, 0x3690: 0x00c4, 0x3691: 0x00c4, + 0x3692: 0x00c4, 0x3693: 0x00c2, 0x3694: 0x00c2, 0x3695: 0x00c2, 0x3696: 0x00c2, 0x3697: 0x00c1, + 0x3698: 0x00c2, 0x3699: 0x00c2, 0x369a: 0x00c2, 0x369b: 0x00c2, 0x369c: 0x00c2, 0x369d: 0x00c4, + 0x369e: 0x00c2, 0x369f: 0x00c2, 0x36a0: 0x00c2, 0x36a1: 0x00c4, 0x36a2: 0x00c0, 0x36a3: 0x00c0, + 0x36a4: 0x00c4, 0x36a5: 0x00c3, 0x36a6: 0x00c3, + 0x36ab: 0x0082, 0x36ac: 0x0082, 0x36ad: 0x0082, 0x36ae: 0x0082, 0x36af: 0x0084, + 0x36b0: 0x0080, 0x36b1: 0x0080, 0x36b2: 0x0080, 0x36b3: 0x0080, 0x36b4: 0x0080, 0x36b5: 0x0080, + 0x36b6: 0x0080, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x00c0, 0x36c1: 0x00c0, 0x36c2: 0x00c0, 0x36c3: 0x00c0, 0x36c4: 0x00c0, 0x36c5: 0x00c0, + 0x36c6: 0x00c0, 0x36c7: 0x00c0, 0x36c8: 0x00c0, 0x36c9: 0x00c0, 0x36ca: 0x00c0, 0x36cb: 0x00c0, + 0x36cc: 0x00c0, 0x36cd: 0x00c0, 0x36ce: 0x00c0, 0x36cf: 0x00c0, 0x36d0: 0x00c0, 0x36d1: 0x00c0, + 0x36d2: 0x00c0, 0x36d3: 0x00c0, 0x36d4: 0x00c0, 0x36d5: 0x00c0, 0x36d6: 0x00c0, 0x36d7: 0x00c0, + 0x36d8: 0x00c0, 0x36d9: 0x00c0, 0x36da: 0x00c0, 0x36db: 0x00c0, 0x36dc: 0x00c0, 0x36dd: 0x00c0, + 0x36de: 0x00c0, 0x36df: 0x00c0, 0x36e0: 0x00c0, 0x36e1: 0x00c0, 0x36e2: 0x00c0, 0x36e3: 0x00c0, + 0x36e4: 0x00c0, 0x36e5: 0x00c0, 0x36e6: 0x00c0, 0x36e7: 0x00c0, 0x36e8: 0x00c0, 0x36e9: 0x00c0, + 0x36ea: 0x00c0, 0x36eb: 0x00c0, 0x36ec: 0x00c0, 0x36ed: 0x00c0, 0x36ee: 0x00c0, 0x36ef: 0x00c0, + 0x36f0: 0x00c0, 0x36f1: 0x00c0, 0x36f2: 0x00c0, 0x36f3: 0x00c0, 0x36f4: 0x00c0, 0x36f5: 0x00c0, + 0x36f9: 0x0080, 0x36fa: 0x0080, 0x36fb: 0x0080, + 0x36fc: 0x0080, 0x36fd: 0x0080, 0x36fe: 0x0080, 0x36ff: 0x0080, + // Block 0xdc, offset 0x3700 + 0x3700: 0x00c0, 0x3701: 0x00c0, 0x3702: 0x00c0, 0x3703: 0x00c0, 0x3704: 0x00c0, 0x3705: 0x00c0, + 0x3706: 0x00c0, 0x3707: 0x00c0, 0x3708: 0x00c0, 0x3709: 0x00c0, 0x370a: 0x00c0, 0x370b: 0x00c0, + 0x370c: 0x00c0, 0x370d: 0x00c0, 0x370e: 0x00c0, 0x370f: 0x00c0, 0x3710: 0x00c0, 0x3711: 0x00c0, + 0x3712: 0x00c0, 0x3713: 0x00c0, 0x3714: 0x00c0, 0x3715: 0x00c0, + 0x3718: 0x0080, 0x3719: 0x0080, 0x371a: 0x0080, 0x371b: 0x0080, 0x371c: 0x0080, 0x371d: 0x0080, + 0x371e: 0x0080, 0x371f: 0x0080, 0x3720: 0x00c0, 0x3721: 0x00c0, 0x3722: 0x00c0, 0x3723: 0x00c0, + 0x3724: 0x00c0, 0x3725: 0x00c0, 0x3726: 0x00c0, 0x3727: 0x00c0, 0x3728: 0x00c0, 0x3729: 0x00c0, + 0x372a: 0x00c0, 0x372b: 0x00c0, 0x372c: 0x00c0, 0x372d: 0x00c0, 0x372e: 0x00c0, 0x372f: 0x00c0, + 0x3730: 0x00c0, 0x3731: 0x00c0, 0x3732: 0x00c0, + 0x3738: 0x0080, 0x3739: 0x0080, 0x373a: 0x0080, 0x373b: 0x0080, + 0x373c: 0x0080, 0x373d: 0x0080, 0x373e: 0x0080, 0x373f: 0x0080, + // Block 0xdd, offset 0x3740 + 0x3740: 0x00c2, 0x3741: 0x00c4, 0x3742: 0x00c2, 0x3743: 0x00c4, 0x3744: 0x00c4, 0x3745: 0x00c4, + 0x3746: 0x00c2, 0x3747: 0x00c2, 0x3748: 0x00c2, 0x3749: 0x00c4, 0x374a: 0x00c2, 0x374b: 0x00c2, + 0x374c: 0x00c4, 0x374d: 0x00c2, 0x374e: 0x00c4, 0x374f: 0x00c4, 0x3750: 0x00c2, 0x3751: 0x00c4, + 0x3759: 0x0080, 0x375a: 0x0080, 0x375b: 0x0080, 0x375c: 0x0080, + 0x3769: 0x0084, + 0x376a: 0x0084, 0x376b: 0x0084, 0x376c: 0x0084, 0x376d: 0x0082, 0x376e: 0x0082, 0x376f: 0x0080, + // Block 0xde, offset 0x3780 + 0x3780: 0x00c0, 0x3781: 0x00c0, 0x3782: 0x00c0, 0x3783: 0x00c0, 0x3784: 0x00c0, 0x3785: 0x00c0, + 0x3786: 0x00c0, 0x3787: 0x00c0, 0x3788: 0x00c0, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x00c0, 0x37c1: 0x00c0, 0x37c2: 0x00c0, 0x37c3: 0x00c0, 0x37c4: 0x00c0, 0x37c5: 0x00c0, + 0x37c6: 0x00c0, 0x37c7: 0x00c0, 0x37c8: 0x00c0, 0x37c9: 0x00c0, 0x37ca: 0x00c0, 0x37cb: 0x00c0, + 0x37cc: 0x00c0, 0x37cd: 0x00c0, 0x37ce: 0x00c0, 0x37cf: 0x00c0, 0x37d0: 0x00c0, 0x37d1: 0x00c0, + 0x37d2: 0x00c0, 0x37d3: 0x00c0, 0x37d4: 0x00c0, 0x37d5: 0x00c0, 0x37d6: 0x00c0, 0x37d7: 0x00c0, + 0x37d8: 0x00c0, 0x37d9: 0x00c0, 0x37da: 0x00c0, 0x37db: 0x00c0, 0x37dc: 0x00c0, 0x37dd: 0x00c0, + 0x37de: 0x00c0, 0x37df: 0x00c0, 0x37e0: 0x00c0, 0x37e1: 0x00c0, 0x37e2: 0x00c0, 0x37e3: 0x00c0, + 0x37e4: 0x00c0, 0x37e5: 0x00c0, 0x37e6: 0x00c0, 0x37e7: 0x00c0, 0x37e8: 0x00c0, 0x37e9: 0x00c0, + 0x37ea: 0x00c0, 0x37eb: 0x00c0, 0x37ec: 0x00c0, 0x37ed: 0x00c0, 0x37ee: 0x00c0, 0x37ef: 0x00c0, + 0x37f0: 0x00c0, 0x37f1: 0x00c0, 0x37f2: 0x00c0, + // Block 0xe0, offset 0x3800 + 0x3800: 0x00c0, 0x3801: 0x00c0, 0x3802: 0x00c0, 0x3803: 0x00c0, 0x3804: 0x00c0, 0x3805: 0x00c0, + 0x3806: 0x00c0, 0x3807: 0x00c0, 0x3808: 0x00c0, 0x3809: 0x00c0, 0x380a: 0x00c0, 0x380b: 0x00c0, + 0x380c: 0x00c0, 0x380d: 0x00c0, 0x380e: 0x00c0, 0x380f: 0x00c0, 0x3810: 0x00c0, 0x3811: 0x00c0, + 0x3812: 0x00c0, 0x3813: 0x00c0, 0x3814: 0x00c0, 0x3815: 0x00c0, 0x3816: 0x00c0, 0x3817: 0x00c0, + 0x3818: 0x00c0, 0x3819: 0x00c0, 0x381a: 0x00c0, 0x381b: 0x00c0, 0x381c: 0x00c0, 0x381d: 0x00c0, + 0x381e: 0x00c0, 0x381f: 0x00c0, 0x3820: 0x00c0, 0x3821: 0x00c0, 0x3822: 0x00c0, 0x3823: 0x00c0, + 0x3824: 0x00c0, 0x3825: 0x00c0, 0x3826: 0x00c0, 0x3827: 0x00c0, 0x3828: 0x00c0, 0x3829: 0x00c0, + 0x382a: 0x00c0, 0x382b: 0x00c0, 0x382c: 0x00c0, 0x382d: 0x00c0, 0x382e: 0x00c0, 0x382f: 0x00c0, + 0x3830: 0x00c0, 0x3831: 0x00c0, 0x3832: 0x00c0, + 0x383a: 0x0080, 0x383b: 0x0080, + 0x383c: 0x0080, 0x383d: 0x0080, 0x383e: 0x0080, 0x383f: 0x0080, + // Block 0xe1, offset 0x3840 + 0x3840: 0x00c1, 0x3841: 0x00c2, 0x3842: 0x00c2, 0x3843: 0x00c2, 0x3844: 0x00c2, 0x3845: 0x00c2, + 0x3846: 0x00c2, 0x3847: 0x00c2, 0x3848: 0x00c2, 0x3849: 0x00c2, 0x384a: 0x00c2, 0x384b: 0x00c2, + 0x384c: 0x00c2, 0x384d: 0x00c2, 0x384e: 0x00c2, 0x384f: 0x00c2, 0x3850: 0x00c2, 0x3851: 0x00c2, + 0x3852: 0x00c2, 0x3853: 0x00c2, 0x3854: 0x00c2, 0x3855: 0x00c2, 0x3856: 0x00c2, 0x3857: 0x00c2, + 0x3858: 0x00c2, 0x3859: 0x00c2, 0x385a: 0x00c2, 0x385b: 0x00c2, 0x385c: 0x00c2, 0x385d: 0x00c2, + 0x385e: 0x00c2, 0x385f: 0x00c2, 0x3860: 0x00c2, 0x3861: 0x00c2, 0x3862: 0x00c4, 0x3863: 0x00c2, + 0x3864: 0x00c3, 0x3865: 0x00c3, 0x3866: 0x00c3, 0x3867: 0x00c3, + 0x3870: 0x00c0, 0x3871: 0x00c0, 0x3872: 0x00c0, 0x3873: 0x00c0, 0x3874: 0x00c0, 0x3875: 0x00c0, + 0x3876: 0x00c0, 0x3877: 0x00c0, 0x3878: 0x00c0, 0x3879: 0x00c0, + // Block 0xe2, offset 0x3880 + 0x38a0: 0x0080, 0x38a1: 0x0080, 0x38a2: 0x0080, 0x38a3: 0x0080, + 0x38a4: 0x0080, 0x38a5: 0x0080, 0x38a6: 0x0080, 0x38a7: 0x0080, 0x38a8: 0x0080, 0x38a9: 0x0080, + 0x38aa: 0x0080, 0x38ab: 0x0080, 0x38ac: 0x0080, 0x38ad: 0x0080, 0x38ae: 0x0080, 0x38af: 0x0080, + 0x38b0: 0x0080, 0x38b1: 0x0080, 0x38b2: 0x0080, 0x38b3: 0x0080, 0x38b4: 0x0080, 0x38b5: 0x0080, + 0x38b6: 0x0080, 0x38b7: 0x0080, 0x38b8: 0x0080, 0x38b9: 0x0080, 0x38ba: 0x0080, 0x38bb: 0x0080, + 0x38bc: 0x0080, 0x38bd: 0x0080, 0x38be: 0x0080, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x00c0, 0x38c1: 0x00c0, 0x38c2: 0x00c0, 0x38c3: 0x00c0, 0x38c4: 0x00c0, 0x38c5: 0x00c0, + 0x38c6: 0x00c0, 0x38c7: 0x00c0, 0x38c8: 0x00c0, 0x38c9: 0x00c0, 0x38ca: 0x00c0, 0x38cb: 0x00c0, + 0x38cc: 0x00c0, 0x38cd: 0x00c0, 0x38ce: 0x00c0, 0x38cf: 0x00c0, 0x38d0: 0x00c0, 0x38d1: 0x00c0, + 0x38d2: 0x00c0, 0x38d3: 0x00c0, 0x38d4: 0x00c0, 0x38d5: 0x00c0, 0x38d6: 0x00c0, 0x38d7: 0x00c0, + 0x38d8: 0x00c0, 0x38d9: 0x00c0, 0x38da: 0x00c0, 0x38db: 0x00c0, 0x38dc: 0x00c0, 0x38dd: 0x0080, + 0x38de: 0x0080, 0x38df: 0x0080, 0x38e0: 0x0080, 0x38e1: 0x0080, 0x38e2: 0x0080, 0x38e3: 0x0080, + 0x38e4: 0x0080, 0x38e5: 0x0080, 0x38e6: 0x0080, 0x38e7: 0x00c0, + 0x38f0: 0x00c2, 0x38f1: 0x00c2, 0x38f2: 0x00c2, 0x38f3: 0x00c4, 0x38f4: 0x00c2, 0x38f5: 0x00c2, + 0x38f6: 0x00c2, 0x38f7: 0x00c2, 0x38f8: 0x00c2, 0x38f9: 0x00c2, 0x38fa: 0x00c2, 0x38fb: 0x00c2, + 0x38fc: 0x00c2, 0x38fd: 0x00c2, 0x38fe: 0x00c2, 0x38ff: 0x00c2, + // Block 0xe4, offset 0x3900 + 0x3900: 0x00c2, 0x3901: 0x00c2, 0x3902: 0x00c2, 0x3903: 0x00c2, 0x3904: 0x00c2, 0x3905: 0x00c0, + 0x3906: 0x00c3, 0x3907: 0x00c3, 0x3908: 0x00c3, 0x3909: 0x00c3, 0x390a: 0x00c3, 0x390b: 0x00c3, + 0x390c: 0x00c3, 0x390d: 0x00c3, 0x390e: 0x00c3, 0x390f: 0x00c3, 0x3910: 0x00c3, 0x3911: 0x0082, + 0x3912: 0x0082, 0x3913: 0x0082, 0x3914: 0x0084, 0x3915: 0x0080, 0x3916: 0x0080, 0x3917: 0x0080, + 0x3918: 0x0080, 0x3919: 0x0080, + // Block 0xe5, offset 0x3940 + 0x3940: 0x00c0, 0x3941: 0x00c3, 0x3942: 0x00c0, 0x3943: 0x00c0, 0x3944: 0x00c0, 0x3945: 0x00c0, + 0x3946: 0x00c0, 0x3947: 0x00c0, 0x3948: 0x00c0, 0x3949: 0x00c0, 0x394a: 0x00c0, 0x394b: 0x00c0, + 0x394c: 0x00c0, 0x394d: 0x00c0, 0x394e: 0x00c0, 0x394f: 0x00c0, 0x3950: 0x00c0, 0x3951: 0x00c0, + 0x3952: 0x00c0, 0x3953: 0x00c0, 0x3954: 0x00c0, 0x3955: 0x00c0, 0x3956: 0x00c0, 0x3957: 0x00c0, + 0x3958: 0x00c0, 0x3959: 0x00c0, 0x395a: 0x00c0, 0x395b: 0x00c0, 0x395c: 0x00c0, 0x395d: 0x00c0, + 0x395e: 0x00c0, 0x395f: 0x00c0, 0x3960: 0x00c0, 0x3961: 0x00c0, 0x3962: 0x00c0, 0x3963: 0x00c0, + 0x3964: 0x00c0, 0x3965: 0x00c0, 0x3966: 0x00c0, 0x3967: 0x00c0, 0x3968: 0x00c0, 0x3969: 0x00c0, + 0x396a: 0x00c0, 0x396b: 0x00c0, 0x396c: 0x00c0, 0x396d: 0x00c0, 0x396e: 0x00c0, 0x396f: 0x00c0, + 0x3970: 0x00c0, 0x3971: 0x00c0, 0x3972: 0x00c0, 0x3973: 0x00c0, 0x3974: 0x00c0, 0x3975: 0x00c0, + 0x3976: 0x00c0, 0x3977: 0x00c0, 0x3978: 0x00c3, 0x3979: 0x00c3, 0x397a: 0x00c3, 0x397b: 0x00c3, + 0x397c: 0x00c3, 0x397d: 0x00c3, 0x397e: 0x00c3, 0x397f: 0x00c3, + // Block 0xe6, offset 0x3980 + 0x3980: 0x00c3, 0x3981: 0x00c3, 0x3982: 0x00c3, 0x3983: 0x00c3, 0x3984: 0x00c3, 0x3985: 0x00c3, + 0x3986: 0x00c6, 0x3987: 0x0080, 0x3988: 0x0080, 0x3989: 0x0080, 0x398a: 0x0080, 0x398b: 0x0080, + 0x398c: 0x0080, 0x398d: 0x0080, + 0x3992: 0x0080, 0x3993: 0x0080, 0x3994: 0x0080, 0x3995: 0x0080, 0x3996: 0x0080, 0x3997: 0x0080, + 0x3998: 0x0080, 0x3999: 0x0080, 0x399a: 0x0080, 0x399b: 0x0080, 0x399c: 0x0080, 0x399d: 0x0080, + 0x399e: 0x0080, 0x399f: 0x0080, 0x39a0: 0x0080, 0x39a1: 0x0080, 0x39a2: 0x0080, 0x39a3: 0x0080, + 0x39a4: 0x0080, 0x39a5: 0x0080, 0x39a6: 0x00c0, 0x39a7: 0x00c0, 0x39a8: 0x00c0, 0x39a9: 0x00c0, + 0x39aa: 0x00c0, 0x39ab: 0x00c0, 0x39ac: 0x00c0, 0x39ad: 0x00c0, 0x39ae: 0x00c0, 0x39af: 0x00c0, + 0x39bf: 0x00c6, + // Block 0xe7, offset 0x39c0 + 0x39c0: 0x00c3, 0x39c1: 0x00c3, 0x39c2: 0x00c0, 0x39c3: 0x00c0, 0x39c4: 0x00c0, 0x39c5: 0x00c0, + 0x39c6: 0x00c0, 0x39c7: 0x00c0, 0x39c8: 0x00c0, 0x39c9: 0x00c0, 0x39ca: 0x00c0, 0x39cb: 0x00c0, + 0x39cc: 0x00c0, 0x39cd: 0x00c0, 0x39ce: 0x00c0, 0x39cf: 0x00c0, 0x39d0: 0x00c0, 0x39d1: 0x00c0, + 0x39d2: 0x00c0, 0x39d3: 0x00c0, 0x39d4: 0x00c0, 0x39d5: 0x00c0, 0x39d6: 0x00c0, 0x39d7: 0x00c0, + 0x39d8: 0x00c0, 0x39d9: 0x00c0, 0x39da: 0x00c0, 0x39db: 0x00c0, 0x39dc: 0x00c0, 0x39dd: 0x00c0, + 0x39de: 0x00c0, 0x39df: 0x00c0, 0x39e0: 0x00c0, 0x39e1: 0x00c0, 0x39e2: 0x00c0, 0x39e3: 0x00c0, + 0x39e4: 0x00c0, 0x39e5: 0x00c0, 0x39e6: 0x00c0, 0x39e7: 0x00c0, 0x39e8: 0x00c0, 0x39e9: 0x00c0, + 0x39ea: 0x00c0, 0x39eb: 0x00c0, 0x39ec: 0x00c0, 0x39ed: 0x00c0, 0x39ee: 0x00c0, 0x39ef: 0x00c0, + 0x39f0: 0x00c0, 0x39f1: 0x00c0, 0x39f2: 0x00c0, 0x39f3: 0x00c3, 0x39f4: 0x00c3, 0x39f5: 0x00c3, + 0x39f6: 0x00c3, 0x39f7: 0x00c0, 0x39f8: 0x00c0, 0x39f9: 0x00c6, 0x39fa: 0x00c3, 0x39fb: 0x0080, + 0x39fc: 0x0080, 0x39fd: 0x0040, 0x39fe: 0x0080, 0x39ff: 0x0080, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0x0080, 0x3a01: 0x0080, + 0x3a0d: 0x0040, 0x3a10: 0x00c0, 0x3a11: 0x00c0, + 0x3a12: 0x00c0, 0x3a13: 0x00c0, 0x3a14: 0x00c0, 0x3a15: 0x00c0, 0x3a16: 0x00c0, 0x3a17: 0x00c0, + 0x3a18: 0x00c0, 0x3a19: 0x00c0, 0x3a1a: 0x00c0, 0x3a1b: 0x00c0, 0x3a1c: 0x00c0, 0x3a1d: 0x00c0, + 0x3a1e: 0x00c0, 0x3a1f: 0x00c0, 0x3a20: 0x00c0, 0x3a21: 0x00c0, 0x3a22: 0x00c0, 0x3a23: 0x00c0, + 0x3a24: 0x00c0, 0x3a25: 0x00c0, 0x3a26: 0x00c0, 0x3a27: 0x00c0, 0x3a28: 0x00c0, + 0x3a30: 0x00c0, 0x3a31: 0x00c0, 0x3a32: 0x00c0, 0x3a33: 0x00c0, 0x3a34: 0x00c0, 0x3a35: 0x00c0, + 0x3a36: 0x00c0, 0x3a37: 0x00c0, 0x3a38: 0x00c0, 0x3a39: 0x00c0, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x00c3, 0x3a41: 0x00c3, 0x3a42: 0x00c3, 0x3a43: 0x00c0, 0x3a44: 0x00c0, 0x3a45: 0x00c0, + 0x3a46: 0x00c0, 0x3a47: 0x00c0, 0x3a48: 0x00c0, 0x3a49: 0x00c0, 0x3a4a: 0x00c0, 0x3a4b: 0x00c0, + 0x3a4c: 0x00c0, 0x3a4d: 0x00c0, 0x3a4e: 0x00c0, 0x3a4f: 0x00c0, 0x3a50: 0x00c0, 0x3a51: 0x00c0, + 0x3a52: 0x00c0, 0x3a53: 0x00c0, 0x3a54: 0x00c0, 0x3a55: 0x00c0, 0x3a56: 0x00c0, 0x3a57: 0x00c0, + 0x3a58: 0x00c0, 0x3a59: 0x00c0, 0x3a5a: 0x00c0, 0x3a5b: 0x00c0, 0x3a5c: 0x00c0, 0x3a5d: 0x00c0, + 0x3a5e: 0x00c0, 0x3a5f: 0x00c0, 0x3a60: 0x00c0, 0x3a61: 0x00c0, 0x3a62: 0x00c0, 0x3a63: 0x00c0, + 0x3a64: 0x00c0, 0x3a65: 0x00c0, 0x3a66: 0x00c0, 0x3a67: 0x00c3, 0x3a68: 0x00c3, 0x3a69: 0x00c3, + 0x3a6a: 0x00c3, 0x3a6b: 0x00c3, 0x3a6c: 0x00c0, 0x3a6d: 0x00c3, 0x3a6e: 0x00c3, 0x3a6f: 0x00c3, + 0x3a70: 0x00c3, 0x3a71: 0x00c3, 0x3a72: 0x00c3, 0x3a73: 0x00c6, 0x3a74: 0x00c6, + 0x3a76: 0x00c0, 0x3a77: 0x00c0, 0x3a78: 0x00c0, 0x3a79: 0x00c0, 0x3a7a: 0x00c0, 0x3a7b: 0x00c0, + 0x3a7c: 0x00c0, 0x3a7d: 0x00c0, 0x3a7e: 0x00c0, 0x3a7f: 0x00c0, + // Block 0xea, offset 0x3a80 + 0x3a80: 0x0080, 0x3a81: 0x0080, 0x3a82: 0x0080, 0x3a83: 0x0080, 0x3a84: 0x00c0, 0x3a85: 0x00c0, + 0x3a86: 0x00c0, + 0x3a90: 0x00c0, 0x3a91: 0x00c0, + 0x3a92: 0x00c0, 0x3a93: 0x00c0, 0x3a94: 0x00c0, 0x3a95: 0x00c0, 0x3a96: 0x00c0, 0x3a97: 0x00c0, + 0x3a98: 0x00c0, 0x3a99: 0x00c0, 0x3a9a: 0x00c0, 0x3a9b: 0x00c0, 0x3a9c: 0x00c0, 0x3a9d: 0x00c0, + 0x3a9e: 0x00c0, 0x3a9f: 0x00c0, 0x3aa0: 0x00c0, 0x3aa1: 0x00c0, 0x3aa2: 0x00c0, 0x3aa3: 0x00c0, + 0x3aa4: 0x00c0, 0x3aa5: 0x00c0, 0x3aa6: 0x00c0, 0x3aa7: 0x00c0, 0x3aa8: 0x00c0, 0x3aa9: 0x00c0, + 0x3aaa: 0x00c0, 0x3aab: 0x00c0, 0x3aac: 0x00c0, 0x3aad: 0x00c0, 0x3aae: 0x00c0, 0x3aaf: 0x00c0, + 0x3ab0: 0x00c0, 0x3ab1: 0x00c0, 0x3ab2: 0x00c0, 0x3ab3: 0x00c3, 0x3ab4: 0x0080, 0x3ab5: 0x0080, + 0x3ab6: 0x00c0, + // Block 0xeb, offset 0x3ac0 + 0x3ac0: 0x00c3, 0x3ac1: 0x00c3, 0x3ac2: 0x00c0, 0x3ac3: 0x00c0, 0x3ac4: 0x00c0, 0x3ac5: 0x00c0, + 0x3ac6: 0x00c0, 0x3ac7: 0x00c0, 0x3ac8: 0x00c0, 0x3ac9: 0x00c0, 0x3aca: 0x00c0, 0x3acb: 0x00c0, + 0x3acc: 0x00c0, 0x3acd: 0x00c0, 0x3ace: 0x00c0, 0x3acf: 0x00c0, 0x3ad0: 0x00c0, 0x3ad1: 0x00c0, + 0x3ad2: 0x00c0, 0x3ad3: 0x00c0, 0x3ad4: 0x00c0, 0x3ad5: 0x00c0, 0x3ad6: 0x00c0, 0x3ad7: 0x00c0, + 0x3ad8: 0x00c0, 0x3ad9: 0x00c0, 0x3ada: 0x00c0, 0x3adb: 0x00c0, 0x3adc: 0x00c0, 0x3add: 0x00c0, + 0x3ade: 0x00c0, 0x3adf: 0x00c0, 0x3ae0: 0x00c0, 0x3ae1: 0x00c0, 0x3ae2: 0x00c0, 0x3ae3: 0x00c0, + 0x3ae4: 0x00c0, 0x3ae5: 0x00c0, 0x3ae6: 0x00c0, 0x3ae7: 0x00c0, 0x3ae8: 0x00c0, 0x3ae9: 0x00c0, + 0x3aea: 0x00c0, 0x3aeb: 0x00c0, 0x3aec: 0x00c0, 0x3aed: 0x00c0, 0x3aee: 0x00c0, 0x3aef: 0x00c0, + 0x3af0: 0x00c0, 0x3af1: 0x00c0, 0x3af2: 0x00c0, 0x3af3: 0x00c0, 0x3af4: 0x00c0, 0x3af5: 0x00c0, + 0x3af6: 0x00c3, 0x3af7: 0x00c3, 0x3af8: 0x00c3, 0x3af9: 0x00c3, 0x3afa: 0x00c3, 0x3afb: 0x00c3, + 0x3afc: 0x00c3, 0x3afd: 0x00c3, 0x3afe: 0x00c3, 0x3aff: 0x00c0, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x00c5, 0x3b01: 0x00c0, 0x3b02: 0x00c0, 0x3b03: 0x00c0, 0x3b04: 0x00c0, 0x3b05: 0x0080, + 0x3b06: 0x0080, 0x3b07: 0x0080, 0x3b08: 0x0080, 0x3b09: 0x00c3, 0x3b0a: 0x00c3, 0x3b0b: 0x00c3, + 0x3b0c: 0x00c3, 0x3b0d: 0x0080, 0x3b10: 0x00c0, 0x3b11: 0x00c0, + 0x3b12: 0x00c0, 0x3b13: 0x00c0, 0x3b14: 0x00c0, 0x3b15: 0x00c0, 0x3b16: 0x00c0, 0x3b17: 0x00c0, + 0x3b18: 0x00c0, 0x3b19: 0x00c0, 0x3b1a: 0x00c0, 0x3b1b: 0x0080, 0x3b1c: 0x00c0, 0x3b1d: 0x0080, + 0x3b1e: 0x0080, 0x3b1f: 0x0080, 0x3b21: 0x0080, 0x3b22: 0x0080, 0x3b23: 0x0080, + 0x3b24: 0x0080, 0x3b25: 0x0080, 0x3b26: 0x0080, 0x3b27: 0x0080, 0x3b28: 0x0080, 0x3b29: 0x0080, + 0x3b2a: 0x0080, 0x3b2b: 0x0080, 0x3b2c: 0x0080, 0x3b2d: 0x0080, 0x3b2e: 0x0080, 0x3b2f: 0x0080, + 0x3b30: 0x0080, 0x3b31: 0x0080, 0x3b32: 0x0080, 0x3b33: 0x0080, 0x3b34: 0x0080, + // Block 0xed, offset 0x3b40 + 0x3b40: 0x00c0, 0x3b41: 0x00c0, 0x3b42: 0x00c0, 0x3b43: 0x00c0, 0x3b44: 0x00c0, 0x3b45: 0x00c0, + 0x3b46: 0x00c0, 0x3b47: 0x00c0, 0x3b48: 0x00c0, 0x3b49: 0x00c0, 0x3b4a: 0x00c0, 0x3b4b: 0x00c0, + 0x3b4c: 0x00c0, 0x3b4d: 0x00c0, 0x3b4e: 0x00c0, 0x3b4f: 0x00c0, 0x3b50: 0x00c0, 0x3b51: 0x00c0, + 0x3b53: 0x00c0, 0x3b54: 0x00c0, 0x3b55: 0x00c0, 0x3b56: 0x00c0, 0x3b57: 0x00c0, + 0x3b58: 0x00c0, 0x3b59: 0x00c0, 0x3b5a: 0x00c0, 0x3b5b: 0x00c0, 0x3b5c: 0x00c0, 0x3b5d: 0x00c0, + 0x3b5e: 0x00c0, 0x3b5f: 0x00c0, 0x3b60: 0x00c0, 0x3b61: 0x00c0, 0x3b62: 0x00c0, 0x3b63: 0x00c0, + 0x3b64: 0x00c0, 0x3b65: 0x00c0, 0x3b66: 0x00c0, 0x3b67: 0x00c0, 0x3b68: 0x00c0, 0x3b69: 0x00c0, + 0x3b6a: 0x00c0, 0x3b6b: 0x00c0, 0x3b6c: 0x00c0, 0x3b6d: 0x00c0, 0x3b6e: 0x00c0, 0x3b6f: 0x00c3, + 0x3b70: 0x00c3, 0x3b71: 0x00c3, 0x3b72: 0x00c0, 0x3b73: 0x00c0, 0x3b74: 0x00c3, 0x3b75: 0x00c5, + 0x3b76: 0x00c3, 0x3b77: 0x00c3, 0x3b78: 0x0080, 0x3b79: 0x0080, 0x3b7a: 0x0080, 0x3b7b: 0x0080, + 0x3b7c: 0x0080, 0x3b7d: 0x0080, 0x3b7e: 0x00c3, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x00c0, 0x3b81: 0x00c0, 0x3b82: 0x00c0, 0x3b83: 0x00c0, 0x3b84: 0x00c0, 0x3b85: 0x00c0, + 0x3b86: 0x00c0, 0x3b88: 0x00c0, 0x3b8a: 0x00c0, 0x3b8b: 0x00c0, + 0x3b8c: 0x00c0, 0x3b8d: 0x00c0, 0x3b8f: 0x00c0, 0x3b90: 0x00c0, 0x3b91: 0x00c0, + 0x3b92: 0x00c0, 0x3b93: 0x00c0, 0x3b94: 0x00c0, 0x3b95: 0x00c0, 0x3b96: 0x00c0, 0x3b97: 0x00c0, + 0x3b98: 0x00c0, 0x3b99: 0x00c0, 0x3b9a: 0x00c0, 0x3b9b: 0x00c0, 0x3b9c: 0x00c0, 0x3b9d: 0x00c0, + 0x3b9f: 0x00c0, 0x3ba0: 0x00c0, 0x3ba1: 0x00c0, 0x3ba2: 0x00c0, 0x3ba3: 0x00c0, + 0x3ba4: 0x00c0, 0x3ba5: 0x00c0, 0x3ba6: 0x00c0, 0x3ba7: 0x00c0, 0x3ba8: 0x00c0, 0x3ba9: 0x0080, + 0x3bb0: 0x00c0, 0x3bb1: 0x00c0, 0x3bb2: 0x00c0, 0x3bb3: 0x00c0, 0x3bb4: 0x00c0, 0x3bb5: 0x00c0, + 0x3bb6: 0x00c0, 0x3bb7: 0x00c0, 0x3bb8: 0x00c0, 0x3bb9: 0x00c0, 0x3bba: 0x00c0, 0x3bbb: 0x00c0, + 0x3bbc: 0x00c0, 0x3bbd: 0x00c0, 0x3bbe: 0x00c0, 0x3bbf: 0x00c0, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x00c0, 0x3bc1: 0x00c0, 0x3bc2: 0x00c0, 0x3bc3: 0x00c0, 0x3bc4: 0x00c0, 0x3bc5: 0x00c0, + 0x3bc6: 0x00c0, 0x3bc7: 0x00c0, 0x3bc8: 0x00c0, 0x3bc9: 0x00c0, 0x3bca: 0x00c0, 0x3bcb: 0x00c0, + 0x3bcc: 0x00c0, 0x3bcd: 0x00c0, 0x3bce: 0x00c0, 0x3bcf: 0x00c0, 0x3bd0: 0x00c0, 0x3bd1: 0x00c0, + 0x3bd2: 0x00c0, 0x3bd3: 0x00c0, 0x3bd4: 0x00c0, 0x3bd5: 0x00c0, 0x3bd6: 0x00c0, 0x3bd7: 0x00c0, + 0x3bd8: 0x00c0, 0x3bd9: 0x00c0, 0x3bda: 0x00c0, 0x3bdb: 0x00c0, 0x3bdc: 0x00c0, 0x3bdd: 0x00c0, + 0x3bde: 0x00c0, 0x3bdf: 0x00c3, 0x3be0: 0x00c0, 0x3be1: 0x00c0, 0x3be2: 0x00c0, 0x3be3: 0x00c3, + 0x3be4: 0x00c3, 0x3be5: 0x00c3, 0x3be6: 0x00c3, 0x3be7: 0x00c3, 0x3be8: 0x00c3, 0x3be9: 0x00c3, + 0x3bea: 0x00c6, + 0x3bf0: 0x00c0, 0x3bf1: 0x00c0, 0x3bf2: 0x00c0, 0x3bf3: 0x00c0, 0x3bf4: 0x00c0, 0x3bf5: 0x00c0, + 0x3bf6: 0x00c0, 0x3bf7: 0x00c0, 0x3bf8: 0x00c0, 0x3bf9: 0x00c0, + // Block 0xf0, offset 0x3c00 + 0x3c00: 0x00c3, 0x3c01: 0x00c3, 0x3c02: 0x00c0, 0x3c03: 0x00c0, 0x3c05: 0x00c0, + 0x3c06: 0x00c0, 0x3c07: 0x00c0, 0x3c08: 0x00c0, 0x3c09: 0x00c0, 0x3c0a: 0x00c0, 0x3c0b: 0x00c0, + 0x3c0c: 0x00c0, 0x3c0f: 0x00c0, 0x3c10: 0x00c0, + 0x3c13: 0x00c0, 0x3c14: 0x00c0, 0x3c15: 0x00c0, 0x3c16: 0x00c0, 0x3c17: 0x00c0, + 0x3c18: 0x00c0, 0x3c19: 0x00c0, 0x3c1a: 0x00c0, 0x3c1b: 0x00c0, 0x3c1c: 0x00c0, 0x3c1d: 0x00c0, + 0x3c1e: 0x00c0, 0x3c1f: 0x00c0, 0x3c20: 0x00c0, 0x3c21: 0x00c0, 0x3c22: 0x00c0, 0x3c23: 0x00c0, + 0x3c24: 0x00c0, 0x3c25: 0x00c0, 0x3c26: 0x00c0, 0x3c27: 0x00c0, 0x3c28: 0x00c0, + 0x3c2a: 0x00c0, 0x3c2b: 0x00c0, 0x3c2c: 0x00c0, 0x3c2d: 0x00c0, 0x3c2e: 0x00c0, 0x3c2f: 0x00c0, + 0x3c30: 0x00c0, 0x3c32: 0x00c0, 0x3c33: 0x00c0, 0x3c35: 0x00c0, + 0x3c36: 0x00c0, 0x3c37: 0x00c0, 0x3c38: 0x00c0, 0x3c39: 0x00c0, 0x3c3b: 0x00c3, + 0x3c3c: 0x00c3, 0x3c3d: 0x00c0, 0x3c3e: 0x00c0, 0x3c3f: 0x00c0, + // Block 0xf1, offset 0x3c40 + 0x3c40: 0x00c3, 0x3c41: 0x00c0, 0x3c42: 0x00c0, 0x3c43: 0x00c0, 0x3c44: 0x00c0, + 0x3c47: 0x00c0, 0x3c48: 0x00c0, 0x3c4b: 0x00c0, + 0x3c4c: 0x00c0, 0x3c4d: 0x00c5, 0x3c50: 0x00c0, + 0x3c57: 0x00c0, + 0x3c5d: 0x00c0, + 0x3c5e: 0x00c0, 0x3c5f: 0x00c0, 0x3c60: 0x00c0, 0x3c61: 0x00c0, 0x3c62: 0x00c0, 0x3c63: 0x00c0, + 0x3c66: 0x00c3, 0x3c67: 0x00c3, 0x3c68: 0x00c3, 0x3c69: 0x00c3, + 0x3c6a: 0x00c3, 0x3c6b: 0x00c3, 0x3c6c: 0x00c3, + 0x3c70: 0x00c3, 0x3c71: 0x00c3, 0x3c72: 0x00c3, 0x3c73: 0x00c3, 0x3c74: 0x00c3, + // Block 0xf2, offset 0x3c80 + 0x3c80: 0x00c0, 0x3c81: 0x00c0, 0x3c82: 0x00c0, 0x3c83: 0x00c0, 0x3c84: 0x00c0, 0x3c85: 0x00c0, + 0x3c86: 0x00c0, 0x3c87: 0x00c0, 0x3c88: 0x00c0, 0x3c89: 0x00c0, 0x3c8a: 0x00c0, 0x3c8b: 0x00c0, + 0x3c8c: 0x00c0, 0x3c8d: 0x00c0, 0x3c8e: 0x00c0, 0x3c8f: 0x00c0, 0x3c90: 0x00c0, 0x3c91: 0x00c0, + 0x3c92: 0x00c0, 0x3c93: 0x00c0, 0x3c94: 0x00c0, 0x3c95: 0x00c0, 0x3c96: 0x00c0, 0x3c97: 0x00c0, + 0x3c98: 0x00c0, 0x3c99: 0x00c0, 0x3c9a: 0x00c0, 0x3c9b: 0x00c0, 0x3c9c: 0x00c0, 0x3c9d: 0x00c0, + 0x3c9e: 0x00c0, 0x3c9f: 0x00c0, 0x3ca0: 0x00c0, 0x3ca1: 0x00c0, 0x3ca2: 0x00c0, 0x3ca3: 0x00c0, + 0x3ca4: 0x00c0, 0x3ca5: 0x00c0, 0x3ca6: 0x00c0, 0x3ca7: 0x00c0, 0x3ca8: 0x00c0, 0x3ca9: 0x00c0, + 0x3caa: 0x00c0, 0x3cab: 0x00c0, 0x3cac: 0x00c0, 0x3cad: 0x00c0, 0x3cae: 0x00c0, 0x3caf: 0x00c0, + 0x3cb0: 0x00c0, 0x3cb1: 0x00c0, 0x3cb2: 0x00c0, 0x3cb3: 0x00c0, 0x3cb4: 0x00c0, 0x3cb5: 0x00c0, + 0x3cb6: 0x00c0, 0x3cb7: 0x00c0, 0x3cb8: 0x00c3, 0x3cb9: 0x00c3, 0x3cba: 0x00c3, 0x3cbb: 0x00c3, + 0x3cbc: 0x00c3, 0x3cbd: 0x00c3, 0x3cbe: 0x00c3, 0x3cbf: 0x00c3, + // Block 0xf3, offset 0x3cc0 + 0x3cc0: 0x00c0, 0x3cc1: 0x00c0, 0x3cc2: 0x00c6, 0x3cc3: 0x00c3, 0x3cc4: 0x00c3, 0x3cc5: 0x00c0, + 0x3cc6: 0x00c3, 0x3cc7: 0x00c0, 0x3cc8: 0x00c0, 0x3cc9: 0x00c0, 0x3cca: 0x00c0, 0x3ccb: 0x0080, + 0x3ccc: 0x0080, 0x3ccd: 0x0080, 0x3cce: 0x0080, 0x3ccf: 0x0080, 0x3cd0: 0x00c0, 0x3cd1: 0x00c0, + 0x3cd2: 0x00c0, 0x3cd3: 0x00c0, 0x3cd4: 0x00c0, 0x3cd5: 0x00c0, 0x3cd6: 0x00c0, 0x3cd7: 0x00c0, + 0x3cd8: 0x00c0, 0x3cd9: 0x00c0, 0x3cdb: 0x0080, 0x3cdd: 0x0080, + 0x3cde: 0x00c3, + // Block 0xf4, offset 0x3d00 + 0x3d00: 0x00c0, 0x3d01: 0x00c0, 0x3d02: 0x00c0, 0x3d03: 0x00c0, 0x3d04: 0x00c0, 0x3d05: 0x00c0, + 0x3d06: 0x00c0, 0x3d07: 0x00c0, 0x3d08: 0x00c0, 0x3d09: 0x00c0, 0x3d0a: 0x00c0, 0x3d0b: 0x00c0, + 0x3d0c: 0x00c0, 0x3d0d: 0x00c0, 0x3d0e: 0x00c0, 0x3d0f: 0x00c0, 0x3d10: 0x00c0, 0x3d11: 0x00c0, + 0x3d12: 0x00c0, 0x3d13: 0x00c0, 0x3d14: 0x00c0, 0x3d15: 0x00c0, 0x3d16: 0x00c0, 0x3d17: 0x00c0, + 0x3d18: 0x00c0, 0x3d19: 0x00c0, 0x3d1a: 0x00c0, 0x3d1b: 0x00c0, 0x3d1c: 0x00c0, 0x3d1d: 0x00c0, + 0x3d1e: 0x00c0, 0x3d1f: 0x00c0, 0x3d20: 0x00c0, 0x3d21: 0x00c0, 0x3d22: 0x00c0, 0x3d23: 0x00c0, + 0x3d24: 0x00c0, 0x3d25: 0x00c0, 0x3d26: 0x00c0, 0x3d27: 0x00c0, 0x3d28: 0x00c0, 0x3d29: 0x00c0, + 0x3d2a: 0x00c0, 0x3d2b: 0x00c0, 0x3d2c: 0x00c0, 0x3d2d: 0x00c0, 0x3d2e: 0x00c0, 0x3d2f: 0x00c0, + 0x3d30: 0x00c0, 0x3d31: 0x00c0, 0x3d32: 0x00c0, 0x3d33: 0x00c3, 0x3d34: 0x00c3, 0x3d35: 0x00c3, + 0x3d36: 0x00c3, 0x3d37: 0x00c3, 0x3d38: 0x00c3, 0x3d39: 0x00c0, 0x3d3a: 0x00c3, 0x3d3b: 0x00c0, + 0x3d3c: 0x00c0, 0x3d3d: 0x00c0, 0x3d3e: 0x00c0, 0x3d3f: 0x00c3, + // Block 0xf5, offset 0x3d40 + 0x3d40: 0x00c3, 0x3d41: 0x00c0, 0x3d42: 0x00c6, 0x3d43: 0x00c3, 0x3d44: 0x00c0, 0x3d45: 0x00c0, + 0x3d46: 0x0080, 0x3d47: 0x00c0, + 0x3d50: 0x00c0, 0x3d51: 0x00c0, + 0x3d52: 0x00c0, 0x3d53: 0x00c0, 0x3d54: 0x00c0, 0x3d55: 0x00c0, 0x3d56: 0x00c0, 0x3d57: 0x00c0, + 0x3d58: 0x00c0, 0x3d59: 0x00c0, + // Block 0xf6, offset 0x3d80 + 0x3d80: 0x00c0, 0x3d81: 0x00c0, 0x3d82: 0x00c0, 0x3d83: 0x00c0, 0x3d84: 0x00c0, 0x3d85: 0x00c0, + 0x3d86: 0x00c0, 0x3d87: 0x00c0, 0x3d88: 0x00c0, 0x3d89: 0x00c0, 0x3d8a: 0x00c0, 0x3d8b: 0x00c0, + 0x3d8c: 0x00c0, 0x3d8d: 0x00c0, 0x3d8e: 0x00c0, 0x3d8f: 0x00c0, 0x3d90: 0x00c0, 0x3d91: 0x00c0, + 0x3d92: 0x00c0, 0x3d93: 0x00c0, 0x3d94: 0x00c0, 0x3d95: 0x00c0, 0x3d96: 0x00c0, 0x3d97: 0x00c0, + 0x3d98: 0x00c0, 0x3d99: 0x00c0, 0x3d9a: 0x00c0, 0x3d9b: 0x00c0, 0x3d9c: 0x00c0, 0x3d9d: 0x00c0, + 0x3d9e: 0x00c0, 0x3d9f: 0x00c0, 0x3da0: 0x00c0, 0x3da1: 0x00c0, 0x3da2: 0x00c0, 0x3da3: 0x00c0, + 0x3da4: 0x00c0, 0x3da5: 0x00c0, 0x3da6: 0x00c0, 0x3da7: 0x00c0, 0x3da8: 0x00c0, 0x3da9: 0x00c0, + 0x3daa: 0x00c0, 0x3dab: 0x00c0, 0x3dac: 0x00c0, 0x3dad: 0x00c0, 0x3dae: 0x00c0, 0x3daf: 0x00c0, + 0x3db0: 0x00c0, 0x3db1: 0x00c0, 0x3db2: 0x00c3, 0x3db3: 0x00c3, 0x3db4: 0x00c3, 0x3db5: 0x00c3, + 0x3db8: 0x00c0, 0x3db9: 0x00c0, 0x3dba: 0x00c0, 0x3dbb: 0x00c0, + 0x3dbc: 0x00c3, 0x3dbd: 0x00c3, 0x3dbe: 0x00c0, 0x3dbf: 0x00c6, + // Block 0xf7, offset 0x3dc0 + 0x3dc0: 0x00c3, 0x3dc1: 0x0080, 0x3dc2: 0x0080, 0x3dc3: 0x0080, 0x3dc4: 0x0080, 0x3dc5: 0x0080, + 0x3dc6: 0x0080, 0x3dc7: 0x0080, 0x3dc8: 0x0080, 0x3dc9: 0x0080, 0x3dca: 0x0080, 0x3dcb: 0x0080, + 0x3dcc: 0x0080, 0x3dcd: 0x0080, 0x3dce: 0x0080, 0x3dcf: 0x0080, 0x3dd0: 0x0080, 0x3dd1: 0x0080, + 0x3dd2: 0x0080, 0x3dd3: 0x0080, 0x3dd4: 0x0080, 0x3dd5: 0x0080, 0x3dd6: 0x0080, 0x3dd7: 0x0080, + 0x3dd8: 0x00c0, 0x3dd9: 0x00c0, 0x3dda: 0x00c0, 0x3ddb: 0x00c0, 0x3ddc: 0x00c3, 0x3ddd: 0x00c3, + // Block 0xf8, offset 0x3e00 + 0x3e00: 0x00c0, 0x3e01: 0x00c0, 0x3e02: 0x00c0, 0x3e03: 0x00c0, 0x3e04: 0x00c0, 0x3e05: 0x00c0, + 0x3e06: 0x00c0, 0x3e07: 0x00c0, 0x3e08: 0x00c0, 0x3e09: 0x00c0, 0x3e0a: 0x00c0, 0x3e0b: 0x00c0, + 0x3e0c: 0x00c0, 0x3e0d: 0x00c0, 0x3e0e: 0x00c0, 0x3e0f: 0x00c0, 0x3e10: 0x00c0, 0x3e11: 0x00c0, + 0x3e12: 0x00c0, 0x3e13: 0x00c0, 0x3e14: 0x00c0, 0x3e15: 0x00c0, 0x3e16: 0x00c0, 0x3e17: 0x00c0, + 0x3e18: 0x00c0, 0x3e19: 0x00c0, 0x3e1a: 0x00c0, 0x3e1b: 0x00c0, 0x3e1c: 0x00c0, 0x3e1d: 0x00c0, + 0x3e1e: 0x00c0, 0x3e1f: 0x00c0, 0x3e20: 0x00c0, 0x3e21: 0x00c0, 0x3e22: 0x00c0, 0x3e23: 0x00c0, + 0x3e24: 0x00c0, 0x3e25: 0x00c0, 0x3e26: 0x00c0, 0x3e27: 0x00c0, 0x3e28: 0x00c0, 0x3e29: 0x00c0, + 0x3e2a: 0x00c0, 0x3e2b: 0x00c0, 0x3e2c: 0x00c0, 0x3e2d: 0x00c0, 0x3e2e: 0x00c0, 0x3e2f: 0x00c0, + 0x3e30: 0x00c0, 0x3e31: 0x00c0, 0x3e32: 0x00c0, 0x3e33: 0x00c3, 0x3e34: 0x00c3, 0x3e35: 0x00c3, + 0x3e36: 0x00c3, 0x3e37: 0x00c3, 0x3e38: 0x00c3, 0x3e39: 0x00c3, 0x3e3a: 0x00c3, 0x3e3b: 0x00c0, + 0x3e3c: 0x00c0, 0x3e3d: 0x00c3, 0x3e3e: 0x00c0, 0x3e3f: 0x00c6, + // Block 0xf9, offset 0x3e40 + 0x3e40: 0x00c3, 0x3e41: 0x0080, 0x3e42: 0x0080, 0x3e43: 0x0080, 0x3e44: 0x00c0, + 0x3e50: 0x00c0, 0x3e51: 0x00c0, + 0x3e52: 0x00c0, 0x3e53: 0x00c0, 0x3e54: 0x00c0, 0x3e55: 0x00c0, 0x3e56: 0x00c0, 0x3e57: 0x00c0, + 0x3e58: 0x00c0, 0x3e59: 0x00c0, + 0x3e60: 0x0080, 0x3e61: 0x0080, 0x3e62: 0x0080, 0x3e63: 0x0080, + 0x3e64: 0x0080, 0x3e65: 0x0080, 0x3e66: 0x0080, 0x3e67: 0x0080, 0x3e68: 0x0080, 0x3e69: 0x0080, + 0x3e6a: 0x0080, 0x3e6b: 0x0080, 0x3e6c: 0x0080, + // Block 0xfa, offset 0x3e80 + 0x3e80: 0x00c0, 0x3e81: 0x00c0, 0x3e82: 0x00c0, 0x3e83: 0x00c0, 0x3e84: 0x00c0, 0x3e85: 0x00c0, + 0x3e86: 0x00c0, 0x3e87: 0x00c0, 0x3e88: 0x00c0, 0x3e89: 0x00c0, 0x3e8a: 0x00c0, 0x3e8b: 0x00c0, + 0x3e8c: 0x00c0, 0x3e8d: 0x00c0, 0x3e8e: 0x00c0, 0x3e8f: 0x00c0, 0x3e90: 0x00c0, 0x3e91: 0x00c0, + 0x3e92: 0x00c0, 0x3e93: 0x00c0, 0x3e94: 0x00c0, 0x3e95: 0x00c0, 0x3e96: 0x00c0, 0x3e97: 0x00c0, + 0x3e98: 0x00c0, 0x3e99: 0x00c0, 0x3e9a: 0x00c0, 0x3e9b: 0x00c0, 0x3e9c: 0x00c0, 0x3e9d: 0x00c0, + 0x3e9e: 0x00c0, 0x3e9f: 0x00c0, 0x3ea0: 0x00c0, 0x3ea1: 0x00c0, 0x3ea2: 0x00c0, 0x3ea3: 0x00c0, + 0x3ea4: 0x00c0, 0x3ea5: 0x00c0, 0x3ea6: 0x00c0, 0x3ea7: 0x00c0, 0x3ea8: 0x00c0, 0x3ea9: 0x00c0, + 0x3eaa: 0x00c0, 0x3eab: 0x00c3, 0x3eac: 0x00c0, 0x3ead: 0x00c3, 0x3eae: 0x00c0, 0x3eaf: 0x00c0, + 0x3eb0: 0x00c3, 0x3eb1: 0x00c3, 0x3eb2: 0x00c3, 0x3eb3: 0x00c3, 0x3eb4: 0x00c3, 0x3eb5: 0x00c3, + 0x3eb6: 0x00c5, 0x3eb7: 0x00c3, + // Block 0xfb, offset 0x3ec0 + 0x3ec0: 0x00c0, 0x3ec1: 0x00c0, 0x3ec2: 0x00c0, 0x3ec3: 0x00c0, 0x3ec4: 0x00c0, 0x3ec5: 0x00c0, + 0x3ec6: 0x00c0, 0x3ec7: 0x00c0, 0x3ec8: 0x00c0, 0x3ec9: 0x00c0, + // Block 0xfc, offset 0x3f00 + 0x3f00: 0x00c0, 0x3f01: 0x00c0, 0x3f02: 0x00c0, 0x3f03: 0x00c0, 0x3f04: 0x00c0, 0x3f05: 0x00c0, + 0x3f06: 0x00c0, 0x3f07: 0x00c0, 0x3f08: 0x00c0, 0x3f09: 0x00c0, 0x3f0a: 0x00c0, 0x3f0b: 0x00c0, + 0x3f0c: 0x00c0, 0x3f0d: 0x00c0, 0x3f0e: 0x00c0, 0x3f0f: 0x00c0, 0x3f10: 0x00c0, 0x3f11: 0x00c0, + 0x3f12: 0x00c0, 0x3f13: 0x00c0, 0x3f14: 0x00c0, 0x3f15: 0x00c0, 0x3f16: 0x00c0, 0x3f17: 0x00c0, + 0x3f18: 0x00c0, 0x3f19: 0x00c0, 0x3f1a: 0x00c0, 0x3f1d: 0x00c3, + 0x3f1e: 0x00c3, 0x3f1f: 0x00c3, 0x3f20: 0x00c0, 0x3f21: 0x00c0, 0x3f22: 0x00c3, 0x3f23: 0x00c3, + 0x3f24: 0x00c3, 0x3f25: 0x00c3, 0x3f26: 0x00c0, 0x3f27: 0x00c3, 0x3f28: 0x00c3, 0x3f29: 0x00c3, + 0x3f2a: 0x00c3, 0x3f2b: 0x00c6, + 0x3f30: 0x00c0, 0x3f31: 0x00c0, 0x3f32: 0x00c0, 0x3f33: 0x00c0, 0x3f34: 0x00c0, 0x3f35: 0x00c0, + 0x3f36: 0x00c0, 0x3f37: 0x00c0, 0x3f38: 0x00c0, 0x3f39: 0x00c0, 0x3f3a: 0x0080, 0x3f3b: 0x0080, + 0x3f3c: 0x0080, 0x3f3d: 0x0080, 0x3f3e: 0x0080, 0x3f3f: 0x0080, + // Block 0xfd, offset 0x3f40 + 0x3f40: 0x00c0, 0x3f41: 0x00c0, 0x3f42: 0x00c0, 0x3f43: 0x00c0, 0x3f44: 0x00c0, 0x3f45: 0x00c0, + 0x3f46: 0x00c0, 0x3f47: 0x00c0, 0x3f48: 0x00c0, 0x3f49: 0x00c0, 0x3f4a: 0x00c0, 0x3f4b: 0x00c0, + 0x3f4c: 0x00c0, 0x3f4d: 0x00c0, 0x3f4e: 0x00c0, 0x3f4f: 0x00c0, 0x3f50: 0x00c0, 0x3f51: 0x00c0, + 0x3f52: 0x00c0, 0x3f53: 0x00c0, 0x3f54: 0x00c0, 0x3f55: 0x00c0, 0x3f56: 0x00c0, 0x3f57: 0x00c0, + 0x3f58: 0x00c0, 0x3f59: 0x00c0, 0x3f5a: 0x00c0, 0x3f5b: 0x00c0, 0x3f5c: 0x00c0, 0x3f5d: 0x00c0, + 0x3f5e: 0x00c0, 0x3f5f: 0x00c0, 0x3f60: 0x00c0, 0x3f61: 0x00c0, 0x3f62: 0x00c0, 0x3f63: 0x00c0, + 0x3f64: 0x00c0, 0x3f65: 0x00c0, 0x3f66: 0x00c0, 0x3f67: 0x00c0, 0x3f68: 0x00c0, 0x3f69: 0x00c0, + 0x3f6a: 0x00c0, 0x3f6b: 0x00c0, 0x3f6c: 0x00c0, 0x3f6d: 0x00c0, 0x3f6e: 0x00c0, 0x3f6f: 0x00c3, + 0x3f70: 0x00c3, 0x3f71: 0x00c3, 0x3f72: 0x00c3, 0x3f73: 0x00c3, 0x3f74: 0x00c3, 0x3f75: 0x00c3, + 0x3f76: 0x00c3, 0x3f77: 0x00c3, 0x3f78: 0x00c0, 0x3f79: 0x00c6, 0x3f7a: 0x00c3, 0x3f7b: 0x0080, + // Block 0xfe, offset 0x3f80 + 0x3fa0: 0x00c0, 0x3fa1: 0x00c0, 0x3fa2: 0x00c0, 0x3fa3: 0x00c0, + 0x3fa4: 0x00c0, 0x3fa5: 0x00c0, 0x3fa6: 0x00c0, 0x3fa7: 0x00c0, 0x3fa8: 0x00c0, 0x3fa9: 0x00c0, + 0x3faa: 0x00c0, 0x3fab: 0x00c0, 0x3fac: 0x00c0, 0x3fad: 0x00c0, 0x3fae: 0x00c0, 0x3faf: 0x00c0, + 0x3fb0: 0x00c0, 0x3fb1: 0x00c0, 0x3fb2: 0x00c0, 0x3fb3: 0x00c0, 0x3fb4: 0x00c0, 0x3fb5: 0x00c0, + 0x3fb6: 0x00c0, 0x3fb7: 0x00c0, 0x3fb8: 0x00c0, 0x3fb9: 0x00c0, 0x3fba: 0x00c0, 0x3fbb: 0x00c0, + 0x3fbc: 0x00c0, 0x3fbd: 0x00c0, 0x3fbe: 0x00c0, 0x3fbf: 0x00c0, + // Block 0xff, offset 0x3fc0 + 0x3fc0: 0x00c0, 0x3fc1: 0x00c0, 0x3fc2: 0x00c0, 0x3fc3: 0x00c0, 0x3fc4: 0x00c0, 0x3fc5: 0x00c0, + 0x3fc6: 0x00c0, 0x3fc7: 0x00c0, 0x3fc8: 0x00c0, 0x3fc9: 0x00c0, 0x3fca: 0x00c0, 0x3fcb: 0x00c0, + 0x3fcc: 0x00c0, 0x3fcd: 0x00c0, 0x3fce: 0x00c0, 0x3fcf: 0x00c0, 0x3fd0: 0x00c0, 0x3fd1: 0x00c0, + 0x3fd2: 0x00c0, 0x3fd3: 0x00c0, 0x3fd4: 0x00c0, 0x3fd5: 0x00c0, 0x3fd6: 0x00c0, 0x3fd7: 0x00c0, + 0x3fd8: 0x00c0, 0x3fd9: 0x00c0, 0x3fda: 0x00c0, 0x3fdb: 0x00c0, 0x3fdc: 0x00c0, 0x3fdd: 0x00c0, + 0x3fde: 0x00c0, 0x3fdf: 0x00c0, 0x3fe0: 0x00c0, 0x3fe1: 0x00c0, 0x3fe2: 0x00c0, 0x3fe3: 0x00c0, + 0x3fe4: 0x00c0, 0x3fe5: 0x00c0, 0x3fe6: 0x00c0, 0x3fe7: 0x00c0, 0x3fe8: 0x00c0, 0x3fe9: 0x00c0, + 0x3fea: 0x0080, 0x3feb: 0x0080, 0x3fec: 0x0080, 0x3fed: 0x0080, 0x3fee: 0x0080, 0x3fef: 0x0080, + 0x3ff0: 0x0080, 0x3ff1: 0x0080, 0x3ff2: 0x0080, + 0x3fff: 0x00c0, + // Block 0x100, offset 0x4000 + 0x4000: 0x00c0, 0x4001: 0x00c3, 0x4002: 0x00c3, 0x4003: 0x00c3, 0x4004: 0x00c3, 0x4005: 0x00c3, + 0x4006: 0x00c3, 0x4007: 0x00c3, 0x4008: 0x00c3, 0x4009: 0x00c3, 0x400a: 0x00c3, 0x400b: 0x00c0, + 0x400c: 0x00c0, 0x400d: 0x00c0, 0x400e: 0x00c0, 0x400f: 0x00c0, 0x4010: 0x00c0, 0x4011: 0x00c0, + 0x4012: 0x00c0, 0x4013: 0x00c0, 0x4014: 0x00c0, 0x4015: 0x00c0, 0x4016: 0x00c0, 0x4017: 0x00c0, + 0x4018: 0x00c0, 0x4019: 0x00c0, 0x401a: 0x00c0, 0x401b: 0x00c0, 0x401c: 0x00c0, 0x401d: 0x00c0, + 0x401e: 0x00c0, 0x401f: 0x00c0, 0x4020: 0x00c0, 0x4021: 0x00c0, 0x4022: 0x00c0, 0x4023: 0x00c0, + 0x4024: 0x00c0, 0x4025: 0x00c0, 0x4026: 0x00c0, 0x4027: 0x00c0, 0x4028: 0x00c0, 0x4029: 0x00c0, + 0x402a: 0x00c0, 0x402b: 0x00c0, 0x402c: 0x00c0, 0x402d: 0x00c0, 0x402e: 0x00c0, 0x402f: 0x00c0, + 0x4030: 0x00c0, 0x4031: 0x00c0, 0x4032: 0x00c0, 0x4033: 0x00c3, 0x4034: 0x00c6, 0x4035: 0x00c3, + 0x4036: 0x00c3, 0x4037: 0x00c3, 0x4038: 0x00c3, 0x4039: 0x00c0, 0x403a: 0x00c0, 0x403b: 0x00c3, + 0x403c: 0x00c3, 0x403d: 0x00c3, 0x403e: 0x00c3, 0x403f: 0x0080, + // Block 0x101, offset 0x4040 + 0x4040: 0x0080, 0x4041: 0x0080, 0x4042: 0x0080, 0x4043: 0x0080, 0x4044: 0x0080, 0x4045: 0x0080, + 0x4046: 0x0080, 0x4047: 0x00c6, + 0x4050: 0x00c0, 0x4051: 0x00c3, + 0x4052: 0x00c3, 0x4053: 0x00c3, 0x4054: 0x00c3, 0x4055: 0x00c3, 0x4056: 0x00c3, 0x4057: 0x00c0, + 0x4058: 0x00c0, 0x4059: 0x00c3, 0x405a: 0x00c3, 0x405b: 0x00c3, 0x405c: 0x00c0, 0x405d: 0x00c0, + 0x405e: 0x00c0, 0x405f: 0x00c0, 0x4060: 0x00c0, 0x4061: 0x00c0, 0x4062: 0x00c0, 0x4063: 0x00c0, + 0x4064: 0x00c0, 0x4065: 0x00c0, 0x4066: 0x00c0, 0x4067: 0x00c0, 0x4068: 0x00c0, 0x4069: 0x00c0, + 0x406a: 0x00c0, 0x406b: 0x00c0, 0x406c: 0x00c0, 0x406d: 0x00c0, 0x406e: 0x00c0, 0x406f: 0x00c0, + 0x4070: 0x00c0, 0x4071: 0x00c0, 0x4072: 0x00c0, 0x4073: 0x00c0, 0x4074: 0x00c0, 0x4075: 0x00c0, + 0x4076: 0x00c0, 0x4077: 0x00c0, 0x4078: 0x00c0, 0x4079: 0x00c0, 0x407a: 0x00c0, 0x407b: 0x00c0, + 0x407c: 0x00c0, 0x407d: 0x00c0, 0x407e: 0x00c0, 0x407f: 0x00c0, + // Block 0x102, offset 0x4080 + 0x4080: 0x00c0, 0x4081: 0x00c0, 0x4082: 0x00c0, 0x4083: 0x00c0, + 0x4086: 0x00c0, 0x4087: 0x00c0, 0x4088: 0x00c0, 0x4089: 0x00c0, 0x408a: 0x00c3, 0x408b: 0x00c3, + 0x408c: 0x00c3, 0x408d: 0x00c3, 0x408e: 0x00c3, 0x408f: 0x00c3, 0x4090: 0x00c3, 0x4091: 0x00c3, + 0x4092: 0x00c3, 0x4093: 0x00c3, 0x4094: 0x00c3, 0x4095: 0x00c3, 0x4096: 0x00c3, 0x4097: 0x00c0, + 0x4098: 0x00c3, 0x4099: 0x00c6, 0x409a: 0x0080, 0x409b: 0x0080, 0x409c: 0x0080, 0x409d: 0x00c0, + 0x409e: 0x0080, 0x409f: 0x0080, 0x40a0: 0x0080, 0x40a1: 0x0080, 0x40a2: 0x0080, + // Block 0x103, offset 0x40c0 + 0x40c0: 0x00c0, 0x40c1: 0x00c0, 0x40c2: 0x00c0, 0x40c3: 0x00c0, 0x40c4: 0x00c0, 0x40c5: 0x00c0, + 0x40c6: 0x00c0, 0x40c7: 0x00c0, 0x40c8: 0x00c0, 0x40c9: 0x00c0, 0x40ca: 0x00c0, 0x40cb: 0x00c0, + 0x40cc: 0x00c0, 0x40cd: 0x00c0, 0x40ce: 0x00c0, 0x40cf: 0x00c0, 0x40d0: 0x00c0, 0x40d1: 0x00c0, + 0x40d2: 0x00c0, 0x40d3: 0x00c0, 0x40d4: 0x00c0, 0x40d5: 0x00c0, 0x40d6: 0x00c0, 0x40d7: 0x00c0, + 0x40d8: 0x00c0, 0x40d9: 0x00c0, 0x40da: 0x00c0, 0x40db: 0x00c0, 0x40dc: 0x00c0, 0x40dd: 0x00c0, + 0x40de: 0x00c0, 0x40df: 0x00c0, 0x40e0: 0x00c0, 0x40e1: 0x00c0, 0x40e2: 0x00c0, 0x40e3: 0x00c0, + 0x40e4: 0x00c0, 0x40e5: 0x00c0, 0x40e6: 0x00c0, 0x40e7: 0x00c0, 0x40e8: 0x00c0, 0x40e9: 0x00c0, + 0x40ea: 0x00c0, 0x40eb: 0x00c0, 0x40ec: 0x00c0, 0x40ed: 0x00c0, 0x40ee: 0x00c0, 0x40ef: 0x00c0, + 0x40f0: 0x00c0, 0x40f1: 0x00c0, 0x40f2: 0x00c0, 0x40f3: 0x00c0, 0x40f4: 0x00c0, 0x40f5: 0x00c0, + 0x40f6: 0x00c0, 0x40f7: 0x00c0, 0x40f8: 0x00c0, + // Block 0x104, offset 0x4100 + 0x4100: 0x00c0, 0x4101: 0x00c0, 0x4102: 0x00c0, 0x4103: 0x00c0, 0x4104: 0x00c0, 0x4105: 0x00c0, + 0x4106: 0x00c0, 0x4107: 0x00c0, 0x4108: 0x00c0, 0x410a: 0x00c0, 0x410b: 0x00c0, + 0x410c: 0x00c0, 0x410d: 0x00c0, 0x410e: 0x00c0, 0x410f: 0x00c0, 0x4110: 0x00c0, 0x4111: 0x00c0, + 0x4112: 0x00c0, 0x4113: 0x00c0, 0x4114: 0x00c0, 0x4115: 0x00c0, 0x4116: 0x00c0, 0x4117: 0x00c0, + 0x4118: 0x00c0, 0x4119: 0x00c0, 0x411a: 0x00c0, 0x411b: 0x00c0, 0x411c: 0x00c0, 0x411d: 0x00c0, + 0x411e: 0x00c0, 0x411f: 0x00c0, 0x4120: 0x00c0, 0x4121: 0x00c0, 0x4122: 0x00c0, 0x4123: 0x00c0, + 0x4124: 0x00c0, 0x4125: 0x00c0, 0x4126: 0x00c0, 0x4127: 0x00c0, 0x4128: 0x00c0, 0x4129: 0x00c0, + 0x412a: 0x00c0, 0x412b: 0x00c0, 0x412c: 0x00c0, 0x412d: 0x00c0, 0x412e: 0x00c0, 0x412f: 0x00c0, + 0x4130: 0x00c3, 0x4131: 0x00c3, 0x4132: 0x00c3, 0x4133: 0x00c3, 0x4134: 0x00c3, 0x4135: 0x00c3, + 0x4136: 0x00c3, 0x4138: 0x00c3, 0x4139: 0x00c3, 0x413a: 0x00c3, 0x413b: 0x00c3, + 0x413c: 0x00c3, 0x413d: 0x00c3, 0x413e: 0x00c0, 0x413f: 0x00c6, + // Block 0x105, offset 0x4140 + 0x4140: 0x00c0, 0x4141: 0x0080, 0x4142: 0x0080, 0x4143: 0x0080, 0x4144: 0x0080, 0x4145: 0x0080, + 0x4150: 0x00c0, 0x4151: 0x00c0, + 0x4152: 0x00c0, 0x4153: 0x00c0, 0x4154: 0x00c0, 0x4155: 0x00c0, 0x4156: 0x00c0, 0x4157: 0x00c0, + 0x4158: 0x00c0, 0x4159: 0x00c0, 0x415a: 0x0080, 0x415b: 0x0080, 0x415c: 0x0080, 0x415d: 0x0080, + 0x415e: 0x0080, 0x415f: 0x0080, 0x4160: 0x0080, 0x4161: 0x0080, 0x4162: 0x0080, 0x4163: 0x0080, + 0x4164: 0x0080, 0x4165: 0x0080, 0x4166: 0x0080, 0x4167: 0x0080, 0x4168: 0x0080, 0x4169: 0x0080, + 0x416a: 0x0080, 0x416b: 0x0080, 0x416c: 0x0080, + 0x4170: 0x0080, 0x4171: 0x0080, 0x4172: 0x00c0, 0x4173: 0x00c0, 0x4174: 0x00c0, 0x4175: 0x00c0, + 0x4176: 0x00c0, 0x4177: 0x00c0, 0x4178: 0x00c0, 0x4179: 0x00c0, 0x417a: 0x00c0, 0x417b: 0x00c0, + 0x417c: 0x00c0, 0x417d: 0x00c0, 0x417e: 0x00c0, 0x417f: 0x00c0, + // Block 0x106, offset 0x4180 + 0x4180: 0x00c0, 0x4181: 0x00c0, 0x4182: 0x00c0, 0x4183: 0x00c0, 0x4184: 0x00c0, 0x4185: 0x00c0, + 0x4186: 0x00c0, 0x4187: 0x00c0, 0x4188: 0x00c0, 0x4189: 0x00c0, 0x418a: 0x00c0, 0x418b: 0x00c0, + 0x418c: 0x00c0, 0x418d: 0x00c0, 0x418e: 0x00c0, 0x418f: 0x00c0, + 0x4192: 0x00c3, 0x4193: 0x00c3, 0x4194: 0x00c3, 0x4195: 0x00c3, 0x4196: 0x00c3, 0x4197: 0x00c3, + 0x4198: 0x00c3, 0x4199: 0x00c3, 0x419a: 0x00c3, 0x419b: 0x00c3, 0x419c: 0x00c3, 0x419d: 0x00c3, + 0x419e: 0x00c3, 0x419f: 0x00c3, 0x41a0: 0x00c3, 0x41a1: 0x00c3, 0x41a2: 0x00c3, 0x41a3: 0x00c3, + 0x41a4: 0x00c3, 0x41a5: 0x00c3, 0x41a6: 0x00c3, 0x41a7: 0x00c3, 0x41a9: 0x00c0, + 0x41aa: 0x00c3, 0x41ab: 0x00c3, 0x41ac: 0x00c3, 0x41ad: 0x00c3, 0x41ae: 0x00c3, 0x41af: 0x00c3, + 0x41b0: 0x00c3, 0x41b1: 0x00c0, 0x41b2: 0x00c3, 0x41b3: 0x00c3, 0x41b4: 0x00c0, 0x41b5: 0x00c3, + 0x41b6: 0x00c3, + // Block 0x107, offset 0x41c0 + 0x41c0: 0x00c0, 0x41c1: 0x00c0, 0x41c2: 0x00c0, 0x41c3: 0x00c0, 0x41c4: 0x00c0, 0x41c5: 0x00c0, + 0x41c6: 0x00c0, 0x41c8: 0x00c0, 0x41c9: 0x00c0, 0x41cb: 0x00c0, + 0x41cc: 0x00c0, 0x41cd: 0x00c0, 0x41ce: 0x00c0, 0x41cf: 0x00c0, 0x41d0: 0x00c0, 0x41d1: 0x00c0, + 0x41d2: 0x00c0, 0x41d3: 0x00c0, 0x41d4: 0x00c0, 0x41d5: 0x00c0, 0x41d6: 0x00c0, 0x41d7: 0x00c0, + 0x41d8: 0x00c0, 0x41d9: 0x00c0, 0x41da: 0x00c0, 0x41db: 0x00c0, 0x41dc: 0x00c0, 0x41dd: 0x00c0, + 0x41de: 0x00c0, 0x41df: 0x00c0, 0x41e0: 0x00c0, 0x41e1: 0x00c0, 0x41e2: 0x00c0, 0x41e3: 0x00c0, + 0x41e4: 0x00c0, 0x41e5: 0x00c0, 0x41e6: 0x00c0, 0x41e7: 0x00c0, 0x41e8: 0x00c0, 0x41e9: 0x00c0, + 0x41ea: 0x00c0, 0x41eb: 0x00c0, 0x41ec: 0x00c0, 0x41ed: 0x00c0, 0x41ee: 0x00c0, 0x41ef: 0x00c0, + 0x41f0: 0x00c0, 0x41f1: 0x00c3, 0x41f2: 0x00c3, 0x41f3: 0x00c3, 0x41f4: 0x00c3, 0x41f5: 0x00c3, + 0x41f6: 0x00c3, 0x41fa: 0x00c3, + 0x41fc: 0x00c3, 0x41fd: 0x00c3, 0x41ff: 0x00c3, + // Block 0x108, offset 0x4200 + 0x4200: 0x00c3, 0x4201: 0x00c3, 0x4202: 0x00c3, 0x4203: 0x00c3, 0x4204: 0x00c6, 0x4205: 0x00c6, + 0x4206: 0x00c0, 0x4207: 0x00c3, + 0x4210: 0x00c0, 0x4211: 0x00c0, + 0x4212: 0x00c0, 0x4213: 0x00c0, 0x4214: 0x00c0, 0x4215: 0x00c0, 0x4216: 0x00c0, 0x4217: 0x00c0, + 0x4218: 0x00c0, 0x4219: 0x00c0, + 0x4220: 0x00c0, 0x4221: 0x00c0, 0x4222: 0x00c0, 0x4223: 0x00c0, + 0x4224: 0x00c0, 0x4225: 0x00c0, 0x4227: 0x00c0, 0x4228: 0x00c0, + 0x422a: 0x00c0, 0x422b: 0x00c0, 0x422c: 0x00c0, 0x422d: 0x00c0, 0x422e: 0x00c0, 0x422f: 0x00c0, + 0x4230: 0x00c0, 0x4231: 0x00c0, 0x4232: 0x00c0, 0x4233: 0x00c0, 0x4234: 0x00c0, 0x4235: 0x00c0, + 0x4236: 0x00c0, 0x4237: 0x00c0, 0x4238: 0x00c0, 0x4239: 0x00c0, 0x423a: 0x00c0, 0x423b: 0x00c0, + 0x423c: 0x00c0, 0x423d: 0x00c0, 0x423e: 0x00c0, 0x423f: 0x00c0, + // Block 0x109, offset 0x4240 + 0x4240: 0x00c0, 0x4241: 0x00c0, 0x4242: 0x00c0, 0x4243: 0x00c0, 0x4244: 0x00c0, 0x4245: 0x00c0, + 0x4246: 0x00c0, 0x4247: 0x00c0, 0x4248: 0x00c0, 0x4249: 0x00c0, 0x424a: 0x00c0, 0x424b: 0x00c0, + 0x424c: 0x00c0, 0x424d: 0x00c0, 0x424e: 0x00c0, 0x4250: 0x00c3, 0x4251: 0x00c3, + 0x4253: 0x00c0, 0x4254: 0x00c0, 0x4255: 0x00c3, 0x4256: 0x00c0, 0x4257: 0x00c6, + 0x4258: 0x00c0, + 0x4260: 0x00c0, 0x4261: 0x00c0, 0x4262: 0x00c0, 0x4263: 0x00c0, + 0x4264: 0x00c0, 0x4265: 0x00c0, 0x4266: 0x00c0, 0x4267: 0x00c0, 0x4268: 0x00c0, 0x4269: 0x00c0, + // Block 0x10a, offset 0x4280 + 0x42a0: 0x00c0, 0x42a1: 0x00c0, 0x42a2: 0x00c0, 0x42a3: 0x00c0, + 0x42a4: 0x00c0, 0x42a5: 0x00c0, 0x42a6: 0x00c0, 0x42a7: 0x00c0, 0x42a8: 0x00c0, 0x42a9: 0x00c0, + 0x42aa: 0x00c0, 0x42ab: 0x00c0, 0x42ac: 0x00c0, 0x42ad: 0x00c0, 0x42ae: 0x00c0, 0x42af: 0x00c0, + 0x42b0: 0x00c0, 0x42b1: 0x00c0, 0x42b2: 0x00c0, 0x42b3: 0x00c3, 0x42b4: 0x00c3, 0x42b5: 0x00c0, + 0x42b6: 0x00c0, 0x42b7: 0x0080, 0x42b8: 0x0080, + // Block 0x10b, offset 0x42c0 + 0x42c0: 0x00c0, 0x42c1: 0x00c0, 0x42c2: 0x00c0, 0x42c3: 0x00c0, 0x42c4: 0x00c0, 0x42c5: 0x00c0, + 0x42c6: 0x00c0, 0x42c7: 0x00c0, 0x42c8: 0x00c0, 0x42c9: 0x00c0, 0x42ca: 0x00c0, 0x42cb: 0x00c0, + 0x42cc: 0x00c0, 0x42cd: 0x00c0, 0x42ce: 0x00c0, 0x42cf: 0x00c0, 0x42d0: 0x00c0, 0x42d1: 0x00c0, + 0x42d2: 0x00c0, 0x42d3: 0x00c0, 0x42d4: 0x00c0, 0x42d5: 0x00c0, 0x42d6: 0x00c0, 0x42d7: 0x00c0, + 0x42d8: 0x00c0, 0x42d9: 0x00c0, + // Block 0x10c, offset 0x4300 + 0x4300: 0x0080, 0x4301: 0x0080, 0x4302: 0x0080, 0x4303: 0x0080, 0x4304: 0x0080, 0x4305: 0x0080, + 0x4306: 0x0080, 0x4307: 0x0080, 0x4308: 0x0080, 0x4309: 0x0080, 0x430a: 0x0080, 0x430b: 0x0080, + 0x430c: 0x0080, 0x430d: 0x0080, 0x430e: 0x0080, 0x430f: 0x0080, 0x4310: 0x0080, 0x4311: 0x0080, + 0x4312: 0x0080, 0x4313: 0x0080, 0x4314: 0x0080, 0x4315: 0x0080, 0x4316: 0x0080, 0x4317: 0x0080, + 0x4318: 0x0080, 0x4319: 0x0080, 0x431a: 0x0080, 0x431b: 0x0080, 0x431c: 0x0080, 0x431d: 0x0080, + 0x431e: 0x0080, 0x431f: 0x0080, 0x4320: 0x0080, 0x4321: 0x0080, 0x4322: 0x0080, 0x4323: 0x0080, + 0x4324: 0x0080, 0x4325: 0x0080, 0x4326: 0x0080, 0x4327: 0x0080, 0x4328: 0x0080, 0x4329: 0x0080, + 0x432a: 0x0080, 0x432b: 0x0080, 0x432c: 0x0080, 0x432d: 0x0080, 0x432e: 0x0080, + 0x4330: 0x0080, 0x4331: 0x0080, 0x4332: 0x0080, 0x4333: 0x0080, 0x4334: 0x0080, + // Block 0x10d, offset 0x4340 + 0x4340: 0x00c0, 0x4341: 0x00c0, 0x4342: 0x00c0, 0x4343: 0x00c0, + // Block 0x10e, offset 0x4380 + 0x4380: 0x00c0, 0x4381: 0x00c0, 0x4382: 0x00c0, 0x4383: 0x00c0, 0x4384: 0x00c0, 0x4385: 0x00c0, + 0x4386: 0x00c0, 0x4387: 0x00c0, 0x4388: 0x00c0, 0x4389: 0x00c0, 0x438a: 0x00c0, 0x438b: 0x00c0, + 0x438c: 0x00c0, 0x438d: 0x00c0, 0x438e: 0x00c0, 0x438f: 0x00c0, 0x4390: 0x00c0, 0x4391: 0x00c0, + 0x4392: 0x00c0, 0x4393: 0x00c0, 0x4394: 0x00c0, 0x4395: 0x00c0, 0x4396: 0x00c0, 0x4397: 0x00c0, + 0x4398: 0x00c0, 0x4399: 0x00c0, 0x439a: 0x00c0, 0x439b: 0x00c0, 0x439c: 0x00c0, 0x439d: 0x00c0, + 0x439e: 0x00c0, 0x439f: 0x00c0, 0x43a0: 0x00c0, 0x43a1: 0x00c0, 0x43a2: 0x00c0, 0x43a3: 0x00c0, + 0x43a4: 0x00c0, 0x43a5: 0x00c0, 0x43a6: 0x00c0, 0x43a7: 0x00c0, 0x43a8: 0x00c0, 0x43a9: 0x00c0, + 0x43aa: 0x00c0, 0x43ab: 0x00c0, 0x43ac: 0x00c0, 0x43ad: 0x00c0, 0x43ae: 0x00c0, + // Block 0x10f, offset 0x43c0 + 0x43c0: 0x00c0, 0x43c1: 0x00c0, 0x43c2: 0x00c0, 0x43c3: 0x00c0, 0x43c4: 0x00c0, 0x43c5: 0x00c0, + 0x43c6: 0x00c0, + // Block 0x110, offset 0x4400 + 0x4400: 0x00c0, 0x4401: 0x00c0, 0x4402: 0x00c0, 0x4403: 0x00c0, 0x4404: 0x00c0, 0x4405: 0x00c0, + 0x4406: 0x00c0, 0x4407: 0x00c0, 0x4408: 0x00c0, 0x4409: 0x00c0, 0x440a: 0x00c0, 0x440b: 0x00c0, + 0x440c: 0x00c0, 0x440d: 0x00c0, 0x440e: 0x00c0, 0x440f: 0x00c0, 0x4410: 0x00c0, 0x4411: 0x00c0, + 0x4412: 0x00c0, 0x4413: 0x00c0, 0x4414: 0x00c0, 0x4415: 0x00c0, 0x4416: 0x00c0, 0x4417: 0x00c0, + 0x4418: 0x00c0, 0x4419: 0x00c0, 0x441a: 0x00c0, 0x441b: 0x00c0, 0x441c: 0x00c0, 0x441d: 0x00c0, + 0x441e: 0x00c0, 0x4420: 0x00c0, 0x4421: 0x00c0, 0x4422: 0x00c0, 0x4423: 0x00c0, + 0x4424: 0x00c0, 0x4425: 0x00c0, 0x4426: 0x00c0, 0x4427: 0x00c0, 0x4428: 0x00c0, 0x4429: 0x00c0, + 0x442e: 0x0080, 0x442f: 0x0080, + // Block 0x111, offset 0x4440 + 0x4450: 0x00c0, 0x4451: 0x00c0, + 0x4452: 0x00c0, 0x4453: 0x00c0, 0x4454: 0x00c0, 0x4455: 0x00c0, 0x4456: 0x00c0, 0x4457: 0x00c0, + 0x4458: 0x00c0, 0x4459: 0x00c0, 0x445a: 0x00c0, 0x445b: 0x00c0, 0x445c: 0x00c0, 0x445d: 0x00c0, + 0x445e: 0x00c0, 0x445f: 0x00c0, 0x4460: 0x00c0, 0x4461: 0x00c0, 0x4462: 0x00c0, 0x4463: 0x00c0, + 0x4464: 0x00c0, 0x4465: 0x00c0, 0x4466: 0x00c0, 0x4467: 0x00c0, 0x4468: 0x00c0, 0x4469: 0x00c0, + 0x446a: 0x00c0, 0x446b: 0x00c0, 0x446c: 0x00c0, 0x446d: 0x00c0, + 0x4470: 0x00c3, 0x4471: 0x00c3, 0x4472: 0x00c3, 0x4473: 0x00c3, 0x4474: 0x00c3, 0x4475: 0x0080, + // Block 0x112, offset 0x4480 + 0x4480: 0x00c0, 0x4481: 0x00c0, 0x4482: 0x00c0, 0x4483: 0x00c0, 0x4484: 0x00c0, 0x4485: 0x00c0, + 0x4486: 0x00c0, 0x4487: 0x00c0, 0x4488: 0x00c0, 0x4489: 0x00c0, 0x448a: 0x00c0, 0x448b: 0x00c0, + 0x448c: 0x00c0, 0x448d: 0x00c0, 0x448e: 0x00c0, 0x448f: 0x00c0, 0x4490: 0x00c0, 0x4491: 0x00c0, + 0x4492: 0x00c0, 0x4493: 0x00c0, 0x4494: 0x00c0, 0x4495: 0x00c0, 0x4496: 0x00c0, 0x4497: 0x00c0, + 0x4498: 0x00c0, 0x4499: 0x00c0, 0x449a: 0x00c0, 0x449b: 0x00c0, 0x449c: 0x00c0, 0x449d: 0x00c0, + 0x449e: 0x00c0, 0x449f: 0x00c0, 0x44a0: 0x00c0, 0x44a1: 0x00c0, 0x44a2: 0x00c0, 0x44a3: 0x00c0, + 0x44a4: 0x00c0, 0x44a5: 0x00c0, 0x44a6: 0x00c0, 0x44a7: 0x00c0, 0x44a8: 0x00c0, 0x44a9: 0x00c0, + 0x44aa: 0x00c0, 0x44ab: 0x00c0, 0x44ac: 0x00c0, 0x44ad: 0x00c0, 0x44ae: 0x00c0, 0x44af: 0x00c0, + 0x44b0: 0x00c3, 0x44b1: 0x00c3, 0x44b2: 0x00c3, 0x44b3: 0x00c3, 0x44b4: 0x00c3, 0x44b5: 0x00c3, + 0x44b6: 0x00c3, 0x44b7: 0x0080, 0x44b8: 0x0080, 0x44b9: 0x0080, 0x44ba: 0x0080, 0x44bb: 0x0080, + 0x44bc: 0x0080, 0x44bd: 0x0080, 0x44be: 0x0080, 0x44bf: 0x0080, + // Block 0x113, offset 0x44c0 + 0x44c0: 0x00c0, 0x44c1: 0x00c0, 0x44c2: 0x00c0, 0x44c3: 0x00c0, 0x44c4: 0x0080, 0x44c5: 0x0080, + 0x44d0: 0x00c0, 0x44d1: 0x00c0, + 0x44d2: 0x00c0, 0x44d3: 0x00c0, 0x44d4: 0x00c0, 0x44d5: 0x00c0, 0x44d6: 0x00c0, 0x44d7: 0x00c0, + 0x44d8: 0x00c0, 0x44d9: 0x00c0, 0x44db: 0x0080, 0x44dc: 0x0080, 0x44dd: 0x0080, + 0x44de: 0x0080, 0x44df: 0x0080, 0x44e0: 0x0080, 0x44e1: 0x0080, 0x44e3: 0x00c0, + 0x44e4: 0x00c0, 0x44e5: 0x00c0, 0x44e6: 0x00c0, 0x44e7: 0x00c0, 0x44e8: 0x00c0, 0x44e9: 0x00c0, + 0x44ea: 0x00c0, 0x44eb: 0x00c0, 0x44ec: 0x00c0, 0x44ed: 0x00c0, 0x44ee: 0x00c0, 0x44ef: 0x00c0, + 0x44f0: 0x00c0, 0x44f1: 0x00c0, 0x44f2: 0x00c0, 0x44f3: 0x00c0, 0x44f4: 0x00c0, 0x44f5: 0x00c0, + 0x44f6: 0x00c0, 0x44f7: 0x00c0, + 0x44fd: 0x00c0, 0x44fe: 0x00c0, 0x44ff: 0x00c0, + // Block 0x114, offset 0x4500 + 0x4500: 0x00c0, 0x4501: 0x00c0, 0x4502: 0x00c0, 0x4503: 0x00c0, 0x4504: 0x00c0, 0x4505: 0x00c0, + 0x4506: 0x00c0, 0x4507: 0x00c0, 0x4508: 0x00c0, 0x4509: 0x00c0, 0x450a: 0x00c0, 0x450b: 0x00c0, + 0x450c: 0x00c0, 0x450d: 0x00c0, 0x450e: 0x00c0, 0x450f: 0x00c0, + // Block 0x115, offset 0x4540 + 0x4540: 0x0080, 0x4541: 0x0080, 0x4542: 0x0080, 0x4543: 0x0080, 0x4544: 0x0080, 0x4545: 0x0080, + 0x4546: 0x0080, 0x4547: 0x0080, 0x4548: 0x0080, 0x4549: 0x0080, 0x454a: 0x0080, 0x454b: 0x0080, + 0x454c: 0x0080, 0x454d: 0x0080, 0x454e: 0x0080, 0x454f: 0x0080, 0x4550: 0x0080, 0x4551: 0x0080, + 0x4552: 0x0080, 0x4553: 0x0080, 0x4554: 0x0080, 0x4555: 0x0080, 0x4556: 0x0080, 0x4557: 0x0080, + 0x4558: 0x0080, 0x4559: 0x0080, 0x455a: 0x0080, + // Block 0x116, offset 0x4580 + 0x4580: 0x00c0, 0x4581: 0x00c0, 0x4582: 0x00c0, 0x4583: 0x00c0, 0x4584: 0x00c0, + 0x4590: 0x00c0, 0x4591: 0x00c0, + 0x4592: 0x00c0, 0x4593: 0x00c0, 0x4594: 0x00c0, 0x4595: 0x00c0, 0x4596: 0x00c0, 0x4597: 0x00c0, + 0x4598: 0x00c0, 0x4599: 0x00c0, 0x459a: 0x00c0, 0x459b: 0x00c0, 0x459c: 0x00c0, 0x459d: 0x00c0, + 0x459e: 0x00c0, 0x459f: 0x00c0, 0x45a0: 0x00c0, 0x45a1: 0x00c0, 0x45a2: 0x00c0, 0x45a3: 0x00c0, + 0x45a4: 0x00c0, 0x45a5: 0x00c0, 0x45a6: 0x00c0, 0x45a7: 0x00c0, 0x45a8: 0x00c0, 0x45a9: 0x00c0, + 0x45aa: 0x00c0, 0x45ab: 0x00c0, 0x45ac: 0x00c0, 0x45ad: 0x00c0, 0x45ae: 0x00c0, 0x45af: 0x00c0, + 0x45b0: 0x00c0, 0x45b1: 0x00c0, 0x45b2: 0x00c0, 0x45b3: 0x00c0, 0x45b4: 0x00c0, 0x45b5: 0x00c0, + 0x45b6: 0x00c0, 0x45b7: 0x00c0, 0x45b8: 0x00c0, 0x45b9: 0x00c0, 0x45ba: 0x00c0, 0x45bb: 0x00c0, + 0x45bc: 0x00c0, 0x45bd: 0x00c0, 0x45be: 0x00c0, + // Block 0x117, offset 0x45c0 + 0x45cf: 0x00c3, 0x45d0: 0x00c3, 0x45d1: 0x00c3, + 0x45d2: 0x00c3, 0x45d3: 0x00c0, 0x45d4: 0x00c0, 0x45d5: 0x00c0, 0x45d6: 0x00c0, 0x45d7: 0x00c0, + 0x45d8: 0x00c0, 0x45d9: 0x00c0, 0x45da: 0x00c0, 0x45db: 0x00c0, 0x45dc: 0x00c0, 0x45dd: 0x00c0, + 0x45de: 0x00c0, 0x45df: 0x00c0, + // Block 0x118, offset 0x4600 + 0x4620: 0x00c0, 0x4621: 0x00c0, + // Block 0x119, offset 0x4640 + 0x4640: 0x00c0, 0x4641: 0x00c0, 0x4642: 0x00c0, 0x4643: 0x00c0, 0x4644: 0x00c0, 0x4645: 0x00c0, + 0x4646: 0x00c0, 0x4647: 0x00c0, 0x4648: 0x00c0, 0x4649: 0x00c0, 0x464a: 0x00c0, 0x464b: 0x00c0, + 0x464c: 0x00c0, 0x464d: 0x00c0, 0x464e: 0x00c0, 0x464f: 0x00c0, 0x4650: 0x00c0, 0x4651: 0x00c0, + 0x4652: 0x00c0, 0x4653: 0x00c0, 0x4654: 0x00c0, 0x4655: 0x00c0, 0x4656: 0x00c0, 0x4657: 0x00c0, + 0x4658: 0x00c0, 0x4659: 0x00c0, 0x465a: 0x00c0, 0x465b: 0x00c0, 0x465c: 0x00c0, 0x465d: 0x00c0, + 0x465e: 0x00c0, 0x465f: 0x00c0, 0x4660: 0x00c0, 0x4661: 0x00c0, 0x4662: 0x00c0, 0x4663: 0x00c0, + 0x4664: 0x00c0, 0x4665: 0x00c0, 0x4666: 0x00c0, 0x4667: 0x00c0, 0x4668: 0x00c0, 0x4669: 0x00c0, + 0x466a: 0x00c0, 0x466b: 0x00c0, 0x466c: 0x00c0, 0x466d: 0x00c0, 0x466e: 0x00c0, 0x466f: 0x00c0, + 0x4670: 0x00c0, 0x4671: 0x00c0, + // Block 0x11a, offset 0x4680 + 0x4680: 0x00cc, 0x4681: 0x00cc, 0x4682: 0x00cc, 0x4683: 0x00cc, 0x4684: 0x00cc, 0x4685: 0x00cc, + 0x4686: 0x00cc, 0x4687: 0x00cc, 0x4688: 0x00cc, 0x4689: 0x00cc, 0x468a: 0x00cc, 0x468b: 0x00cc, + 0x468c: 0x00cc, 0x468d: 0x00cc, 0x468e: 0x00cc, 0x468f: 0x00cc, 0x4690: 0x00cc, 0x4691: 0x00cc, + 0x4692: 0x00cc, 0x4693: 0x00cc, 0x4694: 0x00cc, 0x4695: 0x00cc, 0x4696: 0x00cc, 0x4697: 0x00cc, + 0x4698: 0x00cc, 0x4699: 0x00cc, 0x469a: 0x00cc, 0x469b: 0x00cc, 0x469c: 0x00cc, 0x469d: 0x00cc, + 0x469e: 0x00cc, + // Block 0x11b, offset 0x46c0 + 0x46f0: 0x00c0, 0x46f1: 0x00c0, 0x46f2: 0x00c0, 0x46f3: 0x00c0, 0x46f4: 0x00c0, 0x46f5: 0x00c0, + 0x46f6: 0x00c0, 0x46f7: 0x00c0, 0x46f8: 0x00c0, 0x46f9: 0x00c0, 0x46fa: 0x00c0, 0x46fb: 0x00c0, + 0x46fc: 0x00c0, 0x46fd: 0x00c0, 0x46fe: 0x00c0, 0x46ff: 0x00c0, + // Block 0x11c, offset 0x4700 + 0x4700: 0x00c0, 0x4701: 0x00c0, 0x4702: 0x00c0, 0x4703: 0x00c0, 0x4704: 0x00c0, 0x4705: 0x00c0, + 0x4706: 0x00c0, 0x4707: 0x00c0, 0x4708: 0x00c0, 0x4709: 0x00c0, 0x470a: 0x00c0, 0x470b: 0x00c0, + 0x470c: 0x00c0, 0x470d: 0x00c0, 0x470e: 0x00c0, 0x470f: 0x00c0, 0x4710: 0x00c0, 0x4711: 0x00c0, + 0x4712: 0x00c0, 0x4713: 0x00c0, 0x4714: 0x00c0, 0x4715: 0x00c0, 0x4716: 0x00c0, 0x4717: 0x00c0, + 0x4718: 0x00c0, 0x4719: 0x00c0, 0x471a: 0x00c0, 0x471b: 0x00c0, 0x471c: 0x00c0, 0x471d: 0x00c0, + 0x471e: 0x00c0, 0x471f: 0x00c0, 0x4720: 0x00c0, 0x4721: 0x00c0, 0x4722: 0x00c0, 0x4723: 0x00c0, + 0x4724: 0x00c0, 0x4725: 0x00c0, 0x4726: 0x00c0, 0x4727: 0x00c0, 0x4728: 0x00c0, 0x4729: 0x00c0, + 0x472a: 0x00c0, 0x472b: 0x00c0, 0x472c: 0x00c0, 0x472d: 0x00c0, 0x472e: 0x00c0, 0x472f: 0x00c0, + 0x4730: 0x00c0, 0x4731: 0x00c0, 0x4732: 0x00c0, 0x4733: 0x00c0, 0x4734: 0x00c0, 0x4735: 0x00c0, + 0x4736: 0x00c0, 0x4737: 0x00c0, 0x4738: 0x00c0, 0x4739: 0x00c0, 0x473a: 0x00c0, 0x473b: 0x00c0, + // Block 0x11d, offset 0x4740 + 0x4740: 0x00c0, 0x4741: 0x00c0, 0x4742: 0x00c0, 0x4743: 0x00c0, 0x4744: 0x00c0, 0x4745: 0x00c0, + 0x4746: 0x00c0, 0x4747: 0x00c0, 0x4748: 0x00c0, 0x4749: 0x00c0, 0x474a: 0x00c0, 0x474b: 0x00c0, + 0x474c: 0x00c0, 0x474d: 0x00c0, 0x474e: 0x00c0, 0x474f: 0x00c0, 0x4750: 0x00c0, 0x4751: 0x00c0, + 0x4752: 0x00c0, 0x4753: 0x00c0, 0x4754: 0x00c0, 0x4755: 0x00c0, 0x4756: 0x00c0, 0x4757: 0x00c0, + 0x4758: 0x00c0, 0x4759: 0x00c0, 0x475a: 0x00c0, 0x475b: 0x00c0, 0x475c: 0x00c0, 0x475d: 0x00c0, + 0x475e: 0x00c0, 0x475f: 0x00c0, 0x4760: 0x00c0, 0x4761: 0x00c0, 0x4762: 0x00c0, 0x4763: 0x00c0, + 0x4764: 0x00c0, 0x4765: 0x00c0, 0x4766: 0x00c0, 0x4767: 0x00c0, 0x4768: 0x00c0, 0x4769: 0x00c0, + 0x476a: 0x00c0, + 0x4770: 0x00c0, 0x4771: 0x00c0, 0x4772: 0x00c0, 0x4773: 0x00c0, 0x4774: 0x00c0, 0x4775: 0x00c0, + 0x4776: 0x00c0, 0x4777: 0x00c0, 0x4778: 0x00c0, 0x4779: 0x00c0, 0x477a: 0x00c0, 0x477b: 0x00c0, + 0x477c: 0x00c0, + // Block 0x11e, offset 0x4780 + 0x4780: 0x00c0, 0x4781: 0x00c0, 0x4782: 0x00c0, 0x4783: 0x00c0, 0x4784: 0x00c0, 0x4785: 0x00c0, + 0x4786: 0x00c0, 0x4787: 0x00c0, 0x4788: 0x00c0, + 0x4790: 0x00c0, 0x4791: 0x00c0, + 0x4792: 0x00c0, 0x4793: 0x00c0, 0x4794: 0x00c0, 0x4795: 0x00c0, 0x4796: 0x00c0, 0x4797: 0x00c0, + 0x4798: 0x00c0, 0x4799: 0x00c0, 0x479c: 0x0080, 0x479d: 0x00c3, + 0x479e: 0x00c3, 0x479f: 0x0080, 0x47a0: 0x0040, 0x47a1: 0x0040, 0x47a2: 0x0040, 0x47a3: 0x0040, + // Block 0x11f, offset 0x47c0 + 0x47c0: 0x0080, 0x47c1: 0x0080, 0x47c2: 0x0080, 0x47c3: 0x0080, 0x47c4: 0x0080, 0x47c5: 0x0080, + 0x47c6: 0x0080, 0x47c7: 0x0080, 0x47c8: 0x0080, 0x47c9: 0x0080, 0x47ca: 0x0080, 0x47cb: 0x0080, + 0x47cc: 0x0080, 0x47cd: 0x0080, 0x47ce: 0x0080, 0x47cf: 0x0080, 0x47d0: 0x0080, 0x47d1: 0x0080, + 0x47d2: 0x0080, 0x47d3: 0x0080, 0x47d4: 0x0080, 0x47d5: 0x0080, 0x47d6: 0x0080, 0x47d7: 0x0080, + 0x47d8: 0x0080, 0x47d9: 0x0080, 0x47da: 0x0080, 0x47db: 0x0080, 0x47dc: 0x0080, 0x47dd: 0x0080, + 0x47de: 0x0080, 0x47df: 0x0080, 0x47e0: 0x0080, 0x47e1: 0x0080, 0x47e2: 0x0080, 0x47e3: 0x0080, + 0x47e4: 0x0080, 0x47e5: 0x0080, 0x47e6: 0x0080, 0x47e7: 0x0080, 0x47e8: 0x0080, 0x47e9: 0x0080, + 0x47ea: 0x0080, 0x47eb: 0x0080, 0x47ec: 0x0080, 0x47ed: 0x0080, 0x47ee: 0x0080, 0x47ef: 0x0080, + 0x47f0: 0x0080, 0x47f1: 0x0080, 0x47f2: 0x0080, 0x47f3: 0x0080, 0x47f4: 0x0080, 0x47f5: 0x0080, + // Block 0x120, offset 0x4800 + 0x4800: 0x0080, 0x4801: 0x0080, 0x4802: 0x0080, 0x4803: 0x0080, 0x4804: 0x0080, 0x4805: 0x0080, + 0x4806: 0x0080, 0x4807: 0x0080, 0x4808: 0x0080, 0x4809: 0x0080, 0x480a: 0x0080, 0x480b: 0x0080, + 0x480c: 0x0080, 0x480d: 0x0080, 0x480e: 0x0080, 0x480f: 0x0080, 0x4810: 0x0080, 0x4811: 0x0080, + 0x4812: 0x0080, 0x4813: 0x0080, 0x4814: 0x0080, 0x4815: 0x0080, 0x4816: 0x0080, 0x4817: 0x0080, + 0x4818: 0x0080, 0x4819: 0x0080, 0x481a: 0x0080, 0x481b: 0x0080, 0x481c: 0x0080, 0x481d: 0x0080, + 0x481e: 0x0080, 0x481f: 0x0080, 0x4820: 0x0080, 0x4821: 0x0080, 0x4822: 0x0080, 0x4823: 0x0080, + 0x4824: 0x0080, 0x4825: 0x0080, 0x4826: 0x0080, 0x4829: 0x0080, + 0x482a: 0x0080, 0x482b: 0x0080, 0x482c: 0x0080, 0x482d: 0x0080, 0x482e: 0x0080, 0x482f: 0x0080, + 0x4830: 0x0080, 0x4831: 0x0080, 0x4832: 0x0080, 0x4833: 0x0080, 0x4834: 0x0080, 0x4835: 0x0080, + 0x4836: 0x0080, 0x4837: 0x0080, 0x4838: 0x0080, 0x4839: 0x0080, 0x483a: 0x0080, 0x483b: 0x0080, + 0x483c: 0x0080, 0x483d: 0x0080, 0x483e: 0x0080, 0x483f: 0x0080, + // Block 0x121, offset 0x4840 + 0x4840: 0x0080, 0x4841: 0x0080, 0x4842: 0x0080, 0x4843: 0x0080, 0x4844: 0x0080, 0x4845: 0x0080, + 0x4846: 0x0080, 0x4847: 0x0080, 0x4848: 0x0080, 0x4849: 0x0080, 0x484a: 0x0080, 0x484b: 0x0080, + 0x484c: 0x0080, 0x484d: 0x0080, 0x484e: 0x0080, 0x484f: 0x0080, 0x4850: 0x0080, 0x4851: 0x0080, + 0x4852: 0x0080, 0x4853: 0x0080, 0x4854: 0x0080, 0x4855: 0x0080, 0x4856: 0x0080, 0x4857: 0x0080, + 0x4858: 0x0080, 0x4859: 0x0080, 0x485a: 0x0080, 0x485b: 0x0080, 0x485c: 0x0080, 0x485d: 0x0080, + 0x485e: 0x0080, 0x485f: 0x0080, 0x4860: 0x0080, 0x4861: 0x0080, 0x4862: 0x0080, 0x4863: 0x0080, + 0x4864: 0x0080, 0x4865: 0x00c0, 0x4866: 0x00c0, 0x4867: 0x00c3, 0x4868: 0x00c3, 0x4869: 0x00c3, + 0x486a: 0x0080, 0x486b: 0x0080, 0x486c: 0x0080, 0x486d: 0x00c0, 0x486e: 0x00c0, 0x486f: 0x00c0, + 0x4870: 0x00c0, 0x4871: 0x00c0, 0x4872: 0x00c0, 0x4873: 0x0040, 0x4874: 0x0040, 0x4875: 0x0040, + 0x4876: 0x0040, 0x4877: 0x0040, 0x4878: 0x0040, 0x4879: 0x0040, 0x487a: 0x0040, 0x487b: 0x00c3, + 0x487c: 0x00c3, 0x487d: 0x00c3, 0x487e: 0x00c3, 0x487f: 0x00c3, + // Block 0x122, offset 0x4880 + 0x4880: 0x00c3, 0x4881: 0x00c3, 0x4882: 0x00c3, 0x4883: 0x0080, 0x4884: 0x0080, 0x4885: 0x00c3, + 0x4886: 0x00c3, 0x4887: 0x00c3, 0x4888: 0x00c3, 0x4889: 0x00c3, 0x488a: 0x00c3, 0x488b: 0x00c3, + 0x488c: 0x0080, 0x488d: 0x0080, 0x488e: 0x0080, 0x488f: 0x0080, 0x4890: 0x0080, 0x4891: 0x0080, + 0x4892: 0x0080, 0x4893: 0x0080, 0x4894: 0x0080, 0x4895: 0x0080, 0x4896: 0x0080, 0x4897: 0x0080, + 0x4898: 0x0080, 0x4899: 0x0080, 0x489a: 0x0080, 0x489b: 0x0080, 0x489c: 0x0080, 0x489d: 0x0080, + 0x489e: 0x0080, 0x489f: 0x0080, 0x48a0: 0x0080, 0x48a1: 0x0080, 0x48a2: 0x0080, 0x48a3: 0x0080, + 0x48a4: 0x0080, 0x48a5: 0x0080, 0x48a6: 0x0080, 0x48a7: 0x0080, 0x48a8: 0x0080, 0x48a9: 0x0080, + 0x48aa: 0x00c3, 0x48ab: 0x00c3, 0x48ac: 0x00c3, 0x48ad: 0x00c3, 0x48ae: 0x0080, 0x48af: 0x0080, + 0x48b0: 0x0080, 0x48b1: 0x0080, 0x48b2: 0x0080, 0x48b3: 0x0080, 0x48b4: 0x0080, 0x48b5: 0x0080, + 0x48b6: 0x0080, 0x48b7: 0x0080, 0x48b8: 0x0080, 0x48b9: 0x0080, 0x48ba: 0x0080, 0x48bb: 0x0080, + 0x48bc: 0x0080, 0x48bd: 0x0080, 0x48be: 0x0080, 0x48bf: 0x0080, + // Block 0x123, offset 0x48c0 + 0x48c0: 0x0080, 0x48c1: 0x0080, 0x48c2: 0x0080, 0x48c3: 0x0080, 0x48c4: 0x0080, 0x48c5: 0x0080, + 0x48c6: 0x0080, 0x48c7: 0x0080, 0x48c8: 0x0080, 0x48c9: 0x0080, 0x48ca: 0x0080, 0x48cb: 0x0080, + 0x48cc: 0x0080, 0x48cd: 0x0080, 0x48ce: 0x0080, 0x48cf: 0x0080, 0x48d0: 0x0080, 0x48d1: 0x0080, + 0x48d2: 0x0080, 0x48d3: 0x0080, 0x48d4: 0x0080, 0x48d5: 0x0080, 0x48d6: 0x0080, 0x48d7: 0x0080, + 0x48d8: 0x0080, 0x48d9: 0x0080, 0x48da: 0x0080, 0x48db: 0x0080, 0x48dc: 0x0080, 0x48dd: 0x0080, + 0x48de: 0x0080, 0x48df: 0x0080, 0x48e0: 0x0080, 0x48e1: 0x0080, 0x48e2: 0x0080, 0x48e3: 0x0080, + 0x48e4: 0x0080, 0x48e5: 0x0080, 0x48e6: 0x0080, 0x48e7: 0x0080, 0x48e8: 0x0080, + // Block 0x124, offset 0x4900 + 0x4900: 0x0088, 0x4901: 0x0088, 0x4902: 0x00c9, 0x4903: 0x00c9, 0x4904: 0x00c9, 0x4905: 0x0088, + // Block 0x125, offset 0x4940 + 0x4960: 0x0080, 0x4961: 0x0080, 0x4962: 0x0080, 0x4963: 0x0080, + 0x4964: 0x0080, 0x4965: 0x0080, 0x4966: 0x0080, 0x4967: 0x0080, 0x4968: 0x0080, 0x4969: 0x0080, + 0x496a: 0x0080, 0x496b: 0x0080, 0x496c: 0x0080, 0x496d: 0x0080, 0x496e: 0x0080, 0x496f: 0x0080, + 0x4970: 0x0080, 0x4971: 0x0080, 0x4972: 0x0080, 0x4973: 0x0080, + // Block 0x126, offset 0x4980 + 0x4980: 0x0080, 0x4981: 0x0080, 0x4982: 0x0080, 0x4983: 0x0080, 0x4984: 0x0080, 0x4985: 0x0080, + 0x4986: 0x0080, 0x4987: 0x0080, 0x4988: 0x0080, 0x4989: 0x0080, 0x498a: 0x0080, 0x498b: 0x0080, + 0x498c: 0x0080, 0x498d: 0x0080, 0x498e: 0x0080, 0x498f: 0x0080, 0x4990: 0x0080, 0x4991: 0x0080, + 0x4992: 0x0080, 0x4993: 0x0080, 0x4994: 0x0080, 0x4995: 0x0080, 0x4996: 0x0080, + 0x49a0: 0x0080, 0x49a1: 0x0080, 0x49a2: 0x0080, 0x49a3: 0x0080, + 0x49a4: 0x0080, 0x49a5: 0x0080, 0x49a6: 0x0080, 0x49a7: 0x0080, 0x49a8: 0x0080, 0x49a9: 0x0080, + 0x49aa: 0x0080, 0x49ab: 0x0080, 0x49ac: 0x0080, 0x49ad: 0x0080, 0x49ae: 0x0080, 0x49af: 0x0080, + 0x49b0: 0x0080, 0x49b1: 0x0080, 0x49b2: 0x0080, 0x49b3: 0x0080, 0x49b4: 0x0080, 0x49b5: 0x0080, + 0x49b6: 0x0080, 0x49b7: 0x0080, 0x49b8: 0x0080, + // Block 0x127, offset 0x49c0 + 0x49c0: 0x0080, 0x49c1: 0x0080, 0x49c2: 0x0080, 0x49c3: 0x0080, 0x49c4: 0x0080, 0x49c5: 0x0080, + 0x49c6: 0x0080, 0x49c7: 0x0080, 0x49c8: 0x0080, 0x49c9: 0x0080, 0x49ca: 0x0080, 0x49cb: 0x0080, + 0x49cc: 0x0080, 0x49cd: 0x0080, 0x49ce: 0x0080, 0x49cf: 0x0080, 0x49d0: 0x0080, 0x49d1: 0x0080, + 0x49d2: 0x0080, 0x49d3: 0x0080, 0x49d4: 0x0080, 0x49d6: 0x0080, 0x49d7: 0x0080, + 0x49d8: 0x0080, 0x49d9: 0x0080, 0x49da: 0x0080, 0x49db: 0x0080, 0x49dc: 0x0080, 0x49dd: 0x0080, + 0x49de: 0x0080, 0x49df: 0x0080, 0x49e0: 0x0080, 0x49e1: 0x0080, 0x49e2: 0x0080, 0x49e3: 0x0080, + 0x49e4: 0x0080, 0x49e5: 0x0080, 0x49e6: 0x0080, 0x49e7: 0x0080, 0x49e8: 0x0080, 0x49e9: 0x0080, + 0x49ea: 0x0080, 0x49eb: 0x0080, 0x49ec: 0x0080, 0x49ed: 0x0080, 0x49ee: 0x0080, 0x49ef: 0x0080, + 0x49f0: 0x0080, 0x49f1: 0x0080, 0x49f2: 0x0080, 0x49f3: 0x0080, 0x49f4: 0x0080, 0x49f5: 0x0080, + 0x49f6: 0x0080, 0x49f7: 0x0080, 0x49f8: 0x0080, 0x49f9: 0x0080, 0x49fa: 0x0080, 0x49fb: 0x0080, + 0x49fc: 0x0080, 0x49fd: 0x0080, 0x49fe: 0x0080, 0x49ff: 0x0080, + // Block 0x128, offset 0x4a00 + 0x4a00: 0x0080, 0x4a01: 0x0080, 0x4a02: 0x0080, 0x4a03: 0x0080, 0x4a04: 0x0080, 0x4a05: 0x0080, + 0x4a06: 0x0080, 0x4a07: 0x0080, 0x4a08: 0x0080, 0x4a09: 0x0080, 0x4a0a: 0x0080, 0x4a0b: 0x0080, + 0x4a0c: 0x0080, 0x4a0d: 0x0080, 0x4a0e: 0x0080, 0x4a0f: 0x0080, 0x4a10: 0x0080, 0x4a11: 0x0080, + 0x4a12: 0x0080, 0x4a13: 0x0080, 0x4a14: 0x0080, 0x4a15: 0x0080, 0x4a16: 0x0080, 0x4a17: 0x0080, + 0x4a18: 0x0080, 0x4a19: 0x0080, 0x4a1a: 0x0080, 0x4a1b: 0x0080, 0x4a1c: 0x0080, + 0x4a1e: 0x0080, 0x4a1f: 0x0080, 0x4a22: 0x0080, + 0x4a25: 0x0080, 0x4a26: 0x0080, 0x4a29: 0x0080, + 0x4a2a: 0x0080, 0x4a2b: 0x0080, 0x4a2c: 0x0080, 0x4a2e: 0x0080, 0x4a2f: 0x0080, + 0x4a30: 0x0080, 0x4a31: 0x0080, 0x4a32: 0x0080, 0x4a33: 0x0080, 0x4a34: 0x0080, 0x4a35: 0x0080, + 0x4a36: 0x0080, 0x4a37: 0x0080, 0x4a38: 0x0080, 0x4a39: 0x0080, 0x4a3b: 0x0080, + 0x4a3d: 0x0080, 0x4a3e: 0x0080, 0x4a3f: 0x0080, + // Block 0x129, offset 0x4a40 + 0x4a40: 0x0080, 0x4a41: 0x0080, 0x4a42: 0x0080, 0x4a43: 0x0080, 0x4a45: 0x0080, + 0x4a46: 0x0080, 0x4a47: 0x0080, 0x4a48: 0x0080, 0x4a49: 0x0080, 0x4a4a: 0x0080, 0x4a4b: 0x0080, + 0x4a4c: 0x0080, 0x4a4d: 0x0080, 0x4a4e: 0x0080, 0x4a4f: 0x0080, 0x4a50: 0x0080, 0x4a51: 0x0080, + 0x4a52: 0x0080, 0x4a53: 0x0080, 0x4a54: 0x0080, 0x4a55: 0x0080, 0x4a56: 0x0080, 0x4a57: 0x0080, + 0x4a58: 0x0080, 0x4a59: 0x0080, 0x4a5a: 0x0080, 0x4a5b: 0x0080, 0x4a5c: 0x0080, 0x4a5d: 0x0080, + 0x4a5e: 0x0080, 0x4a5f: 0x0080, 0x4a60: 0x0080, 0x4a61: 0x0080, 0x4a62: 0x0080, 0x4a63: 0x0080, + 0x4a64: 0x0080, 0x4a65: 0x0080, 0x4a66: 0x0080, 0x4a67: 0x0080, 0x4a68: 0x0080, 0x4a69: 0x0080, + 0x4a6a: 0x0080, 0x4a6b: 0x0080, 0x4a6c: 0x0080, 0x4a6d: 0x0080, 0x4a6e: 0x0080, 0x4a6f: 0x0080, + 0x4a70: 0x0080, 0x4a71: 0x0080, 0x4a72: 0x0080, 0x4a73: 0x0080, 0x4a74: 0x0080, 0x4a75: 0x0080, + 0x4a76: 0x0080, 0x4a77: 0x0080, 0x4a78: 0x0080, 0x4a79: 0x0080, 0x4a7a: 0x0080, 0x4a7b: 0x0080, + 0x4a7c: 0x0080, 0x4a7d: 0x0080, 0x4a7e: 0x0080, 0x4a7f: 0x0080, + // Block 0x12a, offset 0x4a80 + 0x4a80: 0x0080, 0x4a81: 0x0080, 0x4a82: 0x0080, 0x4a83: 0x0080, 0x4a84: 0x0080, 0x4a85: 0x0080, + 0x4a87: 0x0080, 0x4a88: 0x0080, 0x4a89: 0x0080, 0x4a8a: 0x0080, + 0x4a8d: 0x0080, 0x4a8e: 0x0080, 0x4a8f: 0x0080, 0x4a90: 0x0080, 0x4a91: 0x0080, + 0x4a92: 0x0080, 0x4a93: 0x0080, 0x4a94: 0x0080, 0x4a96: 0x0080, 0x4a97: 0x0080, + 0x4a98: 0x0080, 0x4a99: 0x0080, 0x4a9a: 0x0080, 0x4a9b: 0x0080, 0x4a9c: 0x0080, + 0x4a9e: 0x0080, 0x4a9f: 0x0080, 0x4aa0: 0x0080, 0x4aa1: 0x0080, 0x4aa2: 0x0080, 0x4aa3: 0x0080, + 0x4aa4: 0x0080, 0x4aa5: 0x0080, 0x4aa6: 0x0080, 0x4aa7: 0x0080, 0x4aa8: 0x0080, 0x4aa9: 0x0080, + 0x4aaa: 0x0080, 0x4aab: 0x0080, 0x4aac: 0x0080, 0x4aad: 0x0080, 0x4aae: 0x0080, 0x4aaf: 0x0080, + 0x4ab0: 0x0080, 0x4ab1: 0x0080, 0x4ab2: 0x0080, 0x4ab3: 0x0080, 0x4ab4: 0x0080, 0x4ab5: 0x0080, + 0x4ab6: 0x0080, 0x4ab7: 0x0080, 0x4ab8: 0x0080, 0x4ab9: 0x0080, 0x4abb: 0x0080, + 0x4abc: 0x0080, 0x4abd: 0x0080, 0x4abe: 0x0080, + // Block 0x12b, offset 0x4ac0 + 0x4ac0: 0x0080, 0x4ac1: 0x0080, 0x4ac2: 0x0080, 0x4ac3: 0x0080, 0x4ac4: 0x0080, + 0x4ac6: 0x0080, 0x4aca: 0x0080, 0x4acb: 0x0080, + 0x4acc: 0x0080, 0x4acd: 0x0080, 0x4ace: 0x0080, 0x4acf: 0x0080, 0x4ad0: 0x0080, + 0x4ad2: 0x0080, 0x4ad3: 0x0080, 0x4ad4: 0x0080, 0x4ad5: 0x0080, 0x4ad6: 0x0080, 0x4ad7: 0x0080, + 0x4ad8: 0x0080, 0x4ad9: 0x0080, 0x4ada: 0x0080, 0x4adb: 0x0080, 0x4adc: 0x0080, 0x4add: 0x0080, + 0x4ade: 0x0080, 0x4adf: 0x0080, 0x4ae0: 0x0080, 0x4ae1: 0x0080, 0x4ae2: 0x0080, 0x4ae3: 0x0080, + 0x4ae4: 0x0080, 0x4ae5: 0x0080, 0x4ae6: 0x0080, 0x4ae7: 0x0080, 0x4ae8: 0x0080, 0x4ae9: 0x0080, + 0x4aea: 0x0080, 0x4aeb: 0x0080, 0x4aec: 0x0080, 0x4aed: 0x0080, 0x4aee: 0x0080, 0x4aef: 0x0080, + 0x4af0: 0x0080, 0x4af1: 0x0080, 0x4af2: 0x0080, 0x4af3: 0x0080, 0x4af4: 0x0080, 0x4af5: 0x0080, + 0x4af6: 0x0080, 0x4af7: 0x0080, 0x4af8: 0x0080, 0x4af9: 0x0080, 0x4afa: 0x0080, 0x4afb: 0x0080, + 0x4afc: 0x0080, 0x4afd: 0x0080, 0x4afe: 0x0080, 0x4aff: 0x0080, + // Block 0x12c, offset 0x4b00 + 0x4b00: 0x0080, 0x4b01: 0x0080, 0x4b02: 0x0080, 0x4b03: 0x0080, 0x4b04: 0x0080, 0x4b05: 0x0080, + 0x4b06: 0x0080, 0x4b07: 0x0080, 0x4b08: 0x0080, 0x4b09: 0x0080, 0x4b0a: 0x0080, 0x4b0b: 0x0080, + 0x4b0c: 0x0080, 0x4b0d: 0x0080, 0x4b0e: 0x0080, 0x4b0f: 0x0080, 0x4b10: 0x0080, 0x4b11: 0x0080, + 0x4b12: 0x0080, 0x4b13: 0x0080, 0x4b14: 0x0080, 0x4b15: 0x0080, 0x4b16: 0x0080, 0x4b17: 0x0080, + 0x4b18: 0x0080, 0x4b19: 0x0080, 0x4b1a: 0x0080, 0x4b1b: 0x0080, 0x4b1c: 0x0080, 0x4b1d: 0x0080, + 0x4b1e: 0x0080, 0x4b1f: 0x0080, 0x4b20: 0x0080, 0x4b21: 0x0080, 0x4b22: 0x0080, 0x4b23: 0x0080, + 0x4b24: 0x0080, 0x4b25: 0x0080, 0x4b28: 0x0080, 0x4b29: 0x0080, + 0x4b2a: 0x0080, 0x4b2b: 0x0080, 0x4b2c: 0x0080, 0x4b2d: 0x0080, 0x4b2e: 0x0080, 0x4b2f: 0x0080, + 0x4b30: 0x0080, 0x4b31: 0x0080, 0x4b32: 0x0080, 0x4b33: 0x0080, 0x4b34: 0x0080, 0x4b35: 0x0080, + 0x4b36: 0x0080, 0x4b37: 0x0080, 0x4b38: 0x0080, 0x4b39: 0x0080, 0x4b3a: 0x0080, 0x4b3b: 0x0080, + 0x4b3c: 0x0080, 0x4b3d: 0x0080, 0x4b3e: 0x0080, 0x4b3f: 0x0080, + // Block 0x12d, offset 0x4b40 + 0x4b40: 0x0080, 0x4b41: 0x0080, 0x4b42: 0x0080, 0x4b43: 0x0080, 0x4b44: 0x0080, 0x4b45: 0x0080, + 0x4b46: 0x0080, 0x4b47: 0x0080, 0x4b48: 0x0080, 0x4b49: 0x0080, 0x4b4a: 0x0080, 0x4b4b: 0x0080, + 0x4b4e: 0x0080, 0x4b4f: 0x0080, 0x4b50: 0x0080, 0x4b51: 0x0080, + 0x4b52: 0x0080, 0x4b53: 0x0080, 0x4b54: 0x0080, 0x4b55: 0x0080, 0x4b56: 0x0080, 0x4b57: 0x0080, + 0x4b58: 0x0080, 0x4b59: 0x0080, 0x4b5a: 0x0080, 0x4b5b: 0x0080, 0x4b5c: 0x0080, 0x4b5d: 0x0080, + 0x4b5e: 0x0080, 0x4b5f: 0x0080, 0x4b60: 0x0080, 0x4b61: 0x0080, 0x4b62: 0x0080, 0x4b63: 0x0080, + 0x4b64: 0x0080, 0x4b65: 0x0080, 0x4b66: 0x0080, 0x4b67: 0x0080, 0x4b68: 0x0080, 0x4b69: 0x0080, + 0x4b6a: 0x0080, 0x4b6b: 0x0080, 0x4b6c: 0x0080, 0x4b6d: 0x0080, 0x4b6e: 0x0080, 0x4b6f: 0x0080, + 0x4b70: 0x0080, 0x4b71: 0x0080, 0x4b72: 0x0080, 0x4b73: 0x0080, 0x4b74: 0x0080, 0x4b75: 0x0080, + 0x4b76: 0x0080, 0x4b77: 0x0080, 0x4b78: 0x0080, 0x4b79: 0x0080, 0x4b7a: 0x0080, 0x4b7b: 0x0080, + 0x4b7c: 0x0080, 0x4b7d: 0x0080, 0x4b7e: 0x0080, 0x4b7f: 0x0080, + // Block 0x12e, offset 0x4b80 + 0x4b80: 0x00c3, 0x4b81: 0x00c3, 0x4b82: 0x00c3, 0x4b83: 0x00c3, 0x4b84: 0x00c3, 0x4b85: 0x00c3, + 0x4b86: 0x00c3, 0x4b87: 0x00c3, 0x4b88: 0x00c3, 0x4b89: 0x00c3, 0x4b8a: 0x00c3, 0x4b8b: 0x00c3, + 0x4b8c: 0x00c3, 0x4b8d: 0x00c3, 0x4b8e: 0x00c3, 0x4b8f: 0x00c3, 0x4b90: 0x00c3, 0x4b91: 0x00c3, + 0x4b92: 0x00c3, 0x4b93: 0x00c3, 0x4b94: 0x00c3, 0x4b95: 0x00c3, 0x4b96: 0x00c3, 0x4b97: 0x00c3, + 0x4b98: 0x00c3, 0x4b99: 0x00c3, 0x4b9a: 0x00c3, 0x4b9b: 0x00c3, 0x4b9c: 0x00c3, 0x4b9d: 0x00c3, + 0x4b9e: 0x00c3, 0x4b9f: 0x00c3, 0x4ba0: 0x00c3, 0x4ba1: 0x00c3, 0x4ba2: 0x00c3, 0x4ba3: 0x00c3, + 0x4ba4: 0x00c3, 0x4ba5: 0x00c3, 0x4ba6: 0x00c3, 0x4ba7: 0x00c3, 0x4ba8: 0x00c3, 0x4ba9: 0x00c3, + 0x4baa: 0x00c3, 0x4bab: 0x00c3, 0x4bac: 0x00c3, 0x4bad: 0x00c3, 0x4bae: 0x00c3, 0x4baf: 0x00c3, + 0x4bb0: 0x00c3, 0x4bb1: 0x00c3, 0x4bb2: 0x00c3, 0x4bb3: 0x00c3, 0x4bb4: 0x00c3, 0x4bb5: 0x00c3, + 0x4bb6: 0x00c3, 0x4bb7: 0x0080, 0x4bb8: 0x0080, 0x4bb9: 0x0080, 0x4bba: 0x0080, 0x4bbb: 0x00c3, + 0x4bbc: 0x00c3, 0x4bbd: 0x00c3, 0x4bbe: 0x00c3, 0x4bbf: 0x00c3, + // Block 0x12f, offset 0x4bc0 + 0x4bc0: 0x00c3, 0x4bc1: 0x00c3, 0x4bc2: 0x00c3, 0x4bc3: 0x00c3, 0x4bc4: 0x00c3, 0x4bc5: 0x00c3, + 0x4bc6: 0x00c3, 0x4bc7: 0x00c3, 0x4bc8: 0x00c3, 0x4bc9: 0x00c3, 0x4bca: 0x00c3, 0x4bcb: 0x00c3, + 0x4bcc: 0x00c3, 0x4bcd: 0x00c3, 0x4bce: 0x00c3, 0x4bcf: 0x00c3, 0x4bd0: 0x00c3, 0x4bd1: 0x00c3, + 0x4bd2: 0x00c3, 0x4bd3: 0x00c3, 0x4bd4: 0x00c3, 0x4bd5: 0x00c3, 0x4bd6: 0x00c3, 0x4bd7: 0x00c3, + 0x4bd8: 0x00c3, 0x4bd9: 0x00c3, 0x4bda: 0x00c3, 0x4bdb: 0x00c3, 0x4bdc: 0x00c3, 0x4bdd: 0x00c3, + 0x4bde: 0x00c3, 0x4bdf: 0x00c3, 0x4be0: 0x00c3, 0x4be1: 0x00c3, 0x4be2: 0x00c3, 0x4be3: 0x00c3, + 0x4be4: 0x00c3, 0x4be5: 0x00c3, 0x4be6: 0x00c3, 0x4be7: 0x00c3, 0x4be8: 0x00c3, 0x4be9: 0x00c3, + 0x4bea: 0x00c3, 0x4beb: 0x00c3, 0x4bec: 0x00c3, 0x4bed: 0x0080, 0x4bee: 0x0080, 0x4bef: 0x0080, + 0x4bf0: 0x0080, 0x4bf1: 0x0080, 0x4bf2: 0x0080, 0x4bf3: 0x0080, 0x4bf4: 0x0080, 0x4bf5: 0x00c3, + 0x4bf6: 0x0080, 0x4bf7: 0x0080, 0x4bf8: 0x0080, 0x4bf9: 0x0080, 0x4bfa: 0x0080, 0x4bfb: 0x0080, + 0x4bfc: 0x0080, 0x4bfd: 0x0080, 0x4bfe: 0x0080, 0x4bff: 0x0080, + // Block 0x130, offset 0x4c00 + 0x4c00: 0x0080, 0x4c01: 0x0080, 0x4c02: 0x0080, 0x4c03: 0x0080, 0x4c04: 0x00c3, 0x4c05: 0x0080, + 0x4c06: 0x0080, 0x4c07: 0x0080, 0x4c08: 0x0080, 0x4c09: 0x0080, 0x4c0a: 0x0080, 0x4c0b: 0x0080, + 0x4c1b: 0x00c3, 0x4c1c: 0x00c3, 0x4c1d: 0x00c3, + 0x4c1e: 0x00c3, 0x4c1f: 0x00c3, 0x4c21: 0x00c3, 0x4c22: 0x00c3, 0x4c23: 0x00c3, + 0x4c24: 0x00c3, 0x4c25: 0x00c3, 0x4c26: 0x00c3, 0x4c27: 0x00c3, 0x4c28: 0x00c3, 0x4c29: 0x00c3, + 0x4c2a: 0x00c3, 0x4c2b: 0x00c3, 0x4c2c: 0x00c3, 0x4c2d: 0x00c3, 0x4c2e: 0x00c3, 0x4c2f: 0x00c3, + // Block 0x131, offset 0x4c40 + 0x4c40: 0x00c3, 0x4c41: 0x00c3, 0x4c42: 0x00c3, 0x4c43: 0x00c3, 0x4c44: 0x00c3, 0x4c45: 0x00c3, + 0x4c46: 0x00c3, 0x4c48: 0x00c3, 0x4c49: 0x00c3, 0x4c4a: 0x00c3, 0x4c4b: 0x00c3, + 0x4c4c: 0x00c3, 0x4c4d: 0x00c3, 0x4c4e: 0x00c3, 0x4c4f: 0x00c3, 0x4c50: 0x00c3, 0x4c51: 0x00c3, + 0x4c52: 0x00c3, 0x4c53: 0x00c3, 0x4c54: 0x00c3, 0x4c55: 0x00c3, 0x4c56: 0x00c3, 0x4c57: 0x00c3, + 0x4c58: 0x00c3, 0x4c5b: 0x00c3, 0x4c5c: 0x00c3, 0x4c5d: 0x00c3, + 0x4c5e: 0x00c3, 0x4c5f: 0x00c3, 0x4c60: 0x00c3, 0x4c61: 0x00c3, 0x4c63: 0x00c3, + 0x4c64: 0x00c3, 0x4c66: 0x00c3, 0x4c67: 0x00c3, 0x4c68: 0x00c3, 0x4c69: 0x00c3, + 0x4c6a: 0x00c3, + // Block 0x132, offset 0x4c80 + 0x4c80: 0x00c0, 0x4c81: 0x00c0, 0x4c82: 0x00c0, 0x4c83: 0x00c0, 0x4c84: 0x00c0, + 0x4c87: 0x0080, 0x4c88: 0x0080, 0x4c89: 0x0080, 0x4c8a: 0x0080, 0x4c8b: 0x0080, + 0x4c8c: 0x0080, 0x4c8d: 0x0080, 0x4c8e: 0x0080, 0x4c8f: 0x0080, 0x4c90: 0x00c3, 0x4c91: 0x00c3, + 0x4c92: 0x00c3, 0x4c93: 0x00c3, 0x4c94: 0x00c3, 0x4c95: 0x00c3, 0x4c96: 0x00c3, + // Block 0x133, offset 0x4cc0 + 0x4cc0: 0x00c2, 0x4cc1: 0x00c2, 0x4cc2: 0x00c2, 0x4cc3: 0x00c2, 0x4cc4: 0x00c2, 0x4cc5: 0x00c2, + 0x4cc6: 0x00c2, 0x4cc7: 0x00c2, 0x4cc8: 0x00c2, 0x4cc9: 0x00c2, 0x4cca: 0x00c2, 0x4ccb: 0x00c2, + 0x4ccc: 0x00c2, 0x4ccd: 0x00c2, 0x4cce: 0x00c2, 0x4ccf: 0x00c2, 0x4cd0: 0x00c2, 0x4cd1: 0x00c2, + 0x4cd2: 0x00c2, 0x4cd3: 0x00c2, 0x4cd4: 0x00c2, 0x4cd5: 0x00c2, 0x4cd6: 0x00c2, 0x4cd7: 0x00c2, + 0x4cd8: 0x00c2, 0x4cd9: 0x00c2, 0x4cda: 0x00c2, 0x4cdb: 0x00c2, 0x4cdc: 0x00c2, 0x4cdd: 0x00c2, + 0x4cde: 0x00c2, 0x4cdf: 0x00c2, 0x4ce0: 0x00c2, 0x4ce1: 0x00c2, 0x4ce2: 0x00c2, 0x4ce3: 0x00c2, + 0x4ce4: 0x00c2, 0x4ce5: 0x00c2, 0x4ce6: 0x00c2, 0x4ce7: 0x00c2, 0x4ce8: 0x00c2, 0x4ce9: 0x00c2, + 0x4cea: 0x00c2, 0x4ceb: 0x00c2, 0x4cec: 0x00c2, 0x4ced: 0x00c2, 0x4cee: 0x00c2, 0x4cef: 0x00c2, + 0x4cf0: 0x00c2, 0x4cf1: 0x00c2, 0x4cf2: 0x00c2, 0x4cf3: 0x00c2, 0x4cf4: 0x00c2, 0x4cf5: 0x00c2, + 0x4cf6: 0x00c2, 0x4cf7: 0x00c2, 0x4cf8: 0x00c2, 0x4cf9: 0x00c2, 0x4cfa: 0x00c2, 0x4cfb: 0x00c2, + 0x4cfc: 0x00c2, 0x4cfd: 0x00c2, 0x4cfe: 0x00c2, 0x4cff: 0x00c2, + // Block 0x134, offset 0x4d00 + 0x4d00: 0x00c2, 0x4d01: 0x00c2, 0x4d02: 0x00c2, 0x4d03: 0x00c2, 0x4d04: 0x00c3, 0x4d05: 0x00c3, + 0x4d06: 0x00c3, 0x4d07: 0x00c3, 0x4d08: 0x00c3, 0x4d09: 0x00c3, 0x4d0a: 0x00c3, + 0x4d10: 0x00c0, 0x4d11: 0x00c0, + 0x4d12: 0x00c0, 0x4d13: 0x00c0, 0x4d14: 0x00c0, 0x4d15: 0x00c0, 0x4d16: 0x00c0, 0x4d17: 0x00c0, + 0x4d18: 0x00c0, 0x4d19: 0x00c0, + 0x4d1e: 0x0080, 0x4d1f: 0x0080, + // Block 0x135, offset 0x4d40 + 0x4d71: 0x0080, 0x4d72: 0x0080, 0x4d73: 0x0080, 0x4d74: 0x0080, 0x4d75: 0x0080, + 0x4d76: 0x0080, 0x4d77: 0x0080, 0x4d78: 0x0080, 0x4d79: 0x0080, 0x4d7a: 0x0080, 0x4d7b: 0x0080, + 0x4d7c: 0x0080, 0x4d7d: 0x0080, 0x4d7e: 0x0080, 0x4d7f: 0x0080, + // Block 0x136, offset 0x4d80 + 0x4d80: 0x0080, 0x4d81: 0x0080, 0x4d82: 0x0080, 0x4d83: 0x0080, 0x4d84: 0x0080, 0x4d85: 0x0080, + 0x4d86: 0x0080, 0x4d87: 0x0080, 0x4d88: 0x0080, 0x4d89: 0x0080, 0x4d8a: 0x0080, 0x4d8b: 0x0080, + 0x4d8c: 0x0080, 0x4d8d: 0x0080, 0x4d8e: 0x0080, 0x4d8f: 0x0080, 0x4d90: 0x0080, 0x4d91: 0x0080, + 0x4d92: 0x0080, 0x4d93: 0x0080, 0x4d94: 0x0080, 0x4d95: 0x0080, 0x4d96: 0x0080, 0x4d97: 0x0080, + 0x4d98: 0x0080, 0x4d99: 0x0080, 0x4d9a: 0x0080, 0x4d9b: 0x0080, 0x4d9c: 0x0080, 0x4d9d: 0x0080, + 0x4d9e: 0x0080, 0x4d9f: 0x0080, 0x4da0: 0x0080, 0x4da1: 0x0080, 0x4da2: 0x0080, 0x4da3: 0x0080, + 0x4da4: 0x0080, 0x4da5: 0x0080, 0x4da6: 0x0080, 0x4da7: 0x0080, 0x4da8: 0x0080, 0x4da9: 0x0080, + 0x4daa: 0x0080, 0x4dab: 0x0080, 0x4dac: 0x0080, 0x4dad: 0x0080, 0x4dae: 0x0080, 0x4daf: 0x0080, + 0x4db0: 0x0080, 0x4db1: 0x0080, 0x4db2: 0x0080, 0x4db3: 0x0080, 0x4db4: 0x0080, + // Block 0x137, offset 0x4dc0 + 0x4dc0: 0x0080, 0x4dc1: 0x0080, 0x4dc2: 0x0080, 0x4dc3: 0x0080, 0x4dc5: 0x0080, + 0x4dc6: 0x0080, 0x4dc7: 0x0080, 0x4dc8: 0x0080, 0x4dc9: 0x0080, 0x4dca: 0x0080, 0x4dcb: 0x0080, + 0x4dcc: 0x0080, 0x4dcd: 0x0080, 0x4dce: 0x0080, 0x4dcf: 0x0080, 0x4dd0: 0x0080, 0x4dd1: 0x0080, + 0x4dd2: 0x0080, 0x4dd3: 0x0080, 0x4dd4: 0x0080, 0x4dd5: 0x0080, 0x4dd6: 0x0080, 0x4dd7: 0x0080, + 0x4dd8: 0x0080, 0x4dd9: 0x0080, 0x4dda: 0x0080, 0x4ddb: 0x0080, 0x4ddc: 0x0080, 0x4ddd: 0x0080, + 0x4dde: 0x0080, 0x4ddf: 0x0080, 0x4de1: 0x0080, 0x4de2: 0x0080, + 0x4de4: 0x0080, 0x4de7: 0x0080, 0x4de9: 0x0080, + 0x4dea: 0x0080, 0x4deb: 0x0080, 0x4dec: 0x0080, 0x4ded: 0x0080, 0x4dee: 0x0080, 0x4def: 0x0080, + 0x4df0: 0x0080, 0x4df1: 0x0080, 0x4df2: 0x0080, 0x4df4: 0x0080, 0x4df5: 0x0080, + 0x4df6: 0x0080, 0x4df7: 0x0080, 0x4df9: 0x0080, 0x4dfb: 0x0080, + // Block 0x138, offset 0x4e00 + 0x4e02: 0x0080, + 0x4e07: 0x0080, 0x4e09: 0x0080, 0x4e0b: 0x0080, + 0x4e0d: 0x0080, 0x4e0e: 0x0080, 0x4e0f: 0x0080, 0x4e11: 0x0080, + 0x4e12: 0x0080, 0x4e14: 0x0080, 0x4e17: 0x0080, + 0x4e19: 0x0080, 0x4e1b: 0x0080, 0x4e1d: 0x0080, + 0x4e1f: 0x0080, 0x4e21: 0x0080, 0x4e22: 0x0080, + 0x4e24: 0x0080, 0x4e27: 0x0080, 0x4e28: 0x0080, 0x4e29: 0x0080, + 0x4e2a: 0x0080, 0x4e2c: 0x0080, 0x4e2d: 0x0080, 0x4e2e: 0x0080, 0x4e2f: 0x0080, + 0x4e30: 0x0080, 0x4e31: 0x0080, 0x4e32: 0x0080, 0x4e34: 0x0080, 0x4e35: 0x0080, + 0x4e36: 0x0080, 0x4e37: 0x0080, 0x4e39: 0x0080, 0x4e3a: 0x0080, 0x4e3b: 0x0080, + 0x4e3c: 0x0080, 0x4e3e: 0x0080, + // Block 0x139, offset 0x4e40 + 0x4e40: 0x0080, 0x4e41: 0x0080, 0x4e42: 0x0080, 0x4e43: 0x0080, 0x4e44: 0x0080, 0x4e45: 0x0080, + 0x4e46: 0x0080, 0x4e47: 0x0080, 0x4e48: 0x0080, 0x4e49: 0x0080, 0x4e4b: 0x0080, + 0x4e4c: 0x0080, 0x4e4d: 0x0080, 0x4e4e: 0x0080, 0x4e4f: 0x0080, 0x4e50: 0x0080, 0x4e51: 0x0080, + 0x4e52: 0x0080, 0x4e53: 0x0080, 0x4e54: 0x0080, 0x4e55: 0x0080, 0x4e56: 0x0080, 0x4e57: 0x0080, + 0x4e58: 0x0080, 0x4e59: 0x0080, 0x4e5a: 0x0080, 0x4e5b: 0x0080, + 0x4e61: 0x0080, 0x4e62: 0x0080, 0x4e63: 0x0080, + 0x4e65: 0x0080, 0x4e66: 0x0080, 0x4e67: 0x0080, 0x4e68: 0x0080, 0x4e69: 0x0080, + 0x4e6b: 0x0080, 0x4e6c: 0x0080, 0x4e6d: 0x0080, 0x4e6e: 0x0080, 0x4e6f: 0x0080, + 0x4e70: 0x0080, 0x4e71: 0x0080, 0x4e72: 0x0080, 0x4e73: 0x0080, 0x4e74: 0x0080, 0x4e75: 0x0080, + 0x4e76: 0x0080, 0x4e77: 0x0080, 0x4e78: 0x0080, 0x4e79: 0x0080, 0x4e7a: 0x0080, 0x4e7b: 0x0080, + // Block 0x13a, offset 0x4e80 + 0x4eb0: 0x0080, 0x4eb1: 0x0080, + // Block 0x13b, offset 0x4ec0 + 0x4ec0: 0x0080, 0x4ec1: 0x0080, 0x4ec2: 0x0080, 0x4ec3: 0x0080, 0x4ec4: 0x0080, 0x4ec5: 0x0080, + 0x4ec6: 0x0080, 0x4ec7: 0x0080, 0x4ec8: 0x0080, 0x4ec9: 0x0080, 0x4eca: 0x0080, 0x4ecb: 0x0080, + 0x4ecc: 0x0080, 0x4ecd: 0x0080, 0x4ece: 0x0080, 0x4ecf: 0x0080, 0x4ed0: 0x0080, 0x4ed1: 0x0080, + 0x4ed2: 0x0080, 0x4ed3: 0x0080, 0x4ed4: 0x0080, 0x4ed5: 0x0080, 0x4ed6: 0x0080, 0x4ed7: 0x0080, + 0x4ed8: 0x0080, 0x4ed9: 0x0080, 0x4eda: 0x0080, 0x4edb: 0x0080, 0x4edc: 0x0080, 0x4edd: 0x0080, + 0x4ede: 0x0080, 0x4edf: 0x0080, 0x4ee0: 0x0080, 0x4ee1: 0x0080, 0x4ee2: 0x0080, 0x4ee3: 0x0080, + 0x4ee4: 0x0080, 0x4ee5: 0x0080, 0x4ee6: 0x0080, 0x4ee7: 0x0080, 0x4ee8: 0x0080, 0x4ee9: 0x0080, + 0x4eea: 0x0080, 0x4eeb: 0x0080, + 0x4ef0: 0x0080, 0x4ef1: 0x0080, 0x4ef2: 0x0080, 0x4ef3: 0x0080, 0x4ef4: 0x0080, 0x4ef5: 0x0080, + 0x4ef6: 0x0080, 0x4ef7: 0x0080, 0x4ef8: 0x0080, 0x4ef9: 0x0080, 0x4efa: 0x0080, 0x4efb: 0x0080, + 0x4efc: 0x0080, 0x4efd: 0x0080, 0x4efe: 0x0080, 0x4eff: 0x0080, + // Block 0x13c, offset 0x4f00 + 0x4f00: 0x0080, 0x4f01: 0x0080, 0x4f02: 0x0080, 0x4f03: 0x0080, 0x4f04: 0x0080, 0x4f05: 0x0080, + 0x4f06: 0x0080, 0x4f07: 0x0080, 0x4f08: 0x0080, 0x4f09: 0x0080, 0x4f0a: 0x0080, 0x4f0b: 0x0080, + 0x4f0c: 0x0080, 0x4f0d: 0x0080, 0x4f0e: 0x0080, 0x4f0f: 0x0080, 0x4f10: 0x0080, 0x4f11: 0x0080, + 0x4f12: 0x0080, 0x4f13: 0x0080, + 0x4f20: 0x0080, 0x4f21: 0x0080, 0x4f22: 0x0080, 0x4f23: 0x0080, + 0x4f24: 0x0080, 0x4f25: 0x0080, 0x4f26: 0x0080, 0x4f27: 0x0080, 0x4f28: 0x0080, 0x4f29: 0x0080, + 0x4f2a: 0x0080, 0x4f2b: 0x0080, 0x4f2c: 0x0080, 0x4f2d: 0x0080, 0x4f2e: 0x0080, + 0x4f31: 0x0080, 0x4f32: 0x0080, 0x4f33: 0x0080, 0x4f34: 0x0080, 0x4f35: 0x0080, + 0x4f36: 0x0080, 0x4f37: 0x0080, 0x4f38: 0x0080, 0x4f39: 0x0080, 0x4f3a: 0x0080, 0x4f3b: 0x0080, + 0x4f3c: 0x0080, 0x4f3d: 0x0080, 0x4f3e: 0x0080, 0x4f3f: 0x0080, + // Block 0x13d, offset 0x4f40 + 0x4f41: 0x0080, 0x4f42: 0x0080, 0x4f43: 0x0080, 0x4f44: 0x0080, 0x4f45: 0x0080, + 0x4f46: 0x0080, 0x4f47: 0x0080, 0x4f48: 0x0080, 0x4f49: 0x0080, 0x4f4a: 0x0080, 0x4f4b: 0x0080, + 0x4f4c: 0x0080, 0x4f4d: 0x0080, 0x4f4e: 0x0080, 0x4f4f: 0x0080, 0x4f51: 0x0080, + 0x4f52: 0x0080, 0x4f53: 0x0080, 0x4f54: 0x0080, 0x4f55: 0x0080, 0x4f56: 0x0080, 0x4f57: 0x0080, + 0x4f58: 0x0080, 0x4f59: 0x0080, 0x4f5a: 0x0080, 0x4f5b: 0x0080, 0x4f5c: 0x0080, 0x4f5d: 0x0080, + 0x4f5e: 0x0080, 0x4f5f: 0x0080, 0x4f60: 0x0080, 0x4f61: 0x0080, 0x4f62: 0x0080, 0x4f63: 0x0080, + 0x4f64: 0x0080, 0x4f65: 0x0080, 0x4f66: 0x0080, 0x4f67: 0x0080, 0x4f68: 0x0080, 0x4f69: 0x0080, + 0x4f6a: 0x0080, 0x4f6b: 0x0080, 0x4f6c: 0x0080, 0x4f6d: 0x0080, 0x4f6e: 0x0080, 0x4f6f: 0x0080, + 0x4f70: 0x0080, 0x4f71: 0x0080, 0x4f72: 0x0080, 0x4f73: 0x0080, 0x4f74: 0x0080, 0x4f75: 0x0080, + // Block 0x13e, offset 0x4f80 + 0x4f80: 0x0080, 0x4f81: 0x0080, 0x4f82: 0x0080, 0x4f83: 0x0080, 0x4f84: 0x0080, 0x4f85: 0x0080, + 0x4f86: 0x0080, 0x4f87: 0x0080, 0x4f88: 0x0080, 0x4f89: 0x0080, 0x4f8a: 0x0080, 0x4f8b: 0x0080, + 0x4f8c: 0x0080, 0x4f90: 0x0080, 0x4f91: 0x0080, + 0x4f92: 0x0080, 0x4f93: 0x0080, 0x4f94: 0x0080, 0x4f95: 0x0080, 0x4f96: 0x0080, 0x4f97: 0x0080, + 0x4f98: 0x0080, 0x4f99: 0x0080, 0x4f9a: 0x0080, 0x4f9b: 0x0080, 0x4f9c: 0x0080, 0x4f9d: 0x0080, + 0x4f9e: 0x0080, 0x4f9f: 0x0080, 0x4fa0: 0x0080, 0x4fa1: 0x0080, 0x4fa2: 0x0080, 0x4fa3: 0x0080, + 0x4fa4: 0x0080, 0x4fa5: 0x0080, 0x4fa6: 0x0080, 0x4fa7: 0x0080, 0x4fa8: 0x0080, 0x4fa9: 0x0080, + 0x4faa: 0x0080, 0x4fab: 0x0080, 0x4fac: 0x0080, 0x4fad: 0x0080, 0x4fae: 0x0080, 0x4faf: 0x0080, + 0x4fb0: 0x0080, 0x4fb1: 0x0080, 0x4fb2: 0x0080, 0x4fb3: 0x0080, 0x4fb4: 0x0080, 0x4fb5: 0x0080, + 0x4fb6: 0x0080, 0x4fb7: 0x0080, 0x4fb8: 0x0080, 0x4fb9: 0x0080, 0x4fba: 0x0080, 0x4fbb: 0x0080, + 0x4fbc: 0x0080, 0x4fbd: 0x0080, 0x4fbe: 0x0080, 0x4fbf: 0x0080, + // Block 0x13f, offset 0x4fc0 + 0x4fc0: 0x0080, 0x4fc1: 0x0080, 0x4fc2: 0x0080, 0x4fc3: 0x0080, 0x4fc4: 0x0080, 0x4fc5: 0x0080, + 0x4fc6: 0x0080, 0x4fc7: 0x0080, 0x4fc8: 0x0080, 0x4fc9: 0x0080, 0x4fca: 0x0080, 0x4fcb: 0x0080, + 0x4fcc: 0x0080, 0x4fcd: 0x0080, 0x4fce: 0x0080, 0x4fcf: 0x0080, 0x4fd0: 0x0080, 0x4fd1: 0x0080, + 0x4fd2: 0x0080, 0x4fd3: 0x0080, 0x4fd4: 0x0080, 0x4fd5: 0x0080, 0x4fd6: 0x0080, 0x4fd7: 0x0080, + 0x4fd8: 0x0080, 0x4fd9: 0x0080, 0x4fda: 0x0080, 0x4fdb: 0x0080, 0x4fdc: 0x0080, 0x4fdd: 0x0080, + 0x4fde: 0x0080, 0x4fdf: 0x0080, 0x4fe0: 0x0080, 0x4fe1: 0x0080, 0x4fe2: 0x0080, 0x4fe3: 0x0080, + 0x4fe4: 0x0080, 0x4fe5: 0x0080, 0x4fe6: 0x0080, 0x4fe7: 0x0080, 0x4fe8: 0x0080, 0x4fe9: 0x0080, + 0x4fea: 0x0080, 0x4feb: 0x0080, 0x4fec: 0x0080, + // Block 0x140, offset 0x5000 + 0x5026: 0x0080, 0x5027: 0x0080, 0x5028: 0x0080, 0x5029: 0x0080, + 0x502a: 0x0080, 0x502b: 0x0080, 0x502c: 0x0080, 0x502d: 0x0080, 0x502e: 0x0080, 0x502f: 0x0080, + 0x5030: 0x0080, 0x5031: 0x0080, 0x5032: 0x0080, 0x5033: 0x0080, 0x5034: 0x0080, 0x5035: 0x0080, + 0x5036: 0x0080, 0x5037: 0x0080, 0x5038: 0x0080, 0x5039: 0x0080, 0x503a: 0x0080, 0x503b: 0x0080, + 0x503c: 0x0080, 0x503d: 0x0080, 0x503e: 0x0080, 0x503f: 0x0080, + // Block 0x141, offset 0x5040 + 0x5040: 0x008c, 0x5041: 0x0080, 0x5042: 0x0080, + 0x5050: 0x0080, 0x5051: 0x0080, + 0x5052: 0x0080, 0x5053: 0x0080, 0x5054: 0x0080, 0x5055: 0x0080, 0x5056: 0x0080, 0x5057: 0x0080, + 0x5058: 0x0080, 0x5059: 0x0080, 0x505a: 0x0080, 0x505b: 0x0080, 0x505c: 0x0080, 0x505d: 0x0080, + 0x505e: 0x0080, 0x505f: 0x0080, 0x5060: 0x0080, 0x5061: 0x0080, 0x5062: 0x0080, 0x5063: 0x0080, + 0x5064: 0x0080, 0x5065: 0x0080, 0x5066: 0x0080, 0x5067: 0x0080, 0x5068: 0x0080, 0x5069: 0x0080, + 0x506a: 0x0080, 0x506b: 0x0080, 0x506c: 0x0080, 0x506d: 0x0080, 0x506e: 0x0080, 0x506f: 0x0080, + 0x5070: 0x0080, 0x5071: 0x0080, 0x5072: 0x0080, 0x5073: 0x0080, 0x5074: 0x0080, 0x5075: 0x0080, + 0x5076: 0x0080, 0x5077: 0x0080, 0x5078: 0x0080, 0x5079: 0x0080, 0x507a: 0x0080, 0x507b: 0x0080, + // Block 0x142, offset 0x5080 + 0x5080: 0x0080, 0x5081: 0x0080, 0x5082: 0x0080, 0x5083: 0x0080, 0x5084: 0x0080, 0x5085: 0x0080, + 0x5086: 0x0080, 0x5087: 0x0080, 0x5088: 0x0080, + 0x5090: 0x0080, 0x5091: 0x0080, + 0x50a0: 0x0080, 0x50a1: 0x0080, 0x50a2: 0x0080, 0x50a3: 0x0080, + 0x50a4: 0x0080, 0x50a5: 0x0080, + // Block 0x143, offset 0x50c0 + 0x50c0: 0x0080, 0x50c1: 0x0080, 0x50c2: 0x0080, 0x50c3: 0x0080, 0x50c4: 0x0080, 0x50c5: 0x0080, + 0x50c6: 0x0080, 0x50c7: 0x0080, 0x50c8: 0x0080, 0x50c9: 0x0080, 0x50ca: 0x0080, 0x50cb: 0x0080, + 0x50cc: 0x0080, 0x50cd: 0x0080, 0x50ce: 0x0080, 0x50cf: 0x0080, 0x50d0: 0x0080, 0x50d1: 0x0080, + 0x50d2: 0x0080, 0x50d3: 0x0080, 0x50d4: 0x0080, + 0x50e0: 0x0080, 0x50e1: 0x0080, 0x50e2: 0x0080, 0x50e3: 0x0080, + 0x50e4: 0x0080, 0x50e5: 0x0080, 0x50e6: 0x0080, 0x50e7: 0x0080, 0x50e8: 0x0080, 0x50e9: 0x0080, + 0x50ea: 0x0080, 0x50eb: 0x0080, 0x50ec: 0x0080, + 0x50f0: 0x0080, 0x50f1: 0x0080, 0x50f2: 0x0080, 0x50f3: 0x0080, 0x50f4: 0x0080, 0x50f5: 0x0080, + 0x50f6: 0x0080, 0x50f7: 0x0080, 0x50f8: 0x0080, 0x50f9: 0x0080, + // Block 0x144, offset 0x5100 + 0x5100: 0x0080, 0x5101: 0x0080, 0x5102: 0x0080, 0x5103: 0x0080, 0x5104: 0x0080, 0x5105: 0x0080, + 0x5106: 0x0080, 0x5107: 0x0080, 0x5108: 0x0080, 0x5109: 0x0080, 0x510a: 0x0080, 0x510b: 0x0080, + 0x510c: 0x0080, 0x510d: 0x0080, 0x510e: 0x0080, 0x510f: 0x0080, 0x5110: 0x0080, 0x5111: 0x0080, + 0x5112: 0x0080, 0x5113: 0x0080, 0x5114: 0x0080, 0x5115: 0x0080, 0x5116: 0x0080, 0x5117: 0x0080, + 0x5118: 0x0080, 0x5119: 0x0080, 0x511a: 0x0080, 0x511b: 0x0080, 0x511c: 0x0080, 0x511d: 0x0080, + 0x511e: 0x0080, 0x511f: 0x0080, 0x5120: 0x0080, 0x5121: 0x0080, 0x5122: 0x0080, 0x5123: 0x0080, + 0x5124: 0x0080, 0x5125: 0x0080, 0x5126: 0x0080, 0x5127: 0x0080, 0x5128: 0x0080, 0x5129: 0x0080, + 0x512a: 0x0080, 0x512b: 0x0080, 0x512c: 0x0080, 0x512d: 0x0080, 0x512e: 0x0080, 0x512f: 0x0080, + 0x5130: 0x0080, 0x5131: 0x0080, 0x5132: 0x0080, 0x5133: 0x0080, + // Block 0x145, offset 0x5140 + 0x5140: 0x0080, 0x5141: 0x0080, 0x5142: 0x0080, 0x5143: 0x0080, 0x5144: 0x0080, 0x5145: 0x0080, + 0x5146: 0x0080, 0x5147: 0x0080, 0x5148: 0x0080, 0x5149: 0x0080, 0x514a: 0x0080, 0x514b: 0x0080, + 0x514c: 0x0080, 0x514d: 0x0080, 0x514e: 0x0080, 0x514f: 0x0080, 0x5150: 0x0080, 0x5151: 0x0080, + 0x5152: 0x0080, 0x5153: 0x0080, 0x5154: 0x0080, 0x5155: 0x0080, 0x5156: 0x0080, 0x5157: 0x0080, + 0x5158: 0x0080, + // Block 0x146, offset 0x5180 + 0x5180: 0x0080, 0x5181: 0x0080, 0x5182: 0x0080, 0x5183: 0x0080, 0x5184: 0x0080, 0x5185: 0x0080, + 0x5186: 0x0080, 0x5187: 0x0080, 0x5188: 0x0080, 0x5189: 0x0080, 0x518a: 0x0080, 0x518b: 0x0080, + 0x5190: 0x0080, 0x5191: 0x0080, + 0x5192: 0x0080, 0x5193: 0x0080, 0x5194: 0x0080, 0x5195: 0x0080, 0x5196: 0x0080, 0x5197: 0x0080, + 0x5198: 0x0080, 0x5199: 0x0080, 0x519a: 0x0080, 0x519b: 0x0080, 0x519c: 0x0080, 0x519d: 0x0080, + 0x519e: 0x0080, 0x519f: 0x0080, 0x51a0: 0x0080, 0x51a1: 0x0080, 0x51a2: 0x0080, 0x51a3: 0x0080, + 0x51a4: 0x0080, 0x51a5: 0x0080, 0x51a6: 0x0080, 0x51a7: 0x0080, 0x51a8: 0x0080, 0x51a9: 0x0080, + 0x51aa: 0x0080, 0x51ab: 0x0080, 0x51ac: 0x0080, 0x51ad: 0x0080, 0x51ae: 0x0080, 0x51af: 0x0080, + 0x51b0: 0x0080, 0x51b1: 0x0080, 0x51b2: 0x0080, 0x51b3: 0x0080, 0x51b4: 0x0080, 0x51b5: 0x0080, + 0x51b6: 0x0080, 0x51b7: 0x0080, 0x51b8: 0x0080, 0x51b9: 0x0080, 0x51ba: 0x0080, 0x51bb: 0x0080, + 0x51bc: 0x0080, 0x51bd: 0x0080, 0x51be: 0x0080, 0x51bf: 0x0080, + // Block 0x147, offset 0x51c0 + 0x51c0: 0x0080, 0x51c1: 0x0080, 0x51c2: 0x0080, 0x51c3: 0x0080, 0x51c4: 0x0080, 0x51c5: 0x0080, + 0x51c6: 0x0080, 0x51c7: 0x0080, + 0x51d0: 0x0080, 0x51d1: 0x0080, + 0x51d2: 0x0080, 0x51d3: 0x0080, 0x51d4: 0x0080, 0x51d5: 0x0080, 0x51d6: 0x0080, 0x51d7: 0x0080, + 0x51d8: 0x0080, 0x51d9: 0x0080, + 0x51e0: 0x0080, 0x51e1: 0x0080, 0x51e2: 0x0080, 0x51e3: 0x0080, + 0x51e4: 0x0080, 0x51e5: 0x0080, 0x51e6: 0x0080, 0x51e7: 0x0080, 0x51e8: 0x0080, 0x51e9: 0x0080, + 0x51ea: 0x0080, 0x51eb: 0x0080, 0x51ec: 0x0080, 0x51ed: 0x0080, 0x51ee: 0x0080, 0x51ef: 0x0080, + 0x51f0: 0x0080, 0x51f1: 0x0080, 0x51f2: 0x0080, 0x51f3: 0x0080, 0x51f4: 0x0080, 0x51f5: 0x0080, + 0x51f6: 0x0080, 0x51f7: 0x0080, 0x51f8: 0x0080, 0x51f9: 0x0080, 0x51fa: 0x0080, 0x51fb: 0x0080, + 0x51fc: 0x0080, 0x51fd: 0x0080, 0x51fe: 0x0080, 0x51ff: 0x0080, + // Block 0x148, offset 0x5200 + 0x5200: 0x0080, 0x5201: 0x0080, 0x5202: 0x0080, 0x5203: 0x0080, 0x5204: 0x0080, 0x5205: 0x0080, + 0x5206: 0x0080, 0x5207: 0x0080, + 0x5210: 0x0080, 0x5211: 0x0080, + 0x5212: 0x0080, 0x5213: 0x0080, 0x5214: 0x0080, 0x5215: 0x0080, 0x5216: 0x0080, 0x5217: 0x0080, + 0x5218: 0x0080, 0x5219: 0x0080, 0x521a: 0x0080, 0x521b: 0x0080, 0x521c: 0x0080, 0x521d: 0x0080, + 0x521e: 0x0080, 0x521f: 0x0080, 0x5220: 0x0080, 0x5221: 0x0080, 0x5222: 0x0080, 0x5223: 0x0080, + 0x5224: 0x0080, 0x5225: 0x0080, 0x5226: 0x0080, 0x5227: 0x0080, 0x5228: 0x0080, 0x5229: 0x0080, + 0x522a: 0x0080, 0x522b: 0x0080, 0x522c: 0x0080, 0x522d: 0x0080, + // Block 0x149, offset 0x5240 + 0x5240: 0x0080, 0x5241: 0x0080, 0x5242: 0x0080, 0x5243: 0x0080, 0x5244: 0x0080, 0x5245: 0x0080, + 0x5246: 0x0080, 0x5247: 0x0080, 0x5248: 0x0080, 0x5249: 0x0080, 0x524a: 0x0080, 0x524b: 0x0080, + 0x5250: 0x0080, 0x5251: 0x0080, + 0x5252: 0x0080, 0x5253: 0x0080, 0x5254: 0x0080, 0x5255: 0x0080, 0x5256: 0x0080, 0x5257: 0x0080, + 0x5258: 0x0080, 0x5259: 0x0080, 0x525a: 0x0080, 0x525b: 0x0080, 0x525c: 0x0080, 0x525d: 0x0080, + 0x525e: 0x0080, 0x525f: 0x0080, 0x5260: 0x0080, 0x5261: 0x0080, 0x5262: 0x0080, 0x5263: 0x0080, + 0x5264: 0x0080, 0x5265: 0x0080, 0x5266: 0x0080, 0x5267: 0x0080, 0x5268: 0x0080, 0x5269: 0x0080, + 0x526a: 0x0080, 0x526b: 0x0080, 0x526c: 0x0080, 0x526d: 0x0080, 0x526e: 0x0080, 0x526f: 0x0080, + 0x5270: 0x0080, 0x5271: 0x0080, 0x5272: 0x0080, 0x5273: 0x0080, 0x5274: 0x0080, 0x5275: 0x0080, + 0x5276: 0x0080, 0x5277: 0x0080, 0x5278: 0x0080, 0x5279: 0x0080, 0x527a: 0x0080, 0x527b: 0x0080, + 0x527c: 0x0080, 0x527d: 0x0080, 0x527e: 0x0080, + // Block 0x14a, offset 0x5280 + 0x5280: 0x0080, 0x5281: 0x0080, 0x5282: 0x0080, 0x5283: 0x0080, 0x5284: 0x0080, 0x5285: 0x0080, + 0x5286: 0x0080, 0x5287: 0x0080, 0x5288: 0x0080, 0x5289: 0x0080, 0x528a: 0x0080, 0x528b: 0x0080, + 0x528c: 0x0080, 0x528d: 0x0080, 0x528e: 0x0080, 0x528f: 0x0080, 0x5290: 0x0080, 0x5291: 0x0080, + 0x5292: 0x0080, 0x5293: 0x0080, 0x5294: 0x0080, 0x5295: 0x0080, 0x5296: 0x0080, 0x5297: 0x0080, + 0x5298: 0x0080, 0x5299: 0x0080, 0x529a: 0x0080, 0x529b: 0x0080, 0x529c: 0x0080, 0x529d: 0x0080, + 0x529e: 0x0080, 0x529f: 0x0080, 0x52a0: 0x0080, 0x52a1: 0x0080, 0x52a2: 0x0080, 0x52a3: 0x0080, + 0x52a4: 0x0080, 0x52a5: 0x0080, 0x52a6: 0x0080, 0x52a7: 0x0080, 0x52a8: 0x0080, 0x52a9: 0x0080, + 0x52aa: 0x0080, 0x52ab: 0x0080, 0x52ac: 0x0080, 0x52ad: 0x0080, 0x52ae: 0x0080, 0x52af: 0x0080, + 0x52b0: 0x0080, 0x52b3: 0x0080, 0x52b4: 0x0080, 0x52b5: 0x0080, + 0x52b6: 0x0080, 0x52ba: 0x0080, + 0x52bc: 0x0080, 0x52bd: 0x0080, 0x52be: 0x0080, 0x52bf: 0x0080, + // Block 0x14b, offset 0x52c0 + 0x52c0: 0x0080, 0x52c1: 0x0080, 0x52c2: 0x0080, 0x52c3: 0x0080, 0x52c4: 0x0080, 0x52c5: 0x0080, + 0x52c6: 0x0080, 0x52c7: 0x0080, 0x52c8: 0x0080, 0x52c9: 0x0080, 0x52ca: 0x0080, 0x52cb: 0x0080, + 0x52cc: 0x0080, 0x52cd: 0x0080, 0x52ce: 0x0080, 0x52cf: 0x0080, 0x52d0: 0x0080, 0x52d1: 0x0080, + 0x52d2: 0x0080, 0x52d3: 0x0080, 0x52d4: 0x0080, 0x52d5: 0x0080, 0x52d6: 0x0080, 0x52d7: 0x0080, + 0x52d8: 0x0080, 0x52d9: 0x0080, 0x52da: 0x0080, 0x52db: 0x0080, 0x52dc: 0x0080, 0x52dd: 0x0080, + 0x52de: 0x0080, 0x52df: 0x0080, 0x52e0: 0x0080, 0x52e1: 0x0080, 0x52e2: 0x0080, + 0x52f0: 0x0080, 0x52f1: 0x0080, 0x52f2: 0x0080, 0x52f3: 0x0080, 0x52f4: 0x0080, 0x52f5: 0x0080, + 0x52f6: 0x0080, 0x52f7: 0x0080, 0x52f8: 0x0080, 0x52f9: 0x0080, + // Block 0x14c, offset 0x5300 + 0x5300: 0x0080, 0x5301: 0x0080, 0x5302: 0x0080, + 0x5310: 0x0080, 0x5311: 0x0080, + 0x5312: 0x0080, 0x5313: 0x0080, 0x5314: 0x0080, 0x5315: 0x0080, 0x5316: 0x0080, 0x5317: 0x0080, + 0x5318: 0x0080, 0x5319: 0x0080, 0x531a: 0x0080, 0x531b: 0x0080, 0x531c: 0x0080, 0x531d: 0x0080, + 0x531e: 0x0080, 0x531f: 0x0080, 0x5320: 0x0080, 0x5321: 0x0080, 0x5322: 0x0080, 0x5323: 0x0080, + 0x5324: 0x0080, 0x5325: 0x0080, 0x5326: 0x0080, 0x5327: 0x0080, 0x5328: 0x0080, 0x5329: 0x0080, + 0x532a: 0x0080, 0x532b: 0x0080, 0x532c: 0x0080, 0x532d: 0x0080, 0x532e: 0x0080, 0x532f: 0x0080, + 0x5330: 0x0080, 0x5331: 0x0080, 0x5332: 0x0080, 0x5333: 0x0080, 0x5334: 0x0080, 0x5335: 0x0080, + 0x5336: 0x0080, 0x5337: 0x0080, 0x5338: 0x0080, 0x5339: 0x0080, 0x533a: 0x0080, 0x533b: 0x0080, + 0x533c: 0x0080, 0x533d: 0x0080, 0x533e: 0x0080, 0x533f: 0x0080, + // Block 0x14d, offset 0x5340 + 0x5360: 0x0080, 0x5361: 0x0080, 0x5362: 0x0080, 0x5363: 0x0080, + 0x5364: 0x0080, 0x5365: 0x0080, 0x5366: 0x0080, 0x5367: 0x0080, 0x5368: 0x0080, 0x5369: 0x0080, + 0x536a: 0x0080, 0x536b: 0x0080, 0x536c: 0x0080, 0x536d: 0x0080, + // Block 0x14e, offset 0x5380 + 0x5380: 0x00cc, 0x5381: 0x00cc, 0x5382: 0x00cc, 0x5383: 0x00cc, 0x5384: 0x00cc, 0x5385: 0x00cc, + 0x5386: 0x00cc, 0x5387: 0x00cc, 0x5388: 0x00cc, 0x5389: 0x00cc, 0x538a: 0x00cc, 0x538b: 0x00cc, + 0x538c: 0x00cc, 0x538d: 0x00cc, 0x538e: 0x00cc, 0x538f: 0x00cc, 0x5390: 0x00cc, 0x5391: 0x00cc, + 0x5392: 0x00cc, 0x5393: 0x00cc, 0x5394: 0x00cc, 0x5395: 0x00cc, 0x5396: 0x00cc, + // Block 0x14f, offset 0x53c0 + 0x53c0: 0x00cc, 0x53c1: 0x00cc, 0x53c2: 0x00cc, 0x53c3: 0x00cc, 0x53c4: 0x00cc, 0x53c5: 0x00cc, + 0x53c6: 0x00cc, 0x53c7: 0x00cc, 0x53c8: 0x00cc, 0x53c9: 0x00cc, 0x53ca: 0x00cc, 0x53cb: 0x00cc, + 0x53cc: 0x00cc, 0x53cd: 0x00cc, 0x53ce: 0x00cc, 0x53cf: 0x00cc, 0x53d0: 0x00cc, 0x53d1: 0x00cc, + 0x53d2: 0x00cc, 0x53d3: 0x00cc, 0x53d4: 0x00cc, 0x53d5: 0x00cc, 0x53d6: 0x00cc, 0x53d7: 0x00cc, + 0x53d8: 0x00cc, 0x53d9: 0x00cc, 0x53da: 0x00cc, 0x53db: 0x00cc, 0x53dc: 0x00cc, 0x53dd: 0x00cc, + 0x53de: 0x00cc, 0x53df: 0x00cc, 0x53e0: 0x00cc, 0x53e1: 0x00cc, 0x53e2: 0x00cc, 0x53e3: 0x00cc, + 0x53e4: 0x00cc, 0x53e5: 0x00cc, 0x53e6: 0x00cc, 0x53e7: 0x00cc, 0x53e8: 0x00cc, 0x53e9: 0x00cc, + 0x53ea: 0x00cc, 0x53eb: 0x00cc, 0x53ec: 0x00cc, 0x53ed: 0x00cc, 0x53ee: 0x00cc, 0x53ef: 0x00cc, + 0x53f0: 0x00cc, 0x53f1: 0x00cc, 0x53f2: 0x00cc, 0x53f3: 0x00cc, 0x53f4: 0x00cc, + // Block 0x150, offset 0x5400 + 0x5400: 0x00cc, 0x5401: 0x00cc, 0x5402: 0x00cc, 0x5403: 0x00cc, 0x5404: 0x00cc, 0x5405: 0x00cc, + 0x5406: 0x00cc, 0x5407: 0x00cc, 0x5408: 0x00cc, 0x5409: 0x00cc, 0x540a: 0x00cc, 0x540b: 0x00cc, + 0x540c: 0x00cc, 0x540d: 0x00cc, 0x540e: 0x00cc, 0x540f: 0x00cc, 0x5410: 0x00cc, 0x5411: 0x00cc, + 0x5412: 0x00cc, 0x5413: 0x00cc, 0x5414: 0x00cc, 0x5415: 0x00cc, 0x5416: 0x00cc, 0x5417: 0x00cc, + 0x5418: 0x00cc, 0x5419: 0x00cc, 0x541a: 0x00cc, 0x541b: 0x00cc, 0x541c: 0x00cc, 0x541d: 0x00cc, + 0x5420: 0x00cc, 0x5421: 0x00cc, 0x5422: 0x00cc, 0x5423: 0x00cc, + 0x5424: 0x00cc, 0x5425: 0x00cc, 0x5426: 0x00cc, 0x5427: 0x00cc, 0x5428: 0x00cc, 0x5429: 0x00cc, + 0x542a: 0x00cc, 0x542b: 0x00cc, 0x542c: 0x00cc, 0x542d: 0x00cc, 0x542e: 0x00cc, 0x542f: 0x00cc, + 0x5430: 0x00cc, 0x5431: 0x00cc, 0x5432: 0x00cc, 0x5433: 0x00cc, 0x5434: 0x00cc, 0x5435: 0x00cc, + 0x5436: 0x00cc, 0x5437: 0x00cc, 0x5438: 0x00cc, 0x5439: 0x00cc, 0x543a: 0x00cc, 0x543b: 0x00cc, + 0x543c: 0x00cc, 0x543d: 0x00cc, 0x543e: 0x00cc, 0x543f: 0x00cc, + // Block 0x151, offset 0x5440 + 0x5440: 0x00cc, 0x5441: 0x00cc, 0x5442: 0x00cc, 0x5443: 0x00cc, 0x5444: 0x00cc, 0x5445: 0x00cc, + 0x5446: 0x00cc, 0x5447: 0x00cc, 0x5448: 0x00cc, 0x5449: 0x00cc, 0x544a: 0x00cc, 0x544b: 0x00cc, + 0x544c: 0x00cc, 0x544d: 0x00cc, 0x544e: 0x00cc, 0x544f: 0x00cc, 0x5450: 0x00cc, 0x5451: 0x00cc, + 0x5452: 0x00cc, 0x5453: 0x00cc, 0x5454: 0x00cc, 0x5455: 0x00cc, 0x5456: 0x00cc, 0x5457: 0x00cc, + 0x5458: 0x00cc, 0x5459: 0x00cc, 0x545a: 0x00cc, 0x545b: 0x00cc, 0x545c: 0x00cc, 0x545d: 0x00cc, + 0x545e: 0x00cc, 0x545f: 0x00cc, 0x5460: 0x00cc, 0x5461: 0x00cc, + 0x5470: 0x00cc, 0x5471: 0x00cc, 0x5472: 0x00cc, 0x5473: 0x00cc, 0x5474: 0x00cc, 0x5475: 0x00cc, + 0x5476: 0x00cc, 0x5477: 0x00cc, 0x5478: 0x00cc, 0x5479: 0x00cc, 0x547a: 0x00cc, 0x547b: 0x00cc, + 0x547c: 0x00cc, 0x547d: 0x00cc, 0x547e: 0x00cc, 0x547f: 0x00cc, + // Block 0x152, offset 0x5480 + 0x5480: 0x00cc, 0x5481: 0x00cc, 0x5482: 0x00cc, 0x5483: 0x00cc, 0x5484: 0x00cc, 0x5485: 0x00cc, + 0x5486: 0x00cc, 0x5487: 0x00cc, 0x5488: 0x00cc, 0x5489: 0x00cc, 0x548a: 0x00cc, 0x548b: 0x00cc, + 0x548c: 0x00cc, 0x548d: 0x00cc, 0x548e: 0x00cc, 0x548f: 0x00cc, 0x5490: 0x00cc, 0x5491: 0x00cc, + 0x5492: 0x00cc, 0x5493: 0x00cc, 0x5494: 0x00cc, 0x5495: 0x00cc, 0x5496: 0x00cc, 0x5497: 0x00cc, + 0x5498: 0x00cc, 0x5499: 0x00cc, 0x549a: 0x00cc, 0x549b: 0x00cc, 0x549c: 0x00cc, 0x549d: 0x00cc, + 0x549e: 0x00cc, 0x549f: 0x00cc, 0x54a0: 0x00cc, + // Block 0x153, offset 0x54c0 + 0x54c0: 0x008c, 0x54c1: 0x008c, 0x54c2: 0x008c, 0x54c3: 0x008c, 0x54c4: 0x008c, 0x54c5: 0x008c, + 0x54c6: 0x008c, 0x54c7: 0x008c, 0x54c8: 0x008c, 0x54c9: 0x008c, 0x54ca: 0x008c, 0x54cb: 0x008c, + 0x54cc: 0x008c, 0x54cd: 0x008c, 0x54ce: 0x008c, 0x54cf: 0x008c, 0x54d0: 0x008c, 0x54d1: 0x008c, + 0x54d2: 0x008c, 0x54d3: 0x008c, 0x54d4: 0x008c, 0x54d5: 0x008c, 0x54d6: 0x008c, 0x54d7: 0x008c, + 0x54d8: 0x008c, 0x54d9: 0x008c, 0x54da: 0x008c, 0x54db: 0x008c, 0x54dc: 0x008c, 0x54dd: 0x008c, + // Block 0x154, offset 0x5500 + 0x5501: 0x0040, + 0x5520: 0x0040, 0x5521: 0x0040, 0x5522: 0x0040, 0x5523: 0x0040, + 0x5524: 0x0040, 0x5525: 0x0040, 0x5526: 0x0040, 0x5527: 0x0040, 0x5528: 0x0040, 0x5529: 0x0040, + 0x552a: 0x0040, 0x552b: 0x0040, 0x552c: 0x0040, 0x552d: 0x0040, 0x552e: 0x0040, 0x552f: 0x0040, + 0x5530: 0x0040, 0x5531: 0x0040, 0x5532: 0x0040, 0x5533: 0x0040, 0x5534: 0x0040, 0x5535: 0x0040, + 0x5536: 0x0040, 0x5537: 0x0040, 0x5538: 0x0040, 0x5539: 0x0040, 0x553a: 0x0040, 0x553b: 0x0040, + 0x553c: 0x0040, 0x553d: 0x0040, 0x553e: 0x0040, 0x553f: 0x0040, + // Block 0x155, offset 0x5540 + 0x5540: 0x0040, 0x5541: 0x0040, 0x5542: 0x0040, 0x5543: 0x0040, 0x5544: 0x0040, 0x5545: 0x0040, + 0x5546: 0x0040, 0x5547: 0x0040, 0x5548: 0x0040, 0x5549: 0x0040, 0x554a: 0x0040, 0x554b: 0x0040, + 0x554c: 0x0040, 0x554d: 0x0040, 0x554e: 0x0040, 0x554f: 0x0040, 0x5550: 0x0040, 0x5551: 0x0040, + 0x5552: 0x0040, 0x5553: 0x0040, 0x5554: 0x0040, 0x5555: 0x0040, 0x5556: 0x0040, 0x5557: 0x0040, + 0x5558: 0x0040, 0x5559: 0x0040, 0x555a: 0x0040, 0x555b: 0x0040, 0x555c: 0x0040, 0x555d: 0x0040, + 0x555e: 0x0040, 0x555f: 0x0040, 0x5560: 0x0040, 0x5561: 0x0040, 0x5562: 0x0040, 0x5563: 0x0040, + 0x5564: 0x0040, 0x5565: 0x0040, 0x5566: 0x0040, 0x5567: 0x0040, 0x5568: 0x0040, 0x5569: 0x0040, + 0x556a: 0x0040, 0x556b: 0x0040, 0x556c: 0x0040, 0x556d: 0x0040, 0x556e: 0x0040, 0x556f: 0x0040, + // Block 0x156, offset 0x5580 + 0x5580: 0x0040, 0x5581: 0x0040, 0x5582: 0x0040, 0x5583: 0x0040, 0x5584: 0x0040, 0x5585: 0x0040, + 0x5586: 0x0040, 0x5587: 0x0040, 0x5588: 0x0040, 0x5589: 0x0040, 0x558a: 0x0040, 0x558b: 0x0040, + 0x558c: 0x0040, 0x558d: 0x0040, 0x558e: 0x0040, 0x558f: 0x0040, 0x5590: 0x0040, 0x5591: 0x0040, + 0x5592: 0x0040, 0x5593: 0x0040, 0x5594: 0x0040, 0x5595: 0x0040, 0x5596: 0x0040, 0x5597: 0x0040, + 0x5598: 0x0040, 0x5599: 0x0040, 0x559a: 0x0040, 0x559b: 0x0040, 0x559c: 0x0040, 0x559d: 0x0040, + 0x559e: 0x0040, 0x559f: 0x0040, 0x55a0: 0x0040, 0x55a1: 0x0040, 0x55a2: 0x0040, 0x55a3: 0x0040, + 0x55a4: 0x0040, 0x55a5: 0x0040, 0x55a6: 0x0040, 0x55a7: 0x0040, 0x55a8: 0x0040, 0x55a9: 0x0040, + 0x55aa: 0x0040, 0x55ab: 0x0040, 0x55ac: 0x0040, 0x55ad: 0x0040, 0x55ae: 0x0040, 0x55af: 0x0040, + 0x55b0: 0x0040, 0x55b1: 0x0040, 0x55b2: 0x0040, 0x55b3: 0x0040, 0x55b4: 0x0040, 0x55b5: 0x0040, + 0x55b6: 0x0040, 0x55b7: 0x0040, 0x55b8: 0x0040, 0x55b9: 0x0040, 0x55ba: 0x0040, 0x55bb: 0x0040, + 0x55bc: 0x0040, 0x55bd: 0x0040, +} + +// derivedPropertiesIndex: 37 blocks, 2368 entries, 4736 bytes +// Block 0 is the zero block. +var derivedPropertiesIndex = [2368]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc6: 0x05, 0xc7: 0x06, + 0xc8: 0x05, 0xc9: 0x05, 0xca: 0x07, 0xcb: 0x08, 0xcc: 0x09, 0xcd: 0x0a, 0xce: 0x0b, 0xcf: 0x0c, + 0xd0: 0x05, 0xd1: 0x05, 0xd2: 0x0d, 0xd3: 0x05, 0xd4: 0x0e, 0xd5: 0x0f, 0xd6: 0x10, 0xd7: 0x11, + 0xd8: 0x12, 0xd9: 0x13, 0xda: 0x14, 0xdb: 0x15, 0xdc: 0x16, 0xdd: 0x17, 0xde: 0x18, 0xdf: 0x19, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x0a, 0xec: 0x0a, 0xed: 0x0b, 0xee: 0x0c, 0xef: 0x0d, + 0xf0: 0x1e, 0xf3: 0x21, 0xf4: 0x22, + // Block 0x4, offset 0x100 + 0x120: 0x1a, 0x121: 0x1b, 0x122: 0x1c, 0x123: 0x1d, 0x124: 0x1e, 0x125: 0x1f, 0x126: 0x20, 0x127: 0x21, + 0x128: 0x22, 0x129: 0x23, 0x12a: 0x24, 0x12b: 0x25, 0x12c: 0x26, 0x12d: 0x27, 0x12e: 0x28, 0x12f: 0x29, + 0x130: 0x2a, 0x131: 0x2b, 0x132: 0x2c, 0x133: 0x2d, 0x134: 0x2e, 0x135: 0x2f, 0x136: 0x30, 0x137: 0x31, + 0x138: 0x32, 0x139: 0x33, 0x13a: 0x34, 0x13b: 0x35, 0x13c: 0x36, 0x13d: 0x37, 0x13e: 0x38, 0x13f: 0x39, + // Block 0x5, offset 0x140 + 0x140: 0x3a, 0x141: 0x3b, 0x142: 0x3c, 0x143: 0x3d, 0x144: 0x3e, 0x145: 0x3e, 0x146: 0x3e, 0x147: 0x3e, + 0x148: 0x05, 0x149: 0x3f, 0x14a: 0x40, 0x14b: 0x41, 0x14c: 0x42, 0x14d: 0x43, 0x14e: 0x44, 0x14f: 0x45, + 0x150: 0x46, 0x151: 0x05, 0x152: 0x05, 0x153: 0x05, 0x154: 0x05, 0x155: 0x05, 0x156: 0x05, 0x157: 0x05, + 0x158: 0x05, 0x159: 0x47, 0x15a: 0x48, 0x15b: 0x49, 0x15c: 0x4a, 0x15d: 0x4b, 0x15e: 0x4c, 0x15f: 0x4d, + 0x160: 0x4e, 0x161: 0x4f, 0x162: 0x50, 0x163: 0x51, 0x164: 0x52, 0x165: 0x53, 0x166: 0x54, 0x167: 0x55, + 0x168: 0x56, 0x169: 0x57, 0x16a: 0x58, 0x16c: 0x59, 0x16d: 0x5a, 0x16e: 0x5b, 0x16f: 0x5c, + 0x170: 0x5d, 0x171: 0x5e, 0x172: 0x5f, 0x173: 0x60, 0x174: 0x61, 0x175: 0x62, 0x176: 0x63, 0x177: 0x64, + 0x178: 0x05, 0x179: 0x05, 0x17a: 0x65, 0x17b: 0x05, 0x17c: 0x66, 0x17d: 0x67, 0x17e: 0x68, 0x17f: 0x69, + // Block 0x6, offset 0x180 + 0x180: 0x6a, 0x181: 0x6b, 0x182: 0x6c, 0x183: 0x6d, 0x184: 0x6e, 0x185: 0x6f, 0x186: 0x70, 0x187: 0x71, + 0x188: 0x71, 0x189: 0x71, 0x18a: 0x71, 0x18b: 0x71, 0x18c: 0x71, 0x18d: 0x71, 0x18e: 0x71, 0x18f: 0x71, + 0x190: 0x72, 0x191: 0x73, 0x192: 0x71, 0x193: 0x71, 0x194: 0x71, 0x195: 0x71, 0x196: 0x71, 0x197: 0x71, + 0x198: 0x71, 0x199: 0x71, 0x19a: 0x71, 0x19b: 0x71, 0x19c: 0x71, 0x19d: 0x71, 0x19e: 0x71, 0x19f: 0x71, + 0x1a0: 0x71, 0x1a1: 0x71, 0x1a2: 0x71, 0x1a3: 0x71, 0x1a4: 0x71, 0x1a5: 0x71, 0x1a6: 0x71, 0x1a7: 0x71, + 0x1a8: 0x71, 0x1a9: 0x71, 0x1aa: 0x71, 0x1ab: 0x71, 0x1ac: 0x71, 0x1ad: 0x74, 0x1ae: 0x75, 0x1af: 0x76, + 0x1b0: 0x77, 0x1b1: 0x78, 0x1b2: 0x05, 0x1b3: 0x79, 0x1b4: 0x7a, 0x1b5: 0x7b, 0x1b6: 0x7c, 0x1b7: 0x7d, + 0x1b8: 0x7e, 0x1b9: 0x7f, 0x1ba: 0x80, 0x1bb: 0x81, 0x1bc: 0x82, 0x1bd: 0x82, 0x1be: 0x82, 0x1bf: 0x83, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x84, 0x1c1: 0x85, 0x1c2: 0x86, 0x1c3: 0x87, 0x1c4: 0x88, 0x1c5: 0x89, 0x1c6: 0x8a, 0x1c7: 0x8b, + 0x1c8: 0x8c, 0x1c9: 0x71, 0x1ca: 0x71, 0x1cb: 0x8d, 0x1cc: 0x82, 0x1cd: 0x8e, 0x1ce: 0x71, 0x1cf: 0x71, + 0x1d0: 0x8f, 0x1d1: 0x8f, 0x1d2: 0x8f, 0x1d3: 0x8f, 0x1d4: 0x8f, 0x1d5: 0x8f, 0x1d6: 0x8f, 0x1d7: 0x8f, + 0x1d8: 0x8f, 0x1d9: 0x8f, 0x1da: 0x8f, 0x1db: 0x8f, 0x1dc: 0x8f, 0x1dd: 0x8f, 0x1de: 0x8f, 0x1df: 0x8f, + 0x1e0: 0x8f, 0x1e1: 0x8f, 0x1e2: 0x8f, 0x1e3: 0x8f, 0x1e4: 0x8f, 0x1e5: 0x8f, 0x1e6: 0x8f, 0x1e7: 0x8f, + 0x1e8: 0x8f, 0x1e9: 0x8f, 0x1ea: 0x8f, 0x1eb: 0x8f, 0x1ec: 0x8f, 0x1ed: 0x8f, 0x1ee: 0x8f, 0x1ef: 0x8f, + 0x1f0: 0x8f, 0x1f1: 0x8f, 0x1f2: 0x8f, 0x1f3: 0x8f, 0x1f4: 0x8f, 0x1f5: 0x8f, 0x1f6: 0x8f, 0x1f7: 0x8f, + 0x1f8: 0x8f, 0x1f9: 0x8f, 0x1fa: 0x8f, 0x1fb: 0x8f, 0x1fc: 0x8f, 0x1fd: 0x8f, 0x1fe: 0x8f, 0x1ff: 0x8f, + // Block 0x8, offset 0x200 + 0x200: 0x8f, 0x201: 0x8f, 0x202: 0x8f, 0x203: 0x8f, 0x204: 0x8f, 0x205: 0x8f, 0x206: 0x8f, 0x207: 0x8f, + 0x208: 0x8f, 0x209: 0x8f, 0x20a: 0x8f, 0x20b: 0x8f, 0x20c: 0x8f, 0x20d: 0x8f, 0x20e: 0x8f, 0x20f: 0x8f, + 0x210: 0x8f, 0x211: 0x8f, 0x212: 0x8f, 0x213: 0x8f, 0x214: 0x8f, 0x215: 0x8f, 0x216: 0x8f, 0x217: 0x8f, + 0x218: 0x8f, 0x219: 0x8f, 0x21a: 0x8f, 0x21b: 0x8f, 0x21c: 0x8f, 0x21d: 0x8f, 0x21e: 0x8f, 0x21f: 0x8f, + 0x220: 0x8f, 0x221: 0x8f, 0x222: 0x8f, 0x223: 0x8f, 0x224: 0x8f, 0x225: 0x8f, 0x226: 0x8f, 0x227: 0x8f, + 0x228: 0x8f, 0x229: 0x8f, 0x22a: 0x8f, 0x22b: 0x8f, 0x22c: 0x8f, 0x22d: 0x8f, 0x22e: 0x8f, 0x22f: 0x8f, + 0x230: 0x8f, 0x231: 0x8f, 0x232: 0x8f, 0x233: 0x8f, 0x234: 0x8f, 0x235: 0x8f, 0x236: 0x90, 0x237: 0x71, + 0x238: 0x8f, 0x239: 0x8f, 0x23a: 0x8f, 0x23b: 0x8f, 0x23c: 0x8f, 0x23d: 0x8f, 0x23e: 0x8f, 0x23f: 0x8f, + // Block 0x9, offset 0x240 + 0x240: 0x8f, 0x241: 0x8f, 0x242: 0x8f, 0x243: 0x8f, 0x244: 0x8f, 0x245: 0x8f, 0x246: 0x8f, 0x247: 0x8f, + 0x248: 0x8f, 0x249: 0x8f, 0x24a: 0x8f, 0x24b: 0x8f, 0x24c: 0x8f, 0x24d: 0x8f, 0x24e: 0x8f, 0x24f: 0x8f, + 0x250: 0x8f, 0x251: 0x8f, 0x252: 0x8f, 0x253: 0x8f, 0x254: 0x8f, 0x255: 0x8f, 0x256: 0x8f, 0x257: 0x8f, + 0x258: 0x8f, 0x259: 0x8f, 0x25a: 0x8f, 0x25b: 0x8f, 0x25c: 0x8f, 0x25d: 0x8f, 0x25e: 0x8f, 0x25f: 0x8f, + 0x260: 0x8f, 0x261: 0x8f, 0x262: 0x8f, 0x263: 0x8f, 0x264: 0x8f, 0x265: 0x8f, 0x266: 0x8f, 0x267: 0x8f, + 0x268: 0x8f, 0x269: 0x8f, 0x26a: 0x8f, 0x26b: 0x8f, 0x26c: 0x8f, 0x26d: 0x8f, 0x26e: 0x8f, 0x26f: 0x8f, + 0x270: 0x8f, 0x271: 0x8f, 0x272: 0x8f, 0x273: 0x8f, 0x274: 0x8f, 0x275: 0x8f, 0x276: 0x8f, 0x277: 0x8f, + 0x278: 0x8f, 0x279: 0x8f, 0x27a: 0x8f, 0x27b: 0x8f, 0x27c: 0x8f, 0x27d: 0x8f, 0x27e: 0x8f, 0x27f: 0x8f, + // Block 0xa, offset 0x280 + 0x280: 0x8f, 0x281: 0x8f, 0x282: 0x8f, 0x283: 0x8f, 0x284: 0x8f, 0x285: 0x8f, 0x286: 0x8f, 0x287: 0x8f, + 0x288: 0x8f, 0x289: 0x8f, 0x28a: 0x8f, 0x28b: 0x8f, 0x28c: 0x8f, 0x28d: 0x8f, 0x28e: 0x8f, 0x28f: 0x8f, + 0x290: 0x8f, 0x291: 0x8f, 0x292: 0x8f, 0x293: 0x8f, 0x294: 0x8f, 0x295: 0x8f, 0x296: 0x8f, 0x297: 0x8f, + 0x298: 0x8f, 0x299: 0x8f, 0x29a: 0x8f, 0x29b: 0x8f, 0x29c: 0x8f, 0x29d: 0x8f, 0x29e: 0x8f, 0x29f: 0x8f, + 0x2a0: 0x8f, 0x2a1: 0x8f, 0x2a2: 0x8f, 0x2a3: 0x8f, 0x2a4: 0x8f, 0x2a5: 0x8f, 0x2a6: 0x8f, 0x2a7: 0x8f, + 0x2a8: 0x8f, 0x2a9: 0x8f, 0x2aa: 0x8f, 0x2ab: 0x8f, 0x2ac: 0x8f, 0x2ad: 0x8f, 0x2ae: 0x8f, 0x2af: 0x8f, + 0x2b0: 0x8f, 0x2b1: 0x8f, 0x2b2: 0x8f, 0x2b3: 0x8f, 0x2b4: 0x8f, 0x2b5: 0x8f, 0x2b6: 0x8f, 0x2b7: 0x8f, + 0x2b8: 0x8f, 0x2b9: 0x8f, 0x2ba: 0x8f, 0x2bb: 0x8f, 0x2bc: 0x8f, 0x2bd: 0x8f, 0x2be: 0x8f, 0x2bf: 0x91, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x05, 0x2c1: 0x05, 0x2c2: 0x05, 0x2c3: 0x05, 0x2c4: 0x05, 0x2c5: 0x05, 0x2c6: 0x05, 0x2c7: 0x05, + 0x2c8: 0x05, 0x2c9: 0x05, 0x2ca: 0x05, 0x2cb: 0x05, 0x2cc: 0x05, 0x2cd: 0x05, 0x2ce: 0x05, 0x2cf: 0x05, + 0x2d0: 0x05, 0x2d1: 0x05, 0x2d2: 0x92, 0x2d3: 0x93, 0x2d4: 0x05, 0x2d5: 0x05, 0x2d6: 0x05, 0x2d7: 0x05, + 0x2d8: 0x94, 0x2d9: 0x95, 0x2da: 0x96, 0x2db: 0x97, 0x2dc: 0x98, 0x2dd: 0x99, 0x2de: 0x9a, 0x2df: 0x9b, + 0x2e0: 0x9c, 0x2e1: 0x9d, 0x2e2: 0x05, 0x2e3: 0x9e, 0x2e4: 0x9f, 0x2e5: 0xa0, 0x2e6: 0xa1, 0x2e7: 0xa2, + 0x2e8: 0xa3, 0x2e9: 0xa4, 0x2ea: 0xa5, 0x2eb: 0xa6, 0x2ec: 0xa7, 0x2ed: 0xa8, 0x2ee: 0x05, 0x2ef: 0xa9, + 0x2f0: 0x05, 0x2f1: 0x05, 0x2f2: 0x05, 0x2f3: 0x05, 0x2f4: 0x05, 0x2f5: 0x05, 0x2f6: 0x05, 0x2f7: 0x05, + 0x2f8: 0x05, 0x2f9: 0x05, 0x2fa: 0x05, 0x2fb: 0x05, 0x2fc: 0x05, 0x2fd: 0x05, 0x2fe: 0x05, 0x2ff: 0x05, + // Block 0xc, offset 0x300 + 0x300: 0x05, 0x301: 0x05, 0x302: 0x05, 0x303: 0x05, 0x304: 0x05, 0x305: 0x05, 0x306: 0x05, 0x307: 0x05, + 0x308: 0x05, 0x309: 0x05, 0x30a: 0x05, 0x30b: 0x05, 0x30c: 0x05, 0x30d: 0x05, 0x30e: 0x05, 0x30f: 0x05, + 0x310: 0x05, 0x311: 0x05, 0x312: 0x05, 0x313: 0x05, 0x314: 0x05, 0x315: 0x05, 0x316: 0x05, 0x317: 0x05, + 0x318: 0x05, 0x319: 0x05, 0x31a: 0x05, 0x31b: 0x05, 0x31c: 0x05, 0x31d: 0x05, 0x31e: 0x05, 0x31f: 0x05, + 0x320: 0x05, 0x321: 0x05, 0x322: 0x05, 0x323: 0x05, 0x324: 0x05, 0x325: 0x05, 0x326: 0x05, 0x327: 0x05, + 0x328: 0x05, 0x329: 0x05, 0x32a: 0x05, 0x32b: 0x05, 0x32c: 0x05, 0x32d: 0x05, 0x32e: 0x05, 0x32f: 0x05, + 0x330: 0x05, 0x331: 0x05, 0x332: 0x05, 0x333: 0x05, 0x334: 0x05, 0x335: 0x05, 0x336: 0x05, 0x337: 0x05, + 0x338: 0x05, 0x339: 0x05, 0x33a: 0x05, 0x33b: 0x05, 0x33c: 0x05, 0x33d: 0x05, 0x33e: 0x05, 0x33f: 0x05, + // Block 0xd, offset 0x340 + 0x340: 0x05, 0x341: 0x05, 0x342: 0x05, 0x343: 0x05, 0x344: 0x05, 0x345: 0x05, 0x346: 0x05, 0x347: 0x05, + 0x348: 0x05, 0x349: 0x05, 0x34a: 0x05, 0x34b: 0x05, 0x34c: 0x05, 0x34d: 0x05, 0x34e: 0x05, 0x34f: 0x05, + 0x350: 0x05, 0x351: 0x05, 0x352: 0x05, 0x353: 0x05, 0x354: 0x05, 0x355: 0x05, 0x356: 0x05, 0x357: 0x05, + 0x358: 0x05, 0x359: 0x05, 0x35a: 0x05, 0x35b: 0x05, 0x35c: 0x05, 0x35d: 0x05, 0x35e: 0xaa, 0x35f: 0xab, + // Block 0xe, offset 0x380 + 0x380: 0x3e, 0x381: 0x3e, 0x382: 0x3e, 0x383: 0x3e, 0x384: 0x3e, 0x385: 0x3e, 0x386: 0x3e, 0x387: 0x3e, + 0x388: 0x3e, 0x389: 0x3e, 0x38a: 0x3e, 0x38b: 0x3e, 0x38c: 0x3e, 0x38d: 0x3e, 0x38e: 0x3e, 0x38f: 0x3e, + 0x390: 0x3e, 0x391: 0x3e, 0x392: 0x3e, 0x393: 0x3e, 0x394: 0x3e, 0x395: 0x3e, 0x396: 0x3e, 0x397: 0x3e, + 0x398: 0x3e, 0x399: 0x3e, 0x39a: 0x3e, 0x39b: 0x3e, 0x39c: 0x3e, 0x39d: 0x3e, 0x39e: 0x3e, 0x39f: 0x3e, + 0x3a0: 0x3e, 0x3a1: 0x3e, 0x3a2: 0x3e, 0x3a3: 0x3e, 0x3a4: 0x3e, 0x3a5: 0x3e, 0x3a6: 0x3e, 0x3a7: 0x3e, + 0x3a8: 0x3e, 0x3a9: 0x3e, 0x3aa: 0x3e, 0x3ab: 0x3e, 0x3ac: 0x3e, 0x3ad: 0x3e, 0x3ae: 0x3e, 0x3af: 0x3e, + 0x3b0: 0x3e, 0x3b1: 0x3e, 0x3b2: 0x3e, 0x3b3: 0x3e, 0x3b4: 0x3e, 0x3b5: 0x3e, 0x3b6: 0x3e, 0x3b7: 0x3e, + 0x3b8: 0x3e, 0x3b9: 0x3e, 0x3ba: 0x3e, 0x3bb: 0x3e, 0x3bc: 0x3e, 0x3bd: 0x3e, 0x3be: 0x3e, 0x3bf: 0x3e, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x3e, 0x3c1: 0x3e, 0x3c2: 0x3e, 0x3c3: 0x3e, 0x3c4: 0x3e, 0x3c5: 0x3e, 0x3c6: 0x3e, 0x3c7: 0x3e, + 0x3c8: 0x3e, 0x3c9: 0x3e, 0x3ca: 0x3e, 0x3cb: 0x3e, 0x3cc: 0x3e, 0x3cd: 0x3e, 0x3ce: 0x3e, 0x3cf: 0x3e, + 0x3d0: 0x3e, 0x3d1: 0x3e, 0x3d2: 0x3e, 0x3d3: 0x3e, 0x3d4: 0x3e, 0x3d5: 0x3e, 0x3d6: 0x3e, 0x3d7: 0x3e, + 0x3d8: 0x3e, 0x3d9: 0x3e, 0x3da: 0x3e, 0x3db: 0x3e, 0x3dc: 0x3e, 0x3dd: 0x3e, 0x3de: 0x3e, 0x3df: 0x3e, + 0x3e0: 0x3e, 0x3e1: 0x3e, 0x3e2: 0x3e, 0x3e3: 0x3e, 0x3e4: 0x82, 0x3e5: 0x82, 0x3e6: 0x82, 0x3e7: 0x82, + 0x3e8: 0xac, 0x3e9: 0xad, 0x3ea: 0x82, 0x3eb: 0xae, 0x3ec: 0xaf, 0x3ed: 0xb0, 0x3ee: 0x71, 0x3ef: 0xb1, + 0x3f0: 0x71, 0x3f1: 0x71, 0x3f2: 0x71, 0x3f3: 0x71, 0x3f4: 0x71, 0x3f5: 0xb2, 0x3f6: 0xb3, 0x3f7: 0xb4, + 0x3f8: 0xb5, 0x3f9: 0xb6, 0x3fa: 0x71, 0x3fb: 0xb7, 0x3fc: 0xb8, 0x3fd: 0xb9, 0x3fe: 0xba, 0x3ff: 0xbb, + // Block 0x10, offset 0x400 + 0x400: 0xbc, 0x401: 0xbd, 0x402: 0x05, 0x403: 0xbe, 0x404: 0xbf, 0x405: 0xc0, 0x406: 0xc1, 0x407: 0xc2, + 0x40a: 0xc3, 0x40b: 0xc4, 0x40c: 0xc5, 0x40d: 0xc6, 0x40e: 0xc7, 0x40f: 0xc8, + 0x410: 0x05, 0x411: 0x05, 0x412: 0xc9, 0x413: 0xca, 0x414: 0xcb, 0x415: 0xcc, + 0x418: 0x05, 0x419: 0x05, 0x41a: 0x05, 0x41b: 0x05, 0x41c: 0xcd, 0x41d: 0xce, + 0x420: 0xcf, 0x421: 0xd0, 0x422: 0xd1, 0x423: 0xd2, 0x424: 0xd3, 0x426: 0xd4, 0x427: 0xb3, + 0x428: 0xd5, 0x429: 0xd6, 0x42a: 0xd7, 0x42b: 0xd8, 0x42c: 0xd9, 0x42d: 0xda, 0x42e: 0xdb, + 0x430: 0x05, 0x431: 0xdc, 0x432: 0xdd, 0x433: 0xde, 0x434: 0xdf, + 0x439: 0xe0, 0x43c: 0xe1, 0x43d: 0xe2, + // Block 0x11, offset 0x440 + 0x440: 0xe3, 0x441: 0xe4, 0x442: 0xe5, 0x443: 0xe6, 0x444: 0xe7, 0x445: 0xe8, 0x446: 0xe9, 0x447: 0xea, + 0x448: 0xeb, 0x44a: 0xec, 0x44b: 0xed, 0x44c: 0xee, 0x44d: 0xef, + 0x450: 0xf0, 0x451: 0xf1, 0x452: 0xf2, 0x453: 0xf3, 0x456: 0xf4, 0x457: 0xf5, + 0x458: 0xf6, 0x459: 0xf7, 0x45a: 0xf8, 0x45b: 0xf9, 0x45c: 0xfa, + 0x460: 0xfb, 0x462: 0xfc, 0x463: 0xfd, + 0x468: 0xfe, 0x469: 0xff, 0x46a: 0x100, 0x46b: 0x101, + 0x470: 0x102, 0x471: 0x103, 0x472: 0x104, 0x474: 0x105, 0x475: 0x106, 0x476: 0x107, + 0x47b: 0x108, + // Block 0x12, offset 0x480 + 0x480: 0x05, 0x481: 0x05, 0x482: 0x05, 0x483: 0x05, 0x484: 0x05, 0x485: 0x05, 0x486: 0x05, 0x487: 0x05, + 0x488: 0x05, 0x489: 0x05, 0x48a: 0x05, 0x48b: 0x05, 0x48c: 0x05, 0x48d: 0x05, 0x48e: 0x109, + 0x490: 0x71, 0x491: 0x10a, 0x492: 0x05, 0x493: 0x05, 0x494: 0x05, 0x495: 0x10b, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x05, 0x4c1: 0x05, 0x4c2: 0x05, 0x4c3: 0x05, 0x4c4: 0x05, 0x4c5: 0x05, 0x4c6: 0x05, 0x4c7: 0x05, + 0x4c8: 0x05, 0x4c9: 0x05, 0x4ca: 0x05, 0x4cb: 0x05, 0x4cc: 0x05, 0x4cd: 0x05, 0x4ce: 0x05, 0x4cf: 0x05, + 0x4d0: 0x10c, + // Block 0x14, offset 0x500 + 0x510: 0x05, 0x511: 0x05, 0x512: 0x05, 0x513: 0x05, 0x514: 0x05, 0x515: 0x05, 0x516: 0x05, 0x517: 0x05, + 0x518: 0x05, 0x519: 0x10d, + // Block 0x15, offset 0x540 + 0x560: 0x05, 0x561: 0x05, 0x562: 0x05, 0x563: 0x05, 0x564: 0x05, 0x565: 0x05, 0x566: 0x05, 0x567: 0x05, + 0x568: 0x101, 0x569: 0x10e, 0x56b: 0x10f, 0x56c: 0x110, 0x56d: 0x111, 0x56e: 0x112, + 0x579: 0x05, 0x57a: 0x113, 0x57c: 0x05, 0x57d: 0x114, 0x57e: 0x115, 0x57f: 0x116, + // Block 0x16, offset 0x580 + 0x580: 0x05, 0x581: 0x05, 0x582: 0x05, 0x583: 0x05, 0x584: 0x05, 0x585: 0x05, 0x586: 0x05, 0x587: 0x05, + 0x588: 0x05, 0x589: 0x05, 0x58a: 0x05, 0x58b: 0x05, 0x58c: 0x05, 0x58d: 0x05, 0x58e: 0x05, 0x58f: 0x05, + 0x590: 0x05, 0x591: 0x05, 0x592: 0x05, 0x593: 0x05, 0x594: 0x05, 0x595: 0x05, 0x596: 0x05, 0x597: 0x05, + 0x598: 0x05, 0x599: 0x05, 0x59a: 0x05, 0x59b: 0x05, 0x59c: 0x05, 0x59d: 0x05, 0x59e: 0x05, 0x59f: 0x117, + 0x5a0: 0x05, 0x5a1: 0x05, 0x5a2: 0x05, 0x5a3: 0x05, 0x5a4: 0x05, 0x5a5: 0x05, 0x5a6: 0x05, 0x5a7: 0x05, + 0x5a8: 0x05, 0x5a9: 0x05, 0x5aa: 0x05, 0x5ab: 0xdd, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x8f, 0x5c1: 0x8f, 0x5c2: 0x8f, 0x5c3: 0x8f, 0x5c4: 0x118, 0x5c5: 0x119, 0x5c6: 0x05, 0x5c7: 0x05, + 0x5c8: 0x05, 0x5c9: 0x05, 0x5ca: 0x05, 0x5cb: 0x11a, + 0x5f0: 0x05, 0x5f1: 0x11b, 0x5f2: 0x11c, + // Block 0x18, offset 0x600 + 0x600: 0x71, 0x601: 0x71, 0x602: 0x71, 0x603: 0x11d, 0x604: 0x11e, 0x605: 0x11f, 0x606: 0x120, 0x607: 0x121, + 0x608: 0xc0, 0x609: 0x122, 0x60b: 0x123, 0x60c: 0x71, 0x60d: 0x124, + 0x610: 0x71, 0x611: 0x125, 0x612: 0x126, 0x613: 0x127, 0x614: 0x128, 0x615: 0x129, 0x616: 0x71, 0x617: 0x71, + 0x618: 0x71, 0x619: 0x71, 0x61a: 0x12a, 0x61b: 0x71, 0x61c: 0x71, 0x61d: 0x71, 0x61e: 0x71, 0x61f: 0x12b, + 0x620: 0x71, 0x621: 0x71, 0x622: 0x71, 0x623: 0x71, 0x624: 0x71, 0x625: 0x71, 0x626: 0x71, 0x627: 0x71, + 0x628: 0x12c, 0x629: 0x12d, 0x62a: 0x12e, + // Block 0x19, offset 0x640 + 0x640: 0x12f, + 0x660: 0x05, 0x661: 0x05, 0x662: 0x05, 0x663: 0x130, 0x664: 0x131, 0x665: 0x132, + 0x671: 0x133, 0x672: 0x134, + 0x678: 0x135, 0x679: 0x136, 0x67a: 0x137, 0x67b: 0x138, + // Block 0x1a, offset 0x680 + 0x680: 0x139, 0x681: 0x71, 0x682: 0x13a, 0x683: 0x13b, 0x684: 0x13c, 0x685: 0x139, 0x686: 0x13d, 0x687: 0x13e, + 0x688: 0x13f, 0x689: 0x140, 0x68c: 0x71, 0x68d: 0x71, 0x68e: 0x71, 0x68f: 0x71, + 0x690: 0x71, 0x691: 0x71, 0x692: 0x71, 0x693: 0x71, 0x694: 0x71, 0x695: 0x71, 0x696: 0x71, 0x697: 0x71, + 0x698: 0x71, 0x699: 0x71, 0x69a: 0x71, 0x69b: 0x141, 0x69c: 0x71, 0x69d: 0x142, 0x69e: 0x71, 0x69f: 0x143, + 0x6a0: 0x144, 0x6a1: 0x145, 0x6a2: 0x146, 0x6a4: 0x147, 0x6a5: 0x148, 0x6a6: 0x149, 0x6a7: 0x14a, + 0x6a9: 0x14b, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x8f, 0x6c1: 0x8f, 0x6c2: 0x8f, 0x6c3: 0x8f, 0x6c4: 0x8f, 0x6c5: 0x8f, 0x6c6: 0x8f, 0x6c7: 0x8f, + 0x6c8: 0x8f, 0x6c9: 0x8f, 0x6ca: 0x8f, 0x6cb: 0x8f, 0x6cc: 0x8f, 0x6cd: 0x8f, 0x6ce: 0x8f, 0x6cf: 0x8f, + 0x6d0: 0x8f, 0x6d1: 0x8f, 0x6d2: 0x8f, 0x6d3: 0x8f, 0x6d4: 0x8f, 0x6d5: 0x8f, 0x6d6: 0x8f, 0x6d7: 0x8f, + 0x6d8: 0x8f, 0x6d9: 0x8f, 0x6da: 0x8f, 0x6db: 0x14c, 0x6dc: 0x8f, 0x6dd: 0x8f, 0x6de: 0x8f, 0x6df: 0x8f, + 0x6e0: 0x8f, 0x6e1: 0x8f, 0x6e2: 0x8f, 0x6e3: 0x8f, 0x6e4: 0x8f, 0x6e5: 0x8f, 0x6e6: 0x8f, 0x6e7: 0x8f, + 0x6e8: 0x8f, 0x6e9: 0x8f, 0x6ea: 0x8f, 0x6eb: 0x8f, 0x6ec: 0x8f, 0x6ed: 0x8f, 0x6ee: 0x8f, 0x6ef: 0x8f, + 0x6f0: 0x8f, 0x6f1: 0x8f, 0x6f2: 0x8f, 0x6f3: 0x8f, 0x6f4: 0x8f, 0x6f5: 0x8f, 0x6f6: 0x8f, 0x6f7: 0x8f, + 0x6f8: 0x8f, 0x6f9: 0x8f, 0x6fa: 0x8f, 0x6fb: 0x8f, 0x6fc: 0x8f, 0x6fd: 0x8f, 0x6fe: 0x8f, 0x6ff: 0x8f, + // Block 0x1c, offset 0x700 + 0x700: 0x8f, 0x701: 0x8f, 0x702: 0x8f, 0x703: 0x8f, 0x704: 0x8f, 0x705: 0x8f, 0x706: 0x8f, 0x707: 0x8f, + 0x708: 0x8f, 0x709: 0x8f, 0x70a: 0x8f, 0x70b: 0x8f, 0x70c: 0x8f, 0x70d: 0x8f, 0x70e: 0x8f, 0x70f: 0x8f, + 0x710: 0x8f, 0x711: 0x8f, 0x712: 0x8f, 0x713: 0x8f, 0x714: 0x8f, 0x715: 0x8f, 0x716: 0x8f, 0x717: 0x8f, + 0x718: 0x8f, 0x719: 0x8f, 0x71a: 0x8f, 0x71b: 0x8f, 0x71c: 0x14d, 0x71d: 0x8f, 0x71e: 0x8f, 0x71f: 0x8f, + 0x720: 0x14e, 0x721: 0x8f, 0x722: 0x8f, 0x723: 0x8f, 0x724: 0x8f, 0x725: 0x8f, 0x726: 0x8f, 0x727: 0x8f, + 0x728: 0x8f, 0x729: 0x8f, 0x72a: 0x8f, 0x72b: 0x8f, 0x72c: 0x8f, 0x72d: 0x8f, 0x72e: 0x8f, 0x72f: 0x8f, + 0x730: 0x8f, 0x731: 0x8f, 0x732: 0x8f, 0x733: 0x8f, 0x734: 0x8f, 0x735: 0x8f, 0x736: 0x8f, 0x737: 0x8f, + 0x738: 0x8f, 0x739: 0x8f, 0x73a: 0x8f, 0x73b: 0x8f, 0x73c: 0x8f, 0x73d: 0x8f, 0x73e: 0x8f, 0x73f: 0x8f, + // Block 0x1d, offset 0x740 + 0x740: 0x8f, 0x741: 0x8f, 0x742: 0x8f, 0x743: 0x8f, 0x744: 0x8f, 0x745: 0x8f, 0x746: 0x8f, 0x747: 0x8f, + 0x748: 0x8f, 0x749: 0x8f, 0x74a: 0x8f, 0x74b: 0x8f, 0x74c: 0x8f, 0x74d: 0x8f, 0x74e: 0x8f, 0x74f: 0x8f, + 0x750: 0x8f, 0x751: 0x8f, 0x752: 0x8f, 0x753: 0x8f, 0x754: 0x8f, 0x755: 0x8f, 0x756: 0x8f, 0x757: 0x8f, + 0x758: 0x8f, 0x759: 0x8f, 0x75a: 0x8f, 0x75b: 0x8f, 0x75c: 0x8f, 0x75d: 0x8f, 0x75e: 0x8f, 0x75f: 0x8f, + 0x760: 0x8f, 0x761: 0x8f, 0x762: 0x8f, 0x763: 0x8f, 0x764: 0x8f, 0x765: 0x8f, 0x766: 0x8f, 0x767: 0x8f, + 0x768: 0x8f, 0x769: 0x8f, 0x76a: 0x8f, 0x76b: 0x8f, 0x76c: 0x8f, 0x76d: 0x8f, 0x76e: 0x8f, 0x76f: 0x8f, + 0x770: 0x8f, 0x771: 0x8f, 0x772: 0x8f, 0x773: 0x8f, 0x774: 0x8f, 0x775: 0x8f, 0x776: 0x8f, 0x777: 0x8f, + 0x778: 0x8f, 0x779: 0x8f, 0x77a: 0x14f, 0x77b: 0x8f, 0x77c: 0x8f, 0x77d: 0x8f, 0x77e: 0x8f, 0x77f: 0x8f, + // Block 0x1e, offset 0x780 + 0x780: 0x8f, 0x781: 0x8f, 0x782: 0x8f, 0x783: 0x8f, 0x784: 0x8f, 0x785: 0x8f, 0x786: 0x8f, 0x787: 0x8f, + 0x788: 0x8f, 0x789: 0x8f, 0x78a: 0x8f, 0x78b: 0x8f, 0x78c: 0x8f, 0x78d: 0x8f, 0x78e: 0x8f, 0x78f: 0x8f, + 0x790: 0x8f, 0x791: 0x8f, 0x792: 0x8f, 0x793: 0x8f, 0x794: 0x8f, 0x795: 0x8f, 0x796: 0x8f, 0x797: 0x8f, + 0x798: 0x8f, 0x799: 0x8f, 0x79a: 0x8f, 0x79b: 0x8f, 0x79c: 0x8f, 0x79d: 0x8f, 0x79e: 0x8f, 0x79f: 0x8f, + 0x7a0: 0x8f, 0x7a1: 0x8f, 0x7a2: 0x8f, 0x7a3: 0x8f, 0x7a4: 0x8f, 0x7a5: 0x8f, 0x7a6: 0x8f, 0x7a7: 0x8f, + 0x7a8: 0x8f, 0x7a9: 0x8f, 0x7aa: 0x8f, 0x7ab: 0x8f, 0x7ac: 0x8f, 0x7ad: 0x8f, 0x7ae: 0x8f, 0x7af: 0x150, + // Block 0x1f, offset 0x7c0 + 0x7e0: 0x82, 0x7e1: 0x82, 0x7e2: 0x82, 0x7e3: 0x82, 0x7e4: 0x82, 0x7e5: 0x82, 0x7e6: 0x82, 0x7e7: 0x82, + 0x7e8: 0x151, + // Block 0x20, offset 0x800 + 0x810: 0x0e, 0x811: 0x0f, 0x812: 0x10, 0x813: 0x11, 0x814: 0x12, 0x816: 0x13, 0x817: 0x0a, + 0x818: 0x14, 0x81b: 0x15, 0x81d: 0x16, 0x81e: 0x17, 0x81f: 0x18, + 0x820: 0x07, 0x821: 0x07, 0x822: 0x07, 0x823: 0x07, 0x824: 0x07, 0x825: 0x07, 0x826: 0x07, 0x827: 0x07, + 0x828: 0x07, 0x829: 0x07, 0x82a: 0x19, 0x82b: 0x1a, 0x82c: 0x1b, 0x82d: 0x07, 0x82e: 0x1c, 0x82f: 0x1d, + // Block 0x21, offset 0x840 + 0x840: 0x152, 0x841: 0x3e, 0x844: 0x3e, 0x845: 0x3e, 0x846: 0x3e, 0x847: 0x153, + // Block 0x22, offset 0x880 + 0x880: 0x3e, 0x881: 0x3e, 0x882: 0x3e, 0x883: 0x3e, 0x884: 0x3e, 0x885: 0x3e, 0x886: 0x3e, 0x887: 0x3e, + 0x888: 0x3e, 0x889: 0x3e, 0x88a: 0x3e, 0x88b: 0x3e, 0x88c: 0x3e, 0x88d: 0x3e, 0x88e: 0x3e, 0x88f: 0x3e, + 0x890: 0x3e, 0x891: 0x3e, 0x892: 0x3e, 0x893: 0x3e, 0x894: 0x3e, 0x895: 0x3e, 0x896: 0x3e, 0x897: 0x3e, + 0x898: 0x3e, 0x899: 0x3e, 0x89a: 0x3e, 0x89b: 0x3e, 0x89c: 0x3e, 0x89d: 0x3e, 0x89e: 0x3e, 0x89f: 0x3e, + 0x8a0: 0x3e, 0x8a1: 0x3e, 0x8a2: 0x3e, 0x8a3: 0x3e, 0x8a4: 0x3e, 0x8a5: 0x3e, 0x8a6: 0x3e, 0x8a7: 0x3e, + 0x8a8: 0x3e, 0x8a9: 0x3e, 0x8aa: 0x3e, 0x8ab: 0x3e, 0x8ac: 0x3e, 0x8ad: 0x3e, 0x8ae: 0x3e, 0x8af: 0x3e, + 0x8b0: 0x3e, 0x8b1: 0x3e, 0x8b2: 0x3e, 0x8b3: 0x3e, 0x8b4: 0x3e, 0x8b5: 0x3e, 0x8b6: 0x3e, 0x8b7: 0x3e, + 0x8b8: 0x3e, 0x8b9: 0x3e, 0x8ba: 0x3e, 0x8bb: 0x3e, 0x8bc: 0x3e, 0x8bd: 0x3e, 0x8be: 0x3e, 0x8bf: 0x154, + // Block 0x23, offset 0x8c0 + 0x8e0: 0x1f, + 0x8f0: 0x0c, 0x8f1: 0x0c, 0x8f2: 0x0c, 0x8f3: 0x0c, 0x8f4: 0x0c, 0x8f5: 0x0c, 0x8f6: 0x0c, 0x8f7: 0x0c, + 0x8f8: 0x0c, 0x8f9: 0x0c, 0x8fa: 0x0c, 0x8fb: 0x0c, 0x8fc: 0x0c, 0x8fd: 0x0c, 0x8fe: 0x0c, 0x8ff: 0x20, + // Block 0x24, offset 0x900 + 0x900: 0x0c, 0x901: 0x0c, 0x902: 0x0c, 0x903: 0x0c, 0x904: 0x0c, 0x905: 0x0c, 0x906: 0x0c, 0x907: 0x0c, + 0x908: 0x0c, 0x909: 0x0c, 0x90a: 0x0c, 0x90b: 0x0c, 0x90c: 0x0c, 0x90d: 0x0c, 0x90e: 0x0c, 0x90f: 0x20, +} + +// Total table size 26688 bytes (26KiB); checksum: 811C9DC5 diff --git a/vendor/golang.org/x/text/secure/precis/tables12.0.0.go b/vendor/golang.org/x/text/secure/precis/tables12.0.0.go new file mode 100644 index 00000000000..254bbc7930e --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/tables12.0.0.go @@ -0,0 +1,4119 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +//go:build go1.14 && !go1.16 +// +build go1.14,!go1.16 + +package precis + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "12.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// derivedPropertiesTrie. Total size: 27264 bytes (26.62 KiB). Checksum: 529104c7ecd852f6. +type derivedPropertiesTrie struct{} + +func newDerivedPropertiesTrie(i int) *derivedPropertiesTrie { + return &derivedPropertiesTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *derivedPropertiesTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(derivedPropertiesValues[n<<6+uint32(b)]) + } +} + +// derivedPropertiesValues: 352 blocks, 22528 entries, 22528 bytes +// The third block is the zero block. +var derivedPropertiesValues = [22528]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x0040, 0x01: 0x0040, 0x02: 0x0040, 0x03: 0x0040, 0x04: 0x0040, 0x05: 0x0040, + 0x06: 0x0040, 0x07: 0x0040, 0x08: 0x0040, 0x09: 0x0040, 0x0a: 0x0040, 0x0b: 0x0040, + 0x0c: 0x0040, 0x0d: 0x0040, 0x0e: 0x0040, 0x0f: 0x0040, 0x10: 0x0040, 0x11: 0x0040, + 0x12: 0x0040, 0x13: 0x0040, 0x14: 0x0040, 0x15: 0x0040, 0x16: 0x0040, 0x17: 0x0040, + 0x18: 0x0040, 0x19: 0x0040, 0x1a: 0x0040, 0x1b: 0x0040, 0x1c: 0x0040, 0x1d: 0x0040, + 0x1e: 0x0040, 0x1f: 0x0040, 0x20: 0x0080, 0x21: 0x00c0, 0x22: 0x00c0, 0x23: 0x00c0, + 0x24: 0x00c0, 0x25: 0x00c0, 0x26: 0x00c0, 0x27: 0x00c0, 0x28: 0x00c0, 0x29: 0x00c0, + 0x2a: 0x00c0, 0x2b: 0x00c0, 0x2c: 0x00c0, 0x2d: 0x00c0, 0x2e: 0x00c0, 0x2f: 0x00c0, + 0x30: 0x00c0, 0x31: 0x00c0, 0x32: 0x00c0, 0x33: 0x00c0, 0x34: 0x00c0, 0x35: 0x00c0, + 0x36: 0x00c0, 0x37: 0x00c0, 0x38: 0x00c0, 0x39: 0x00c0, 0x3a: 0x00c0, 0x3b: 0x00c0, + 0x3c: 0x00c0, 0x3d: 0x00c0, 0x3e: 0x00c0, 0x3f: 0x00c0, + // Block 0x1, offset 0x40 + 0x40: 0x00c0, 0x41: 0x00c0, 0x42: 0x00c0, 0x43: 0x00c0, 0x44: 0x00c0, 0x45: 0x00c0, + 0x46: 0x00c0, 0x47: 0x00c0, 0x48: 0x00c0, 0x49: 0x00c0, 0x4a: 0x00c0, 0x4b: 0x00c0, + 0x4c: 0x00c0, 0x4d: 0x00c0, 0x4e: 0x00c0, 0x4f: 0x00c0, 0x50: 0x00c0, 0x51: 0x00c0, + 0x52: 0x00c0, 0x53: 0x00c0, 0x54: 0x00c0, 0x55: 0x00c0, 0x56: 0x00c0, 0x57: 0x00c0, + 0x58: 0x00c0, 0x59: 0x00c0, 0x5a: 0x00c0, 0x5b: 0x00c0, 0x5c: 0x00c0, 0x5d: 0x00c0, + 0x5e: 0x00c0, 0x5f: 0x00c0, 0x60: 0x00c0, 0x61: 0x00c0, 0x62: 0x00c0, 0x63: 0x00c0, + 0x64: 0x00c0, 0x65: 0x00c0, 0x66: 0x00c0, 0x67: 0x00c0, 0x68: 0x00c0, 0x69: 0x00c0, + 0x6a: 0x00c0, 0x6b: 0x00c0, 0x6c: 0x00c7, 0x6d: 0x00c0, 0x6e: 0x00c0, 0x6f: 0x00c0, + 0x70: 0x00c0, 0x71: 0x00c0, 0x72: 0x00c0, 0x73: 0x00c0, 0x74: 0x00c0, 0x75: 0x00c0, + 0x76: 0x00c0, 0x77: 0x00c0, 0x78: 0x00c0, 0x79: 0x00c0, 0x7a: 0x00c0, 0x7b: 0x00c0, + 0x7c: 0x00c0, 0x7d: 0x00c0, 0x7e: 0x00c0, 0x7f: 0x0040, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x0080, 0xe1: 0x0080, 0xe2: 0x0080, 0xe3: 0x0080, + 0xe4: 0x0080, 0xe5: 0x0080, 0xe6: 0x0080, 0xe7: 0x0080, 0xe8: 0x0080, 0xe9: 0x0080, + 0xea: 0x0080, 0xeb: 0x0080, 0xec: 0x0080, 0xed: 0x0040, 0xee: 0x0080, 0xef: 0x0080, + 0xf0: 0x0080, 0xf1: 0x0080, 0xf2: 0x0080, 0xf3: 0x0080, 0xf4: 0x0080, 0xf5: 0x0080, + 0xf6: 0x0080, 0xf7: 0x004f, 0xf8: 0x0080, 0xf9: 0x0080, 0xfa: 0x0080, 0xfb: 0x0080, + 0xfc: 0x0080, 0xfd: 0x0080, 0xfe: 0x0080, 0xff: 0x0080, + // Block 0x4, offset 0x100 + 0x100: 0x00c0, 0x101: 0x00c0, 0x102: 0x00c0, 0x103: 0x00c0, 0x104: 0x00c0, 0x105: 0x00c0, + 0x106: 0x00c0, 0x107: 0x00c0, 0x108: 0x00c0, 0x109: 0x00c0, 0x10a: 0x00c0, 0x10b: 0x00c0, + 0x10c: 0x00c0, 0x10d: 0x00c0, 0x10e: 0x00c0, 0x10f: 0x00c0, 0x110: 0x00c0, 0x111: 0x00c0, + 0x112: 0x00c0, 0x113: 0x00c0, 0x114: 0x00c0, 0x115: 0x00c0, 0x116: 0x00c0, 0x117: 0x0080, + 0x118: 0x00c0, 0x119: 0x00c0, 0x11a: 0x00c0, 0x11b: 0x00c0, 0x11c: 0x00c0, 0x11d: 0x00c0, + 0x11e: 0x00c0, 0x11f: 0x00c0, 0x120: 0x00c0, 0x121: 0x00c0, 0x122: 0x00c0, 0x123: 0x00c0, + 0x124: 0x00c0, 0x125: 0x00c0, 0x126: 0x00c0, 0x127: 0x00c0, 0x128: 0x00c0, 0x129: 0x00c0, + 0x12a: 0x00c0, 0x12b: 0x00c0, 0x12c: 0x00c0, 0x12d: 0x00c0, 0x12e: 0x00c0, 0x12f: 0x00c0, + 0x130: 0x00c0, 0x131: 0x00c0, 0x132: 0x00c0, 0x133: 0x00c0, 0x134: 0x00c0, 0x135: 0x00c0, + 0x136: 0x00c0, 0x137: 0x0080, 0x138: 0x00c0, 0x139: 0x00c0, 0x13a: 0x00c0, 0x13b: 0x00c0, + 0x13c: 0x00c0, 0x13d: 0x00c0, 0x13e: 0x00c0, 0x13f: 0x00c0, + // Block 0x5, offset 0x140 + 0x140: 0x00c0, 0x141: 0x00c0, 0x142: 0x00c0, 0x143: 0x00c0, 0x144: 0x00c0, 0x145: 0x00c0, + 0x146: 0x00c0, 0x147: 0x00c0, 0x148: 0x00c0, 0x149: 0x00c0, 0x14a: 0x00c0, 0x14b: 0x00c0, + 0x14c: 0x00c0, 0x14d: 0x00c0, 0x14e: 0x00c0, 0x14f: 0x00c0, 0x150: 0x00c0, 0x151: 0x00c0, + 0x152: 0x00c0, 0x153: 0x00c0, 0x154: 0x00c0, 0x155: 0x00c0, 0x156: 0x00c0, 0x157: 0x00c0, + 0x158: 0x00c0, 0x159: 0x00c0, 0x15a: 0x00c0, 0x15b: 0x00c0, 0x15c: 0x00c0, 0x15d: 0x00c0, + 0x15e: 0x00c0, 0x15f: 0x00c0, 0x160: 0x00c0, 0x161: 0x00c0, 0x162: 0x00c0, 0x163: 0x00c0, + 0x164: 0x00c0, 0x165: 0x00c0, 0x166: 0x00c0, 0x167: 0x00c0, 0x168: 0x00c0, 0x169: 0x00c0, + 0x16a: 0x00c0, 0x16b: 0x00c0, 0x16c: 0x00c0, 0x16d: 0x00c0, 0x16e: 0x00c0, 0x16f: 0x00c0, + 0x170: 0x00c0, 0x171: 0x00c0, 0x172: 0x0080, 0x173: 0x0080, 0x174: 0x00c0, 0x175: 0x00c0, + 0x176: 0x00c0, 0x177: 0x00c0, 0x178: 0x00c0, 0x179: 0x00c0, 0x17a: 0x00c0, 0x17b: 0x00c0, + 0x17c: 0x00c0, 0x17d: 0x00c0, 0x17e: 0x00c0, 0x17f: 0x0080, + // Block 0x6, offset 0x180 + 0x180: 0x0080, 0x181: 0x00c0, 0x182: 0x00c0, 0x183: 0x00c0, 0x184: 0x00c0, 0x185: 0x00c0, + 0x186: 0x00c0, 0x187: 0x00c0, 0x188: 0x00c0, 0x189: 0x0080, 0x18a: 0x00c0, 0x18b: 0x00c0, + 0x18c: 0x00c0, 0x18d: 0x00c0, 0x18e: 0x00c0, 0x18f: 0x00c0, 0x190: 0x00c0, 0x191: 0x00c0, + 0x192: 0x00c0, 0x193: 0x00c0, 0x194: 0x00c0, 0x195: 0x00c0, 0x196: 0x00c0, 0x197: 0x00c0, + 0x198: 0x00c0, 0x199: 0x00c0, 0x19a: 0x00c0, 0x19b: 0x00c0, 0x19c: 0x00c0, 0x19d: 0x00c0, + 0x19e: 0x00c0, 0x19f: 0x00c0, 0x1a0: 0x00c0, 0x1a1: 0x00c0, 0x1a2: 0x00c0, 0x1a3: 0x00c0, + 0x1a4: 0x00c0, 0x1a5: 0x00c0, 0x1a6: 0x00c0, 0x1a7: 0x00c0, 0x1a8: 0x00c0, 0x1a9: 0x00c0, + 0x1aa: 0x00c0, 0x1ab: 0x00c0, 0x1ac: 0x00c0, 0x1ad: 0x00c0, 0x1ae: 0x00c0, 0x1af: 0x00c0, + 0x1b0: 0x00c0, 0x1b1: 0x00c0, 0x1b2: 0x00c0, 0x1b3: 0x00c0, 0x1b4: 0x00c0, 0x1b5: 0x00c0, + 0x1b6: 0x00c0, 0x1b7: 0x00c0, 0x1b8: 0x00c0, 0x1b9: 0x00c0, 0x1ba: 0x00c0, 0x1bb: 0x00c0, + 0x1bc: 0x00c0, 0x1bd: 0x00c0, 0x1be: 0x00c0, 0x1bf: 0x0080, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x00c0, 0x1c1: 0x00c0, 0x1c2: 0x00c0, 0x1c3: 0x00c0, 0x1c4: 0x00c0, 0x1c5: 0x00c0, + 0x1c6: 0x00c0, 0x1c7: 0x00c0, 0x1c8: 0x00c0, 0x1c9: 0x00c0, 0x1ca: 0x00c0, 0x1cb: 0x00c0, + 0x1cc: 0x00c0, 0x1cd: 0x00c0, 0x1ce: 0x00c0, 0x1cf: 0x00c0, 0x1d0: 0x00c0, 0x1d1: 0x00c0, + 0x1d2: 0x00c0, 0x1d3: 0x00c0, 0x1d4: 0x00c0, 0x1d5: 0x00c0, 0x1d6: 0x00c0, 0x1d7: 0x00c0, + 0x1d8: 0x00c0, 0x1d9: 0x00c0, 0x1da: 0x00c0, 0x1db: 0x00c0, 0x1dc: 0x00c0, 0x1dd: 0x00c0, + 0x1de: 0x00c0, 0x1df: 0x00c0, 0x1e0: 0x00c0, 0x1e1: 0x00c0, 0x1e2: 0x00c0, 0x1e3: 0x00c0, + 0x1e4: 0x00c0, 0x1e5: 0x00c0, 0x1e6: 0x00c0, 0x1e7: 0x00c0, 0x1e8: 0x00c0, 0x1e9: 0x00c0, + 0x1ea: 0x00c0, 0x1eb: 0x00c0, 0x1ec: 0x00c0, 0x1ed: 0x00c0, 0x1ee: 0x00c0, 0x1ef: 0x00c0, + 0x1f0: 0x00c0, 0x1f1: 0x00c0, 0x1f2: 0x00c0, 0x1f3: 0x00c0, 0x1f4: 0x00c0, 0x1f5: 0x00c0, + 0x1f6: 0x00c0, 0x1f7: 0x00c0, 0x1f8: 0x00c0, 0x1f9: 0x00c0, 0x1fa: 0x00c0, 0x1fb: 0x00c0, + 0x1fc: 0x00c0, 0x1fd: 0x00c0, 0x1fe: 0x00c0, 0x1ff: 0x00c0, + // Block 0x8, offset 0x200 + 0x200: 0x00c0, 0x201: 0x00c0, 0x202: 0x00c0, 0x203: 0x00c0, 0x204: 0x0080, 0x205: 0x0080, + 0x206: 0x0080, 0x207: 0x0080, 0x208: 0x0080, 0x209: 0x0080, 0x20a: 0x0080, 0x20b: 0x0080, + 0x20c: 0x0080, 0x20d: 0x00c0, 0x20e: 0x00c0, 0x20f: 0x00c0, 0x210: 0x00c0, 0x211: 0x00c0, + 0x212: 0x00c0, 0x213: 0x00c0, 0x214: 0x00c0, 0x215: 0x00c0, 0x216: 0x00c0, 0x217: 0x00c0, + 0x218: 0x00c0, 0x219: 0x00c0, 0x21a: 0x00c0, 0x21b: 0x00c0, 0x21c: 0x00c0, 0x21d: 0x00c0, + 0x21e: 0x00c0, 0x21f: 0x00c0, 0x220: 0x00c0, 0x221: 0x00c0, 0x222: 0x00c0, 0x223: 0x00c0, + 0x224: 0x00c0, 0x225: 0x00c0, 0x226: 0x00c0, 0x227: 0x00c0, 0x228: 0x00c0, 0x229: 0x00c0, + 0x22a: 0x00c0, 0x22b: 0x00c0, 0x22c: 0x00c0, 0x22d: 0x00c0, 0x22e: 0x00c0, 0x22f: 0x00c0, + 0x230: 0x00c0, 0x231: 0x0080, 0x232: 0x0080, 0x233: 0x0080, 0x234: 0x00c0, 0x235: 0x00c0, + 0x236: 0x00c0, 0x237: 0x00c0, 0x238: 0x00c0, 0x239: 0x00c0, 0x23a: 0x00c0, 0x23b: 0x00c0, + 0x23c: 0x00c0, 0x23d: 0x00c0, 0x23e: 0x00c0, 0x23f: 0x00c0, + // Block 0x9, offset 0x240 + 0x240: 0x00c0, 0x241: 0x00c0, 0x242: 0x00c0, 0x243: 0x00c0, 0x244: 0x00c0, 0x245: 0x00c0, + 0x246: 0x00c0, 0x247: 0x00c0, 0x248: 0x00c0, 0x249: 0x00c0, 0x24a: 0x00c0, 0x24b: 0x00c0, + 0x24c: 0x00c0, 0x24d: 0x00c0, 0x24e: 0x00c0, 0x24f: 0x00c0, 0x250: 0x00c0, 0x251: 0x00c0, + 0x252: 0x00c0, 0x253: 0x00c0, 0x254: 0x00c0, 0x255: 0x00c0, 0x256: 0x00c0, 0x257: 0x00c0, + 0x258: 0x00c0, 0x259: 0x00c0, 0x25a: 0x00c0, 0x25b: 0x00c0, 0x25c: 0x00c0, 0x25d: 0x00c0, + 0x25e: 0x00c0, 0x25f: 0x00c0, 0x260: 0x00c0, 0x261: 0x00c0, 0x262: 0x00c0, 0x263: 0x00c0, + 0x264: 0x00c0, 0x265: 0x00c0, 0x266: 0x00c0, 0x267: 0x00c0, 0x268: 0x00c0, 0x269: 0x00c0, + 0x26a: 0x00c0, 0x26b: 0x00c0, 0x26c: 0x00c0, 0x26d: 0x00c0, 0x26e: 0x00c0, 0x26f: 0x00c0, + 0x270: 0x0080, 0x271: 0x0080, 0x272: 0x0080, 0x273: 0x0080, 0x274: 0x0080, 0x275: 0x0080, + 0x276: 0x0080, 0x277: 0x0080, 0x278: 0x0080, 0x279: 0x00c0, 0x27a: 0x00c0, 0x27b: 0x00c0, + 0x27c: 0x00c0, 0x27d: 0x00c0, 0x27e: 0x00c0, 0x27f: 0x00c0, + // Block 0xa, offset 0x280 + 0x280: 0x00c0, 0x281: 0x00c0, 0x282: 0x0080, 0x283: 0x0080, 0x284: 0x0080, 0x285: 0x0080, + 0x286: 0x00c0, 0x287: 0x00c0, 0x288: 0x00c0, 0x289: 0x00c0, 0x28a: 0x00c0, 0x28b: 0x00c0, + 0x28c: 0x00c0, 0x28d: 0x00c0, 0x28e: 0x00c0, 0x28f: 0x00c0, 0x290: 0x00c0, 0x291: 0x00c0, + 0x292: 0x0080, 0x293: 0x0080, 0x294: 0x0080, 0x295: 0x0080, 0x296: 0x0080, 0x297: 0x0080, + 0x298: 0x0080, 0x299: 0x0080, 0x29a: 0x0080, 0x29b: 0x0080, 0x29c: 0x0080, 0x29d: 0x0080, + 0x29e: 0x0080, 0x29f: 0x0080, 0x2a0: 0x0080, 0x2a1: 0x0080, 0x2a2: 0x0080, 0x2a3: 0x0080, + 0x2a4: 0x0080, 0x2a5: 0x0080, 0x2a6: 0x0080, 0x2a7: 0x0080, 0x2a8: 0x0080, 0x2a9: 0x0080, + 0x2aa: 0x0080, 0x2ab: 0x0080, 0x2ac: 0x00c0, 0x2ad: 0x0080, 0x2ae: 0x00c0, 0x2af: 0x0080, + 0x2b0: 0x0080, 0x2b1: 0x0080, 0x2b2: 0x0080, 0x2b3: 0x0080, 0x2b4: 0x0080, 0x2b5: 0x0080, + 0x2b6: 0x0080, 0x2b7: 0x0080, 0x2b8: 0x0080, 0x2b9: 0x0080, 0x2ba: 0x0080, 0x2bb: 0x0080, + 0x2bc: 0x0080, 0x2bd: 0x0080, 0x2be: 0x0080, 0x2bf: 0x0080, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x00c3, 0x2c1: 0x00c3, 0x2c2: 0x00c3, 0x2c3: 0x00c3, 0x2c4: 0x00c3, 0x2c5: 0x00c3, + 0x2c6: 0x00c3, 0x2c7: 0x00c3, 0x2c8: 0x00c3, 0x2c9: 0x00c3, 0x2ca: 0x00c3, 0x2cb: 0x00c3, + 0x2cc: 0x00c3, 0x2cd: 0x00c3, 0x2ce: 0x00c3, 0x2cf: 0x00c3, 0x2d0: 0x00c3, 0x2d1: 0x00c3, + 0x2d2: 0x00c3, 0x2d3: 0x00c3, 0x2d4: 0x00c3, 0x2d5: 0x00c3, 0x2d6: 0x00c3, 0x2d7: 0x00c3, + 0x2d8: 0x00c3, 0x2d9: 0x00c3, 0x2da: 0x00c3, 0x2db: 0x00c3, 0x2dc: 0x00c3, 0x2dd: 0x00c3, + 0x2de: 0x00c3, 0x2df: 0x00c3, 0x2e0: 0x00c3, 0x2e1: 0x00c3, 0x2e2: 0x00c3, 0x2e3: 0x00c3, + 0x2e4: 0x00c3, 0x2e5: 0x00c3, 0x2e6: 0x00c3, 0x2e7: 0x00c3, 0x2e8: 0x00c3, 0x2e9: 0x00c3, + 0x2ea: 0x00c3, 0x2eb: 0x00c3, 0x2ec: 0x00c3, 0x2ed: 0x00c3, 0x2ee: 0x00c3, 0x2ef: 0x00c3, + 0x2f0: 0x00c3, 0x2f1: 0x00c3, 0x2f2: 0x00c3, 0x2f3: 0x00c3, 0x2f4: 0x00c3, 0x2f5: 0x00c3, + 0x2f6: 0x00c3, 0x2f7: 0x00c3, 0x2f8: 0x00c3, 0x2f9: 0x00c3, 0x2fa: 0x00c3, 0x2fb: 0x00c3, + 0x2fc: 0x00c3, 0x2fd: 0x00c3, 0x2fe: 0x00c3, 0x2ff: 0x00c3, + // Block 0xc, offset 0x300 + 0x300: 0x0083, 0x301: 0x0083, 0x302: 0x00c3, 0x303: 0x0083, 0x304: 0x0083, 0x305: 0x00c3, + 0x306: 0x00c3, 0x307: 0x00c3, 0x308: 0x00c3, 0x309: 0x00c3, 0x30a: 0x00c3, 0x30b: 0x00c3, + 0x30c: 0x00c3, 0x30d: 0x00c3, 0x30e: 0x00c3, 0x30f: 0x0040, 0x310: 0x00c3, 0x311: 0x00c3, + 0x312: 0x00c3, 0x313: 0x00c3, 0x314: 0x00c3, 0x315: 0x00c3, 0x316: 0x00c3, 0x317: 0x00c3, + 0x318: 0x00c3, 0x319: 0x00c3, 0x31a: 0x00c3, 0x31b: 0x00c3, 0x31c: 0x00c3, 0x31d: 0x00c3, + 0x31e: 0x00c3, 0x31f: 0x00c3, 0x320: 0x00c3, 0x321: 0x00c3, 0x322: 0x00c3, 0x323: 0x00c3, + 0x324: 0x00c3, 0x325: 0x00c3, 0x326: 0x00c3, 0x327: 0x00c3, 0x328: 0x00c3, 0x329: 0x00c3, + 0x32a: 0x00c3, 0x32b: 0x00c3, 0x32c: 0x00c3, 0x32d: 0x00c3, 0x32e: 0x00c3, 0x32f: 0x00c3, + 0x330: 0x00c8, 0x331: 0x00c8, 0x332: 0x00c8, 0x333: 0x00c8, 0x334: 0x0080, 0x335: 0x0050, + 0x336: 0x00c8, 0x337: 0x00c8, 0x33a: 0x0088, 0x33b: 0x00c8, + 0x33c: 0x00c8, 0x33d: 0x00c8, 0x33e: 0x0080, 0x33f: 0x00c8, + // Block 0xd, offset 0x340 + 0x344: 0x0088, 0x345: 0x0080, + 0x346: 0x00c8, 0x347: 0x0080, 0x348: 0x00c8, 0x349: 0x00c8, 0x34a: 0x00c8, + 0x34c: 0x00c8, 0x34e: 0x00c8, 0x34f: 0x00c8, 0x350: 0x00c8, 0x351: 0x00c8, + 0x352: 0x00c8, 0x353: 0x00c8, 0x354: 0x00c8, 0x355: 0x00c8, 0x356: 0x00c8, 0x357: 0x00c8, + 0x358: 0x00c8, 0x359: 0x00c8, 0x35a: 0x00c8, 0x35b: 0x00c8, 0x35c: 0x00c8, 0x35d: 0x00c8, + 0x35e: 0x00c8, 0x35f: 0x00c8, 0x360: 0x00c8, 0x361: 0x00c8, 0x363: 0x00c8, + 0x364: 0x00c8, 0x365: 0x00c8, 0x366: 0x00c8, 0x367: 0x00c8, 0x368: 0x00c8, 0x369: 0x00c8, + 0x36a: 0x00c8, 0x36b: 0x00c8, 0x36c: 0x00c8, 0x36d: 0x00c8, 0x36e: 0x00c8, 0x36f: 0x00c8, + 0x370: 0x00c8, 0x371: 0x00c8, 0x372: 0x00c8, 0x373: 0x00c8, 0x374: 0x00c8, 0x375: 0x00c8, + 0x376: 0x00c8, 0x377: 0x00c8, 0x378: 0x00c8, 0x379: 0x00c8, 0x37a: 0x00c8, 0x37b: 0x00c8, + 0x37c: 0x00c8, 0x37d: 0x00c8, 0x37e: 0x00c8, 0x37f: 0x00c8, + // Block 0xe, offset 0x380 + 0x380: 0x00c8, 0x381: 0x00c8, 0x382: 0x00c8, 0x383: 0x00c8, 0x384: 0x00c8, 0x385: 0x00c8, + 0x386: 0x00c8, 0x387: 0x00c8, 0x388: 0x00c8, 0x389: 0x00c8, 0x38a: 0x00c8, 0x38b: 0x00c8, + 0x38c: 0x00c8, 0x38d: 0x00c8, 0x38e: 0x00c8, 0x38f: 0x00c8, 0x390: 0x0088, 0x391: 0x0088, + 0x392: 0x0088, 0x393: 0x0088, 0x394: 0x0088, 0x395: 0x0088, 0x396: 0x0088, 0x397: 0x00c8, + 0x398: 0x00c8, 0x399: 0x00c8, 0x39a: 0x00c8, 0x39b: 0x00c8, 0x39c: 0x00c8, 0x39d: 0x00c8, + 0x39e: 0x00c8, 0x39f: 0x00c8, 0x3a0: 0x00c8, 0x3a1: 0x00c8, 0x3a2: 0x00c0, 0x3a3: 0x00c0, + 0x3a4: 0x00c0, 0x3a5: 0x00c0, 0x3a6: 0x00c0, 0x3a7: 0x00c0, 0x3a8: 0x00c0, 0x3a9: 0x00c0, + 0x3aa: 0x00c0, 0x3ab: 0x00c0, 0x3ac: 0x00c0, 0x3ad: 0x00c0, 0x3ae: 0x00c0, 0x3af: 0x00c0, + 0x3b0: 0x0088, 0x3b1: 0x0088, 0x3b2: 0x0088, 0x3b3: 0x00c8, 0x3b4: 0x0088, 0x3b5: 0x0088, + 0x3b6: 0x0088, 0x3b7: 0x00c8, 0x3b8: 0x00c8, 0x3b9: 0x0088, 0x3ba: 0x00c8, 0x3bb: 0x00c8, + 0x3bc: 0x00c8, 0x3bd: 0x00c8, 0x3be: 0x00c8, 0x3bf: 0x00c8, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x00c0, 0x3c1: 0x00c0, 0x3c2: 0x0080, 0x3c3: 0x00c3, 0x3c4: 0x00c3, 0x3c5: 0x00c3, + 0x3c6: 0x00c3, 0x3c7: 0x00c3, 0x3c8: 0x0083, 0x3c9: 0x0083, 0x3ca: 0x00c0, 0x3cb: 0x00c0, + 0x3cc: 0x00c0, 0x3cd: 0x00c0, 0x3ce: 0x00c0, 0x3cf: 0x00c0, 0x3d0: 0x00c0, 0x3d1: 0x00c0, + 0x3d2: 0x00c0, 0x3d3: 0x00c0, 0x3d4: 0x00c0, 0x3d5: 0x00c0, 0x3d6: 0x00c0, 0x3d7: 0x00c0, + 0x3d8: 0x00c0, 0x3d9: 0x00c0, 0x3da: 0x00c0, 0x3db: 0x00c0, 0x3dc: 0x00c0, 0x3dd: 0x00c0, + 0x3de: 0x00c0, 0x3df: 0x00c0, 0x3e0: 0x00c0, 0x3e1: 0x00c0, 0x3e2: 0x00c0, 0x3e3: 0x00c0, + 0x3e4: 0x00c0, 0x3e5: 0x00c0, 0x3e6: 0x00c0, 0x3e7: 0x00c0, 0x3e8: 0x00c0, 0x3e9: 0x00c0, + 0x3ea: 0x00c0, 0x3eb: 0x00c0, 0x3ec: 0x00c0, 0x3ed: 0x00c0, 0x3ee: 0x00c0, 0x3ef: 0x00c0, + 0x3f0: 0x00c0, 0x3f1: 0x00c0, 0x3f2: 0x00c0, 0x3f3: 0x00c0, 0x3f4: 0x00c0, 0x3f5: 0x00c0, + 0x3f6: 0x00c0, 0x3f7: 0x00c0, 0x3f8: 0x00c0, 0x3f9: 0x00c0, 0x3fa: 0x00c0, 0x3fb: 0x00c0, + 0x3fc: 0x00c0, 0x3fd: 0x00c0, 0x3fe: 0x00c0, 0x3ff: 0x00c0, + // Block 0x10, offset 0x400 + 0x400: 0x00c0, 0x401: 0x00c0, 0x402: 0x00c0, 0x403: 0x00c0, 0x404: 0x00c0, 0x405: 0x00c0, + 0x406: 0x00c0, 0x407: 0x00c0, 0x408: 0x00c0, 0x409: 0x00c0, 0x40a: 0x00c0, 0x40b: 0x00c0, + 0x40c: 0x00c0, 0x40d: 0x00c0, 0x40e: 0x00c0, 0x40f: 0x00c0, 0x410: 0x00c0, 0x411: 0x00c0, + 0x412: 0x00c0, 0x413: 0x00c0, 0x414: 0x00c0, 0x415: 0x00c0, 0x416: 0x00c0, 0x417: 0x00c0, + 0x418: 0x00c0, 0x419: 0x00c0, 0x41a: 0x00c0, 0x41b: 0x00c0, 0x41c: 0x00c0, 0x41d: 0x00c0, + 0x41e: 0x00c0, 0x41f: 0x00c0, 0x420: 0x00c0, 0x421: 0x00c0, 0x422: 0x00c0, 0x423: 0x00c0, + 0x424: 0x00c0, 0x425: 0x00c0, 0x426: 0x00c0, 0x427: 0x00c0, 0x428: 0x00c0, 0x429: 0x00c0, + 0x42a: 0x00c0, 0x42b: 0x00c0, 0x42c: 0x00c0, 0x42d: 0x00c0, 0x42e: 0x00c0, 0x42f: 0x00c0, + 0x431: 0x00c0, 0x432: 0x00c0, 0x433: 0x00c0, 0x434: 0x00c0, 0x435: 0x00c0, + 0x436: 0x00c0, 0x437: 0x00c0, 0x438: 0x00c0, 0x439: 0x00c0, 0x43a: 0x00c0, 0x43b: 0x00c0, + 0x43c: 0x00c0, 0x43d: 0x00c0, 0x43e: 0x00c0, 0x43f: 0x00c0, + // Block 0x11, offset 0x440 + 0x440: 0x00c0, 0x441: 0x00c0, 0x442: 0x00c0, 0x443: 0x00c0, 0x444: 0x00c0, 0x445: 0x00c0, + 0x446: 0x00c0, 0x447: 0x00c0, 0x448: 0x00c0, 0x449: 0x00c0, 0x44a: 0x00c0, 0x44b: 0x00c0, + 0x44c: 0x00c0, 0x44d: 0x00c0, 0x44e: 0x00c0, 0x44f: 0x00c0, 0x450: 0x00c0, 0x451: 0x00c0, + 0x452: 0x00c0, 0x453: 0x00c0, 0x454: 0x00c0, 0x455: 0x00c0, 0x456: 0x00c0, + 0x459: 0x00c0, 0x45a: 0x0080, 0x45b: 0x0080, 0x45c: 0x0080, 0x45d: 0x0080, + 0x45e: 0x0080, 0x45f: 0x0080, 0x460: 0x00c0, 0x461: 0x00c0, 0x462: 0x00c0, 0x463: 0x00c0, + 0x464: 0x00c0, 0x465: 0x00c0, 0x466: 0x00c0, 0x467: 0x00c0, 0x468: 0x00c0, 0x469: 0x00c0, + 0x46a: 0x00c0, 0x46b: 0x00c0, 0x46c: 0x00c0, 0x46d: 0x00c0, 0x46e: 0x00c0, 0x46f: 0x00c0, + 0x470: 0x00c0, 0x471: 0x00c0, 0x472: 0x00c0, 0x473: 0x00c0, 0x474: 0x00c0, 0x475: 0x00c0, + 0x476: 0x00c0, 0x477: 0x00c0, 0x478: 0x00c0, 0x479: 0x00c0, 0x47a: 0x00c0, 0x47b: 0x00c0, + 0x47c: 0x00c0, 0x47d: 0x00c0, 0x47e: 0x00c0, 0x47f: 0x00c0, + // Block 0x12, offset 0x480 + 0x480: 0x00c0, 0x481: 0x00c0, 0x482: 0x00c0, 0x483: 0x00c0, 0x484: 0x00c0, 0x485: 0x00c0, + 0x486: 0x00c0, 0x487: 0x0080, 0x488: 0x00c0, 0x489: 0x0080, 0x48a: 0x0080, + 0x48d: 0x0080, 0x48e: 0x0080, 0x48f: 0x0080, 0x491: 0x00cb, + 0x492: 0x00cb, 0x493: 0x00cb, 0x494: 0x00cb, 0x495: 0x00cb, 0x496: 0x00cb, 0x497: 0x00cb, + 0x498: 0x00cb, 0x499: 0x00cb, 0x49a: 0x00cb, 0x49b: 0x00cb, 0x49c: 0x00cb, 0x49d: 0x00cb, + 0x49e: 0x00cb, 0x49f: 0x00cb, 0x4a0: 0x00cb, 0x4a1: 0x00cb, 0x4a2: 0x00cb, 0x4a3: 0x00cb, + 0x4a4: 0x00cb, 0x4a5: 0x00cb, 0x4a6: 0x00cb, 0x4a7: 0x00cb, 0x4a8: 0x00cb, 0x4a9: 0x00cb, + 0x4aa: 0x00cb, 0x4ab: 0x00cb, 0x4ac: 0x00cb, 0x4ad: 0x00cb, 0x4ae: 0x00cb, 0x4af: 0x00cb, + 0x4b0: 0x00cb, 0x4b1: 0x00cb, 0x4b2: 0x00cb, 0x4b3: 0x00cb, 0x4b4: 0x00cb, 0x4b5: 0x00cb, + 0x4b6: 0x00cb, 0x4b7: 0x00cb, 0x4b8: 0x00cb, 0x4b9: 0x00cb, 0x4ba: 0x00cb, 0x4bb: 0x00cb, + 0x4bc: 0x00cb, 0x4bd: 0x00cb, 0x4be: 0x008a, 0x4bf: 0x00cb, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x008a, 0x4c1: 0x00cb, 0x4c2: 0x00cb, 0x4c3: 0x008a, 0x4c4: 0x00cb, 0x4c5: 0x00cb, + 0x4c6: 0x008a, 0x4c7: 0x00cb, + 0x4d0: 0x00ca, 0x4d1: 0x00ca, + 0x4d2: 0x00ca, 0x4d3: 0x00ca, 0x4d4: 0x00ca, 0x4d5: 0x00ca, 0x4d6: 0x00ca, 0x4d7: 0x00ca, + 0x4d8: 0x00ca, 0x4d9: 0x00ca, 0x4da: 0x00ca, 0x4db: 0x00ca, 0x4dc: 0x00ca, 0x4dd: 0x00ca, + 0x4de: 0x00ca, 0x4df: 0x00ca, 0x4e0: 0x00ca, 0x4e1: 0x00ca, 0x4e2: 0x00ca, 0x4e3: 0x00ca, + 0x4e4: 0x00ca, 0x4e5: 0x00ca, 0x4e6: 0x00ca, 0x4e7: 0x00ca, 0x4e8: 0x00ca, 0x4e9: 0x00ca, + 0x4ea: 0x00ca, 0x4ef: 0x00ca, + 0x4f0: 0x00ca, 0x4f1: 0x00ca, 0x4f2: 0x00ca, 0x4f3: 0x0051, 0x4f4: 0x0051, + // Block 0x14, offset 0x500 + 0x500: 0x0040, 0x501: 0x0040, 0x502: 0x0040, 0x503: 0x0040, 0x504: 0x0040, 0x505: 0x0040, + 0x506: 0x0080, 0x507: 0x0080, 0x508: 0x0080, 0x509: 0x0080, 0x50a: 0x0080, 0x50b: 0x0080, + 0x50c: 0x0080, 0x50d: 0x0080, 0x50e: 0x0080, 0x50f: 0x0080, 0x510: 0x00c3, 0x511: 0x00c3, + 0x512: 0x00c3, 0x513: 0x00c3, 0x514: 0x00c3, 0x515: 0x00c3, 0x516: 0x00c3, 0x517: 0x00c3, + 0x518: 0x00c3, 0x519: 0x00c3, 0x51a: 0x00c3, 0x51b: 0x0080, 0x51c: 0x0040, + 0x51e: 0x0080, 0x51f: 0x0080, 0x520: 0x00c2, 0x521: 0x00c0, 0x522: 0x00c4, 0x523: 0x00c4, + 0x524: 0x00c4, 0x525: 0x00c4, 0x526: 0x00c2, 0x527: 0x00c4, 0x528: 0x00c2, 0x529: 0x00c4, + 0x52a: 0x00c2, 0x52b: 0x00c2, 0x52c: 0x00c2, 0x52d: 0x00c2, 0x52e: 0x00c2, 0x52f: 0x00c4, + 0x530: 0x00c4, 0x531: 0x00c4, 0x532: 0x00c4, 0x533: 0x00c2, 0x534: 0x00c2, 0x535: 0x00c2, + 0x536: 0x00c2, 0x537: 0x00c2, 0x538: 0x00c2, 0x539: 0x00c2, 0x53a: 0x00c2, 0x53b: 0x00c2, + 0x53c: 0x00c2, 0x53d: 0x00c2, 0x53e: 0x00c2, 0x53f: 0x00c2, + // Block 0x15, offset 0x540 + 0x540: 0x0040, 0x541: 0x00c2, 0x542: 0x00c2, 0x543: 0x00c2, 0x544: 0x00c2, 0x545: 0x00c2, + 0x546: 0x00c2, 0x547: 0x00c2, 0x548: 0x00c4, 0x549: 0x00c2, 0x54a: 0x00c2, 0x54b: 0x00c3, + 0x54c: 0x00c3, 0x54d: 0x00c3, 0x54e: 0x00c3, 0x54f: 0x00c3, 0x550: 0x00c3, 0x551: 0x00c3, + 0x552: 0x00c3, 0x553: 0x00c3, 0x554: 0x00c3, 0x555: 0x00c3, 0x556: 0x00c3, 0x557: 0x00c3, + 0x558: 0x00c3, 0x559: 0x00c3, 0x55a: 0x00c3, 0x55b: 0x00c3, 0x55c: 0x00c3, 0x55d: 0x00c3, + 0x55e: 0x00c3, 0x55f: 0x00c3, 0x560: 0x0053, 0x561: 0x0053, 0x562: 0x0053, 0x563: 0x0053, + 0x564: 0x0053, 0x565: 0x0053, 0x566: 0x0053, 0x567: 0x0053, 0x568: 0x0053, 0x569: 0x0053, + 0x56a: 0x0080, 0x56b: 0x0080, 0x56c: 0x0080, 0x56d: 0x0080, 0x56e: 0x00c2, 0x56f: 0x00c2, + 0x570: 0x00c3, 0x571: 0x00c4, 0x572: 0x00c4, 0x573: 0x00c4, 0x574: 0x00c0, 0x575: 0x0084, + 0x576: 0x0084, 0x577: 0x0084, 0x578: 0x0082, 0x579: 0x00c2, 0x57a: 0x00c2, 0x57b: 0x00c2, + 0x57c: 0x00c2, 0x57d: 0x00c2, 0x57e: 0x00c2, 0x57f: 0x00c2, + // Block 0x16, offset 0x580 + 0x580: 0x00c2, 0x581: 0x00c2, 0x582: 0x00c2, 0x583: 0x00c2, 0x584: 0x00c2, 0x585: 0x00c2, + 0x586: 0x00c2, 0x587: 0x00c2, 0x588: 0x00c4, 0x589: 0x00c4, 0x58a: 0x00c4, 0x58b: 0x00c4, + 0x58c: 0x00c4, 0x58d: 0x00c4, 0x58e: 0x00c4, 0x58f: 0x00c4, 0x590: 0x00c4, 0x591: 0x00c4, + 0x592: 0x00c4, 0x593: 0x00c4, 0x594: 0x00c4, 0x595: 0x00c4, 0x596: 0x00c4, 0x597: 0x00c4, + 0x598: 0x00c4, 0x599: 0x00c4, 0x59a: 0x00c2, 0x59b: 0x00c2, 0x59c: 0x00c2, 0x59d: 0x00c2, + 0x59e: 0x00c2, 0x59f: 0x00c2, 0x5a0: 0x00c2, 0x5a1: 0x00c2, 0x5a2: 0x00c2, 0x5a3: 0x00c2, + 0x5a4: 0x00c2, 0x5a5: 0x00c2, 0x5a6: 0x00c2, 0x5a7: 0x00c2, 0x5a8: 0x00c2, 0x5a9: 0x00c2, + 0x5aa: 0x00c2, 0x5ab: 0x00c2, 0x5ac: 0x00c2, 0x5ad: 0x00c2, 0x5ae: 0x00c2, 0x5af: 0x00c2, + 0x5b0: 0x00c2, 0x5b1: 0x00c2, 0x5b2: 0x00c2, 0x5b3: 0x00c2, 0x5b4: 0x00c2, 0x5b5: 0x00c2, + 0x5b6: 0x00c2, 0x5b7: 0x00c2, 0x5b8: 0x00c2, 0x5b9: 0x00c2, 0x5ba: 0x00c2, 0x5bb: 0x00c2, + 0x5bc: 0x00c2, 0x5bd: 0x00c2, 0x5be: 0x00c2, 0x5bf: 0x00c2, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x00c4, 0x5c1: 0x00c2, 0x5c2: 0x00c2, 0x5c3: 0x00c4, 0x5c4: 0x00c4, 0x5c5: 0x00c4, + 0x5c6: 0x00c4, 0x5c7: 0x00c4, 0x5c8: 0x00c4, 0x5c9: 0x00c4, 0x5ca: 0x00c4, 0x5cb: 0x00c4, + 0x5cc: 0x00c2, 0x5cd: 0x00c4, 0x5ce: 0x00c2, 0x5cf: 0x00c4, 0x5d0: 0x00c2, 0x5d1: 0x00c2, + 0x5d2: 0x00c4, 0x5d3: 0x00c4, 0x5d4: 0x0080, 0x5d5: 0x00c4, 0x5d6: 0x00c3, 0x5d7: 0x00c3, + 0x5d8: 0x00c3, 0x5d9: 0x00c3, 0x5da: 0x00c3, 0x5db: 0x00c3, 0x5dc: 0x00c3, 0x5dd: 0x0040, + 0x5de: 0x0080, 0x5df: 0x00c3, 0x5e0: 0x00c3, 0x5e1: 0x00c3, 0x5e2: 0x00c3, 0x5e3: 0x00c3, + 0x5e4: 0x00c3, 0x5e5: 0x00c0, 0x5e6: 0x00c0, 0x5e7: 0x00c3, 0x5e8: 0x00c3, 0x5e9: 0x0080, + 0x5ea: 0x00c3, 0x5eb: 0x00c3, 0x5ec: 0x00c3, 0x5ed: 0x00c3, 0x5ee: 0x00c4, 0x5ef: 0x00c4, + 0x5f0: 0x0054, 0x5f1: 0x0054, 0x5f2: 0x0054, 0x5f3: 0x0054, 0x5f4: 0x0054, 0x5f5: 0x0054, + 0x5f6: 0x0054, 0x5f7: 0x0054, 0x5f8: 0x0054, 0x5f9: 0x0054, 0x5fa: 0x00c2, 0x5fb: 0x00c2, + 0x5fc: 0x00c2, 0x5fd: 0x00c0, 0x5fe: 0x00c0, 0x5ff: 0x00c2, + // Block 0x18, offset 0x600 + 0x600: 0x0080, 0x601: 0x0080, 0x602: 0x0080, 0x603: 0x0080, 0x604: 0x0080, 0x605: 0x0080, + 0x606: 0x0080, 0x607: 0x0080, 0x608: 0x0080, 0x609: 0x0080, 0x60a: 0x0080, 0x60b: 0x0080, + 0x60c: 0x0080, 0x60d: 0x0080, 0x60f: 0x0040, 0x610: 0x00c4, 0x611: 0x00c3, + 0x612: 0x00c2, 0x613: 0x00c2, 0x614: 0x00c2, 0x615: 0x00c4, 0x616: 0x00c4, 0x617: 0x00c4, + 0x618: 0x00c4, 0x619: 0x00c4, 0x61a: 0x00c2, 0x61b: 0x00c2, 0x61c: 0x00c2, 0x61d: 0x00c2, + 0x61e: 0x00c4, 0x61f: 0x00c2, 0x620: 0x00c2, 0x621: 0x00c2, 0x622: 0x00c2, 0x623: 0x00c2, + 0x624: 0x00c2, 0x625: 0x00c2, 0x626: 0x00c2, 0x627: 0x00c2, 0x628: 0x00c4, 0x629: 0x00c2, + 0x62a: 0x00c4, 0x62b: 0x00c2, 0x62c: 0x00c4, 0x62d: 0x00c2, 0x62e: 0x00c2, 0x62f: 0x00c4, + 0x630: 0x00c3, 0x631: 0x00c3, 0x632: 0x00c3, 0x633: 0x00c3, 0x634: 0x00c3, 0x635: 0x00c3, + 0x636: 0x00c3, 0x637: 0x00c3, 0x638: 0x00c3, 0x639: 0x00c3, 0x63a: 0x00c3, 0x63b: 0x00c3, + 0x63c: 0x00c3, 0x63d: 0x00c3, 0x63e: 0x00c3, 0x63f: 0x00c3, + // Block 0x19, offset 0x640 + 0x640: 0x00c3, 0x641: 0x00c3, 0x642: 0x00c3, 0x643: 0x00c3, 0x644: 0x00c3, 0x645: 0x00c3, + 0x646: 0x00c3, 0x647: 0x00c3, 0x648: 0x00c3, 0x649: 0x00c3, 0x64a: 0x00c3, + 0x64d: 0x00c4, 0x64e: 0x00c2, 0x64f: 0x00c2, 0x650: 0x00c2, 0x651: 0x00c2, + 0x652: 0x00c2, 0x653: 0x00c2, 0x654: 0x00c2, 0x655: 0x00c2, 0x656: 0x00c2, 0x657: 0x00c2, + 0x658: 0x00c2, 0x659: 0x00c4, 0x65a: 0x00c4, 0x65b: 0x00c4, 0x65c: 0x00c2, 0x65d: 0x00c2, + 0x65e: 0x00c2, 0x65f: 0x00c2, 0x660: 0x00c2, 0x661: 0x00c2, 0x662: 0x00c2, 0x663: 0x00c2, + 0x664: 0x00c2, 0x665: 0x00c2, 0x666: 0x00c2, 0x667: 0x00c2, 0x668: 0x00c2, 0x669: 0x00c2, + 0x66a: 0x00c2, 0x66b: 0x00c4, 0x66c: 0x00c4, 0x66d: 0x00c2, 0x66e: 0x00c2, 0x66f: 0x00c2, + 0x670: 0x00c2, 0x671: 0x00c4, 0x672: 0x00c2, 0x673: 0x00c4, 0x674: 0x00c4, 0x675: 0x00c2, + 0x676: 0x00c2, 0x677: 0x00c2, 0x678: 0x00c4, 0x679: 0x00c4, 0x67a: 0x00c2, 0x67b: 0x00c2, + 0x67c: 0x00c2, 0x67d: 0x00c2, 0x67e: 0x00c2, 0x67f: 0x00c2, + // Block 0x1a, offset 0x680 + 0x680: 0x00c0, 0x681: 0x00c0, 0x682: 0x00c0, 0x683: 0x00c0, 0x684: 0x00c0, 0x685: 0x00c0, + 0x686: 0x00c0, 0x687: 0x00c0, 0x688: 0x00c0, 0x689: 0x00c0, 0x68a: 0x00c0, 0x68b: 0x00c0, + 0x68c: 0x00c0, 0x68d: 0x00c0, 0x68e: 0x00c0, 0x68f: 0x00c0, 0x690: 0x00c0, 0x691: 0x00c0, + 0x692: 0x00c0, 0x693: 0x00c0, 0x694: 0x00c0, 0x695: 0x00c0, 0x696: 0x00c0, 0x697: 0x00c0, + 0x698: 0x00c0, 0x699: 0x00c0, 0x69a: 0x00c0, 0x69b: 0x00c0, 0x69c: 0x00c0, 0x69d: 0x00c0, + 0x69e: 0x00c0, 0x69f: 0x00c0, 0x6a0: 0x00c0, 0x6a1: 0x00c0, 0x6a2: 0x00c0, 0x6a3: 0x00c0, + 0x6a4: 0x00c0, 0x6a5: 0x00c0, 0x6a6: 0x00c3, 0x6a7: 0x00c3, 0x6a8: 0x00c3, 0x6a9: 0x00c3, + 0x6aa: 0x00c3, 0x6ab: 0x00c3, 0x6ac: 0x00c3, 0x6ad: 0x00c3, 0x6ae: 0x00c3, 0x6af: 0x00c3, + 0x6b0: 0x00c3, 0x6b1: 0x00c0, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x00c0, 0x6c1: 0x00c0, 0x6c2: 0x00c0, 0x6c3: 0x00c0, 0x6c4: 0x00c0, 0x6c5: 0x00c0, + 0x6c6: 0x00c0, 0x6c7: 0x00c0, 0x6c8: 0x00c0, 0x6c9: 0x00c0, 0x6ca: 0x00c2, 0x6cb: 0x00c2, + 0x6cc: 0x00c2, 0x6cd: 0x00c2, 0x6ce: 0x00c2, 0x6cf: 0x00c2, 0x6d0: 0x00c2, 0x6d1: 0x00c2, + 0x6d2: 0x00c2, 0x6d3: 0x00c2, 0x6d4: 0x00c2, 0x6d5: 0x00c2, 0x6d6: 0x00c2, 0x6d7: 0x00c2, + 0x6d8: 0x00c2, 0x6d9: 0x00c2, 0x6da: 0x00c2, 0x6db: 0x00c2, 0x6dc: 0x00c2, 0x6dd: 0x00c2, + 0x6de: 0x00c2, 0x6df: 0x00c2, 0x6e0: 0x00c2, 0x6e1: 0x00c2, 0x6e2: 0x00c2, 0x6e3: 0x00c2, + 0x6e4: 0x00c2, 0x6e5: 0x00c2, 0x6e6: 0x00c2, 0x6e7: 0x00c2, 0x6e8: 0x00c2, 0x6e9: 0x00c2, + 0x6ea: 0x00c2, 0x6eb: 0x00c3, 0x6ec: 0x00c3, 0x6ed: 0x00c3, 0x6ee: 0x00c3, 0x6ef: 0x00c3, + 0x6f0: 0x00c3, 0x6f1: 0x00c3, 0x6f2: 0x00c3, 0x6f3: 0x00c3, 0x6f4: 0x00c0, 0x6f5: 0x00c0, + 0x6f6: 0x0080, 0x6f7: 0x0080, 0x6f8: 0x0080, 0x6f9: 0x0080, 0x6fa: 0x0040, + 0x6fd: 0x00c3, 0x6fe: 0x0080, 0x6ff: 0x0080, + // Block 0x1c, offset 0x700 + 0x700: 0x00c0, 0x701: 0x00c0, 0x702: 0x00c0, 0x703: 0x00c0, 0x704: 0x00c0, 0x705: 0x00c0, + 0x706: 0x00c0, 0x707: 0x00c0, 0x708: 0x00c0, 0x709: 0x00c0, 0x70a: 0x00c0, 0x70b: 0x00c0, + 0x70c: 0x00c0, 0x70d: 0x00c0, 0x70e: 0x00c0, 0x70f: 0x00c0, 0x710: 0x00c0, 0x711: 0x00c0, + 0x712: 0x00c0, 0x713: 0x00c0, 0x714: 0x00c0, 0x715: 0x00c0, 0x716: 0x00c3, 0x717: 0x00c3, + 0x718: 0x00c3, 0x719: 0x00c3, 0x71a: 0x00c0, 0x71b: 0x00c3, 0x71c: 0x00c3, 0x71d: 0x00c3, + 0x71e: 0x00c3, 0x71f: 0x00c3, 0x720: 0x00c3, 0x721: 0x00c3, 0x722: 0x00c3, 0x723: 0x00c3, + 0x724: 0x00c0, 0x725: 0x00c3, 0x726: 0x00c3, 0x727: 0x00c3, 0x728: 0x00c0, 0x729: 0x00c3, + 0x72a: 0x00c3, 0x72b: 0x00c3, 0x72c: 0x00c3, 0x72d: 0x00c3, + 0x730: 0x0080, 0x731: 0x0080, 0x732: 0x0080, 0x733: 0x0080, 0x734: 0x0080, 0x735: 0x0080, + 0x736: 0x0080, 0x737: 0x0080, 0x738: 0x0080, 0x739: 0x0080, 0x73a: 0x0080, 0x73b: 0x0080, + 0x73c: 0x0080, 0x73d: 0x0080, 0x73e: 0x0080, + // Block 0x1d, offset 0x740 + 0x740: 0x00c4, 0x741: 0x00c2, 0x742: 0x00c2, 0x743: 0x00c2, 0x744: 0x00c2, 0x745: 0x00c2, + 0x746: 0x00c4, 0x747: 0x00c4, 0x748: 0x00c2, 0x749: 0x00c4, 0x74a: 0x00c2, 0x74b: 0x00c2, + 0x74c: 0x00c2, 0x74d: 0x00c2, 0x74e: 0x00c2, 0x74f: 0x00c2, 0x750: 0x00c2, 0x751: 0x00c2, + 0x752: 0x00c2, 0x753: 0x00c2, 0x754: 0x00c4, 0x755: 0x00c2, 0x756: 0x00c0, 0x757: 0x00c0, + 0x758: 0x00c0, 0x759: 0x00c3, 0x75a: 0x00c3, 0x75b: 0x00c3, + 0x75e: 0x0080, 0x760: 0x00c2, 0x761: 0x00c0, 0x762: 0x00c2, 0x763: 0x00c2, + 0x764: 0x00c2, 0x765: 0x00c2, 0x766: 0x00c0, 0x767: 0x00c4, 0x768: 0x00c2, 0x769: 0x00c4, + 0x76a: 0x00c4, + // Block 0x1e, offset 0x780 + 0x7a0: 0x00c2, 0x7a1: 0x00c2, 0x7a2: 0x00c2, 0x7a3: 0x00c2, + 0x7a4: 0x00c2, 0x7a5: 0x00c2, 0x7a6: 0x00c2, 0x7a7: 0x00c2, 0x7a8: 0x00c2, 0x7a9: 0x00c2, + 0x7aa: 0x00c4, 0x7ab: 0x00c4, 0x7ac: 0x00c4, 0x7ad: 0x00c0, 0x7ae: 0x00c4, 0x7af: 0x00c2, + 0x7b0: 0x00c2, 0x7b1: 0x00c4, 0x7b2: 0x00c4, 0x7b3: 0x00c2, 0x7b4: 0x00c2, + 0x7b6: 0x00c2, 0x7b7: 0x00c2, 0x7b8: 0x00c2, 0x7b9: 0x00c4, 0x7ba: 0x00c2, 0x7bb: 0x00c2, + 0x7bc: 0x00c2, 0x7bd: 0x00c2, + // Block 0x1f, offset 0x7c0 + 0x7d3: 0x00c3, 0x7d4: 0x00c3, 0x7d5: 0x00c3, 0x7d6: 0x00c3, 0x7d7: 0x00c3, + 0x7d8: 0x00c3, 0x7d9: 0x00c3, 0x7da: 0x00c3, 0x7db: 0x00c3, 0x7dc: 0x00c3, 0x7dd: 0x00c3, + 0x7de: 0x00c3, 0x7df: 0x00c3, 0x7e0: 0x00c3, 0x7e1: 0x00c3, 0x7e2: 0x0040, 0x7e3: 0x00c3, + 0x7e4: 0x00c3, 0x7e5: 0x00c3, 0x7e6: 0x00c3, 0x7e7: 0x00c3, 0x7e8: 0x00c3, 0x7e9: 0x00c3, + 0x7ea: 0x00c3, 0x7eb: 0x00c3, 0x7ec: 0x00c3, 0x7ed: 0x00c3, 0x7ee: 0x00c3, 0x7ef: 0x00c3, + 0x7f0: 0x00c3, 0x7f1: 0x00c3, 0x7f2: 0x00c3, 0x7f3: 0x00c3, 0x7f4: 0x00c3, 0x7f5: 0x00c3, + 0x7f6: 0x00c3, 0x7f7: 0x00c3, 0x7f8: 0x00c3, 0x7f9: 0x00c3, 0x7fa: 0x00c3, 0x7fb: 0x00c3, + 0x7fc: 0x00c3, 0x7fd: 0x00c3, 0x7fe: 0x00c3, 0x7ff: 0x00c3, + // Block 0x20, offset 0x800 + 0x800: 0x00c3, 0x801: 0x00c3, 0x802: 0x00c3, 0x803: 0x00c0, 0x804: 0x00c0, 0x805: 0x00c0, + 0x806: 0x00c0, 0x807: 0x00c0, 0x808: 0x00c0, 0x809: 0x00c0, 0x80a: 0x00c0, 0x80b: 0x00c0, + 0x80c: 0x00c0, 0x80d: 0x00c0, 0x80e: 0x00c0, 0x80f: 0x00c0, 0x810: 0x00c0, 0x811: 0x00c0, + 0x812: 0x00c0, 0x813: 0x00c0, 0x814: 0x00c0, 0x815: 0x00c0, 0x816: 0x00c0, 0x817: 0x00c0, + 0x818: 0x00c0, 0x819: 0x00c0, 0x81a: 0x00c0, 0x81b: 0x00c0, 0x81c: 0x00c0, 0x81d: 0x00c0, + 0x81e: 0x00c0, 0x81f: 0x00c0, 0x820: 0x00c0, 0x821: 0x00c0, 0x822: 0x00c0, 0x823: 0x00c0, + 0x824: 0x00c0, 0x825: 0x00c0, 0x826: 0x00c0, 0x827: 0x00c0, 0x828: 0x00c0, 0x829: 0x00c0, + 0x82a: 0x00c0, 0x82b: 0x00c0, 0x82c: 0x00c0, 0x82d: 0x00c0, 0x82e: 0x00c0, 0x82f: 0x00c0, + 0x830: 0x00c0, 0x831: 0x00c0, 0x832: 0x00c0, 0x833: 0x00c0, 0x834: 0x00c0, 0x835: 0x00c0, + 0x836: 0x00c0, 0x837: 0x00c0, 0x838: 0x00c0, 0x839: 0x00c0, 0x83a: 0x00c3, 0x83b: 0x00c0, + 0x83c: 0x00c3, 0x83d: 0x00c0, 0x83e: 0x00c0, 0x83f: 0x00c0, + // Block 0x21, offset 0x840 + 0x840: 0x00c0, 0x841: 0x00c3, 0x842: 0x00c3, 0x843: 0x00c3, 0x844: 0x00c3, 0x845: 0x00c3, + 0x846: 0x00c3, 0x847: 0x00c3, 0x848: 0x00c3, 0x849: 0x00c0, 0x84a: 0x00c0, 0x84b: 0x00c0, + 0x84c: 0x00c0, 0x84d: 0x00c6, 0x84e: 0x00c0, 0x84f: 0x00c0, 0x850: 0x00c0, 0x851: 0x00c3, + 0x852: 0x00c3, 0x853: 0x00c3, 0x854: 0x00c3, 0x855: 0x00c3, 0x856: 0x00c3, 0x857: 0x00c3, + 0x858: 0x0080, 0x859: 0x0080, 0x85a: 0x0080, 0x85b: 0x0080, 0x85c: 0x0080, 0x85d: 0x0080, + 0x85e: 0x0080, 0x85f: 0x0080, 0x860: 0x00c0, 0x861: 0x00c0, 0x862: 0x00c3, 0x863: 0x00c3, + 0x864: 0x0080, 0x865: 0x0080, 0x866: 0x00c0, 0x867: 0x00c0, 0x868: 0x00c0, 0x869: 0x00c0, + 0x86a: 0x00c0, 0x86b: 0x00c0, 0x86c: 0x00c0, 0x86d: 0x00c0, 0x86e: 0x00c0, 0x86f: 0x00c0, + 0x870: 0x0080, 0x871: 0x00c0, 0x872: 0x00c0, 0x873: 0x00c0, 0x874: 0x00c0, 0x875: 0x00c0, + 0x876: 0x00c0, 0x877: 0x00c0, 0x878: 0x00c0, 0x879: 0x00c0, 0x87a: 0x00c0, 0x87b: 0x00c0, + 0x87c: 0x00c0, 0x87d: 0x00c0, 0x87e: 0x00c0, 0x87f: 0x00c0, + // Block 0x22, offset 0x880 + 0x880: 0x00c0, 0x881: 0x00c3, 0x882: 0x00c0, 0x883: 0x00c0, 0x885: 0x00c0, + 0x886: 0x00c0, 0x887: 0x00c0, 0x888: 0x00c0, 0x889: 0x00c0, 0x88a: 0x00c0, 0x88b: 0x00c0, + 0x88c: 0x00c0, 0x88f: 0x00c0, 0x890: 0x00c0, + 0x893: 0x00c0, 0x894: 0x00c0, 0x895: 0x00c0, 0x896: 0x00c0, 0x897: 0x00c0, + 0x898: 0x00c0, 0x899: 0x00c0, 0x89a: 0x00c0, 0x89b: 0x00c0, 0x89c: 0x00c0, 0x89d: 0x00c0, + 0x89e: 0x00c0, 0x89f: 0x00c0, 0x8a0: 0x00c0, 0x8a1: 0x00c0, 0x8a2: 0x00c0, 0x8a3: 0x00c0, + 0x8a4: 0x00c0, 0x8a5: 0x00c0, 0x8a6: 0x00c0, 0x8a7: 0x00c0, 0x8a8: 0x00c0, + 0x8aa: 0x00c0, 0x8ab: 0x00c0, 0x8ac: 0x00c0, 0x8ad: 0x00c0, 0x8ae: 0x00c0, 0x8af: 0x00c0, + 0x8b0: 0x00c0, 0x8b2: 0x00c0, + 0x8b6: 0x00c0, 0x8b7: 0x00c0, 0x8b8: 0x00c0, 0x8b9: 0x00c0, + 0x8bc: 0x00c3, 0x8bd: 0x00c0, 0x8be: 0x00c0, 0x8bf: 0x00c0, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x00c0, 0x8c1: 0x00c3, 0x8c2: 0x00c3, 0x8c3: 0x00c3, 0x8c4: 0x00c3, + 0x8c7: 0x00c0, 0x8c8: 0x00c0, 0x8cb: 0x00c0, + 0x8cc: 0x00c0, 0x8cd: 0x00c6, 0x8ce: 0x00c0, + 0x8d7: 0x00c0, + 0x8dc: 0x0080, 0x8dd: 0x0080, + 0x8df: 0x0080, 0x8e0: 0x00c0, 0x8e1: 0x00c0, 0x8e2: 0x00c3, 0x8e3: 0x00c3, + 0x8e6: 0x00c0, 0x8e7: 0x00c0, 0x8e8: 0x00c0, 0x8e9: 0x00c0, + 0x8ea: 0x00c0, 0x8eb: 0x00c0, 0x8ec: 0x00c0, 0x8ed: 0x00c0, 0x8ee: 0x00c0, 0x8ef: 0x00c0, + 0x8f0: 0x00c0, 0x8f1: 0x00c0, 0x8f2: 0x0080, 0x8f3: 0x0080, 0x8f4: 0x0080, 0x8f5: 0x0080, + 0x8f6: 0x0080, 0x8f7: 0x0080, 0x8f8: 0x0080, 0x8f9: 0x0080, 0x8fa: 0x0080, 0x8fb: 0x0080, + 0x8fc: 0x00c0, 0x8fd: 0x0080, 0x8fe: 0x00c3, + // Block 0x24, offset 0x900 + 0x901: 0x00c3, 0x902: 0x00c3, 0x903: 0x00c0, 0x905: 0x00c0, + 0x906: 0x00c0, 0x907: 0x00c0, 0x908: 0x00c0, 0x909: 0x00c0, 0x90a: 0x00c0, + 0x90f: 0x00c0, 0x910: 0x00c0, + 0x913: 0x00c0, 0x914: 0x00c0, 0x915: 0x00c0, 0x916: 0x00c0, 0x917: 0x00c0, + 0x918: 0x00c0, 0x919: 0x00c0, 0x91a: 0x00c0, 0x91b: 0x00c0, 0x91c: 0x00c0, 0x91d: 0x00c0, + 0x91e: 0x00c0, 0x91f: 0x00c0, 0x920: 0x00c0, 0x921: 0x00c0, 0x922: 0x00c0, 0x923: 0x00c0, + 0x924: 0x00c0, 0x925: 0x00c0, 0x926: 0x00c0, 0x927: 0x00c0, 0x928: 0x00c0, + 0x92a: 0x00c0, 0x92b: 0x00c0, 0x92c: 0x00c0, 0x92d: 0x00c0, 0x92e: 0x00c0, 0x92f: 0x00c0, + 0x930: 0x00c0, 0x932: 0x00c0, 0x933: 0x0080, 0x935: 0x00c0, + 0x936: 0x0080, 0x938: 0x00c0, 0x939: 0x00c0, + 0x93c: 0x00c3, 0x93e: 0x00c0, 0x93f: 0x00c0, + // Block 0x25, offset 0x940 + 0x940: 0x00c0, 0x941: 0x00c3, 0x942: 0x00c3, + 0x947: 0x00c3, 0x948: 0x00c3, 0x94b: 0x00c3, + 0x94c: 0x00c3, 0x94d: 0x00c6, 0x951: 0x00c3, + 0x959: 0x0080, 0x95a: 0x0080, 0x95b: 0x0080, 0x95c: 0x00c0, + 0x95e: 0x0080, + 0x966: 0x00c0, 0x967: 0x00c0, 0x968: 0x00c0, 0x969: 0x00c0, + 0x96a: 0x00c0, 0x96b: 0x00c0, 0x96c: 0x00c0, 0x96d: 0x00c0, 0x96e: 0x00c0, 0x96f: 0x00c0, + 0x970: 0x00c3, 0x971: 0x00c3, 0x972: 0x00c0, 0x973: 0x00c0, 0x974: 0x00c0, 0x975: 0x00c3, + 0x976: 0x0080, + // Block 0x26, offset 0x980 + 0x981: 0x00c3, 0x982: 0x00c3, 0x983: 0x00c0, 0x985: 0x00c0, + 0x986: 0x00c0, 0x987: 0x00c0, 0x988: 0x00c0, 0x989: 0x00c0, 0x98a: 0x00c0, 0x98b: 0x00c0, + 0x98c: 0x00c0, 0x98d: 0x00c0, 0x98f: 0x00c0, 0x990: 0x00c0, 0x991: 0x00c0, + 0x993: 0x00c0, 0x994: 0x00c0, 0x995: 0x00c0, 0x996: 0x00c0, 0x997: 0x00c0, + 0x998: 0x00c0, 0x999: 0x00c0, 0x99a: 0x00c0, 0x99b: 0x00c0, 0x99c: 0x00c0, 0x99d: 0x00c0, + 0x99e: 0x00c0, 0x99f: 0x00c0, 0x9a0: 0x00c0, 0x9a1: 0x00c0, 0x9a2: 0x00c0, 0x9a3: 0x00c0, + 0x9a4: 0x00c0, 0x9a5: 0x00c0, 0x9a6: 0x00c0, 0x9a7: 0x00c0, 0x9a8: 0x00c0, + 0x9aa: 0x00c0, 0x9ab: 0x00c0, 0x9ac: 0x00c0, 0x9ad: 0x00c0, 0x9ae: 0x00c0, 0x9af: 0x00c0, + 0x9b0: 0x00c0, 0x9b2: 0x00c0, 0x9b3: 0x00c0, 0x9b5: 0x00c0, + 0x9b6: 0x00c0, 0x9b7: 0x00c0, 0x9b8: 0x00c0, 0x9b9: 0x00c0, + 0x9bc: 0x00c3, 0x9bd: 0x00c0, 0x9be: 0x00c0, 0x9bf: 0x00c0, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x00c0, 0x9c1: 0x00c3, 0x9c2: 0x00c3, 0x9c3: 0x00c3, 0x9c4: 0x00c3, 0x9c5: 0x00c3, + 0x9c7: 0x00c3, 0x9c8: 0x00c3, 0x9c9: 0x00c0, 0x9cb: 0x00c0, + 0x9cc: 0x00c0, 0x9cd: 0x00c6, 0x9d0: 0x00c0, + 0x9e0: 0x00c0, 0x9e1: 0x00c0, 0x9e2: 0x00c3, 0x9e3: 0x00c3, + 0x9e6: 0x00c0, 0x9e7: 0x00c0, 0x9e8: 0x00c0, 0x9e9: 0x00c0, + 0x9ea: 0x00c0, 0x9eb: 0x00c0, 0x9ec: 0x00c0, 0x9ed: 0x00c0, 0x9ee: 0x00c0, 0x9ef: 0x00c0, + 0x9f0: 0x0080, 0x9f1: 0x0080, + 0x9f9: 0x00c0, 0x9fa: 0x00c3, 0x9fb: 0x00c3, + 0x9fc: 0x00c3, 0x9fd: 0x00c3, 0x9fe: 0x00c3, 0x9ff: 0x00c3, + // Block 0x28, offset 0xa00 + 0xa01: 0x00c3, 0xa02: 0x00c0, 0xa03: 0x00c0, 0xa05: 0x00c0, + 0xa06: 0x00c0, 0xa07: 0x00c0, 0xa08: 0x00c0, 0xa09: 0x00c0, 0xa0a: 0x00c0, 0xa0b: 0x00c0, + 0xa0c: 0x00c0, 0xa0f: 0x00c0, 0xa10: 0x00c0, + 0xa13: 0x00c0, 0xa14: 0x00c0, 0xa15: 0x00c0, 0xa16: 0x00c0, 0xa17: 0x00c0, + 0xa18: 0x00c0, 0xa19: 0x00c0, 0xa1a: 0x00c0, 0xa1b: 0x00c0, 0xa1c: 0x00c0, 0xa1d: 0x00c0, + 0xa1e: 0x00c0, 0xa1f: 0x00c0, 0xa20: 0x00c0, 0xa21: 0x00c0, 0xa22: 0x00c0, 0xa23: 0x00c0, + 0xa24: 0x00c0, 0xa25: 0x00c0, 0xa26: 0x00c0, 0xa27: 0x00c0, 0xa28: 0x00c0, + 0xa2a: 0x00c0, 0xa2b: 0x00c0, 0xa2c: 0x00c0, 0xa2d: 0x00c0, 0xa2e: 0x00c0, 0xa2f: 0x00c0, + 0xa30: 0x00c0, 0xa32: 0x00c0, 0xa33: 0x00c0, 0xa35: 0x00c0, + 0xa36: 0x00c0, 0xa37: 0x00c0, 0xa38: 0x00c0, 0xa39: 0x00c0, + 0xa3c: 0x00c3, 0xa3d: 0x00c0, 0xa3e: 0x00c0, 0xa3f: 0x00c3, + // Block 0x29, offset 0xa40 + 0xa40: 0x00c0, 0xa41: 0x00c3, 0xa42: 0x00c3, 0xa43: 0x00c3, 0xa44: 0x00c3, + 0xa47: 0x00c0, 0xa48: 0x00c0, 0xa4b: 0x00c0, + 0xa4c: 0x00c0, 0xa4d: 0x00c6, + 0xa56: 0x00c3, 0xa57: 0x00c0, + 0xa5c: 0x0080, 0xa5d: 0x0080, + 0xa5f: 0x00c0, 0xa60: 0x00c0, 0xa61: 0x00c0, 0xa62: 0x00c3, 0xa63: 0x00c3, + 0xa66: 0x00c0, 0xa67: 0x00c0, 0xa68: 0x00c0, 0xa69: 0x00c0, + 0xa6a: 0x00c0, 0xa6b: 0x00c0, 0xa6c: 0x00c0, 0xa6d: 0x00c0, 0xa6e: 0x00c0, 0xa6f: 0x00c0, + 0xa70: 0x0080, 0xa71: 0x00c0, 0xa72: 0x0080, 0xa73: 0x0080, 0xa74: 0x0080, 0xa75: 0x0080, + 0xa76: 0x0080, 0xa77: 0x0080, + // Block 0x2a, offset 0xa80 + 0xa82: 0x00c3, 0xa83: 0x00c0, 0xa85: 0x00c0, + 0xa86: 0x00c0, 0xa87: 0x00c0, 0xa88: 0x00c0, 0xa89: 0x00c0, 0xa8a: 0x00c0, + 0xa8e: 0x00c0, 0xa8f: 0x00c0, 0xa90: 0x00c0, + 0xa92: 0x00c0, 0xa93: 0x00c0, 0xa94: 0x00c0, 0xa95: 0x00c0, + 0xa99: 0x00c0, 0xa9a: 0x00c0, 0xa9c: 0x00c0, + 0xa9e: 0x00c0, 0xa9f: 0x00c0, 0xaa3: 0x00c0, + 0xaa4: 0x00c0, 0xaa8: 0x00c0, 0xaa9: 0x00c0, + 0xaaa: 0x00c0, 0xaae: 0x00c0, 0xaaf: 0x00c0, + 0xab0: 0x00c0, 0xab1: 0x00c0, 0xab2: 0x00c0, 0xab3: 0x00c0, 0xab4: 0x00c0, 0xab5: 0x00c0, + 0xab6: 0x00c0, 0xab7: 0x00c0, 0xab8: 0x00c0, 0xab9: 0x00c0, + 0xabe: 0x00c0, 0xabf: 0x00c0, + // Block 0x2b, offset 0xac0 + 0xac0: 0x00c3, 0xac1: 0x00c0, 0xac2: 0x00c0, + 0xac6: 0x00c0, 0xac7: 0x00c0, 0xac8: 0x00c0, 0xaca: 0x00c0, 0xacb: 0x00c0, + 0xacc: 0x00c0, 0xacd: 0x00c6, 0xad0: 0x00c0, + 0xad7: 0x00c0, + 0xae6: 0x00c0, 0xae7: 0x00c0, 0xae8: 0x00c0, 0xae9: 0x00c0, + 0xaea: 0x00c0, 0xaeb: 0x00c0, 0xaec: 0x00c0, 0xaed: 0x00c0, 0xaee: 0x00c0, 0xaef: 0x00c0, + 0xaf0: 0x0080, 0xaf1: 0x0080, 0xaf2: 0x0080, 0xaf3: 0x0080, 0xaf4: 0x0080, 0xaf5: 0x0080, + 0xaf6: 0x0080, 0xaf7: 0x0080, 0xaf8: 0x0080, 0xaf9: 0x0080, 0xafa: 0x0080, + // Block 0x2c, offset 0xb00 + 0xb00: 0x00c3, 0xb01: 0x00c0, 0xb02: 0x00c0, 0xb03: 0x00c0, 0xb04: 0x00c3, 0xb05: 0x00c0, + 0xb06: 0x00c0, 0xb07: 0x00c0, 0xb08: 0x00c0, 0xb09: 0x00c0, 0xb0a: 0x00c0, 0xb0b: 0x00c0, + 0xb0c: 0x00c0, 0xb0e: 0x00c0, 0xb0f: 0x00c0, 0xb10: 0x00c0, + 0xb12: 0x00c0, 0xb13: 0x00c0, 0xb14: 0x00c0, 0xb15: 0x00c0, 0xb16: 0x00c0, 0xb17: 0x00c0, + 0xb18: 0x00c0, 0xb19: 0x00c0, 0xb1a: 0x00c0, 0xb1b: 0x00c0, 0xb1c: 0x00c0, 0xb1d: 0x00c0, + 0xb1e: 0x00c0, 0xb1f: 0x00c0, 0xb20: 0x00c0, 0xb21: 0x00c0, 0xb22: 0x00c0, 0xb23: 0x00c0, + 0xb24: 0x00c0, 0xb25: 0x00c0, 0xb26: 0x00c0, 0xb27: 0x00c0, 0xb28: 0x00c0, + 0xb2a: 0x00c0, 0xb2b: 0x00c0, 0xb2c: 0x00c0, 0xb2d: 0x00c0, 0xb2e: 0x00c0, 0xb2f: 0x00c0, + 0xb30: 0x00c0, 0xb31: 0x00c0, 0xb32: 0x00c0, 0xb33: 0x00c0, 0xb34: 0x00c0, 0xb35: 0x00c0, + 0xb36: 0x00c0, 0xb37: 0x00c0, 0xb38: 0x00c0, 0xb39: 0x00c0, + 0xb3d: 0x00c0, 0xb3e: 0x00c3, 0xb3f: 0x00c3, + // Block 0x2d, offset 0xb40 + 0xb40: 0x00c3, 0xb41: 0x00c0, 0xb42: 0x00c0, 0xb43: 0x00c0, 0xb44: 0x00c0, + 0xb46: 0x00c3, 0xb47: 0x00c3, 0xb48: 0x00c3, 0xb4a: 0x00c3, 0xb4b: 0x00c3, + 0xb4c: 0x00c3, 0xb4d: 0x00c6, + 0xb55: 0x00c3, 0xb56: 0x00c3, + 0xb58: 0x00c0, 0xb59: 0x00c0, 0xb5a: 0x00c0, + 0xb60: 0x00c0, 0xb61: 0x00c0, 0xb62: 0x00c3, 0xb63: 0x00c3, + 0xb66: 0x00c0, 0xb67: 0x00c0, 0xb68: 0x00c0, 0xb69: 0x00c0, + 0xb6a: 0x00c0, 0xb6b: 0x00c0, 0xb6c: 0x00c0, 0xb6d: 0x00c0, 0xb6e: 0x00c0, 0xb6f: 0x00c0, + 0xb77: 0x0080, 0xb78: 0x0080, 0xb79: 0x0080, 0xb7a: 0x0080, 0xb7b: 0x0080, + 0xb7c: 0x0080, 0xb7d: 0x0080, 0xb7e: 0x0080, 0xb7f: 0x0080, + // Block 0x2e, offset 0xb80 + 0xb80: 0x00c0, 0xb81: 0x00c3, 0xb82: 0x00c0, 0xb83: 0x00c0, 0xb84: 0x0080, 0xb85: 0x00c0, + 0xb86: 0x00c0, 0xb87: 0x00c0, 0xb88: 0x00c0, 0xb89: 0x00c0, 0xb8a: 0x00c0, 0xb8b: 0x00c0, + 0xb8c: 0x00c0, 0xb8e: 0x00c0, 0xb8f: 0x00c0, 0xb90: 0x00c0, + 0xb92: 0x00c0, 0xb93: 0x00c0, 0xb94: 0x00c0, 0xb95: 0x00c0, 0xb96: 0x00c0, 0xb97: 0x00c0, + 0xb98: 0x00c0, 0xb99: 0x00c0, 0xb9a: 0x00c0, 0xb9b: 0x00c0, 0xb9c: 0x00c0, 0xb9d: 0x00c0, + 0xb9e: 0x00c0, 0xb9f: 0x00c0, 0xba0: 0x00c0, 0xba1: 0x00c0, 0xba2: 0x00c0, 0xba3: 0x00c0, + 0xba4: 0x00c0, 0xba5: 0x00c0, 0xba6: 0x00c0, 0xba7: 0x00c0, 0xba8: 0x00c0, + 0xbaa: 0x00c0, 0xbab: 0x00c0, 0xbac: 0x00c0, 0xbad: 0x00c0, 0xbae: 0x00c0, 0xbaf: 0x00c0, + 0xbb0: 0x00c0, 0xbb1: 0x00c0, 0xbb2: 0x00c0, 0xbb3: 0x00c0, 0xbb5: 0x00c0, + 0xbb6: 0x00c0, 0xbb7: 0x00c0, 0xbb8: 0x00c0, 0xbb9: 0x00c0, + 0xbbc: 0x00c3, 0xbbd: 0x00c0, 0xbbe: 0x00c0, 0xbbf: 0x00c3, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x00c0, 0xbc1: 0x00c0, 0xbc2: 0x00c0, 0xbc3: 0x00c0, 0xbc4: 0x00c0, + 0xbc6: 0x00c3, 0xbc7: 0x00c0, 0xbc8: 0x00c0, 0xbca: 0x00c0, 0xbcb: 0x00c0, + 0xbcc: 0x00c3, 0xbcd: 0x00c6, + 0xbd5: 0x00c0, 0xbd6: 0x00c0, + 0xbde: 0x00c0, 0xbe0: 0x00c0, 0xbe1: 0x00c0, 0xbe2: 0x00c3, 0xbe3: 0x00c3, + 0xbe6: 0x00c0, 0xbe7: 0x00c0, 0xbe8: 0x00c0, 0xbe9: 0x00c0, + 0xbea: 0x00c0, 0xbeb: 0x00c0, 0xbec: 0x00c0, 0xbed: 0x00c0, 0xbee: 0x00c0, 0xbef: 0x00c0, + 0xbf1: 0x00c0, 0xbf2: 0x00c0, + // Block 0x30, offset 0xc00 + 0xc00: 0x00c3, 0xc01: 0x00c3, 0xc02: 0x00c0, 0xc03: 0x00c0, 0xc05: 0x00c0, + 0xc06: 0x00c0, 0xc07: 0x00c0, 0xc08: 0x00c0, 0xc09: 0x00c0, 0xc0a: 0x00c0, 0xc0b: 0x00c0, + 0xc0c: 0x00c0, 0xc0e: 0x00c0, 0xc0f: 0x00c0, 0xc10: 0x00c0, + 0xc12: 0x00c0, 0xc13: 0x00c0, 0xc14: 0x00c0, 0xc15: 0x00c0, 0xc16: 0x00c0, 0xc17: 0x00c0, + 0xc18: 0x00c0, 0xc19: 0x00c0, 0xc1a: 0x00c0, 0xc1b: 0x00c0, 0xc1c: 0x00c0, 0xc1d: 0x00c0, + 0xc1e: 0x00c0, 0xc1f: 0x00c0, 0xc20: 0x00c0, 0xc21: 0x00c0, 0xc22: 0x00c0, 0xc23: 0x00c0, + 0xc24: 0x00c0, 0xc25: 0x00c0, 0xc26: 0x00c0, 0xc27: 0x00c0, 0xc28: 0x00c0, 0xc29: 0x00c0, + 0xc2a: 0x00c0, 0xc2b: 0x00c0, 0xc2c: 0x00c0, 0xc2d: 0x00c0, 0xc2e: 0x00c0, 0xc2f: 0x00c0, + 0xc30: 0x00c0, 0xc31: 0x00c0, 0xc32: 0x00c0, 0xc33: 0x00c0, 0xc34: 0x00c0, 0xc35: 0x00c0, + 0xc36: 0x00c0, 0xc37: 0x00c0, 0xc38: 0x00c0, 0xc39: 0x00c0, 0xc3a: 0x00c0, 0xc3b: 0x00c6, + 0xc3c: 0x00c6, 0xc3d: 0x00c0, 0xc3e: 0x00c0, 0xc3f: 0x00c0, + // Block 0x31, offset 0xc40 + 0xc40: 0x00c0, 0xc41: 0x00c3, 0xc42: 0x00c3, 0xc43: 0x00c3, 0xc44: 0x00c3, + 0xc46: 0x00c0, 0xc47: 0x00c0, 0xc48: 0x00c0, 0xc4a: 0x00c0, 0xc4b: 0x00c0, + 0xc4c: 0x00c0, 0xc4d: 0x00c6, 0xc4e: 0x00c0, 0xc4f: 0x0080, + 0xc54: 0x00c0, 0xc55: 0x00c0, 0xc56: 0x00c0, 0xc57: 0x00c0, + 0xc58: 0x0080, 0xc59: 0x0080, 0xc5a: 0x0080, 0xc5b: 0x0080, 0xc5c: 0x0080, 0xc5d: 0x0080, + 0xc5e: 0x0080, 0xc5f: 0x00c0, 0xc60: 0x00c0, 0xc61: 0x00c0, 0xc62: 0x00c3, 0xc63: 0x00c3, + 0xc66: 0x00c0, 0xc67: 0x00c0, 0xc68: 0x00c0, 0xc69: 0x00c0, + 0xc6a: 0x00c0, 0xc6b: 0x00c0, 0xc6c: 0x00c0, 0xc6d: 0x00c0, 0xc6e: 0x00c0, 0xc6f: 0x00c0, + 0xc70: 0x0080, 0xc71: 0x0080, 0xc72: 0x0080, 0xc73: 0x0080, 0xc74: 0x0080, 0xc75: 0x0080, + 0xc76: 0x0080, 0xc77: 0x0080, 0xc78: 0x0080, 0xc79: 0x0080, 0xc7a: 0x00c0, 0xc7b: 0x00c0, + 0xc7c: 0x00c0, 0xc7d: 0x00c0, 0xc7e: 0x00c0, 0xc7f: 0x00c0, + // Block 0x32, offset 0xc80 + 0xc82: 0x00c0, 0xc83: 0x00c0, 0xc85: 0x00c0, + 0xc86: 0x00c0, 0xc87: 0x00c0, 0xc88: 0x00c0, 0xc89: 0x00c0, 0xc8a: 0x00c0, 0xc8b: 0x00c0, + 0xc8c: 0x00c0, 0xc8d: 0x00c0, 0xc8e: 0x00c0, 0xc8f: 0x00c0, 0xc90: 0x00c0, 0xc91: 0x00c0, + 0xc92: 0x00c0, 0xc93: 0x00c0, 0xc94: 0x00c0, 0xc95: 0x00c0, 0xc96: 0x00c0, + 0xc9a: 0x00c0, 0xc9b: 0x00c0, 0xc9c: 0x00c0, 0xc9d: 0x00c0, + 0xc9e: 0x00c0, 0xc9f: 0x00c0, 0xca0: 0x00c0, 0xca1: 0x00c0, 0xca2: 0x00c0, 0xca3: 0x00c0, + 0xca4: 0x00c0, 0xca5: 0x00c0, 0xca6: 0x00c0, 0xca7: 0x00c0, 0xca8: 0x00c0, 0xca9: 0x00c0, + 0xcaa: 0x00c0, 0xcab: 0x00c0, 0xcac: 0x00c0, 0xcad: 0x00c0, 0xcae: 0x00c0, 0xcaf: 0x00c0, + 0xcb0: 0x00c0, 0xcb1: 0x00c0, 0xcb3: 0x00c0, 0xcb4: 0x00c0, 0xcb5: 0x00c0, + 0xcb6: 0x00c0, 0xcb7: 0x00c0, 0xcb8: 0x00c0, 0xcb9: 0x00c0, 0xcba: 0x00c0, 0xcbb: 0x00c0, + 0xcbd: 0x00c0, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x00c0, 0xcc1: 0x00c0, 0xcc2: 0x00c0, 0xcc3: 0x00c0, 0xcc4: 0x00c0, 0xcc5: 0x00c0, + 0xcc6: 0x00c0, 0xcca: 0x00c6, + 0xccf: 0x00c0, 0xcd0: 0x00c0, 0xcd1: 0x00c0, + 0xcd2: 0x00c3, 0xcd3: 0x00c3, 0xcd4: 0x00c3, 0xcd6: 0x00c3, + 0xcd8: 0x00c0, 0xcd9: 0x00c0, 0xcda: 0x00c0, 0xcdb: 0x00c0, 0xcdc: 0x00c0, 0xcdd: 0x00c0, + 0xcde: 0x00c0, 0xcdf: 0x00c0, + 0xce6: 0x00c0, 0xce7: 0x00c0, 0xce8: 0x00c0, 0xce9: 0x00c0, + 0xcea: 0x00c0, 0xceb: 0x00c0, 0xcec: 0x00c0, 0xced: 0x00c0, 0xcee: 0x00c0, 0xcef: 0x00c0, + 0xcf2: 0x00c0, 0xcf3: 0x00c0, 0xcf4: 0x0080, + // Block 0x34, offset 0xd00 + 0xd01: 0x00c0, 0xd02: 0x00c0, 0xd03: 0x00c0, 0xd04: 0x00c0, 0xd05: 0x00c0, + 0xd06: 0x00c0, 0xd07: 0x00c0, 0xd08: 0x00c0, 0xd09: 0x00c0, 0xd0a: 0x00c0, 0xd0b: 0x00c0, + 0xd0c: 0x00c0, 0xd0d: 0x00c0, 0xd0e: 0x00c0, 0xd0f: 0x00c0, 0xd10: 0x00c0, 0xd11: 0x00c0, + 0xd12: 0x00c0, 0xd13: 0x00c0, 0xd14: 0x00c0, 0xd15: 0x00c0, 0xd16: 0x00c0, 0xd17: 0x00c0, + 0xd18: 0x00c0, 0xd19: 0x00c0, 0xd1a: 0x00c0, 0xd1b: 0x00c0, 0xd1c: 0x00c0, 0xd1d: 0x00c0, + 0xd1e: 0x00c0, 0xd1f: 0x00c0, 0xd20: 0x00c0, 0xd21: 0x00c0, 0xd22: 0x00c0, 0xd23: 0x00c0, + 0xd24: 0x00c0, 0xd25: 0x00c0, 0xd26: 0x00c0, 0xd27: 0x00c0, 0xd28: 0x00c0, 0xd29: 0x00c0, + 0xd2a: 0x00c0, 0xd2b: 0x00c0, 0xd2c: 0x00c0, 0xd2d: 0x00c0, 0xd2e: 0x00c0, 0xd2f: 0x00c0, + 0xd30: 0x00c0, 0xd31: 0x00c3, 0xd32: 0x00c0, 0xd33: 0x0080, 0xd34: 0x00c3, 0xd35: 0x00c3, + 0xd36: 0x00c3, 0xd37: 0x00c3, 0xd38: 0x00c3, 0xd39: 0x00c3, 0xd3a: 0x00c6, + 0xd3f: 0x0080, + // Block 0x35, offset 0xd40 + 0xd40: 0x00c0, 0xd41: 0x00c0, 0xd42: 0x00c0, 0xd43: 0x00c0, 0xd44: 0x00c0, 0xd45: 0x00c0, + 0xd46: 0x00c0, 0xd47: 0x00c3, 0xd48: 0x00c3, 0xd49: 0x00c3, 0xd4a: 0x00c3, 0xd4b: 0x00c3, + 0xd4c: 0x00c3, 0xd4d: 0x00c3, 0xd4e: 0x00c3, 0xd4f: 0x0080, 0xd50: 0x00c0, 0xd51: 0x00c0, + 0xd52: 0x00c0, 0xd53: 0x00c0, 0xd54: 0x00c0, 0xd55: 0x00c0, 0xd56: 0x00c0, 0xd57: 0x00c0, + 0xd58: 0x00c0, 0xd59: 0x00c0, 0xd5a: 0x0080, 0xd5b: 0x0080, + // Block 0x36, offset 0xd80 + 0xd81: 0x00c0, 0xd82: 0x00c0, 0xd84: 0x00c0, + 0xd86: 0x00c0, 0xd87: 0x00c0, 0xd88: 0x00c0, 0xd89: 0x00c0, 0xd8a: 0x00c0, + 0xd8c: 0x00c0, 0xd8d: 0x00c0, 0xd8e: 0x00c0, 0xd8f: 0x00c0, 0xd90: 0x00c0, 0xd91: 0x00c0, + 0xd92: 0x00c0, 0xd93: 0x00c0, 0xd94: 0x00c0, 0xd95: 0x00c0, 0xd96: 0x00c0, 0xd97: 0x00c0, + 0xd98: 0x00c0, 0xd99: 0x00c0, 0xd9a: 0x00c0, 0xd9b: 0x00c0, 0xd9c: 0x00c0, 0xd9d: 0x00c0, + 0xd9e: 0x00c0, 0xd9f: 0x00c0, 0xda0: 0x00c0, 0xda1: 0x00c0, 0xda2: 0x00c0, 0xda3: 0x00c0, + 0xda5: 0x00c0, 0xda7: 0x00c0, 0xda8: 0x00c0, 0xda9: 0x00c0, + 0xdaa: 0x00c0, 0xdab: 0x00c0, 0xdac: 0x00c0, 0xdad: 0x00c0, 0xdae: 0x00c0, 0xdaf: 0x00c0, + 0xdb0: 0x00c0, 0xdb1: 0x00c3, 0xdb2: 0x00c0, 0xdb3: 0x0080, 0xdb4: 0x00c3, 0xdb5: 0x00c3, + 0xdb6: 0x00c3, 0xdb7: 0x00c3, 0xdb8: 0x00c3, 0xdb9: 0x00c3, 0xdba: 0x00c6, 0xdbb: 0x00c3, + 0xdbc: 0x00c3, 0xdbd: 0x00c0, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x00c0, 0xdc1: 0x00c0, 0xdc2: 0x00c0, 0xdc3: 0x00c0, 0xdc4: 0x00c0, + 0xdc6: 0x00c0, 0xdc8: 0x00c3, 0xdc9: 0x00c3, 0xdca: 0x00c3, 0xdcb: 0x00c3, + 0xdcc: 0x00c3, 0xdcd: 0x00c3, 0xdd0: 0x00c0, 0xdd1: 0x00c0, + 0xdd2: 0x00c0, 0xdd3: 0x00c0, 0xdd4: 0x00c0, 0xdd5: 0x00c0, 0xdd6: 0x00c0, 0xdd7: 0x00c0, + 0xdd8: 0x00c0, 0xdd9: 0x00c0, 0xddc: 0x0080, 0xddd: 0x0080, + 0xdde: 0x00c0, 0xddf: 0x00c0, + // Block 0x38, offset 0xe00 + 0xe00: 0x00c0, 0xe01: 0x0080, 0xe02: 0x0080, 0xe03: 0x0080, 0xe04: 0x0080, 0xe05: 0x0080, + 0xe06: 0x0080, 0xe07: 0x0080, 0xe08: 0x0080, 0xe09: 0x0080, 0xe0a: 0x0080, 0xe0b: 0x00c0, + 0xe0c: 0x0080, 0xe0d: 0x0080, 0xe0e: 0x0080, 0xe0f: 0x0080, 0xe10: 0x0080, 0xe11: 0x0080, + 0xe12: 0x0080, 0xe13: 0x0080, 0xe14: 0x0080, 0xe15: 0x0080, 0xe16: 0x0080, 0xe17: 0x0080, + 0xe18: 0x00c3, 0xe19: 0x00c3, 0xe1a: 0x0080, 0xe1b: 0x0080, 0xe1c: 0x0080, 0xe1d: 0x0080, + 0xe1e: 0x0080, 0xe1f: 0x0080, 0xe20: 0x00c0, 0xe21: 0x00c0, 0xe22: 0x00c0, 0xe23: 0x00c0, + 0xe24: 0x00c0, 0xe25: 0x00c0, 0xe26: 0x00c0, 0xe27: 0x00c0, 0xe28: 0x00c0, 0xe29: 0x00c0, + 0xe2a: 0x0080, 0xe2b: 0x0080, 0xe2c: 0x0080, 0xe2d: 0x0080, 0xe2e: 0x0080, 0xe2f: 0x0080, + 0xe30: 0x0080, 0xe31: 0x0080, 0xe32: 0x0080, 0xe33: 0x0080, 0xe34: 0x0080, 0xe35: 0x00c3, + 0xe36: 0x0080, 0xe37: 0x00c3, 0xe38: 0x0080, 0xe39: 0x00c3, 0xe3a: 0x0080, 0xe3b: 0x0080, + 0xe3c: 0x0080, 0xe3d: 0x0080, 0xe3e: 0x00c0, 0xe3f: 0x00c0, + // Block 0x39, offset 0xe40 + 0xe40: 0x00c0, 0xe41: 0x00c0, 0xe42: 0x00c0, 0xe43: 0x0080, 0xe44: 0x00c0, 0xe45: 0x00c0, + 0xe46: 0x00c0, 0xe47: 0x00c0, 0xe49: 0x00c0, 0xe4a: 0x00c0, 0xe4b: 0x00c0, + 0xe4c: 0x00c0, 0xe4d: 0x0080, 0xe4e: 0x00c0, 0xe4f: 0x00c0, 0xe50: 0x00c0, 0xe51: 0x00c0, + 0xe52: 0x0080, 0xe53: 0x00c0, 0xe54: 0x00c0, 0xe55: 0x00c0, 0xe56: 0x00c0, 0xe57: 0x0080, + 0xe58: 0x00c0, 0xe59: 0x00c0, 0xe5a: 0x00c0, 0xe5b: 0x00c0, 0xe5c: 0x0080, 0xe5d: 0x00c0, + 0xe5e: 0x00c0, 0xe5f: 0x00c0, 0xe60: 0x00c0, 0xe61: 0x00c0, 0xe62: 0x00c0, 0xe63: 0x00c0, + 0xe64: 0x00c0, 0xe65: 0x00c0, 0xe66: 0x00c0, 0xe67: 0x00c0, 0xe68: 0x00c0, 0xe69: 0x0080, + 0xe6a: 0x00c0, 0xe6b: 0x00c0, 0xe6c: 0x00c0, + 0xe71: 0x00c3, 0xe72: 0x00c3, 0xe73: 0x0083, 0xe74: 0x00c3, 0xe75: 0x0083, + 0xe76: 0x0083, 0xe77: 0x0083, 0xe78: 0x0083, 0xe79: 0x0083, 0xe7a: 0x00c3, 0xe7b: 0x00c3, + 0xe7c: 0x00c3, 0xe7d: 0x00c3, 0xe7e: 0x00c3, 0xe7f: 0x00c0, + // Block 0x3a, offset 0xe80 + 0xe80: 0x00c3, 0xe81: 0x0083, 0xe82: 0x00c3, 0xe83: 0x00c3, 0xe84: 0x00c6, 0xe85: 0x0080, + 0xe86: 0x00c3, 0xe87: 0x00c3, 0xe88: 0x00c0, 0xe89: 0x00c0, 0xe8a: 0x00c0, 0xe8b: 0x00c0, + 0xe8c: 0x00c0, 0xe8d: 0x00c3, 0xe8e: 0x00c3, 0xe8f: 0x00c3, 0xe90: 0x00c3, 0xe91: 0x00c3, + 0xe92: 0x00c3, 0xe93: 0x0083, 0xe94: 0x00c3, 0xe95: 0x00c3, 0xe96: 0x00c3, 0xe97: 0x00c3, + 0xe99: 0x00c3, 0xe9a: 0x00c3, 0xe9b: 0x00c3, 0xe9c: 0x00c3, 0xe9d: 0x0083, + 0xe9e: 0x00c3, 0xe9f: 0x00c3, 0xea0: 0x00c3, 0xea1: 0x00c3, 0xea2: 0x0083, 0xea3: 0x00c3, + 0xea4: 0x00c3, 0xea5: 0x00c3, 0xea6: 0x00c3, 0xea7: 0x0083, 0xea8: 0x00c3, 0xea9: 0x00c3, + 0xeaa: 0x00c3, 0xeab: 0x00c3, 0xeac: 0x0083, 0xead: 0x00c3, 0xeae: 0x00c3, 0xeaf: 0x00c3, + 0xeb0: 0x00c3, 0xeb1: 0x00c3, 0xeb2: 0x00c3, 0xeb3: 0x00c3, 0xeb4: 0x00c3, 0xeb5: 0x00c3, + 0xeb6: 0x00c3, 0xeb7: 0x00c3, 0xeb8: 0x00c3, 0xeb9: 0x0083, 0xeba: 0x00c3, 0xebb: 0x00c3, + 0xebc: 0x00c3, 0xebe: 0x0080, 0xebf: 0x0080, + // Block 0x3b, offset 0xec0 + 0xec0: 0x0080, 0xec1: 0x0080, 0xec2: 0x0080, 0xec3: 0x0080, 0xec4: 0x0080, 0xec5: 0x0080, + 0xec6: 0x00c3, 0xec7: 0x0080, 0xec8: 0x0080, 0xec9: 0x0080, 0xeca: 0x0080, 0xecb: 0x0080, + 0xecc: 0x0080, 0xece: 0x0080, 0xecf: 0x0080, 0xed0: 0x0080, 0xed1: 0x0080, + 0xed2: 0x0080, 0xed3: 0x0080, 0xed4: 0x0080, 0xed5: 0x0080, 0xed6: 0x0080, 0xed7: 0x0080, + 0xed8: 0x0080, 0xed9: 0x0080, 0xeda: 0x0080, + // Block 0x3c, offset 0xf00 + 0xf00: 0x00c0, 0xf01: 0x00c0, 0xf02: 0x00c0, 0xf03: 0x00c0, 0xf04: 0x00c0, 0xf05: 0x00c0, + 0xf06: 0x00c0, 0xf07: 0x00c0, 0xf08: 0x00c0, 0xf09: 0x00c0, 0xf0a: 0x00c0, 0xf0b: 0x00c0, + 0xf0c: 0x00c0, 0xf0d: 0x00c0, 0xf0e: 0x00c0, 0xf0f: 0x00c0, 0xf10: 0x00c0, 0xf11: 0x00c0, + 0xf12: 0x00c0, 0xf13: 0x00c0, 0xf14: 0x00c0, 0xf15: 0x00c0, 0xf16: 0x00c0, 0xf17: 0x00c0, + 0xf18: 0x00c0, 0xf19: 0x00c0, 0xf1a: 0x00c0, 0xf1b: 0x00c0, 0xf1c: 0x00c0, 0xf1d: 0x00c0, + 0xf1e: 0x00c0, 0xf1f: 0x00c0, 0xf20: 0x00c0, 0xf21: 0x00c0, 0xf22: 0x00c0, 0xf23: 0x00c0, + 0xf24: 0x00c0, 0xf25: 0x00c0, 0xf26: 0x00c0, 0xf27: 0x00c0, 0xf28: 0x00c0, 0xf29: 0x00c0, + 0xf2a: 0x00c0, 0xf2b: 0x00c0, 0xf2c: 0x00c0, 0xf2d: 0x00c3, 0xf2e: 0x00c3, 0xf2f: 0x00c3, + 0xf30: 0x00c3, 0xf31: 0x00c0, 0xf32: 0x00c3, 0xf33: 0x00c3, 0xf34: 0x00c3, 0xf35: 0x00c3, + 0xf36: 0x00c3, 0xf37: 0x00c3, 0xf38: 0x00c0, 0xf39: 0x00c6, 0xf3a: 0x00c6, 0xf3b: 0x00c0, + 0xf3c: 0x00c0, 0xf3d: 0x00c3, 0xf3e: 0x00c3, 0xf3f: 0x00c0, + // Block 0x3d, offset 0xf40 + 0xf40: 0x00c0, 0xf41: 0x00c0, 0xf42: 0x00c0, 0xf43: 0x00c0, 0xf44: 0x00c0, 0xf45: 0x00c0, + 0xf46: 0x00c0, 0xf47: 0x00c0, 0xf48: 0x00c0, 0xf49: 0x00c0, 0xf4a: 0x0080, 0xf4b: 0x0080, + 0xf4c: 0x0080, 0xf4d: 0x0080, 0xf4e: 0x0080, 0xf4f: 0x0080, 0xf50: 0x00c0, 0xf51: 0x00c0, + 0xf52: 0x00c0, 0xf53: 0x00c0, 0xf54: 0x00c0, 0xf55: 0x00c0, 0xf56: 0x00c0, 0xf57: 0x00c0, + 0xf58: 0x00c3, 0xf59: 0x00c3, 0xf5a: 0x00c0, 0xf5b: 0x00c0, 0xf5c: 0x00c0, 0xf5d: 0x00c0, + 0xf5e: 0x00c3, 0xf5f: 0x00c3, 0xf60: 0x00c3, 0xf61: 0x00c0, 0xf62: 0x00c0, 0xf63: 0x00c0, + 0xf64: 0x00c0, 0xf65: 0x00c0, 0xf66: 0x00c0, 0xf67: 0x00c0, 0xf68: 0x00c0, 0xf69: 0x00c0, + 0xf6a: 0x00c0, 0xf6b: 0x00c0, 0xf6c: 0x00c0, 0xf6d: 0x00c0, 0xf6e: 0x00c0, 0xf6f: 0x00c0, + 0xf70: 0x00c0, 0xf71: 0x00c3, 0xf72: 0x00c3, 0xf73: 0x00c3, 0xf74: 0x00c3, 0xf75: 0x00c0, + 0xf76: 0x00c0, 0xf77: 0x00c0, 0xf78: 0x00c0, 0xf79: 0x00c0, 0xf7a: 0x00c0, 0xf7b: 0x00c0, + 0xf7c: 0x00c0, 0xf7d: 0x00c0, 0xf7e: 0x00c0, 0xf7f: 0x00c0, + // Block 0x3e, offset 0xf80 + 0xf80: 0x00c0, 0xf81: 0x00c0, 0xf82: 0x00c3, 0xf83: 0x00c0, 0xf84: 0x00c0, 0xf85: 0x00c3, + 0xf86: 0x00c3, 0xf87: 0x00c0, 0xf88: 0x00c0, 0xf89: 0x00c0, 0xf8a: 0x00c0, 0xf8b: 0x00c0, + 0xf8c: 0x00c0, 0xf8d: 0x00c3, 0xf8e: 0x00c0, 0xf8f: 0x00c0, 0xf90: 0x00c0, 0xf91: 0x00c0, + 0xf92: 0x00c0, 0xf93: 0x00c0, 0xf94: 0x00c0, 0xf95: 0x00c0, 0xf96: 0x00c0, 0xf97: 0x00c0, + 0xf98: 0x00c0, 0xf99: 0x00c0, 0xf9a: 0x00c0, 0xf9b: 0x00c0, 0xf9c: 0x00c0, 0xf9d: 0x00c3, + 0xf9e: 0x0080, 0xf9f: 0x0080, 0xfa0: 0x00c0, 0xfa1: 0x00c0, 0xfa2: 0x00c0, 0xfa3: 0x00c0, + 0xfa4: 0x00c0, 0xfa5: 0x00c0, 0xfa6: 0x00c0, 0xfa7: 0x00c0, 0xfa8: 0x00c0, 0xfa9: 0x00c0, + 0xfaa: 0x00c0, 0xfab: 0x00c0, 0xfac: 0x00c0, 0xfad: 0x00c0, 0xfae: 0x00c0, 0xfaf: 0x00c0, + 0xfb0: 0x00c0, 0xfb1: 0x00c0, 0xfb2: 0x00c0, 0xfb3: 0x00c0, 0xfb4: 0x00c0, 0xfb5: 0x00c0, + 0xfb6: 0x00c0, 0xfb7: 0x00c0, 0xfb8: 0x00c0, 0xfb9: 0x00c0, 0xfba: 0x00c0, 0xfbb: 0x00c0, + 0xfbc: 0x00c0, 0xfbd: 0x00c0, 0xfbe: 0x00c0, 0xfbf: 0x00c0, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x00c0, 0xfc1: 0x00c0, 0xfc2: 0x00c0, 0xfc3: 0x00c0, 0xfc4: 0x00c0, 0xfc5: 0x00c0, + 0xfc7: 0x00c0, + 0xfcd: 0x00c0, 0xfd0: 0x00c0, 0xfd1: 0x00c0, + 0xfd2: 0x00c0, 0xfd3: 0x00c0, 0xfd4: 0x00c0, 0xfd5: 0x00c0, 0xfd6: 0x00c0, 0xfd7: 0x00c0, + 0xfd8: 0x00c0, 0xfd9: 0x00c0, 0xfda: 0x00c0, 0xfdb: 0x00c0, 0xfdc: 0x00c0, 0xfdd: 0x00c0, + 0xfde: 0x00c0, 0xfdf: 0x00c0, 0xfe0: 0x00c0, 0xfe1: 0x00c0, 0xfe2: 0x00c0, 0xfe3: 0x00c0, + 0xfe4: 0x00c0, 0xfe5: 0x00c0, 0xfe6: 0x00c0, 0xfe7: 0x00c0, 0xfe8: 0x00c0, 0xfe9: 0x00c0, + 0xfea: 0x00c0, 0xfeb: 0x00c0, 0xfec: 0x00c0, 0xfed: 0x00c0, 0xfee: 0x00c0, 0xfef: 0x00c0, + 0xff0: 0x00c0, 0xff1: 0x00c0, 0xff2: 0x00c0, 0xff3: 0x00c0, 0xff4: 0x00c0, 0xff5: 0x00c0, + 0xff6: 0x00c0, 0xff7: 0x00c0, 0xff8: 0x00c0, 0xff9: 0x00c0, 0xffa: 0x00c0, 0xffb: 0x0080, + 0xffc: 0x0080, 0xffd: 0x00c0, 0xffe: 0x00c0, 0xfff: 0x00c0, + // Block 0x40, offset 0x1000 + 0x1000: 0x0040, 0x1001: 0x0040, 0x1002: 0x0040, 0x1003: 0x0040, 0x1004: 0x0040, 0x1005: 0x0040, + 0x1006: 0x0040, 0x1007: 0x0040, 0x1008: 0x0040, 0x1009: 0x0040, 0x100a: 0x0040, 0x100b: 0x0040, + 0x100c: 0x0040, 0x100d: 0x0040, 0x100e: 0x0040, 0x100f: 0x0040, 0x1010: 0x0040, 0x1011: 0x0040, + 0x1012: 0x0040, 0x1013: 0x0040, 0x1014: 0x0040, 0x1015: 0x0040, 0x1016: 0x0040, 0x1017: 0x0040, + 0x1018: 0x0040, 0x1019: 0x0040, 0x101a: 0x0040, 0x101b: 0x0040, 0x101c: 0x0040, 0x101d: 0x0040, + 0x101e: 0x0040, 0x101f: 0x0040, 0x1020: 0x0040, 0x1021: 0x0040, 0x1022: 0x0040, 0x1023: 0x0040, + 0x1024: 0x0040, 0x1025: 0x0040, 0x1026: 0x0040, 0x1027: 0x0040, 0x1028: 0x0040, 0x1029: 0x0040, + 0x102a: 0x0040, 0x102b: 0x0040, 0x102c: 0x0040, 0x102d: 0x0040, 0x102e: 0x0040, 0x102f: 0x0040, + 0x1030: 0x0040, 0x1031: 0x0040, 0x1032: 0x0040, 0x1033: 0x0040, 0x1034: 0x0040, 0x1035: 0x0040, + 0x1036: 0x0040, 0x1037: 0x0040, 0x1038: 0x0040, 0x1039: 0x0040, 0x103a: 0x0040, 0x103b: 0x0040, + 0x103c: 0x0040, 0x103d: 0x0040, 0x103e: 0x0040, 0x103f: 0x0040, + // Block 0x41, offset 0x1040 + 0x1040: 0x00c0, 0x1041: 0x00c0, 0x1042: 0x00c0, 0x1043: 0x00c0, 0x1044: 0x00c0, 0x1045: 0x00c0, + 0x1046: 0x00c0, 0x1047: 0x00c0, 0x1048: 0x00c0, 0x104a: 0x00c0, 0x104b: 0x00c0, + 0x104c: 0x00c0, 0x104d: 0x00c0, 0x1050: 0x00c0, 0x1051: 0x00c0, + 0x1052: 0x00c0, 0x1053: 0x00c0, 0x1054: 0x00c0, 0x1055: 0x00c0, 0x1056: 0x00c0, + 0x1058: 0x00c0, 0x105a: 0x00c0, 0x105b: 0x00c0, 0x105c: 0x00c0, 0x105d: 0x00c0, + 0x1060: 0x00c0, 0x1061: 0x00c0, 0x1062: 0x00c0, 0x1063: 0x00c0, + 0x1064: 0x00c0, 0x1065: 0x00c0, 0x1066: 0x00c0, 0x1067: 0x00c0, 0x1068: 0x00c0, 0x1069: 0x00c0, + 0x106a: 0x00c0, 0x106b: 0x00c0, 0x106c: 0x00c0, 0x106d: 0x00c0, 0x106e: 0x00c0, 0x106f: 0x00c0, + 0x1070: 0x00c0, 0x1071: 0x00c0, 0x1072: 0x00c0, 0x1073: 0x00c0, 0x1074: 0x00c0, 0x1075: 0x00c0, + 0x1076: 0x00c0, 0x1077: 0x00c0, 0x1078: 0x00c0, 0x1079: 0x00c0, 0x107a: 0x00c0, 0x107b: 0x00c0, + 0x107c: 0x00c0, 0x107d: 0x00c0, 0x107e: 0x00c0, 0x107f: 0x00c0, + // Block 0x42, offset 0x1080 + 0x1080: 0x00c0, 0x1081: 0x00c0, 0x1082: 0x00c0, 0x1083: 0x00c0, 0x1084: 0x00c0, 0x1085: 0x00c0, + 0x1086: 0x00c0, 0x1087: 0x00c0, 0x1088: 0x00c0, 0x108a: 0x00c0, 0x108b: 0x00c0, + 0x108c: 0x00c0, 0x108d: 0x00c0, 0x1090: 0x00c0, 0x1091: 0x00c0, + 0x1092: 0x00c0, 0x1093: 0x00c0, 0x1094: 0x00c0, 0x1095: 0x00c0, 0x1096: 0x00c0, 0x1097: 0x00c0, + 0x1098: 0x00c0, 0x1099: 0x00c0, 0x109a: 0x00c0, 0x109b: 0x00c0, 0x109c: 0x00c0, 0x109d: 0x00c0, + 0x109e: 0x00c0, 0x109f: 0x00c0, 0x10a0: 0x00c0, 0x10a1: 0x00c0, 0x10a2: 0x00c0, 0x10a3: 0x00c0, + 0x10a4: 0x00c0, 0x10a5: 0x00c0, 0x10a6: 0x00c0, 0x10a7: 0x00c0, 0x10a8: 0x00c0, 0x10a9: 0x00c0, + 0x10aa: 0x00c0, 0x10ab: 0x00c0, 0x10ac: 0x00c0, 0x10ad: 0x00c0, 0x10ae: 0x00c0, 0x10af: 0x00c0, + 0x10b0: 0x00c0, 0x10b2: 0x00c0, 0x10b3: 0x00c0, 0x10b4: 0x00c0, 0x10b5: 0x00c0, + 0x10b8: 0x00c0, 0x10b9: 0x00c0, 0x10ba: 0x00c0, 0x10bb: 0x00c0, + 0x10bc: 0x00c0, 0x10bd: 0x00c0, 0x10be: 0x00c0, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x00c0, 0x10c2: 0x00c0, 0x10c3: 0x00c0, 0x10c4: 0x00c0, 0x10c5: 0x00c0, + 0x10c8: 0x00c0, 0x10c9: 0x00c0, 0x10ca: 0x00c0, 0x10cb: 0x00c0, + 0x10cc: 0x00c0, 0x10cd: 0x00c0, 0x10ce: 0x00c0, 0x10cf: 0x00c0, 0x10d0: 0x00c0, 0x10d1: 0x00c0, + 0x10d2: 0x00c0, 0x10d3: 0x00c0, 0x10d4: 0x00c0, 0x10d5: 0x00c0, 0x10d6: 0x00c0, + 0x10d8: 0x00c0, 0x10d9: 0x00c0, 0x10da: 0x00c0, 0x10db: 0x00c0, 0x10dc: 0x00c0, 0x10dd: 0x00c0, + 0x10de: 0x00c0, 0x10df: 0x00c0, 0x10e0: 0x00c0, 0x10e1: 0x00c0, 0x10e2: 0x00c0, 0x10e3: 0x00c0, + 0x10e4: 0x00c0, 0x10e5: 0x00c0, 0x10e6: 0x00c0, 0x10e7: 0x00c0, 0x10e8: 0x00c0, 0x10e9: 0x00c0, + 0x10ea: 0x00c0, 0x10eb: 0x00c0, 0x10ec: 0x00c0, 0x10ed: 0x00c0, 0x10ee: 0x00c0, 0x10ef: 0x00c0, + 0x10f0: 0x00c0, 0x10f1: 0x00c0, 0x10f2: 0x00c0, 0x10f3: 0x00c0, 0x10f4: 0x00c0, 0x10f5: 0x00c0, + 0x10f6: 0x00c0, 0x10f7: 0x00c0, 0x10f8: 0x00c0, 0x10f9: 0x00c0, 0x10fa: 0x00c0, 0x10fb: 0x00c0, + 0x10fc: 0x00c0, 0x10fd: 0x00c0, 0x10fe: 0x00c0, 0x10ff: 0x00c0, + // Block 0x44, offset 0x1100 + 0x1100: 0x00c0, 0x1101: 0x00c0, 0x1102: 0x00c0, 0x1103: 0x00c0, 0x1104: 0x00c0, 0x1105: 0x00c0, + 0x1106: 0x00c0, 0x1107: 0x00c0, 0x1108: 0x00c0, 0x1109: 0x00c0, 0x110a: 0x00c0, 0x110b: 0x00c0, + 0x110c: 0x00c0, 0x110d: 0x00c0, 0x110e: 0x00c0, 0x110f: 0x00c0, 0x1110: 0x00c0, + 0x1112: 0x00c0, 0x1113: 0x00c0, 0x1114: 0x00c0, 0x1115: 0x00c0, + 0x1118: 0x00c0, 0x1119: 0x00c0, 0x111a: 0x00c0, 0x111b: 0x00c0, 0x111c: 0x00c0, 0x111d: 0x00c0, + 0x111e: 0x00c0, 0x111f: 0x00c0, 0x1120: 0x00c0, 0x1121: 0x00c0, 0x1122: 0x00c0, 0x1123: 0x00c0, + 0x1124: 0x00c0, 0x1125: 0x00c0, 0x1126: 0x00c0, 0x1127: 0x00c0, 0x1128: 0x00c0, 0x1129: 0x00c0, + 0x112a: 0x00c0, 0x112b: 0x00c0, 0x112c: 0x00c0, 0x112d: 0x00c0, 0x112e: 0x00c0, 0x112f: 0x00c0, + 0x1130: 0x00c0, 0x1131: 0x00c0, 0x1132: 0x00c0, 0x1133: 0x00c0, 0x1134: 0x00c0, 0x1135: 0x00c0, + 0x1136: 0x00c0, 0x1137: 0x00c0, 0x1138: 0x00c0, 0x1139: 0x00c0, 0x113a: 0x00c0, 0x113b: 0x00c0, + 0x113c: 0x00c0, 0x113d: 0x00c0, 0x113e: 0x00c0, 0x113f: 0x00c0, + // Block 0x45, offset 0x1140 + 0x1140: 0x00c0, 0x1141: 0x00c0, 0x1142: 0x00c0, 0x1143: 0x00c0, 0x1144: 0x00c0, 0x1145: 0x00c0, + 0x1146: 0x00c0, 0x1147: 0x00c0, 0x1148: 0x00c0, 0x1149: 0x00c0, 0x114a: 0x00c0, 0x114b: 0x00c0, + 0x114c: 0x00c0, 0x114d: 0x00c0, 0x114e: 0x00c0, 0x114f: 0x00c0, 0x1150: 0x00c0, 0x1151: 0x00c0, + 0x1152: 0x00c0, 0x1153: 0x00c0, 0x1154: 0x00c0, 0x1155: 0x00c0, 0x1156: 0x00c0, 0x1157: 0x00c0, + 0x1158: 0x00c0, 0x1159: 0x00c0, 0x115a: 0x00c0, 0x115d: 0x00c3, + 0x115e: 0x00c3, 0x115f: 0x00c3, 0x1160: 0x0080, 0x1161: 0x0080, 0x1162: 0x0080, 0x1163: 0x0080, + 0x1164: 0x0080, 0x1165: 0x0080, 0x1166: 0x0080, 0x1167: 0x0080, 0x1168: 0x0080, 0x1169: 0x0080, + 0x116a: 0x0080, 0x116b: 0x0080, 0x116c: 0x0080, 0x116d: 0x0080, 0x116e: 0x0080, 0x116f: 0x0080, + 0x1170: 0x0080, 0x1171: 0x0080, 0x1172: 0x0080, 0x1173: 0x0080, 0x1174: 0x0080, 0x1175: 0x0080, + 0x1176: 0x0080, 0x1177: 0x0080, 0x1178: 0x0080, 0x1179: 0x0080, 0x117a: 0x0080, 0x117b: 0x0080, + 0x117c: 0x0080, + // Block 0x46, offset 0x1180 + 0x1180: 0x00c0, 0x1181: 0x00c0, 0x1182: 0x00c0, 0x1183: 0x00c0, 0x1184: 0x00c0, 0x1185: 0x00c0, + 0x1186: 0x00c0, 0x1187: 0x00c0, 0x1188: 0x00c0, 0x1189: 0x00c0, 0x118a: 0x00c0, 0x118b: 0x00c0, + 0x118c: 0x00c0, 0x118d: 0x00c0, 0x118e: 0x00c0, 0x118f: 0x00c0, 0x1190: 0x0080, 0x1191: 0x0080, + 0x1192: 0x0080, 0x1193: 0x0080, 0x1194: 0x0080, 0x1195: 0x0080, 0x1196: 0x0080, 0x1197: 0x0080, + 0x1198: 0x0080, 0x1199: 0x0080, + 0x11a0: 0x00c0, 0x11a1: 0x00c0, 0x11a2: 0x00c0, 0x11a3: 0x00c0, + 0x11a4: 0x00c0, 0x11a5: 0x00c0, 0x11a6: 0x00c0, 0x11a7: 0x00c0, 0x11a8: 0x00c0, 0x11a9: 0x00c0, + 0x11aa: 0x00c0, 0x11ab: 0x00c0, 0x11ac: 0x00c0, 0x11ad: 0x00c0, 0x11ae: 0x00c0, 0x11af: 0x00c0, + 0x11b0: 0x00c0, 0x11b1: 0x00c0, 0x11b2: 0x00c0, 0x11b3: 0x00c0, 0x11b4: 0x00c0, 0x11b5: 0x00c0, + 0x11b6: 0x00c0, 0x11b7: 0x00c0, 0x11b8: 0x00c0, 0x11b9: 0x00c0, 0x11ba: 0x00c0, 0x11bb: 0x00c0, + 0x11bc: 0x00c0, 0x11bd: 0x00c0, 0x11be: 0x00c0, 0x11bf: 0x00c0, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x00c0, 0x11c1: 0x00c0, 0x11c2: 0x00c0, 0x11c3: 0x00c0, 0x11c4: 0x00c0, 0x11c5: 0x00c0, + 0x11c6: 0x00c0, 0x11c7: 0x00c0, 0x11c8: 0x00c0, 0x11c9: 0x00c0, 0x11ca: 0x00c0, 0x11cb: 0x00c0, + 0x11cc: 0x00c0, 0x11cd: 0x00c0, 0x11ce: 0x00c0, 0x11cf: 0x00c0, 0x11d0: 0x00c0, 0x11d1: 0x00c0, + 0x11d2: 0x00c0, 0x11d3: 0x00c0, 0x11d4: 0x00c0, 0x11d5: 0x00c0, 0x11d6: 0x00c0, 0x11d7: 0x00c0, + 0x11d8: 0x00c0, 0x11d9: 0x00c0, 0x11da: 0x00c0, 0x11db: 0x00c0, 0x11dc: 0x00c0, 0x11dd: 0x00c0, + 0x11de: 0x00c0, 0x11df: 0x00c0, 0x11e0: 0x00c0, 0x11e1: 0x00c0, 0x11e2: 0x00c0, 0x11e3: 0x00c0, + 0x11e4: 0x00c0, 0x11e5: 0x00c0, 0x11e6: 0x00c0, 0x11e7: 0x00c0, 0x11e8: 0x00c0, 0x11e9: 0x00c0, + 0x11ea: 0x00c0, 0x11eb: 0x00c0, 0x11ec: 0x00c0, 0x11ed: 0x00c0, 0x11ee: 0x00c0, 0x11ef: 0x00c0, + 0x11f0: 0x00c0, 0x11f1: 0x00c0, 0x11f2: 0x00c0, 0x11f3: 0x00c0, 0x11f4: 0x00c0, 0x11f5: 0x00c0, + 0x11f8: 0x00c0, 0x11f9: 0x00c0, 0x11fa: 0x00c0, 0x11fb: 0x00c0, + 0x11fc: 0x00c0, 0x11fd: 0x00c0, + // Block 0x48, offset 0x1200 + 0x1200: 0x0080, 0x1201: 0x00c0, 0x1202: 0x00c0, 0x1203: 0x00c0, 0x1204: 0x00c0, 0x1205: 0x00c0, + 0x1206: 0x00c0, 0x1207: 0x00c0, 0x1208: 0x00c0, 0x1209: 0x00c0, 0x120a: 0x00c0, 0x120b: 0x00c0, + 0x120c: 0x00c0, 0x120d: 0x00c0, 0x120e: 0x00c0, 0x120f: 0x00c0, 0x1210: 0x00c0, 0x1211: 0x00c0, + 0x1212: 0x00c0, 0x1213: 0x00c0, 0x1214: 0x00c0, 0x1215: 0x00c0, 0x1216: 0x00c0, 0x1217: 0x00c0, + 0x1218: 0x00c0, 0x1219: 0x00c0, 0x121a: 0x00c0, 0x121b: 0x00c0, 0x121c: 0x00c0, 0x121d: 0x00c0, + 0x121e: 0x00c0, 0x121f: 0x00c0, 0x1220: 0x00c0, 0x1221: 0x00c0, 0x1222: 0x00c0, 0x1223: 0x00c0, + 0x1224: 0x00c0, 0x1225: 0x00c0, 0x1226: 0x00c0, 0x1227: 0x00c0, 0x1228: 0x00c0, 0x1229: 0x00c0, + 0x122a: 0x00c0, 0x122b: 0x00c0, 0x122c: 0x00c0, 0x122d: 0x00c0, 0x122e: 0x00c0, 0x122f: 0x00c0, + 0x1230: 0x00c0, 0x1231: 0x00c0, 0x1232: 0x00c0, 0x1233: 0x00c0, 0x1234: 0x00c0, 0x1235: 0x00c0, + 0x1236: 0x00c0, 0x1237: 0x00c0, 0x1238: 0x00c0, 0x1239: 0x00c0, 0x123a: 0x00c0, 0x123b: 0x00c0, + 0x123c: 0x00c0, 0x123d: 0x00c0, 0x123e: 0x00c0, 0x123f: 0x00c0, + // Block 0x49, offset 0x1240 + 0x1240: 0x00c0, 0x1241: 0x00c0, 0x1242: 0x00c0, 0x1243: 0x00c0, 0x1244: 0x00c0, 0x1245: 0x00c0, + 0x1246: 0x00c0, 0x1247: 0x00c0, 0x1248: 0x00c0, 0x1249: 0x00c0, 0x124a: 0x00c0, 0x124b: 0x00c0, + 0x124c: 0x00c0, 0x124d: 0x00c0, 0x124e: 0x00c0, 0x124f: 0x00c0, 0x1250: 0x00c0, 0x1251: 0x00c0, + 0x1252: 0x00c0, 0x1253: 0x00c0, 0x1254: 0x00c0, 0x1255: 0x00c0, 0x1256: 0x00c0, 0x1257: 0x00c0, + 0x1258: 0x00c0, 0x1259: 0x00c0, 0x125a: 0x00c0, 0x125b: 0x00c0, 0x125c: 0x00c0, 0x125d: 0x00c0, + 0x125e: 0x00c0, 0x125f: 0x00c0, 0x1260: 0x00c0, 0x1261: 0x00c0, 0x1262: 0x00c0, 0x1263: 0x00c0, + 0x1264: 0x00c0, 0x1265: 0x00c0, 0x1266: 0x00c0, 0x1267: 0x00c0, 0x1268: 0x00c0, 0x1269: 0x00c0, + 0x126a: 0x00c0, 0x126b: 0x00c0, 0x126c: 0x00c0, 0x126d: 0x0080, 0x126e: 0x0080, 0x126f: 0x00c0, + 0x1270: 0x00c0, 0x1271: 0x00c0, 0x1272: 0x00c0, 0x1273: 0x00c0, 0x1274: 0x00c0, 0x1275: 0x00c0, + 0x1276: 0x00c0, 0x1277: 0x00c0, 0x1278: 0x00c0, 0x1279: 0x00c0, 0x127a: 0x00c0, 0x127b: 0x00c0, + 0x127c: 0x00c0, 0x127d: 0x00c0, 0x127e: 0x00c0, 0x127f: 0x00c0, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0080, 0x1281: 0x00c0, 0x1282: 0x00c0, 0x1283: 0x00c0, 0x1284: 0x00c0, 0x1285: 0x00c0, + 0x1286: 0x00c0, 0x1287: 0x00c0, 0x1288: 0x00c0, 0x1289: 0x00c0, 0x128a: 0x00c0, 0x128b: 0x00c0, + 0x128c: 0x00c0, 0x128d: 0x00c0, 0x128e: 0x00c0, 0x128f: 0x00c0, 0x1290: 0x00c0, 0x1291: 0x00c0, + 0x1292: 0x00c0, 0x1293: 0x00c0, 0x1294: 0x00c0, 0x1295: 0x00c0, 0x1296: 0x00c0, 0x1297: 0x00c0, + 0x1298: 0x00c0, 0x1299: 0x00c0, 0x129a: 0x00c0, 0x129b: 0x0080, 0x129c: 0x0080, + 0x12a0: 0x00c0, 0x12a1: 0x00c0, 0x12a2: 0x00c0, 0x12a3: 0x00c0, + 0x12a4: 0x00c0, 0x12a5: 0x00c0, 0x12a6: 0x00c0, 0x12a7: 0x00c0, 0x12a8: 0x00c0, 0x12a9: 0x00c0, + 0x12aa: 0x00c0, 0x12ab: 0x00c0, 0x12ac: 0x00c0, 0x12ad: 0x00c0, 0x12ae: 0x00c0, 0x12af: 0x00c0, + 0x12b0: 0x00c0, 0x12b1: 0x00c0, 0x12b2: 0x00c0, 0x12b3: 0x00c0, 0x12b4: 0x00c0, 0x12b5: 0x00c0, + 0x12b6: 0x00c0, 0x12b7: 0x00c0, 0x12b8: 0x00c0, 0x12b9: 0x00c0, 0x12ba: 0x00c0, 0x12bb: 0x00c0, + 0x12bc: 0x00c0, 0x12bd: 0x00c0, 0x12be: 0x00c0, 0x12bf: 0x00c0, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x00c0, 0x12c1: 0x00c0, 0x12c2: 0x00c0, 0x12c3: 0x00c0, 0x12c4: 0x00c0, 0x12c5: 0x00c0, + 0x12c6: 0x00c0, 0x12c7: 0x00c0, 0x12c8: 0x00c0, 0x12c9: 0x00c0, 0x12ca: 0x00c0, 0x12cb: 0x00c0, + 0x12cc: 0x00c0, 0x12cd: 0x00c0, 0x12ce: 0x00c0, 0x12cf: 0x00c0, 0x12d0: 0x00c0, 0x12d1: 0x00c0, + 0x12d2: 0x00c0, 0x12d3: 0x00c0, 0x12d4: 0x00c0, 0x12d5: 0x00c0, 0x12d6: 0x00c0, 0x12d7: 0x00c0, + 0x12d8: 0x00c0, 0x12d9: 0x00c0, 0x12da: 0x00c0, 0x12db: 0x00c0, 0x12dc: 0x00c0, 0x12dd: 0x00c0, + 0x12de: 0x00c0, 0x12df: 0x00c0, 0x12e0: 0x00c0, 0x12e1: 0x00c0, 0x12e2: 0x00c0, 0x12e3: 0x00c0, + 0x12e4: 0x00c0, 0x12e5: 0x00c0, 0x12e6: 0x00c0, 0x12e7: 0x00c0, 0x12e8: 0x00c0, 0x12e9: 0x00c0, + 0x12ea: 0x00c0, 0x12eb: 0x0080, 0x12ec: 0x0080, 0x12ed: 0x0080, 0x12ee: 0x0080, 0x12ef: 0x0080, + 0x12f0: 0x0080, 0x12f1: 0x00c0, 0x12f2: 0x00c0, 0x12f3: 0x00c0, 0x12f4: 0x00c0, 0x12f5: 0x00c0, + 0x12f6: 0x00c0, 0x12f7: 0x00c0, 0x12f8: 0x00c0, + // Block 0x4c, offset 0x1300 + 0x1300: 0x00c0, 0x1301: 0x00c0, 0x1302: 0x00c0, 0x1303: 0x00c0, 0x1304: 0x00c0, 0x1305: 0x00c0, + 0x1306: 0x00c0, 0x1307: 0x00c0, 0x1308: 0x00c0, 0x1309: 0x00c0, 0x130a: 0x00c0, 0x130b: 0x00c0, + 0x130c: 0x00c0, 0x130e: 0x00c0, 0x130f: 0x00c0, 0x1310: 0x00c0, 0x1311: 0x00c0, + 0x1312: 0x00c3, 0x1313: 0x00c3, 0x1314: 0x00c6, + 0x1320: 0x00c0, 0x1321: 0x00c0, 0x1322: 0x00c0, 0x1323: 0x00c0, + 0x1324: 0x00c0, 0x1325: 0x00c0, 0x1326: 0x00c0, 0x1327: 0x00c0, 0x1328: 0x00c0, 0x1329: 0x00c0, + 0x132a: 0x00c0, 0x132b: 0x00c0, 0x132c: 0x00c0, 0x132d: 0x00c0, 0x132e: 0x00c0, 0x132f: 0x00c0, + 0x1330: 0x00c0, 0x1331: 0x00c0, 0x1332: 0x00c3, 0x1333: 0x00c3, 0x1334: 0x00c6, 0x1335: 0x0080, + 0x1336: 0x0080, + // Block 0x4d, offset 0x1340 + 0x1340: 0x00c0, 0x1341: 0x00c0, 0x1342: 0x00c0, 0x1343: 0x00c0, 0x1344: 0x00c0, 0x1345: 0x00c0, + 0x1346: 0x00c0, 0x1347: 0x00c0, 0x1348: 0x00c0, 0x1349: 0x00c0, 0x134a: 0x00c0, 0x134b: 0x00c0, + 0x134c: 0x00c0, 0x134d: 0x00c0, 0x134e: 0x00c0, 0x134f: 0x00c0, 0x1350: 0x00c0, 0x1351: 0x00c0, + 0x1352: 0x00c3, 0x1353: 0x00c3, + 0x1360: 0x00c0, 0x1361: 0x00c0, 0x1362: 0x00c0, 0x1363: 0x00c0, + 0x1364: 0x00c0, 0x1365: 0x00c0, 0x1366: 0x00c0, 0x1367: 0x00c0, 0x1368: 0x00c0, 0x1369: 0x00c0, + 0x136a: 0x00c0, 0x136b: 0x00c0, 0x136c: 0x00c0, 0x136e: 0x00c0, 0x136f: 0x00c0, + 0x1370: 0x00c0, 0x1372: 0x00c3, 0x1373: 0x00c3, + // Block 0x4e, offset 0x1380 + 0x1380: 0x00c0, 0x1381: 0x00c0, 0x1382: 0x00c0, 0x1383: 0x00c0, 0x1384: 0x00c0, 0x1385: 0x00c0, + 0x1386: 0x00c0, 0x1387: 0x00c0, 0x1388: 0x00c0, 0x1389: 0x00c0, 0x138a: 0x00c0, 0x138b: 0x00c0, + 0x138c: 0x00c0, 0x138d: 0x00c0, 0x138e: 0x00c0, 0x138f: 0x00c0, 0x1390: 0x00c0, 0x1391: 0x00c0, + 0x1392: 0x00c0, 0x1393: 0x00c0, 0x1394: 0x00c0, 0x1395: 0x00c0, 0x1396: 0x00c0, 0x1397: 0x00c0, + 0x1398: 0x00c0, 0x1399: 0x00c0, 0x139a: 0x00c0, 0x139b: 0x00c0, 0x139c: 0x00c0, 0x139d: 0x00c0, + 0x139e: 0x00c0, 0x139f: 0x00c0, 0x13a0: 0x00c0, 0x13a1: 0x00c0, 0x13a2: 0x00c0, 0x13a3: 0x00c0, + 0x13a4: 0x00c0, 0x13a5: 0x00c0, 0x13a6: 0x00c0, 0x13a7: 0x00c0, 0x13a8: 0x00c0, 0x13a9: 0x00c0, + 0x13aa: 0x00c0, 0x13ab: 0x00c0, 0x13ac: 0x00c0, 0x13ad: 0x00c0, 0x13ae: 0x00c0, 0x13af: 0x00c0, + 0x13b0: 0x00c0, 0x13b1: 0x00c0, 0x13b2: 0x00c0, 0x13b3: 0x00c0, 0x13b4: 0x0040, 0x13b5: 0x0040, + 0x13b6: 0x00c0, 0x13b7: 0x00c3, 0x13b8: 0x00c3, 0x13b9: 0x00c3, 0x13ba: 0x00c3, 0x13bb: 0x00c3, + 0x13bc: 0x00c3, 0x13bd: 0x00c3, 0x13be: 0x00c0, 0x13bf: 0x00c0, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x00c0, 0x13c1: 0x00c0, 0x13c2: 0x00c0, 0x13c3: 0x00c0, 0x13c4: 0x00c0, 0x13c5: 0x00c0, + 0x13c6: 0x00c3, 0x13c7: 0x00c0, 0x13c8: 0x00c0, 0x13c9: 0x00c3, 0x13ca: 0x00c3, 0x13cb: 0x00c3, + 0x13cc: 0x00c3, 0x13cd: 0x00c3, 0x13ce: 0x00c3, 0x13cf: 0x00c3, 0x13d0: 0x00c3, 0x13d1: 0x00c3, + 0x13d2: 0x00c6, 0x13d3: 0x00c3, 0x13d4: 0x0080, 0x13d5: 0x0080, 0x13d6: 0x0080, 0x13d7: 0x00c0, + 0x13d8: 0x0080, 0x13d9: 0x0080, 0x13da: 0x0080, 0x13db: 0x0080, 0x13dc: 0x00c0, 0x13dd: 0x00c3, + 0x13e0: 0x00c0, 0x13e1: 0x00c0, 0x13e2: 0x00c0, 0x13e3: 0x00c0, + 0x13e4: 0x00c0, 0x13e5: 0x00c0, 0x13e6: 0x00c0, 0x13e7: 0x00c0, 0x13e8: 0x00c0, 0x13e9: 0x00c0, + 0x13f0: 0x0080, 0x13f1: 0x0080, 0x13f2: 0x0080, 0x13f3: 0x0080, 0x13f4: 0x0080, 0x13f5: 0x0080, + 0x13f6: 0x0080, 0x13f7: 0x0080, 0x13f8: 0x0080, 0x13f9: 0x0080, + // Block 0x50, offset 0x1400 + 0x1400: 0x0080, 0x1401: 0x0080, 0x1402: 0x0080, 0x1403: 0x0080, 0x1404: 0x0080, 0x1405: 0x0080, + 0x1406: 0x0080, 0x1407: 0x0082, 0x1408: 0x0080, 0x1409: 0x0080, 0x140a: 0x0080, 0x140b: 0x0040, + 0x140c: 0x0040, 0x140d: 0x0040, 0x140e: 0x0040, 0x1410: 0x00c0, 0x1411: 0x00c0, + 0x1412: 0x00c0, 0x1413: 0x00c0, 0x1414: 0x00c0, 0x1415: 0x00c0, 0x1416: 0x00c0, 0x1417: 0x00c0, + 0x1418: 0x00c0, 0x1419: 0x00c0, + 0x1420: 0x00c2, 0x1421: 0x00c2, 0x1422: 0x00c2, 0x1423: 0x00c2, + 0x1424: 0x00c2, 0x1425: 0x00c2, 0x1426: 0x00c2, 0x1427: 0x00c2, 0x1428: 0x00c2, 0x1429: 0x00c2, + 0x142a: 0x00c2, 0x142b: 0x00c2, 0x142c: 0x00c2, 0x142d: 0x00c2, 0x142e: 0x00c2, 0x142f: 0x00c2, + 0x1430: 0x00c2, 0x1431: 0x00c2, 0x1432: 0x00c2, 0x1433: 0x00c2, 0x1434: 0x00c2, 0x1435: 0x00c2, + 0x1436: 0x00c2, 0x1437: 0x00c2, 0x1438: 0x00c2, 0x1439: 0x00c2, 0x143a: 0x00c2, 0x143b: 0x00c2, + 0x143c: 0x00c2, 0x143d: 0x00c2, 0x143e: 0x00c2, 0x143f: 0x00c2, + // Block 0x51, offset 0x1440 + 0x1440: 0x00c2, 0x1441: 0x00c2, 0x1442: 0x00c2, 0x1443: 0x00c2, 0x1444: 0x00c2, 0x1445: 0x00c2, + 0x1446: 0x00c2, 0x1447: 0x00c2, 0x1448: 0x00c2, 0x1449: 0x00c2, 0x144a: 0x00c2, 0x144b: 0x00c2, + 0x144c: 0x00c2, 0x144d: 0x00c2, 0x144e: 0x00c2, 0x144f: 0x00c2, 0x1450: 0x00c2, 0x1451: 0x00c2, + 0x1452: 0x00c2, 0x1453: 0x00c2, 0x1454: 0x00c2, 0x1455: 0x00c2, 0x1456: 0x00c2, 0x1457: 0x00c2, + 0x1458: 0x00c2, 0x1459: 0x00c2, 0x145a: 0x00c2, 0x145b: 0x00c2, 0x145c: 0x00c2, 0x145d: 0x00c2, + 0x145e: 0x00c2, 0x145f: 0x00c2, 0x1460: 0x00c2, 0x1461: 0x00c2, 0x1462: 0x00c2, 0x1463: 0x00c2, + 0x1464: 0x00c2, 0x1465: 0x00c2, 0x1466: 0x00c2, 0x1467: 0x00c2, 0x1468: 0x00c2, 0x1469: 0x00c2, + 0x146a: 0x00c2, 0x146b: 0x00c2, 0x146c: 0x00c2, 0x146d: 0x00c2, 0x146e: 0x00c2, 0x146f: 0x00c2, + 0x1470: 0x00c2, 0x1471: 0x00c2, 0x1472: 0x00c2, 0x1473: 0x00c2, 0x1474: 0x00c2, 0x1475: 0x00c2, + 0x1476: 0x00c2, 0x1477: 0x00c2, 0x1478: 0x00c2, + // Block 0x52, offset 0x1480 + 0x1480: 0x00c0, 0x1481: 0x00c0, 0x1482: 0x00c0, 0x1483: 0x00c0, 0x1484: 0x00c0, 0x1485: 0x00c3, + 0x1486: 0x00c3, 0x1487: 0x00c2, 0x1488: 0x00c2, 0x1489: 0x00c2, 0x148a: 0x00c2, 0x148b: 0x00c2, + 0x148c: 0x00c2, 0x148d: 0x00c2, 0x148e: 0x00c2, 0x148f: 0x00c2, 0x1490: 0x00c2, 0x1491: 0x00c2, + 0x1492: 0x00c2, 0x1493: 0x00c2, 0x1494: 0x00c2, 0x1495: 0x00c2, 0x1496: 0x00c2, 0x1497: 0x00c2, + 0x1498: 0x00c2, 0x1499: 0x00c2, 0x149a: 0x00c2, 0x149b: 0x00c2, 0x149c: 0x00c2, 0x149d: 0x00c2, + 0x149e: 0x00c2, 0x149f: 0x00c2, 0x14a0: 0x00c2, 0x14a1: 0x00c2, 0x14a2: 0x00c2, 0x14a3: 0x00c2, + 0x14a4: 0x00c2, 0x14a5: 0x00c2, 0x14a6: 0x00c2, 0x14a7: 0x00c2, 0x14a8: 0x00c2, 0x14a9: 0x00c3, + 0x14aa: 0x00c2, + 0x14b0: 0x00c0, 0x14b1: 0x00c0, 0x14b2: 0x00c0, 0x14b3: 0x00c0, 0x14b4: 0x00c0, 0x14b5: 0x00c0, + 0x14b6: 0x00c0, 0x14b7: 0x00c0, 0x14b8: 0x00c0, 0x14b9: 0x00c0, 0x14ba: 0x00c0, 0x14bb: 0x00c0, + 0x14bc: 0x00c0, 0x14bd: 0x00c0, 0x14be: 0x00c0, 0x14bf: 0x00c0, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x00c0, 0x14c1: 0x00c0, 0x14c2: 0x00c0, 0x14c3: 0x00c0, 0x14c4: 0x00c0, 0x14c5: 0x00c0, + 0x14c6: 0x00c0, 0x14c7: 0x00c0, 0x14c8: 0x00c0, 0x14c9: 0x00c0, 0x14ca: 0x00c0, 0x14cb: 0x00c0, + 0x14cc: 0x00c0, 0x14cd: 0x00c0, 0x14ce: 0x00c0, 0x14cf: 0x00c0, 0x14d0: 0x00c0, 0x14d1: 0x00c0, + 0x14d2: 0x00c0, 0x14d3: 0x00c0, 0x14d4: 0x00c0, 0x14d5: 0x00c0, 0x14d6: 0x00c0, 0x14d7: 0x00c0, + 0x14d8: 0x00c0, 0x14d9: 0x00c0, 0x14da: 0x00c0, 0x14db: 0x00c0, 0x14dc: 0x00c0, 0x14dd: 0x00c0, + 0x14de: 0x00c0, 0x14df: 0x00c0, 0x14e0: 0x00c0, 0x14e1: 0x00c0, 0x14e2: 0x00c0, 0x14e3: 0x00c0, + 0x14e4: 0x00c0, 0x14e5: 0x00c0, 0x14e6: 0x00c0, 0x14e7: 0x00c0, 0x14e8: 0x00c0, 0x14e9: 0x00c0, + 0x14ea: 0x00c0, 0x14eb: 0x00c0, 0x14ec: 0x00c0, 0x14ed: 0x00c0, 0x14ee: 0x00c0, 0x14ef: 0x00c0, + 0x14f0: 0x00c0, 0x14f1: 0x00c0, 0x14f2: 0x00c0, 0x14f3: 0x00c0, 0x14f4: 0x00c0, 0x14f5: 0x00c0, + // Block 0x54, offset 0x1500 + 0x1500: 0x00c0, 0x1501: 0x00c0, 0x1502: 0x00c0, 0x1503: 0x00c0, 0x1504: 0x00c0, 0x1505: 0x00c0, + 0x1506: 0x00c0, 0x1507: 0x00c0, 0x1508: 0x00c0, 0x1509: 0x00c0, 0x150a: 0x00c0, 0x150b: 0x00c0, + 0x150c: 0x00c0, 0x150d: 0x00c0, 0x150e: 0x00c0, 0x150f: 0x00c0, 0x1510: 0x00c0, 0x1511: 0x00c0, + 0x1512: 0x00c0, 0x1513: 0x00c0, 0x1514: 0x00c0, 0x1515: 0x00c0, 0x1516: 0x00c0, 0x1517: 0x00c0, + 0x1518: 0x00c0, 0x1519: 0x00c0, 0x151a: 0x00c0, 0x151b: 0x00c0, 0x151c: 0x00c0, 0x151d: 0x00c0, + 0x151e: 0x00c0, 0x1520: 0x00c3, 0x1521: 0x00c3, 0x1522: 0x00c3, 0x1523: 0x00c0, + 0x1524: 0x00c0, 0x1525: 0x00c0, 0x1526: 0x00c0, 0x1527: 0x00c3, 0x1528: 0x00c3, 0x1529: 0x00c0, + 0x152a: 0x00c0, 0x152b: 0x00c0, + 0x1530: 0x00c0, 0x1531: 0x00c0, 0x1532: 0x00c3, 0x1533: 0x00c0, 0x1534: 0x00c0, 0x1535: 0x00c0, + 0x1536: 0x00c0, 0x1537: 0x00c0, 0x1538: 0x00c0, 0x1539: 0x00c3, 0x153a: 0x00c3, 0x153b: 0x00c3, + // Block 0x55, offset 0x1540 + 0x1540: 0x0080, 0x1544: 0x0080, 0x1545: 0x0080, + 0x1546: 0x00c0, 0x1547: 0x00c0, 0x1548: 0x00c0, 0x1549: 0x00c0, 0x154a: 0x00c0, 0x154b: 0x00c0, + 0x154c: 0x00c0, 0x154d: 0x00c0, 0x154e: 0x00c0, 0x154f: 0x00c0, 0x1550: 0x00c0, 0x1551: 0x00c0, + 0x1552: 0x00c0, 0x1553: 0x00c0, 0x1554: 0x00c0, 0x1555: 0x00c0, 0x1556: 0x00c0, 0x1557: 0x00c0, + 0x1558: 0x00c0, 0x1559: 0x00c0, 0x155a: 0x00c0, 0x155b: 0x00c0, 0x155c: 0x00c0, 0x155d: 0x00c0, + 0x155e: 0x00c0, 0x155f: 0x00c0, 0x1560: 0x00c0, 0x1561: 0x00c0, 0x1562: 0x00c0, 0x1563: 0x00c0, + 0x1564: 0x00c0, 0x1565: 0x00c0, 0x1566: 0x00c0, 0x1567: 0x00c0, 0x1568: 0x00c0, 0x1569: 0x00c0, + 0x156a: 0x00c0, 0x156b: 0x00c0, 0x156c: 0x00c0, 0x156d: 0x00c0, + 0x1570: 0x00c0, 0x1571: 0x00c0, 0x1572: 0x00c0, 0x1573: 0x00c0, 0x1574: 0x00c0, + // Block 0x56, offset 0x1580 + 0x1580: 0x00c0, 0x1581: 0x00c0, 0x1582: 0x00c0, 0x1583: 0x00c0, 0x1584: 0x00c0, 0x1585: 0x00c0, + 0x1586: 0x00c0, 0x1587: 0x00c0, 0x1588: 0x00c0, 0x1589: 0x00c0, 0x158a: 0x00c0, 0x158b: 0x00c0, + 0x158c: 0x00c0, 0x158d: 0x00c0, 0x158e: 0x00c0, 0x158f: 0x00c0, 0x1590: 0x00c0, 0x1591: 0x00c0, + 0x1592: 0x00c0, 0x1593: 0x00c0, 0x1594: 0x00c0, 0x1595: 0x00c0, 0x1596: 0x00c0, 0x1597: 0x00c0, + 0x1598: 0x00c0, 0x1599: 0x00c0, 0x159a: 0x00c0, 0x159b: 0x00c0, 0x159c: 0x00c0, 0x159d: 0x00c0, + 0x159e: 0x00c0, 0x159f: 0x00c0, 0x15a0: 0x00c0, 0x15a1: 0x00c0, 0x15a2: 0x00c0, 0x15a3: 0x00c0, + 0x15a4: 0x00c0, 0x15a5: 0x00c0, 0x15a6: 0x00c0, 0x15a7: 0x00c0, 0x15a8: 0x00c0, 0x15a9: 0x00c0, + 0x15aa: 0x00c0, 0x15ab: 0x00c0, + 0x15b0: 0x00c0, 0x15b1: 0x00c0, 0x15b2: 0x00c0, 0x15b3: 0x00c0, 0x15b4: 0x00c0, 0x15b5: 0x00c0, + 0x15b6: 0x00c0, 0x15b7: 0x00c0, 0x15b8: 0x00c0, 0x15b9: 0x00c0, 0x15ba: 0x00c0, 0x15bb: 0x00c0, + 0x15bc: 0x00c0, 0x15bd: 0x00c0, 0x15be: 0x00c0, 0x15bf: 0x00c0, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x00c0, 0x15c1: 0x00c0, 0x15c2: 0x00c0, 0x15c3: 0x00c0, 0x15c4: 0x00c0, 0x15c5: 0x00c0, + 0x15c6: 0x00c0, 0x15c7: 0x00c0, 0x15c8: 0x00c0, 0x15c9: 0x00c0, + 0x15d0: 0x00c0, 0x15d1: 0x00c0, + 0x15d2: 0x00c0, 0x15d3: 0x00c0, 0x15d4: 0x00c0, 0x15d5: 0x00c0, 0x15d6: 0x00c0, 0x15d7: 0x00c0, + 0x15d8: 0x00c0, 0x15d9: 0x00c0, 0x15da: 0x0080, + 0x15de: 0x0080, 0x15df: 0x0080, 0x15e0: 0x0080, 0x15e1: 0x0080, 0x15e2: 0x0080, 0x15e3: 0x0080, + 0x15e4: 0x0080, 0x15e5: 0x0080, 0x15e6: 0x0080, 0x15e7: 0x0080, 0x15e8: 0x0080, 0x15e9: 0x0080, + 0x15ea: 0x0080, 0x15eb: 0x0080, 0x15ec: 0x0080, 0x15ed: 0x0080, 0x15ee: 0x0080, 0x15ef: 0x0080, + 0x15f0: 0x0080, 0x15f1: 0x0080, 0x15f2: 0x0080, 0x15f3: 0x0080, 0x15f4: 0x0080, 0x15f5: 0x0080, + 0x15f6: 0x0080, 0x15f7: 0x0080, 0x15f8: 0x0080, 0x15f9: 0x0080, 0x15fa: 0x0080, 0x15fb: 0x0080, + 0x15fc: 0x0080, 0x15fd: 0x0080, 0x15fe: 0x0080, 0x15ff: 0x0080, + // Block 0x58, offset 0x1600 + 0x1600: 0x00c0, 0x1601: 0x00c0, 0x1602: 0x00c0, 0x1603: 0x00c0, 0x1604: 0x00c0, 0x1605: 0x00c0, + 0x1606: 0x00c0, 0x1607: 0x00c0, 0x1608: 0x00c0, 0x1609: 0x00c0, 0x160a: 0x00c0, 0x160b: 0x00c0, + 0x160c: 0x00c0, 0x160d: 0x00c0, 0x160e: 0x00c0, 0x160f: 0x00c0, 0x1610: 0x00c0, 0x1611: 0x00c0, + 0x1612: 0x00c0, 0x1613: 0x00c0, 0x1614: 0x00c0, 0x1615: 0x00c0, 0x1616: 0x00c0, 0x1617: 0x00c3, + 0x1618: 0x00c3, 0x1619: 0x00c0, 0x161a: 0x00c0, 0x161b: 0x00c3, + 0x161e: 0x0080, 0x161f: 0x0080, 0x1620: 0x00c0, 0x1621: 0x00c0, 0x1622: 0x00c0, 0x1623: 0x00c0, + 0x1624: 0x00c0, 0x1625: 0x00c0, 0x1626: 0x00c0, 0x1627: 0x00c0, 0x1628: 0x00c0, 0x1629: 0x00c0, + 0x162a: 0x00c0, 0x162b: 0x00c0, 0x162c: 0x00c0, 0x162d: 0x00c0, 0x162e: 0x00c0, 0x162f: 0x00c0, + 0x1630: 0x00c0, 0x1631: 0x00c0, 0x1632: 0x00c0, 0x1633: 0x00c0, 0x1634: 0x00c0, 0x1635: 0x00c0, + 0x1636: 0x00c0, 0x1637: 0x00c0, 0x1638: 0x00c0, 0x1639: 0x00c0, 0x163a: 0x00c0, 0x163b: 0x00c0, + 0x163c: 0x00c0, 0x163d: 0x00c0, 0x163e: 0x00c0, 0x163f: 0x00c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x00c0, 0x1641: 0x00c0, 0x1642: 0x00c0, 0x1643: 0x00c0, 0x1644: 0x00c0, 0x1645: 0x00c0, + 0x1646: 0x00c0, 0x1647: 0x00c0, 0x1648: 0x00c0, 0x1649: 0x00c0, 0x164a: 0x00c0, 0x164b: 0x00c0, + 0x164c: 0x00c0, 0x164d: 0x00c0, 0x164e: 0x00c0, 0x164f: 0x00c0, 0x1650: 0x00c0, 0x1651: 0x00c0, + 0x1652: 0x00c0, 0x1653: 0x00c0, 0x1654: 0x00c0, 0x1655: 0x00c0, 0x1656: 0x00c3, 0x1657: 0x00c0, + 0x1658: 0x00c3, 0x1659: 0x00c3, 0x165a: 0x00c3, 0x165b: 0x00c3, 0x165c: 0x00c3, 0x165d: 0x00c3, + 0x165e: 0x00c3, 0x1660: 0x00c6, 0x1661: 0x00c0, 0x1662: 0x00c3, 0x1663: 0x00c0, + 0x1664: 0x00c0, 0x1665: 0x00c3, 0x1666: 0x00c3, 0x1667: 0x00c3, 0x1668: 0x00c3, 0x1669: 0x00c3, + 0x166a: 0x00c3, 0x166b: 0x00c3, 0x166c: 0x00c3, 0x166d: 0x00c0, 0x166e: 0x00c0, 0x166f: 0x00c0, + 0x1670: 0x00c0, 0x1671: 0x00c0, 0x1672: 0x00c0, 0x1673: 0x00c3, 0x1674: 0x00c3, 0x1675: 0x00c3, + 0x1676: 0x00c3, 0x1677: 0x00c3, 0x1678: 0x00c3, 0x1679: 0x00c3, 0x167a: 0x00c3, 0x167b: 0x00c3, + 0x167c: 0x00c3, 0x167f: 0x00c3, + // Block 0x5a, offset 0x1680 + 0x1680: 0x00c0, 0x1681: 0x00c0, 0x1682: 0x00c0, 0x1683: 0x00c0, 0x1684: 0x00c0, 0x1685: 0x00c0, + 0x1686: 0x00c0, 0x1687: 0x00c0, 0x1688: 0x00c0, 0x1689: 0x00c0, + 0x1690: 0x00c0, 0x1691: 0x00c0, + 0x1692: 0x00c0, 0x1693: 0x00c0, 0x1694: 0x00c0, 0x1695: 0x00c0, 0x1696: 0x00c0, 0x1697: 0x00c0, + 0x1698: 0x00c0, 0x1699: 0x00c0, + 0x16a0: 0x0080, 0x16a1: 0x0080, 0x16a2: 0x0080, 0x16a3: 0x0080, + 0x16a4: 0x0080, 0x16a5: 0x0080, 0x16a6: 0x0080, 0x16a7: 0x00c0, 0x16a8: 0x0080, 0x16a9: 0x0080, + 0x16aa: 0x0080, 0x16ab: 0x0080, 0x16ac: 0x0080, 0x16ad: 0x0080, + 0x16b0: 0x00c3, 0x16b1: 0x00c3, 0x16b2: 0x00c3, 0x16b3: 0x00c3, 0x16b4: 0x00c3, 0x16b5: 0x00c3, + 0x16b6: 0x00c3, 0x16b7: 0x00c3, 0x16b8: 0x00c3, 0x16b9: 0x00c3, 0x16ba: 0x00c3, 0x16bb: 0x00c3, + 0x16bc: 0x00c3, 0x16bd: 0x00c3, 0x16be: 0x0083, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x00c3, 0x16c1: 0x00c3, 0x16c2: 0x00c3, 0x16c3: 0x00c3, 0x16c4: 0x00c0, 0x16c5: 0x00c0, + 0x16c6: 0x00c0, 0x16c7: 0x00c0, 0x16c8: 0x00c0, 0x16c9: 0x00c0, 0x16ca: 0x00c0, 0x16cb: 0x00c0, + 0x16cc: 0x00c0, 0x16cd: 0x00c0, 0x16ce: 0x00c0, 0x16cf: 0x00c0, 0x16d0: 0x00c0, 0x16d1: 0x00c0, + 0x16d2: 0x00c0, 0x16d3: 0x00c0, 0x16d4: 0x00c0, 0x16d5: 0x00c0, 0x16d6: 0x00c0, 0x16d7: 0x00c0, + 0x16d8: 0x00c0, 0x16d9: 0x00c0, 0x16da: 0x00c0, 0x16db: 0x00c0, 0x16dc: 0x00c0, 0x16dd: 0x00c0, + 0x16de: 0x00c0, 0x16df: 0x00c0, 0x16e0: 0x00c0, 0x16e1: 0x00c0, 0x16e2: 0x00c0, 0x16e3: 0x00c0, + 0x16e4: 0x00c0, 0x16e5: 0x00c0, 0x16e6: 0x00c0, 0x16e7: 0x00c0, 0x16e8: 0x00c0, 0x16e9: 0x00c0, + 0x16ea: 0x00c0, 0x16eb: 0x00c0, 0x16ec: 0x00c0, 0x16ed: 0x00c0, 0x16ee: 0x00c0, 0x16ef: 0x00c0, + 0x16f0: 0x00c0, 0x16f1: 0x00c0, 0x16f2: 0x00c0, 0x16f3: 0x00c0, 0x16f4: 0x00c3, 0x16f5: 0x00c0, + 0x16f6: 0x00c3, 0x16f7: 0x00c3, 0x16f8: 0x00c3, 0x16f9: 0x00c3, 0x16fa: 0x00c3, 0x16fb: 0x00c0, + 0x16fc: 0x00c3, 0x16fd: 0x00c0, 0x16fe: 0x00c0, 0x16ff: 0x00c0, + // Block 0x5c, offset 0x1700 + 0x1700: 0x00c0, 0x1701: 0x00c0, 0x1702: 0x00c3, 0x1703: 0x00c0, 0x1704: 0x00c5, 0x1705: 0x00c0, + 0x1706: 0x00c0, 0x1707: 0x00c0, 0x1708: 0x00c0, 0x1709: 0x00c0, 0x170a: 0x00c0, 0x170b: 0x00c0, + 0x1710: 0x00c0, 0x1711: 0x00c0, + 0x1712: 0x00c0, 0x1713: 0x00c0, 0x1714: 0x00c0, 0x1715: 0x00c0, 0x1716: 0x00c0, 0x1717: 0x00c0, + 0x1718: 0x00c0, 0x1719: 0x00c0, 0x171a: 0x0080, 0x171b: 0x0080, 0x171c: 0x0080, 0x171d: 0x0080, + 0x171e: 0x0080, 0x171f: 0x0080, 0x1720: 0x0080, 0x1721: 0x0080, 0x1722: 0x0080, 0x1723: 0x0080, + 0x1724: 0x0080, 0x1725: 0x0080, 0x1726: 0x0080, 0x1727: 0x0080, 0x1728: 0x0080, 0x1729: 0x0080, + 0x172a: 0x0080, 0x172b: 0x00c3, 0x172c: 0x00c3, 0x172d: 0x00c3, 0x172e: 0x00c3, 0x172f: 0x00c3, + 0x1730: 0x00c3, 0x1731: 0x00c3, 0x1732: 0x00c3, 0x1733: 0x00c3, 0x1734: 0x0080, 0x1735: 0x0080, + 0x1736: 0x0080, 0x1737: 0x0080, 0x1738: 0x0080, 0x1739: 0x0080, 0x173a: 0x0080, 0x173b: 0x0080, + 0x173c: 0x0080, + // Block 0x5d, offset 0x1740 + 0x1740: 0x00c3, 0x1741: 0x00c3, 0x1742: 0x00c0, 0x1743: 0x00c0, 0x1744: 0x00c0, 0x1745: 0x00c0, + 0x1746: 0x00c0, 0x1747: 0x00c0, 0x1748: 0x00c0, 0x1749: 0x00c0, 0x174a: 0x00c0, 0x174b: 0x00c0, + 0x174c: 0x00c0, 0x174d: 0x00c0, 0x174e: 0x00c0, 0x174f: 0x00c0, 0x1750: 0x00c0, 0x1751: 0x00c0, + 0x1752: 0x00c0, 0x1753: 0x00c0, 0x1754: 0x00c0, 0x1755: 0x00c0, 0x1756: 0x00c0, 0x1757: 0x00c0, + 0x1758: 0x00c0, 0x1759: 0x00c0, 0x175a: 0x00c0, 0x175b: 0x00c0, 0x175c: 0x00c0, 0x175d: 0x00c0, + 0x175e: 0x00c0, 0x175f: 0x00c0, 0x1760: 0x00c0, 0x1761: 0x00c0, 0x1762: 0x00c3, 0x1763: 0x00c3, + 0x1764: 0x00c3, 0x1765: 0x00c3, 0x1766: 0x00c0, 0x1767: 0x00c0, 0x1768: 0x00c3, 0x1769: 0x00c3, + 0x176a: 0x00c5, 0x176b: 0x00c6, 0x176c: 0x00c3, 0x176d: 0x00c3, 0x176e: 0x00c0, 0x176f: 0x00c0, + 0x1770: 0x00c0, 0x1771: 0x00c0, 0x1772: 0x00c0, 0x1773: 0x00c0, 0x1774: 0x00c0, 0x1775: 0x00c0, + 0x1776: 0x00c0, 0x1777: 0x00c0, 0x1778: 0x00c0, 0x1779: 0x00c0, 0x177a: 0x00c0, 0x177b: 0x00c0, + 0x177c: 0x00c0, 0x177d: 0x00c0, 0x177e: 0x00c0, 0x177f: 0x00c0, + // Block 0x5e, offset 0x1780 + 0x1780: 0x00c0, 0x1781: 0x00c0, 0x1782: 0x00c0, 0x1783: 0x00c0, 0x1784: 0x00c0, 0x1785: 0x00c0, + 0x1786: 0x00c0, 0x1787: 0x00c0, 0x1788: 0x00c0, 0x1789: 0x00c0, 0x178a: 0x00c0, 0x178b: 0x00c0, + 0x178c: 0x00c0, 0x178d: 0x00c0, 0x178e: 0x00c0, 0x178f: 0x00c0, 0x1790: 0x00c0, 0x1791: 0x00c0, + 0x1792: 0x00c0, 0x1793: 0x00c0, 0x1794: 0x00c0, 0x1795: 0x00c0, 0x1796: 0x00c0, 0x1797: 0x00c0, + 0x1798: 0x00c0, 0x1799: 0x00c0, 0x179a: 0x00c0, 0x179b: 0x00c0, 0x179c: 0x00c0, 0x179d: 0x00c0, + 0x179e: 0x00c0, 0x179f: 0x00c0, 0x17a0: 0x00c0, 0x17a1: 0x00c0, 0x17a2: 0x00c0, 0x17a3: 0x00c0, + 0x17a4: 0x00c0, 0x17a5: 0x00c0, 0x17a6: 0x00c3, 0x17a7: 0x00c0, 0x17a8: 0x00c3, 0x17a9: 0x00c3, + 0x17aa: 0x00c0, 0x17ab: 0x00c0, 0x17ac: 0x00c0, 0x17ad: 0x00c3, 0x17ae: 0x00c0, 0x17af: 0x00c3, + 0x17b0: 0x00c3, 0x17b1: 0x00c3, 0x17b2: 0x00c5, 0x17b3: 0x00c5, + 0x17bc: 0x0080, 0x17bd: 0x0080, 0x17be: 0x0080, 0x17bf: 0x0080, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x00c0, 0x17c1: 0x00c0, 0x17c2: 0x00c0, 0x17c3: 0x00c0, 0x17c4: 0x00c0, 0x17c5: 0x00c0, + 0x17c6: 0x00c0, 0x17c7: 0x00c0, 0x17c8: 0x00c0, 0x17c9: 0x00c0, 0x17ca: 0x00c0, 0x17cb: 0x00c0, + 0x17cc: 0x00c0, 0x17cd: 0x00c0, 0x17ce: 0x00c0, 0x17cf: 0x00c0, 0x17d0: 0x00c0, 0x17d1: 0x00c0, + 0x17d2: 0x00c0, 0x17d3: 0x00c0, 0x17d4: 0x00c0, 0x17d5: 0x00c0, 0x17d6: 0x00c0, 0x17d7: 0x00c0, + 0x17d8: 0x00c0, 0x17d9: 0x00c0, 0x17da: 0x00c0, 0x17db: 0x00c0, 0x17dc: 0x00c0, 0x17dd: 0x00c0, + 0x17de: 0x00c0, 0x17df: 0x00c0, 0x17e0: 0x00c0, 0x17e1: 0x00c0, 0x17e2: 0x00c0, 0x17e3: 0x00c0, + 0x17e4: 0x00c0, 0x17e5: 0x00c0, 0x17e6: 0x00c0, 0x17e7: 0x00c0, 0x17e8: 0x00c0, 0x17e9: 0x00c0, + 0x17ea: 0x00c0, 0x17eb: 0x00c0, 0x17ec: 0x00c3, 0x17ed: 0x00c3, 0x17ee: 0x00c3, 0x17ef: 0x00c3, + 0x17f0: 0x00c3, 0x17f1: 0x00c3, 0x17f2: 0x00c3, 0x17f3: 0x00c3, 0x17f4: 0x00c0, 0x17f5: 0x00c0, + 0x17f6: 0x00c3, 0x17f7: 0x00c3, 0x17fb: 0x0080, + 0x17fc: 0x0080, 0x17fd: 0x0080, 0x17fe: 0x0080, 0x17ff: 0x0080, + // Block 0x60, offset 0x1800 + 0x1800: 0x00c0, 0x1801: 0x00c0, 0x1802: 0x00c0, 0x1803: 0x00c0, 0x1804: 0x00c0, 0x1805: 0x00c0, + 0x1806: 0x00c0, 0x1807: 0x00c0, 0x1808: 0x00c0, 0x1809: 0x00c0, + 0x180d: 0x00c0, 0x180e: 0x00c0, 0x180f: 0x00c0, 0x1810: 0x00c0, 0x1811: 0x00c0, + 0x1812: 0x00c0, 0x1813: 0x00c0, 0x1814: 0x00c0, 0x1815: 0x00c0, 0x1816: 0x00c0, 0x1817: 0x00c0, + 0x1818: 0x00c0, 0x1819: 0x00c0, 0x181a: 0x00c0, 0x181b: 0x00c0, 0x181c: 0x00c0, 0x181d: 0x00c0, + 0x181e: 0x00c0, 0x181f: 0x00c0, 0x1820: 0x00c0, 0x1821: 0x00c0, 0x1822: 0x00c0, 0x1823: 0x00c0, + 0x1824: 0x00c0, 0x1825: 0x00c0, 0x1826: 0x00c0, 0x1827: 0x00c0, 0x1828: 0x00c0, 0x1829: 0x00c0, + 0x182a: 0x00c0, 0x182b: 0x00c0, 0x182c: 0x00c0, 0x182d: 0x00c0, 0x182e: 0x00c0, 0x182f: 0x00c0, + 0x1830: 0x00c0, 0x1831: 0x00c0, 0x1832: 0x00c0, 0x1833: 0x00c0, 0x1834: 0x00c0, 0x1835: 0x00c0, + 0x1836: 0x00c0, 0x1837: 0x00c0, 0x1838: 0x00c0, 0x1839: 0x00c0, 0x183a: 0x00c0, 0x183b: 0x00c0, + 0x183c: 0x00c0, 0x183d: 0x00c0, 0x183e: 0x0080, 0x183f: 0x0080, + // Block 0x61, offset 0x1840 + 0x1840: 0x00c0, 0x1841: 0x00c0, 0x1842: 0x00c0, 0x1843: 0x00c0, 0x1844: 0x00c0, 0x1845: 0x00c0, + 0x1846: 0x00c0, 0x1847: 0x00c0, 0x1848: 0x00c0, + 0x1850: 0x00c0, 0x1851: 0x00c0, + 0x1852: 0x00c0, 0x1853: 0x00c0, 0x1854: 0x00c0, 0x1855: 0x00c0, 0x1856: 0x00c0, 0x1857: 0x00c0, + 0x1858: 0x00c0, 0x1859: 0x00c0, 0x185a: 0x00c0, 0x185b: 0x00c0, 0x185c: 0x00c0, 0x185d: 0x00c0, + 0x185e: 0x00c0, 0x185f: 0x00c0, 0x1860: 0x00c0, 0x1861: 0x00c0, 0x1862: 0x00c0, 0x1863: 0x00c0, + 0x1864: 0x00c0, 0x1865: 0x00c0, 0x1866: 0x00c0, 0x1867: 0x00c0, 0x1868: 0x00c0, 0x1869: 0x00c0, + 0x186a: 0x00c0, 0x186b: 0x00c0, 0x186c: 0x00c0, 0x186d: 0x00c0, 0x186e: 0x00c0, 0x186f: 0x00c0, + 0x1870: 0x00c0, 0x1871: 0x00c0, 0x1872: 0x00c0, 0x1873: 0x00c0, 0x1874: 0x00c0, 0x1875: 0x00c0, + 0x1876: 0x00c0, 0x1877: 0x00c0, 0x1878: 0x00c0, 0x1879: 0x00c0, 0x187a: 0x00c0, + 0x187d: 0x00c0, 0x187e: 0x00c0, 0x187f: 0x00c0, + // Block 0x62, offset 0x1880 + 0x1880: 0x0080, 0x1881: 0x0080, 0x1882: 0x0080, 0x1883: 0x0080, 0x1884: 0x0080, 0x1885: 0x0080, + 0x1886: 0x0080, 0x1887: 0x0080, + 0x1890: 0x00c3, 0x1891: 0x00c3, + 0x1892: 0x00c3, 0x1893: 0x0080, 0x1894: 0x00c3, 0x1895: 0x00c3, 0x1896: 0x00c3, 0x1897: 0x00c3, + 0x1898: 0x00c3, 0x1899: 0x00c3, 0x189a: 0x00c3, 0x189b: 0x00c3, 0x189c: 0x00c3, 0x189d: 0x00c3, + 0x189e: 0x00c3, 0x189f: 0x00c3, 0x18a0: 0x00c3, 0x18a1: 0x00c0, 0x18a2: 0x00c3, 0x18a3: 0x00c3, + 0x18a4: 0x00c3, 0x18a5: 0x00c3, 0x18a6: 0x00c3, 0x18a7: 0x00c3, 0x18a8: 0x00c3, 0x18a9: 0x00c0, + 0x18aa: 0x00c0, 0x18ab: 0x00c0, 0x18ac: 0x00c0, 0x18ad: 0x00c3, 0x18ae: 0x00c0, 0x18af: 0x00c0, + 0x18b0: 0x00c0, 0x18b1: 0x00c0, 0x18b2: 0x00c0, 0x18b3: 0x00c0, 0x18b4: 0x00c3, 0x18b5: 0x00c0, + 0x18b6: 0x00c0, 0x18b7: 0x00c0, 0x18b8: 0x00c3, 0x18b9: 0x00c3, 0x18ba: 0x00c0, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x00c0, 0x18c1: 0x00c0, 0x18c2: 0x00c0, 0x18c3: 0x00c0, 0x18c4: 0x00c0, 0x18c5: 0x00c0, + 0x18c6: 0x00c0, 0x18c7: 0x00c0, 0x18c8: 0x00c0, 0x18c9: 0x00c0, 0x18ca: 0x00c0, 0x18cb: 0x00c0, + 0x18cc: 0x00c0, 0x18cd: 0x00c0, 0x18ce: 0x00c0, 0x18cf: 0x00c0, 0x18d0: 0x00c0, 0x18d1: 0x00c0, + 0x18d2: 0x00c0, 0x18d3: 0x00c0, 0x18d4: 0x00c0, 0x18d5: 0x00c0, 0x18d6: 0x00c0, 0x18d7: 0x00c0, + 0x18d8: 0x00c0, 0x18d9: 0x00c0, 0x18da: 0x00c0, 0x18db: 0x00c0, 0x18dc: 0x00c0, 0x18dd: 0x00c0, + 0x18de: 0x00c0, 0x18df: 0x00c0, 0x18e0: 0x00c0, 0x18e1: 0x00c0, 0x18e2: 0x00c0, 0x18e3: 0x00c0, + 0x18e4: 0x00c0, 0x18e5: 0x00c0, 0x18e6: 0x00c8, 0x18e7: 0x00c8, 0x18e8: 0x00c8, 0x18e9: 0x00c8, + 0x18ea: 0x00c8, 0x18eb: 0x00c0, 0x18ec: 0x0080, 0x18ed: 0x0080, 0x18ee: 0x0080, 0x18ef: 0x00c0, + 0x18f0: 0x0080, 0x18f1: 0x0080, 0x18f2: 0x0080, 0x18f3: 0x0080, 0x18f4: 0x0080, 0x18f5: 0x0080, + 0x18f6: 0x0080, 0x18f7: 0x0080, 0x18f8: 0x0080, 0x18f9: 0x0080, 0x18fa: 0x0080, 0x18fb: 0x00c0, + 0x18fc: 0x0080, 0x18fd: 0x0080, 0x18fe: 0x0080, 0x18ff: 0x0080, + // Block 0x64, offset 0x1900 + 0x1900: 0x0080, 0x1901: 0x0080, 0x1902: 0x0080, 0x1903: 0x0080, 0x1904: 0x0080, 0x1905: 0x0080, + 0x1906: 0x0080, 0x1907: 0x0080, 0x1908: 0x0080, 0x1909: 0x0080, 0x190a: 0x0080, 0x190b: 0x0080, + 0x190c: 0x0080, 0x190d: 0x0080, 0x190e: 0x00c0, 0x190f: 0x0080, 0x1910: 0x0080, 0x1911: 0x0080, + 0x1912: 0x0080, 0x1913: 0x0080, 0x1914: 0x0080, 0x1915: 0x0080, 0x1916: 0x0080, 0x1917: 0x0080, + 0x1918: 0x0080, 0x1919: 0x0080, 0x191a: 0x0080, 0x191b: 0x0080, 0x191c: 0x0080, 0x191d: 0x0088, + 0x191e: 0x0088, 0x191f: 0x0088, 0x1920: 0x0088, 0x1921: 0x0088, 0x1922: 0x0080, 0x1923: 0x0080, + 0x1924: 0x0080, 0x1925: 0x0080, 0x1926: 0x0088, 0x1927: 0x0088, 0x1928: 0x0088, 0x1929: 0x0088, + 0x192a: 0x0088, 0x192b: 0x00c0, 0x192c: 0x00c0, 0x192d: 0x00c0, 0x192e: 0x00c0, 0x192f: 0x00c0, + 0x1930: 0x00c0, 0x1931: 0x00c0, 0x1932: 0x00c0, 0x1933: 0x00c0, 0x1934: 0x00c0, 0x1935: 0x00c0, + 0x1936: 0x00c0, 0x1937: 0x00c0, 0x1938: 0x0080, 0x1939: 0x00c0, 0x193a: 0x00c0, 0x193b: 0x00c0, + 0x193c: 0x00c0, 0x193d: 0x00c0, 0x193e: 0x00c0, 0x193f: 0x00c0, + // Block 0x65, offset 0x1940 + 0x1940: 0x00c0, 0x1941: 0x00c0, 0x1942: 0x00c0, 0x1943: 0x00c0, 0x1944: 0x00c0, 0x1945: 0x00c0, + 0x1946: 0x00c0, 0x1947: 0x00c0, 0x1948: 0x00c0, 0x1949: 0x00c0, 0x194a: 0x00c0, 0x194b: 0x00c0, + 0x194c: 0x00c0, 0x194d: 0x00c0, 0x194e: 0x00c0, 0x194f: 0x00c0, 0x1950: 0x00c0, 0x1951: 0x00c0, + 0x1952: 0x00c0, 0x1953: 0x00c0, 0x1954: 0x00c0, 0x1955: 0x00c0, 0x1956: 0x00c0, 0x1957: 0x00c0, + 0x1958: 0x00c0, 0x1959: 0x00c0, 0x195a: 0x00c0, 0x195b: 0x0080, 0x195c: 0x0080, 0x195d: 0x0080, + 0x195e: 0x0080, 0x195f: 0x0080, 0x1960: 0x0080, 0x1961: 0x0080, 0x1962: 0x0080, 0x1963: 0x0080, + 0x1964: 0x0080, 0x1965: 0x0080, 0x1966: 0x0080, 0x1967: 0x0080, 0x1968: 0x0080, 0x1969: 0x0080, + 0x196a: 0x0080, 0x196b: 0x0080, 0x196c: 0x0080, 0x196d: 0x0080, 0x196e: 0x0080, 0x196f: 0x0080, + 0x1970: 0x0080, 0x1971: 0x0080, 0x1972: 0x0080, 0x1973: 0x0080, 0x1974: 0x0080, 0x1975: 0x0080, + 0x1976: 0x0080, 0x1977: 0x0080, 0x1978: 0x0080, 0x1979: 0x0080, 0x197a: 0x0080, 0x197b: 0x0080, + 0x197c: 0x0080, 0x197d: 0x0080, 0x197e: 0x0080, 0x197f: 0x0088, + // Block 0x66, offset 0x1980 + 0x1980: 0x00c3, 0x1981: 0x00c3, 0x1982: 0x00c3, 0x1983: 0x00c3, 0x1984: 0x00c3, 0x1985: 0x00c3, + 0x1986: 0x00c3, 0x1987: 0x00c3, 0x1988: 0x00c3, 0x1989: 0x00c3, 0x198a: 0x00c3, 0x198b: 0x00c3, + 0x198c: 0x00c3, 0x198d: 0x00c3, 0x198e: 0x00c3, 0x198f: 0x00c3, 0x1990: 0x00c3, 0x1991: 0x00c3, + 0x1992: 0x00c3, 0x1993: 0x00c3, 0x1994: 0x00c3, 0x1995: 0x00c3, 0x1996: 0x00c3, 0x1997: 0x00c3, + 0x1998: 0x00c3, 0x1999: 0x00c3, 0x199a: 0x00c3, 0x199b: 0x00c3, 0x199c: 0x00c3, 0x199d: 0x00c3, + 0x199e: 0x00c3, 0x199f: 0x00c3, 0x19a0: 0x00c3, 0x19a1: 0x00c3, 0x19a2: 0x00c3, 0x19a3: 0x00c3, + 0x19a4: 0x00c3, 0x19a5: 0x00c3, 0x19a6: 0x00c3, 0x19a7: 0x00c3, 0x19a8: 0x00c3, 0x19a9: 0x00c3, + 0x19aa: 0x00c3, 0x19ab: 0x00c3, 0x19ac: 0x00c3, 0x19ad: 0x00c3, 0x19ae: 0x00c3, 0x19af: 0x00c3, + 0x19b0: 0x00c3, 0x19b1: 0x00c3, 0x19b2: 0x00c3, 0x19b3: 0x00c3, 0x19b4: 0x00c3, 0x19b5: 0x00c3, + 0x19b6: 0x00c3, 0x19b7: 0x00c3, 0x19b8: 0x00c3, 0x19b9: 0x00c3, 0x19bb: 0x00c3, + 0x19bc: 0x00c3, 0x19bd: 0x00c3, 0x19be: 0x00c3, 0x19bf: 0x00c3, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x00c0, 0x19c1: 0x00c0, 0x19c2: 0x00c0, 0x19c3: 0x00c0, 0x19c4: 0x00c0, 0x19c5: 0x00c0, + 0x19c6: 0x00c0, 0x19c7: 0x00c0, 0x19c8: 0x00c0, 0x19c9: 0x00c0, 0x19ca: 0x00c0, 0x19cb: 0x00c0, + 0x19cc: 0x00c0, 0x19cd: 0x00c0, 0x19ce: 0x00c0, 0x19cf: 0x00c0, 0x19d0: 0x00c0, 0x19d1: 0x00c0, + 0x19d2: 0x00c0, 0x19d3: 0x00c0, 0x19d4: 0x00c0, 0x19d5: 0x00c0, 0x19d6: 0x00c0, 0x19d7: 0x00c0, + 0x19d8: 0x00c0, 0x19d9: 0x00c0, 0x19da: 0x0080, 0x19db: 0x0080, 0x19dc: 0x00c0, 0x19dd: 0x00c0, + 0x19de: 0x00c0, 0x19df: 0x00c0, 0x19e0: 0x00c0, 0x19e1: 0x00c0, 0x19e2: 0x00c0, 0x19e3: 0x00c0, + 0x19e4: 0x00c0, 0x19e5: 0x00c0, 0x19e6: 0x00c0, 0x19e7: 0x00c0, 0x19e8: 0x00c0, 0x19e9: 0x00c0, + 0x19ea: 0x00c0, 0x19eb: 0x00c0, 0x19ec: 0x00c0, 0x19ed: 0x00c0, 0x19ee: 0x00c0, 0x19ef: 0x00c0, + 0x19f0: 0x00c0, 0x19f1: 0x00c0, 0x19f2: 0x00c0, 0x19f3: 0x00c0, 0x19f4: 0x00c0, 0x19f5: 0x00c0, + 0x19f6: 0x00c0, 0x19f7: 0x00c0, 0x19f8: 0x00c0, 0x19f9: 0x00c0, 0x19fa: 0x00c0, 0x19fb: 0x00c0, + 0x19fc: 0x00c0, 0x19fd: 0x00c0, 0x19fe: 0x00c0, 0x19ff: 0x00c0, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x00c8, 0x1a01: 0x00c8, 0x1a02: 0x00c8, 0x1a03: 0x00c8, 0x1a04: 0x00c8, 0x1a05: 0x00c8, + 0x1a06: 0x00c8, 0x1a07: 0x00c8, 0x1a08: 0x00c8, 0x1a09: 0x00c8, 0x1a0a: 0x00c8, 0x1a0b: 0x00c8, + 0x1a0c: 0x00c8, 0x1a0d: 0x00c8, 0x1a0e: 0x00c8, 0x1a0f: 0x00c8, 0x1a10: 0x00c8, 0x1a11: 0x00c8, + 0x1a12: 0x00c8, 0x1a13: 0x00c8, 0x1a14: 0x00c8, 0x1a15: 0x00c8, + 0x1a18: 0x00c8, 0x1a19: 0x00c8, 0x1a1a: 0x00c8, 0x1a1b: 0x00c8, 0x1a1c: 0x00c8, 0x1a1d: 0x00c8, + 0x1a20: 0x00c8, 0x1a21: 0x00c8, 0x1a22: 0x00c8, 0x1a23: 0x00c8, + 0x1a24: 0x00c8, 0x1a25: 0x00c8, 0x1a26: 0x00c8, 0x1a27: 0x00c8, 0x1a28: 0x00c8, 0x1a29: 0x00c8, + 0x1a2a: 0x00c8, 0x1a2b: 0x00c8, 0x1a2c: 0x00c8, 0x1a2d: 0x00c8, 0x1a2e: 0x00c8, 0x1a2f: 0x00c8, + 0x1a30: 0x00c8, 0x1a31: 0x00c8, 0x1a32: 0x00c8, 0x1a33: 0x00c8, 0x1a34: 0x00c8, 0x1a35: 0x00c8, + 0x1a36: 0x00c8, 0x1a37: 0x00c8, 0x1a38: 0x00c8, 0x1a39: 0x00c8, 0x1a3a: 0x00c8, 0x1a3b: 0x00c8, + 0x1a3c: 0x00c8, 0x1a3d: 0x00c8, 0x1a3e: 0x00c8, 0x1a3f: 0x00c8, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x00c8, 0x1a41: 0x00c8, 0x1a42: 0x00c8, 0x1a43: 0x00c8, 0x1a44: 0x00c8, 0x1a45: 0x00c8, + 0x1a48: 0x00c8, 0x1a49: 0x00c8, 0x1a4a: 0x00c8, 0x1a4b: 0x00c8, + 0x1a4c: 0x00c8, 0x1a4d: 0x00c8, 0x1a50: 0x00c8, 0x1a51: 0x00c8, + 0x1a52: 0x00c8, 0x1a53: 0x00c8, 0x1a54: 0x00c8, 0x1a55: 0x00c8, 0x1a56: 0x00c8, 0x1a57: 0x00c8, + 0x1a59: 0x00c8, 0x1a5b: 0x00c8, 0x1a5d: 0x00c8, + 0x1a5f: 0x00c8, 0x1a60: 0x00c8, 0x1a61: 0x00c8, 0x1a62: 0x00c8, 0x1a63: 0x00c8, + 0x1a64: 0x00c8, 0x1a65: 0x00c8, 0x1a66: 0x00c8, 0x1a67: 0x00c8, 0x1a68: 0x00c8, 0x1a69: 0x00c8, + 0x1a6a: 0x00c8, 0x1a6b: 0x00c8, 0x1a6c: 0x00c8, 0x1a6d: 0x00c8, 0x1a6e: 0x00c8, 0x1a6f: 0x00c8, + 0x1a70: 0x00c8, 0x1a71: 0x0088, 0x1a72: 0x00c8, 0x1a73: 0x0088, 0x1a74: 0x00c8, 0x1a75: 0x0088, + 0x1a76: 0x00c8, 0x1a77: 0x0088, 0x1a78: 0x00c8, 0x1a79: 0x0088, 0x1a7a: 0x00c8, 0x1a7b: 0x0088, + 0x1a7c: 0x00c8, 0x1a7d: 0x0088, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x00c8, 0x1a81: 0x00c8, 0x1a82: 0x00c8, 0x1a83: 0x00c8, 0x1a84: 0x00c8, 0x1a85: 0x00c8, + 0x1a86: 0x00c8, 0x1a87: 0x00c8, 0x1a88: 0x0088, 0x1a89: 0x0088, 0x1a8a: 0x0088, 0x1a8b: 0x0088, + 0x1a8c: 0x0088, 0x1a8d: 0x0088, 0x1a8e: 0x0088, 0x1a8f: 0x0088, 0x1a90: 0x00c8, 0x1a91: 0x00c8, + 0x1a92: 0x00c8, 0x1a93: 0x00c8, 0x1a94: 0x00c8, 0x1a95: 0x00c8, 0x1a96: 0x00c8, 0x1a97: 0x00c8, + 0x1a98: 0x0088, 0x1a99: 0x0088, 0x1a9a: 0x0088, 0x1a9b: 0x0088, 0x1a9c: 0x0088, 0x1a9d: 0x0088, + 0x1a9e: 0x0088, 0x1a9f: 0x0088, 0x1aa0: 0x00c8, 0x1aa1: 0x00c8, 0x1aa2: 0x00c8, 0x1aa3: 0x00c8, + 0x1aa4: 0x00c8, 0x1aa5: 0x00c8, 0x1aa6: 0x00c8, 0x1aa7: 0x00c8, 0x1aa8: 0x0088, 0x1aa9: 0x0088, + 0x1aaa: 0x0088, 0x1aab: 0x0088, 0x1aac: 0x0088, 0x1aad: 0x0088, 0x1aae: 0x0088, 0x1aaf: 0x0088, + 0x1ab0: 0x00c8, 0x1ab1: 0x00c8, 0x1ab2: 0x00c8, 0x1ab3: 0x00c8, 0x1ab4: 0x00c8, + 0x1ab6: 0x00c8, 0x1ab7: 0x00c8, 0x1ab8: 0x00c8, 0x1ab9: 0x00c8, 0x1aba: 0x00c8, 0x1abb: 0x0088, + 0x1abc: 0x0088, 0x1abd: 0x0088, 0x1abe: 0x0088, 0x1abf: 0x0088, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x0088, 0x1ac1: 0x0088, 0x1ac2: 0x00c8, 0x1ac3: 0x00c8, 0x1ac4: 0x00c8, + 0x1ac6: 0x00c8, 0x1ac7: 0x00c8, 0x1ac8: 0x00c8, 0x1ac9: 0x0088, 0x1aca: 0x00c8, 0x1acb: 0x0088, + 0x1acc: 0x0088, 0x1acd: 0x0088, 0x1ace: 0x0088, 0x1acf: 0x0088, 0x1ad0: 0x00c8, 0x1ad1: 0x00c8, + 0x1ad2: 0x00c8, 0x1ad3: 0x0088, 0x1ad6: 0x00c8, 0x1ad7: 0x00c8, + 0x1ad8: 0x00c8, 0x1ad9: 0x00c8, 0x1ada: 0x00c8, 0x1adb: 0x0088, 0x1add: 0x0088, + 0x1ade: 0x0088, 0x1adf: 0x0088, 0x1ae0: 0x00c8, 0x1ae1: 0x00c8, 0x1ae2: 0x00c8, 0x1ae3: 0x0088, + 0x1ae4: 0x00c8, 0x1ae5: 0x00c8, 0x1ae6: 0x00c8, 0x1ae7: 0x00c8, 0x1ae8: 0x00c8, 0x1ae9: 0x00c8, + 0x1aea: 0x00c8, 0x1aeb: 0x0088, 0x1aec: 0x00c8, 0x1aed: 0x0088, 0x1aee: 0x0088, 0x1aef: 0x0088, + 0x1af2: 0x00c8, 0x1af3: 0x00c8, 0x1af4: 0x00c8, + 0x1af6: 0x00c8, 0x1af7: 0x00c8, 0x1af8: 0x00c8, 0x1af9: 0x0088, 0x1afa: 0x00c8, 0x1afb: 0x0088, + 0x1afc: 0x0088, 0x1afd: 0x0088, 0x1afe: 0x0088, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x0080, 0x1b01: 0x0080, 0x1b02: 0x0080, 0x1b03: 0x0080, 0x1b04: 0x0080, 0x1b05: 0x0080, + 0x1b06: 0x0080, 0x1b07: 0x0080, 0x1b08: 0x0080, 0x1b09: 0x0080, 0x1b0a: 0x0080, 0x1b0b: 0x0040, + 0x1b0c: 0x004d, 0x1b0d: 0x004e, 0x1b0e: 0x0040, 0x1b0f: 0x0040, 0x1b10: 0x0080, 0x1b11: 0x0080, + 0x1b12: 0x0080, 0x1b13: 0x0080, 0x1b14: 0x0080, 0x1b15: 0x0080, 0x1b16: 0x0080, 0x1b17: 0x0080, + 0x1b18: 0x0080, 0x1b19: 0x0080, 0x1b1a: 0x0080, 0x1b1b: 0x0080, 0x1b1c: 0x0080, 0x1b1d: 0x0080, + 0x1b1e: 0x0080, 0x1b1f: 0x0080, 0x1b20: 0x0080, 0x1b21: 0x0080, 0x1b22: 0x0080, 0x1b23: 0x0080, + 0x1b24: 0x0080, 0x1b25: 0x0080, 0x1b26: 0x0080, 0x1b27: 0x0080, 0x1b28: 0x0040, 0x1b29: 0x0040, + 0x1b2a: 0x0040, 0x1b2b: 0x0040, 0x1b2c: 0x0040, 0x1b2d: 0x0040, 0x1b2e: 0x0040, 0x1b2f: 0x0080, + 0x1b30: 0x0080, 0x1b31: 0x0080, 0x1b32: 0x0080, 0x1b33: 0x0080, 0x1b34: 0x0080, 0x1b35: 0x0080, + 0x1b36: 0x0080, 0x1b37: 0x0080, 0x1b38: 0x0080, 0x1b39: 0x0080, 0x1b3a: 0x0080, 0x1b3b: 0x0080, + 0x1b3c: 0x0080, 0x1b3d: 0x0080, 0x1b3e: 0x0080, 0x1b3f: 0x0080, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x0080, 0x1b41: 0x0080, 0x1b42: 0x0080, 0x1b43: 0x0080, 0x1b44: 0x0080, 0x1b45: 0x0080, + 0x1b46: 0x0080, 0x1b47: 0x0080, 0x1b48: 0x0080, 0x1b49: 0x0080, 0x1b4a: 0x0080, 0x1b4b: 0x0080, + 0x1b4c: 0x0080, 0x1b4d: 0x0080, 0x1b4e: 0x0080, 0x1b4f: 0x0080, 0x1b50: 0x0080, 0x1b51: 0x0080, + 0x1b52: 0x0080, 0x1b53: 0x0080, 0x1b54: 0x0080, 0x1b55: 0x0080, 0x1b56: 0x0080, 0x1b57: 0x0080, + 0x1b58: 0x0080, 0x1b59: 0x0080, 0x1b5a: 0x0080, 0x1b5b: 0x0080, 0x1b5c: 0x0080, 0x1b5d: 0x0080, + 0x1b5e: 0x0080, 0x1b5f: 0x0080, 0x1b60: 0x0040, 0x1b61: 0x0040, 0x1b62: 0x0040, 0x1b63: 0x0040, + 0x1b64: 0x0040, 0x1b66: 0x0040, 0x1b67: 0x0040, 0x1b68: 0x0040, 0x1b69: 0x0040, + 0x1b6a: 0x0040, 0x1b6b: 0x0040, 0x1b6c: 0x0040, 0x1b6d: 0x0040, 0x1b6e: 0x0040, 0x1b6f: 0x0040, + 0x1b70: 0x0080, 0x1b71: 0x0080, 0x1b74: 0x0080, 0x1b75: 0x0080, + 0x1b76: 0x0080, 0x1b77: 0x0080, 0x1b78: 0x0080, 0x1b79: 0x0080, 0x1b7a: 0x0080, 0x1b7b: 0x0080, + 0x1b7c: 0x0080, 0x1b7d: 0x0080, 0x1b7e: 0x0080, 0x1b7f: 0x0080, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x0080, 0x1b81: 0x0080, 0x1b82: 0x0080, 0x1b83: 0x0080, 0x1b84: 0x0080, 0x1b85: 0x0080, + 0x1b86: 0x0080, 0x1b87: 0x0080, 0x1b88: 0x0080, 0x1b89: 0x0080, 0x1b8a: 0x0080, 0x1b8b: 0x0080, + 0x1b8c: 0x0080, 0x1b8d: 0x0080, 0x1b8e: 0x0080, 0x1b90: 0x0080, 0x1b91: 0x0080, + 0x1b92: 0x0080, 0x1b93: 0x0080, 0x1b94: 0x0080, 0x1b95: 0x0080, 0x1b96: 0x0080, 0x1b97: 0x0080, + 0x1b98: 0x0080, 0x1b99: 0x0080, 0x1b9a: 0x0080, 0x1b9b: 0x0080, 0x1b9c: 0x0080, + 0x1ba0: 0x0080, 0x1ba1: 0x0080, 0x1ba2: 0x0080, 0x1ba3: 0x0080, + 0x1ba4: 0x0080, 0x1ba5: 0x0080, 0x1ba6: 0x0080, 0x1ba7: 0x0080, 0x1ba8: 0x0080, 0x1ba9: 0x0080, + 0x1baa: 0x0080, 0x1bab: 0x0080, 0x1bac: 0x0080, 0x1bad: 0x0080, 0x1bae: 0x0080, 0x1baf: 0x0080, + 0x1bb0: 0x0080, 0x1bb1: 0x0080, 0x1bb2: 0x0080, 0x1bb3: 0x0080, 0x1bb4: 0x0080, 0x1bb5: 0x0080, + 0x1bb6: 0x0080, 0x1bb7: 0x0080, 0x1bb8: 0x0080, 0x1bb9: 0x0080, 0x1bba: 0x0080, 0x1bbb: 0x0080, + 0x1bbc: 0x0080, 0x1bbd: 0x0080, 0x1bbe: 0x0080, 0x1bbf: 0x0080, + // Block 0x6f, offset 0x1bc0 + 0x1bd0: 0x00c3, 0x1bd1: 0x00c3, + 0x1bd2: 0x00c3, 0x1bd3: 0x00c3, 0x1bd4: 0x00c3, 0x1bd5: 0x00c3, 0x1bd6: 0x00c3, 0x1bd7: 0x00c3, + 0x1bd8: 0x00c3, 0x1bd9: 0x00c3, 0x1bda: 0x00c3, 0x1bdb: 0x00c3, 0x1bdc: 0x00c3, 0x1bdd: 0x0083, + 0x1bde: 0x0083, 0x1bdf: 0x0083, 0x1be0: 0x0083, 0x1be1: 0x00c3, 0x1be2: 0x0083, 0x1be3: 0x0083, + 0x1be4: 0x0083, 0x1be5: 0x00c3, 0x1be6: 0x00c3, 0x1be7: 0x00c3, 0x1be8: 0x00c3, 0x1be9: 0x00c3, + 0x1bea: 0x00c3, 0x1beb: 0x00c3, 0x1bec: 0x00c3, 0x1bed: 0x00c3, 0x1bee: 0x00c3, 0x1bef: 0x00c3, + 0x1bf0: 0x00c3, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x0080, 0x1c01: 0x0080, 0x1c02: 0x0080, 0x1c03: 0x0080, 0x1c04: 0x0080, 0x1c05: 0x0080, + 0x1c06: 0x0080, 0x1c07: 0x0080, 0x1c08: 0x0080, 0x1c09: 0x0080, 0x1c0a: 0x0080, 0x1c0b: 0x0080, + 0x1c0c: 0x0080, 0x1c0d: 0x0080, 0x1c0e: 0x0080, 0x1c0f: 0x0080, 0x1c10: 0x0080, 0x1c11: 0x0080, + 0x1c12: 0x0080, 0x1c13: 0x0080, 0x1c14: 0x0080, 0x1c15: 0x0080, 0x1c16: 0x0080, 0x1c17: 0x0080, + 0x1c18: 0x0080, 0x1c19: 0x0080, 0x1c1a: 0x0080, 0x1c1b: 0x0080, 0x1c1c: 0x0080, 0x1c1d: 0x0080, + 0x1c1e: 0x0080, 0x1c1f: 0x0080, 0x1c20: 0x0080, 0x1c21: 0x0080, 0x1c22: 0x0080, 0x1c23: 0x0080, + 0x1c24: 0x0080, 0x1c25: 0x0080, 0x1c26: 0x0088, 0x1c27: 0x0080, 0x1c28: 0x0080, 0x1c29: 0x0080, + 0x1c2a: 0x0080, 0x1c2b: 0x0080, 0x1c2c: 0x0080, 0x1c2d: 0x0080, 0x1c2e: 0x0080, 0x1c2f: 0x0080, + 0x1c30: 0x0080, 0x1c31: 0x0080, 0x1c32: 0x00c0, 0x1c33: 0x0080, 0x1c34: 0x0080, 0x1c35: 0x0080, + 0x1c36: 0x0080, 0x1c37: 0x0080, 0x1c38: 0x0080, 0x1c39: 0x0080, 0x1c3a: 0x0080, 0x1c3b: 0x0080, + 0x1c3c: 0x0080, 0x1c3d: 0x0080, 0x1c3e: 0x0080, 0x1c3f: 0x0080, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x0080, 0x1c41: 0x0080, 0x1c42: 0x0080, 0x1c43: 0x0080, 0x1c44: 0x0080, 0x1c45: 0x0080, + 0x1c46: 0x0080, 0x1c47: 0x0080, 0x1c48: 0x0080, 0x1c49: 0x0080, 0x1c4a: 0x0080, 0x1c4b: 0x0080, + 0x1c4c: 0x0080, 0x1c4d: 0x0080, 0x1c4e: 0x00c0, 0x1c4f: 0x0080, 0x1c50: 0x0080, 0x1c51: 0x0080, + 0x1c52: 0x0080, 0x1c53: 0x0080, 0x1c54: 0x0080, 0x1c55: 0x0080, 0x1c56: 0x0080, 0x1c57: 0x0080, + 0x1c58: 0x0080, 0x1c59: 0x0080, 0x1c5a: 0x0080, 0x1c5b: 0x0080, 0x1c5c: 0x0080, 0x1c5d: 0x0080, + 0x1c5e: 0x0080, 0x1c5f: 0x0080, 0x1c60: 0x0080, 0x1c61: 0x0080, 0x1c62: 0x0080, 0x1c63: 0x0080, + 0x1c64: 0x0080, 0x1c65: 0x0080, 0x1c66: 0x0080, 0x1c67: 0x0080, 0x1c68: 0x0080, 0x1c69: 0x0080, + 0x1c6a: 0x0080, 0x1c6b: 0x0080, 0x1c6c: 0x0080, 0x1c6d: 0x0080, 0x1c6e: 0x0080, 0x1c6f: 0x0080, + 0x1c70: 0x0080, 0x1c71: 0x0080, 0x1c72: 0x0080, 0x1c73: 0x0080, 0x1c74: 0x0080, 0x1c75: 0x0080, + 0x1c76: 0x0080, 0x1c77: 0x0080, 0x1c78: 0x0080, 0x1c79: 0x0080, 0x1c7a: 0x0080, 0x1c7b: 0x0080, + 0x1c7c: 0x0080, 0x1c7d: 0x0080, 0x1c7e: 0x0080, 0x1c7f: 0x0080, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x0080, 0x1c81: 0x0080, 0x1c82: 0x0080, 0x1c83: 0x00c0, 0x1c84: 0x00c0, 0x1c85: 0x0080, + 0x1c86: 0x0080, 0x1c87: 0x0080, 0x1c88: 0x0080, 0x1c89: 0x0080, 0x1c8a: 0x0080, 0x1c8b: 0x0080, + 0x1c90: 0x0080, 0x1c91: 0x0080, + 0x1c92: 0x0080, 0x1c93: 0x0080, 0x1c94: 0x0080, 0x1c95: 0x0080, 0x1c96: 0x0080, 0x1c97: 0x0080, + 0x1c98: 0x0080, 0x1c99: 0x0080, 0x1c9a: 0x0080, 0x1c9b: 0x0080, 0x1c9c: 0x0080, 0x1c9d: 0x0080, + 0x1c9e: 0x0080, 0x1c9f: 0x0080, 0x1ca0: 0x0080, 0x1ca1: 0x0080, 0x1ca2: 0x0080, 0x1ca3: 0x0080, + 0x1ca4: 0x0080, 0x1ca5: 0x0080, 0x1ca6: 0x0080, 0x1ca7: 0x0080, 0x1ca8: 0x0080, 0x1ca9: 0x0080, + 0x1caa: 0x0080, 0x1cab: 0x0080, 0x1cac: 0x0080, 0x1cad: 0x0080, 0x1cae: 0x0080, 0x1caf: 0x0080, + 0x1cb0: 0x0080, 0x1cb1: 0x0080, 0x1cb2: 0x0080, 0x1cb3: 0x0080, 0x1cb4: 0x0080, 0x1cb5: 0x0080, + 0x1cb6: 0x0080, 0x1cb7: 0x0080, 0x1cb8: 0x0080, 0x1cb9: 0x0080, 0x1cba: 0x0080, 0x1cbb: 0x0080, + 0x1cbc: 0x0080, 0x1cbd: 0x0080, 0x1cbe: 0x0080, 0x1cbf: 0x0080, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0080, 0x1cc1: 0x0080, 0x1cc2: 0x0080, 0x1cc3: 0x0080, 0x1cc4: 0x0080, 0x1cc5: 0x0080, + 0x1cc6: 0x0080, 0x1cc7: 0x0080, 0x1cc8: 0x0080, 0x1cc9: 0x0080, 0x1cca: 0x0080, 0x1ccb: 0x0080, + 0x1ccc: 0x0080, 0x1ccd: 0x0080, 0x1cce: 0x0080, 0x1ccf: 0x0080, 0x1cd0: 0x0080, 0x1cd1: 0x0080, + 0x1cd2: 0x0080, 0x1cd3: 0x0080, 0x1cd4: 0x0080, 0x1cd5: 0x0080, 0x1cd6: 0x0080, 0x1cd7: 0x0080, + 0x1cd8: 0x0080, 0x1cd9: 0x0080, 0x1cda: 0x0080, 0x1cdb: 0x0080, 0x1cdc: 0x0080, 0x1cdd: 0x0080, + 0x1cde: 0x0080, 0x1cdf: 0x0080, 0x1ce0: 0x0080, 0x1ce1: 0x0080, 0x1ce2: 0x0080, 0x1ce3: 0x0080, + 0x1ce4: 0x0080, 0x1ce5: 0x0080, 0x1ce6: 0x0080, 0x1ce7: 0x0080, 0x1ce8: 0x0080, 0x1ce9: 0x0080, + 0x1cea: 0x0080, 0x1ceb: 0x0080, 0x1cec: 0x0080, 0x1ced: 0x0080, 0x1cee: 0x0080, 0x1cef: 0x0080, + 0x1cf0: 0x0080, 0x1cf1: 0x0080, 0x1cf2: 0x0080, 0x1cf3: 0x0080, 0x1cf4: 0x0080, 0x1cf5: 0x0080, + 0x1cf6: 0x0080, 0x1cf7: 0x0080, 0x1cf8: 0x0080, 0x1cf9: 0x0080, 0x1cfa: 0x0080, 0x1cfb: 0x0080, + 0x1cfc: 0x0080, 0x1cfd: 0x0080, 0x1cfe: 0x0080, 0x1cff: 0x0080, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0080, 0x1d01: 0x0080, 0x1d02: 0x0080, 0x1d03: 0x0080, 0x1d04: 0x0080, 0x1d05: 0x0080, + 0x1d06: 0x0080, 0x1d07: 0x0080, 0x1d08: 0x0080, 0x1d09: 0x0080, 0x1d0a: 0x0080, 0x1d0b: 0x0080, + 0x1d0c: 0x0080, 0x1d0d: 0x0080, 0x1d0e: 0x0080, 0x1d0f: 0x0080, 0x1d10: 0x0080, 0x1d11: 0x0080, + 0x1d12: 0x0080, 0x1d13: 0x0080, 0x1d14: 0x0080, 0x1d15: 0x0080, 0x1d16: 0x0080, 0x1d17: 0x0080, + 0x1d18: 0x0080, 0x1d19: 0x0080, 0x1d1a: 0x0080, 0x1d1b: 0x0080, 0x1d1c: 0x0080, 0x1d1d: 0x0080, + 0x1d1e: 0x0080, 0x1d1f: 0x0080, 0x1d20: 0x0080, 0x1d21: 0x0080, 0x1d22: 0x0080, 0x1d23: 0x0080, + 0x1d24: 0x0080, 0x1d25: 0x0080, 0x1d26: 0x0080, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0080, 0x1d41: 0x0080, 0x1d42: 0x0080, 0x1d43: 0x0080, 0x1d44: 0x0080, 0x1d45: 0x0080, + 0x1d46: 0x0080, 0x1d47: 0x0080, 0x1d48: 0x0080, 0x1d49: 0x0080, 0x1d4a: 0x0080, + 0x1d60: 0x0080, 0x1d61: 0x0080, 0x1d62: 0x0080, 0x1d63: 0x0080, + 0x1d64: 0x0080, 0x1d65: 0x0080, 0x1d66: 0x0080, 0x1d67: 0x0080, 0x1d68: 0x0080, 0x1d69: 0x0080, + 0x1d6a: 0x0080, 0x1d6b: 0x0080, 0x1d6c: 0x0080, 0x1d6d: 0x0080, 0x1d6e: 0x0080, 0x1d6f: 0x0080, + 0x1d70: 0x0080, 0x1d71: 0x0080, 0x1d72: 0x0080, 0x1d73: 0x0080, 0x1d74: 0x0080, 0x1d75: 0x0080, + 0x1d76: 0x0080, 0x1d77: 0x0080, 0x1d78: 0x0080, 0x1d79: 0x0080, 0x1d7a: 0x0080, 0x1d7b: 0x0080, + 0x1d7c: 0x0080, 0x1d7d: 0x0080, 0x1d7e: 0x0080, 0x1d7f: 0x0080, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x0080, 0x1d81: 0x0080, 0x1d82: 0x0080, 0x1d83: 0x0080, 0x1d84: 0x0080, 0x1d85: 0x0080, + 0x1d86: 0x0080, 0x1d87: 0x0080, 0x1d88: 0x0080, 0x1d89: 0x0080, 0x1d8a: 0x0080, 0x1d8b: 0x0080, + 0x1d8c: 0x0080, 0x1d8d: 0x0080, 0x1d8e: 0x0080, 0x1d8f: 0x0080, 0x1d90: 0x0080, 0x1d91: 0x0080, + 0x1d92: 0x0080, 0x1d93: 0x0080, 0x1d94: 0x0080, 0x1d95: 0x0080, 0x1d96: 0x0080, 0x1d97: 0x0080, + 0x1d98: 0x0080, 0x1d99: 0x0080, 0x1d9a: 0x0080, 0x1d9b: 0x0080, 0x1d9c: 0x0080, 0x1d9d: 0x0080, + 0x1d9e: 0x0080, 0x1d9f: 0x0080, 0x1da0: 0x0080, 0x1da1: 0x0080, 0x1da2: 0x0080, 0x1da3: 0x0080, + 0x1da4: 0x0080, 0x1da5: 0x0080, 0x1da6: 0x0080, 0x1da7: 0x0080, 0x1da8: 0x0080, 0x1da9: 0x0080, + 0x1daa: 0x0080, 0x1dab: 0x0080, 0x1dac: 0x0080, 0x1dad: 0x0080, 0x1dae: 0x0080, 0x1daf: 0x0080, + 0x1db0: 0x0080, 0x1db1: 0x0080, 0x1db2: 0x0080, 0x1db3: 0x0080, + 0x1db6: 0x0080, 0x1db7: 0x0080, 0x1db8: 0x0080, 0x1db9: 0x0080, 0x1dba: 0x0080, 0x1dbb: 0x0080, + 0x1dbc: 0x0080, 0x1dbd: 0x0080, 0x1dbe: 0x0080, 0x1dbf: 0x0080, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x0080, 0x1dc1: 0x0080, 0x1dc2: 0x0080, 0x1dc3: 0x0080, 0x1dc4: 0x0080, 0x1dc5: 0x0080, + 0x1dc6: 0x0080, 0x1dc7: 0x0080, 0x1dc8: 0x0080, 0x1dc9: 0x0080, 0x1dca: 0x0080, 0x1dcb: 0x0080, + 0x1dcc: 0x0080, 0x1dcd: 0x0080, 0x1dce: 0x0080, 0x1dcf: 0x0080, 0x1dd0: 0x0080, 0x1dd1: 0x0080, + 0x1dd2: 0x0080, 0x1dd3: 0x0080, 0x1dd4: 0x0080, 0x1dd5: 0x0080, + 0x1dd8: 0x0080, 0x1dd9: 0x0080, 0x1dda: 0x0080, 0x1ddb: 0x0080, 0x1ddc: 0x0080, 0x1ddd: 0x0080, + 0x1dde: 0x0080, 0x1ddf: 0x0080, 0x1de0: 0x0080, 0x1de1: 0x0080, 0x1de2: 0x0080, 0x1de3: 0x0080, + 0x1de4: 0x0080, 0x1de5: 0x0080, 0x1de6: 0x0080, 0x1de7: 0x0080, 0x1de8: 0x0080, 0x1de9: 0x0080, + 0x1dea: 0x0080, 0x1deb: 0x0080, 0x1dec: 0x0080, 0x1ded: 0x0080, 0x1dee: 0x0080, 0x1def: 0x0080, + 0x1df0: 0x0080, 0x1df1: 0x0080, 0x1df2: 0x0080, 0x1df3: 0x0080, 0x1df4: 0x0080, 0x1df5: 0x0080, + 0x1df6: 0x0080, 0x1df7: 0x0080, 0x1df8: 0x0080, 0x1df9: 0x0080, 0x1dfa: 0x0080, 0x1dfb: 0x0080, + 0x1dfc: 0x0080, 0x1dfd: 0x0080, 0x1dfe: 0x0080, 0x1dff: 0x0080, + // Block 0x78, offset 0x1e00 + 0x1e00: 0x00c0, 0x1e01: 0x00c0, 0x1e02: 0x00c0, 0x1e03: 0x00c0, 0x1e04: 0x00c0, 0x1e05: 0x00c0, + 0x1e06: 0x00c0, 0x1e07: 0x00c0, 0x1e08: 0x00c0, 0x1e09: 0x00c0, 0x1e0a: 0x00c0, 0x1e0b: 0x00c0, + 0x1e0c: 0x00c0, 0x1e0d: 0x00c0, 0x1e0e: 0x00c0, 0x1e0f: 0x00c0, 0x1e10: 0x00c0, 0x1e11: 0x00c0, + 0x1e12: 0x00c0, 0x1e13: 0x00c0, 0x1e14: 0x00c0, 0x1e15: 0x00c0, 0x1e16: 0x00c0, 0x1e17: 0x00c0, + 0x1e18: 0x00c0, 0x1e19: 0x00c0, 0x1e1a: 0x00c0, 0x1e1b: 0x00c0, 0x1e1c: 0x00c0, 0x1e1d: 0x00c0, + 0x1e1e: 0x00c0, 0x1e1f: 0x00c0, 0x1e20: 0x00c0, 0x1e21: 0x00c0, 0x1e22: 0x00c0, 0x1e23: 0x00c0, + 0x1e24: 0x00c0, 0x1e25: 0x00c0, 0x1e26: 0x00c0, 0x1e27: 0x00c0, 0x1e28: 0x00c0, 0x1e29: 0x00c0, + 0x1e2a: 0x00c0, 0x1e2b: 0x00c0, 0x1e2c: 0x00c0, 0x1e2d: 0x00c0, 0x1e2e: 0x00c0, + 0x1e30: 0x00c0, 0x1e31: 0x00c0, 0x1e32: 0x00c0, 0x1e33: 0x00c0, 0x1e34: 0x00c0, 0x1e35: 0x00c0, + 0x1e36: 0x00c0, 0x1e37: 0x00c0, 0x1e38: 0x00c0, 0x1e39: 0x00c0, 0x1e3a: 0x00c0, 0x1e3b: 0x00c0, + 0x1e3c: 0x00c0, 0x1e3d: 0x00c0, 0x1e3e: 0x00c0, 0x1e3f: 0x00c0, + // Block 0x79, offset 0x1e40 + 0x1e40: 0x00c0, 0x1e41: 0x00c0, 0x1e42: 0x00c0, 0x1e43: 0x00c0, 0x1e44: 0x00c0, 0x1e45: 0x00c0, + 0x1e46: 0x00c0, 0x1e47: 0x00c0, 0x1e48: 0x00c0, 0x1e49: 0x00c0, 0x1e4a: 0x00c0, 0x1e4b: 0x00c0, + 0x1e4c: 0x00c0, 0x1e4d: 0x00c0, 0x1e4e: 0x00c0, 0x1e4f: 0x00c0, 0x1e50: 0x00c0, 0x1e51: 0x00c0, + 0x1e52: 0x00c0, 0x1e53: 0x00c0, 0x1e54: 0x00c0, 0x1e55: 0x00c0, 0x1e56: 0x00c0, 0x1e57: 0x00c0, + 0x1e58: 0x00c0, 0x1e59: 0x00c0, 0x1e5a: 0x00c0, 0x1e5b: 0x00c0, 0x1e5c: 0x00c0, 0x1e5d: 0x00c0, + 0x1e5e: 0x00c0, 0x1e60: 0x00c0, 0x1e61: 0x00c0, 0x1e62: 0x00c0, 0x1e63: 0x00c0, + 0x1e64: 0x00c0, 0x1e65: 0x00c0, 0x1e66: 0x00c0, 0x1e67: 0x00c0, 0x1e68: 0x00c0, 0x1e69: 0x00c0, + 0x1e6a: 0x00c0, 0x1e6b: 0x00c0, 0x1e6c: 0x00c0, 0x1e6d: 0x00c0, 0x1e6e: 0x00c0, 0x1e6f: 0x00c0, + 0x1e70: 0x00c0, 0x1e71: 0x00c0, 0x1e72: 0x00c0, 0x1e73: 0x00c0, 0x1e74: 0x00c0, 0x1e75: 0x00c0, + 0x1e76: 0x00c0, 0x1e77: 0x00c0, 0x1e78: 0x00c0, 0x1e79: 0x00c0, 0x1e7a: 0x00c0, 0x1e7b: 0x00c0, + 0x1e7c: 0x0080, 0x1e7d: 0x0080, 0x1e7e: 0x00c0, 0x1e7f: 0x00c0, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x00c0, 0x1e81: 0x00c0, 0x1e82: 0x00c0, 0x1e83: 0x00c0, 0x1e84: 0x00c0, 0x1e85: 0x00c0, + 0x1e86: 0x00c0, 0x1e87: 0x00c0, 0x1e88: 0x00c0, 0x1e89: 0x00c0, 0x1e8a: 0x00c0, 0x1e8b: 0x00c0, + 0x1e8c: 0x00c0, 0x1e8d: 0x00c0, 0x1e8e: 0x00c0, 0x1e8f: 0x00c0, 0x1e90: 0x00c0, 0x1e91: 0x00c0, + 0x1e92: 0x00c0, 0x1e93: 0x00c0, 0x1e94: 0x00c0, 0x1e95: 0x00c0, 0x1e96: 0x00c0, 0x1e97: 0x00c0, + 0x1e98: 0x00c0, 0x1e99: 0x00c0, 0x1e9a: 0x00c0, 0x1e9b: 0x00c0, 0x1e9c: 0x00c0, 0x1e9d: 0x00c0, + 0x1e9e: 0x00c0, 0x1e9f: 0x00c0, 0x1ea0: 0x00c0, 0x1ea1: 0x00c0, 0x1ea2: 0x00c0, 0x1ea3: 0x00c0, + 0x1ea4: 0x00c0, 0x1ea5: 0x0080, 0x1ea6: 0x0080, 0x1ea7: 0x0080, 0x1ea8: 0x0080, 0x1ea9: 0x0080, + 0x1eaa: 0x0080, 0x1eab: 0x00c0, 0x1eac: 0x00c0, 0x1ead: 0x00c0, 0x1eae: 0x00c0, 0x1eaf: 0x00c3, + 0x1eb0: 0x00c3, 0x1eb1: 0x00c3, 0x1eb2: 0x00c0, 0x1eb3: 0x00c0, + 0x1eb9: 0x0080, 0x1eba: 0x0080, 0x1ebb: 0x0080, + 0x1ebc: 0x0080, 0x1ebd: 0x0080, 0x1ebe: 0x0080, 0x1ebf: 0x0080, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x00c0, 0x1ec1: 0x00c0, 0x1ec2: 0x00c0, 0x1ec3: 0x00c0, 0x1ec4: 0x00c0, 0x1ec5: 0x00c0, + 0x1ec6: 0x00c0, 0x1ec7: 0x00c0, 0x1ec8: 0x00c0, 0x1ec9: 0x00c0, 0x1eca: 0x00c0, 0x1ecb: 0x00c0, + 0x1ecc: 0x00c0, 0x1ecd: 0x00c0, 0x1ece: 0x00c0, 0x1ecf: 0x00c0, 0x1ed0: 0x00c0, 0x1ed1: 0x00c0, + 0x1ed2: 0x00c0, 0x1ed3: 0x00c0, 0x1ed4: 0x00c0, 0x1ed5: 0x00c0, 0x1ed6: 0x00c0, 0x1ed7: 0x00c0, + 0x1ed8: 0x00c0, 0x1ed9: 0x00c0, 0x1eda: 0x00c0, 0x1edb: 0x00c0, 0x1edc: 0x00c0, 0x1edd: 0x00c0, + 0x1ede: 0x00c0, 0x1edf: 0x00c0, 0x1ee0: 0x00c0, 0x1ee1: 0x00c0, 0x1ee2: 0x00c0, 0x1ee3: 0x00c0, + 0x1ee4: 0x00c0, 0x1ee5: 0x00c0, 0x1ee7: 0x00c0, + 0x1eed: 0x00c0, + 0x1ef0: 0x00c0, 0x1ef1: 0x00c0, 0x1ef2: 0x00c0, 0x1ef3: 0x00c0, 0x1ef4: 0x00c0, 0x1ef5: 0x00c0, + 0x1ef6: 0x00c0, 0x1ef7: 0x00c0, 0x1ef8: 0x00c0, 0x1ef9: 0x00c0, 0x1efa: 0x00c0, 0x1efb: 0x00c0, + 0x1efc: 0x00c0, 0x1efd: 0x00c0, 0x1efe: 0x00c0, 0x1eff: 0x00c0, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0x00c0, 0x1f01: 0x00c0, 0x1f02: 0x00c0, 0x1f03: 0x00c0, 0x1f04: 0x00c0, 0x1f05: 0x00c0, + 0x1f06: 0x00c0, 0x1f07: 0x00c0, 0x1f08: 0x00c0, 0x1f09: 0x00c0, 0x1f0a: 0x00c0, 0x1f0b: 0x00c0, + 0x1f0c: 0x00c0, 0x1f0d: 0x00c0, 0x1f0e: 0x00c0, 0x1f0f: 0x00c0, 0x1f10: 0x00c0, 0x1f11: 0x00c0, + 0x1f12: 0x00c0, 0x1f13: 0x00c0, 0x1f14: 0x00c0, 0x1f15: 0x00c0, 0x1f16: 0x00c0, 0x1f17: 0x00c0, + 0x1f18: 0x00c0, 0x1f19: 0x00c0, 0x1f1a: 0x00c0, 0x1f1b: 0x00c0, 0x1f1c: 0x00c0, 0x1f1d: 0x00c0, + 0x1f1e: 0x00c0, 0x1f1f: 0x00c0, 0x1f20: 0x00c0, 0x1f21: 0x00c0, 0x1f22: 0x00c0, 0x1f23: 0x00c0, + 0x1f24: 0x00c0, 0x1f25: 0x00c0, 0x1f26: 0x00c0, 0x1f27: 0x00c0, + 0x1f2f: 0x0080, + 0x1f30: 0x0080, + 0x1f3f: 0x00c6, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0x00c0, 0x1f41: 0x00c0, 0x1f42: 0x00c0, 0x1f43: 0x00c0, 0x1f44: 0x00c0, 0x1f45: 0x00c0, + 0x1f46: 0x00c0, 0x1f47: 0x00c0, 0x1f48: 0x00c0, 0x1f49: 0x00c0, 0x1f4a: 0x00c0, 0x1f4b: 0x00c0, + 0x1f4c: 0x00c0, 0x1f4d: 0x00c0, 0x1f4e: 0x00c0, 0x1f4f: 0x00c0, 0x1f50: 0x00c0, 0x1f51: 0x00c0, + 0x1f52: 0x00c0, 0x1f53: 0x00c0, 0x1f54: 0x00c0, 0x1f55: 0x00c0, 0x1f56: 0x00c0, + 0x1f60: 0x00c0, 0x1f61: 0x00c0, 0x1f62: 0x00c0, 0x1f63: 0x00c0, + 0x1f64: 0x00c0, 0x1f65: 0x00c0, 0x1f66: 0x00c0, 0x1f68: 0x00c0, 0x1f69: 0x00c0, + 0x1f6a: 0x00c0, 0x1f6b: 0x00c0, 0x1f6c: 0x00c0, 0x1f6d: 0x00c0, 0x1f6e: 0x00c0, + 0x1f70: 0x00c0, 0x1f71: 0x00c0, 0x1f72: 0x00c0, 0x1f73: 0x00c0, 0x1f74: 0x00c0, 0x1f75: 0x00c0, + 0x1f76: 0x00c0, 0x1f78: 0x00c0, 0x1f79: 0x00c0, 0x1f7a: 0x00c0, 0x1f7b: 0x00c0, + 0x1f7c: 0x00c0, 0x1f7d: 0x00c0, 0x1f7e: 0x00c0, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0x00c0, 0x1f81: 0x00c0, 0x1f82: 0x00c0, 0x1f83: 0x00c0, 0x1f84: 0x00c0, 0x1f85: 0x00c0, + 0x1f86: 0x00c0, 0x1f88: 0x00c0, 0x1f89: 0x00c0, 0x1f8a: 0x00c0, 0x1f8b: 0x00c0, + 0x1f8c: 0x00c0, 0x1f8d: 0x00c0, 0x1f8e: 0x00c0, 0x1f90: 0x00c0, 0x1f91: 0x00c0, + 0x1f92: 0x00c0, 0x1f93: 0x00c0, 0x1f94: 0x00c0, 0x1f95: 0x00c0, 0x1f96: 0x00c0, + 0x1f98: 0x00c0, 0x1f99: 0x00c0, 0x1f9a: 0x00c0, 0x1f9b: 0x00c0, 0x1f9c: 0x00c0, 0x1f9d: 0x00c0, + 0x1f9e: 0x00c0, 0x1fa0: 0x00c3, 0x1fa1: 0x00c3, 0x1fa2: 0x00c3, 0x1fa3: 0x00c3, + 0x1fa4: 0x00c3, 0x1fa5: 0x00c3, 0x1fa6: 0x00c3, 0x1fa7: 0x00c3, 0x1fa8: 0x00c3, 0x1fa9: 0x00c3, + 0x1faa: 0x00c3, 0x1fab: 0x00c3, 0x1fac: 0x00c3, 0x1fad: 0x00c3, 0x1fae: 0x00c3, 0x1faf: 0x00c3, + 0x1fb0: 0x00c3, 0x1fb1: 0x00c3, 0x1fb2: 0x00c3, 0x1fb3: 0x00c3, 0x1fb4: 0x00c3, 0x1fb5: 0x00c3, + 0x1fb6: 0x00c3, 0x1fb7: 0x00c3, 0x1fb8: 0x00c3, 0x1fb9: 0x00c3, 0x1fba: 0x00c3, 0x1fbb: 0x00c3, + 0x1fbc: 0x00c3, 0x1fbd: 0x00c3, 0x1fbe: 0x00c3, 0x1fbf: 0x00c3, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x0080, 0x1fc1: 0x0080, 0x1fc2: 0x0080, 0x1fc3: 0x0080, 0x1fc4: 0x0080, 0x1fc5: 0x0080, + 0x1fc6: 0x0080, 0x1fc7: 0x0080, 0x1fc8: 0x0080, 0x1fc9: 0x0080, 0x1fca: 0x0080, 0x1fcb: 0x0080, + 0x1fcc: 0x0080, 0x1fcd: 0x0080, 0x1fce: 0x0080, 0x1fcf: 0x0080, 0x1fd0: 0x0080, 0x1fd1: 0x0080, + 0x1fd2: 0x0080, 0x1fd3: 0x0080, 0x1fd4: 0x0080, 0x1fd5: 0x0080, 0x1fd6: 0x0080, 0x1fd7: 0x0080, + 0x1fd8: 0x0080, 0x1fd9: 0x0080, 0x1fda: 0x0080, 0x1fdb: 0x0080, 0x1fdc: 0x0080, 0x1fdd: 0x0080, + 0x1fde: 0x0080, 0x1fdf: 0x0080, 0x1fe0: 0x0080, 0x1fe1: 0x0080, 0x1fe2: 0x0080, 0x1fe3: 0x0080, + 0x1fe4: 0x0080, 0x1fe5: 0x0080, 0x1fe6: 0x0080, 0x1fe7: 0x0080, 0x1fe8: 0x0080, 0x1fe9: 0x0080, + 0x1fea: 0x0080, 0x1feb: 0x0080, 0x1fec: 0x0080, 0x1fed: 0x0080, 0x1fee: 0x0080, 0x1fef: 0x00c0, + 0x1ff0: 0x0080, 0x1ff1: 0x0080, 0x1ff2: 0x0080, 0x1ff3: 0x0080, 0x1ff4: 0x0080, 0x1ff5: 0x0080, + 0x1ff6: 0x0080, 0x1ff7: 0x0080, 0x1ff8: 0x0080, 0x1ff9: 0x0080, 0x1ffa: 0x0080, 0x1ffb: 0x0080, + 0x1ffc: 0x0080, 0x1ffd: 0x0080, 0x1ffe: 0x0080, 0x1fff: 0x0080, + // Block 0x80, offset 0x2000 + 0x2000: 0x0080, 0x2001: 0x0080, 0x2002: 0x0080, 0x2003: 0x0080, 0x2004: 0x0080, 0x2005: 0x0080, + 0x2006: 0x0080, 0x2007: 0x0080, 0x2008: 0x0080, 0x2009: 0x0080, 0x200a: 0x0080, 0x200b: 0x0080, + 0x200c: 0x0080, 0x200d: 0x0080, 0x200e: 0x0080, 0x200f: 0x0080, + // Block 0x81, offset 0x2040 + 0x2040: 0x008c, 0x2041: 0x008c, 0x2042: 0x008c, 0x2043: 0x008c, 0x2044: 0x008c, 0x2045: 0x008c, + 0x2046: 0x008c, 0x2047: 0x008c, 0x2048: 0x008c, 0x2049: 0x008c, 0x204a: 0x008c, 0x204b: 0x008c, + 0x204c: 0x008c, 0x204d: 0x008c, 0x204e: 0x008c, 0x204f: 0x008c, 0x2050: 0x008c, 0x2051: 0x008c, + 0x2052: 0x008c, 0x2053: 0x008c, 0x2054: 0x008c, 0x2055: 0x008c, 0x2056: 0x008c, 0x2057: 0x008c, + 0x2058: 0x008c, 0x2059: 0x008c, 0x205b: 0x008c, 0x205c: 0x008c, 0x205d: 0x008c, + 0x205e: 0x008c, 0x205f: 0x008c, 0x2060: 0x008c, 0x2061: 0x008c, 0x2062: 0x008c, 0x2063: 0x008c, + 0x2064: 0x008c, 0x2065: 0x008c, 0x2066: 0x008c, 0x2067: 0x008c, 0x2068: 0x008c, 0x2069: 0x008c, + 0x206a: 0x008c, 0x206b: 0x008c, 0x206c: 0x008c, 0x206d: 0x008c, 0x206e: 0x008c, 0x206f: 0x008c, + 0x2070: 0x008c, 0x2071: 0x008c, 0x2072: 0x008c, 0x2073: 0x008c, 0x2074: 0x008c, 0x2075: 0x008c, + 0x2076: 0x008c, 0x2077: 0x008c, 0x2078: 0x008c, 0x2079: 0x008c, 0x207a: 0x008c, 0x207b: 0x008c, + 0x207c: 0x008c, 0x207d: 0x008c, 0x207e: 0x008c, 0x207f: 0x008c, + // Block 0x82, offset 0x2080 + 0x2080: 0x008c, 0x2081: 0x008c, 0x2082: 0x008c, 0x2083: 0x008c, 0x2084: 0x008c, 0x2085: 0x008c, + 0x2086: 0x008c, 0x2087: 0x008c, 0x2088: 0x008c, 0x2089: 0x008c, 0x208a: 0x008c, 0x208b: 0x008c, + 0x208c: 0x008c, 0x208d: 0x008c, 0x208e: 0x008c, 0x208f: 0x008c, 0x2090: 0x008c, 0x2091: 0x008c, + 0x2092: 0x008c, 0x2093: 0x008c, 0x2094: 0x008c, 0x2095: 0x008c, 0x2096: 0x008c, 0x2097: 0x008c, + 0x2098: 0x008c, 0x2099: 0x008c, 0x209a: 0x008c, 0x209b: 0x008c, 0x209c: 0x008c, 0x209d: 0x008c, + 0x209e: 0x008c, 0x209f: 0x008c, 0x20a0: 0x008c, 0x20a1: 0x008c, 0x20a2: 0x008c, 0x20a3: 0x008c, + 0x20a4: 0x008c, 0x20a5: 0x008c, 0x20a6: 0x008c, 0x20a7: 0x008c, 0x20a8: 0x008c, 0x20a9: 0x008c, + 0x20aa: 0x008c, 0x20ab: 0x008c, 0x20ac: 0x008c, 0x20ad: 0x008c, 0x20ae: 0x008c, 0x20af: 0x008c, + 0x20b0: 0x008c, 0x20b1: 0x008c, 0x20b2: 0x008c, 0x20b3: 0x008c, + // Block 0x83, offset 0x20c0 + 0x20c0: 0x008c, 0x20c1: 0x008c, 0x20c2: 0x008c, 0x20c3: 0x008c, 0x20c4: 0x008c, 0x20c5: 0x008c, + 0x20c6: 0x008c, 0x20c7: 0x008c, 0x20c8: 0x008c, 0x20c9: 0x008c, 0x20ca: 0x008c, 0x20cb: 0x008c, + 0x20cc: 0x008c, 0x20cd: 0x008c, 0x20ce: 0x008c, 0x20cf: 0x008c, 0x20d0: 0x008c, 0x20d1: 0x008c, + 0x20d2: 0x008c, 0x20d3: 0x008c, 0x20d4: 0x008c, 0x20d5: 0x008c, 0x20d6: 0x008c, 0x20d7: 0x008c, + 0x20d8: 0x008c, 0x20d9: 0x008c, 0x20da: 0x008c, 0x20db: 0x008c, 0x20dc: 0x008c, 0x20dd: 0x008c, + 0x20de: 0x008c, 0x20df: 0x008c, 0x20e0: 0x008c, 0x20e1: 0x008c, 0x20e2: 0x008c, 0x20e3: 0x008c, + 0x20e4: 0x008c, 0x20e5: 0x008c, 0x20e6: 0x008c, 0x20e7: 0x008c, 0x20e8: 0x008c, 0x20e9: 0x008c, + 0x20ea: 0x008c, 0x20eb: 0x008c, 0x20ec: 0x008c, 0x20ed: 0x008c, 0x20ee: 0x008c, 0x20ef: 0x008c, + 0x20f0: 0x008c, 0x20f1: 0x008c, 0x20f2: 0x008c, 0x20f3: 0x008c, 0x20f4: 0x008c, 0x20f5: 0x008c, + 0x20f6: 0x008c, 0x20f7: 0x008c, 0x20f8: 0x008c, 0x20f9: 0x008c, 0x20fa: 0x008c, 0x20fb: 0x008c, + 0x20fc: 0x008c, 0x20fd: 0x008c, 0x20fe: 0x008c, 0x20ff: 0x008c, + // Block 0x84, offset 0x2100 + 0x2100: 0x008c, 0x2101: 0x008c, 0x2102: 0x008c, 0x2103: 0x008c, 0x2104: 0x008c, 0x2105: 0x008c, + 0x2106: 0x008c, 0x2107: 0x008c, 0x2108: 0x008c, 0x2109: 0x008c, 0x210a: 0x008c, 0x210b: 0x008c, + 0x210c: 0x008c, 0x210d: 0x008c, 0x210e: 0x008c, 0x210f: 0x008c, 0x2110: 0x008c, 0x2111: 0x008c, + 0x2112: 0x008c, 0x2113: 0x008c, 0x2114: 0x008c, 0x2115: 0x008c, + 0x2130: 0x0080, 0x2131: 0x0080, 0x2132: 0x0080, 0x2133: 0x0080, 0x2134: 0x0080, 0x2135: 0x0080, + 0x2136: 0x0080, 0x2137: 0x0080, 0x2138: 0x0080, 0x2139: 0x0080, 0x213a: 0x0080, 0x213b: 0x0080, + // Block 0x85, offset 0x2140 + 0x2140: 0x0080, 0x2141: 0x0080, 0x2142: 0x0080, 0x2143: 0x0080, 0x2144: 0x0080, 0x2145: 0x00cc, + 0x2146: 0x00c0, 0x2147: 0x00cc, 0x2148: 0x0080, 0x2149: 0x0080, 0x214a: 0x0080, 0x214b: 0x0080, + 0x214c: 0x0080, 0x214d: 0x0080, 0x214e: 0x0080, 0x214f: 0x0080, 0x2150: 0x0080, 0x2151: 0x0080, + 0x2152: 0x0080, 0x2153: 0x0080, 0x2154: 0x0080, 0x2155: 0x0080, 0x2156: 0x0080, 0x2157: 0x0080, + 0x2158: 0x0080, 0x2159: 0x0080, 0x215a: 0x0080, 0x215b: 0x0080, 0x215c: 0x0080, 0x215d: 0x0080, + 0x215e: 0x0080, 0x215f: 0x0080, 0x2160: 0x0080, 0x2161: 0x008c, 0x2162: 0x008c, 0x2163: 0x008c, + 0x2164: 0x008c, 0x2165: 0x008c, 0x2166: 0x008c, 0x2167: 0x008c, 0x2168: 0x008c, 0x2169: 0x008c, + 0x216a: 0x00c3, 0x216b: 0x00c3, 0x216c: 0x00c3, 0x216d: 0x00c3, 0x216e: 0x0040, 0x216f: 0x0040, + 0x2170: 0x0080, 0x2171: 0x0040, 0x2172: 0x0040, 0x2173: 0x0040, 0x2174: 0x0040, 0x2175: 0x0040, + 0x2176: 0x0080, 0x2177: 0x0080, 0x2178: 0x008c, 0x2179: 0x008c, 0x217a: 0x008c, 0x217b: 0x0040, + 0x217c: 0x00c0, 0x217d: 0x0080, 0x217e: 0x0080, 0x217f: 0x0080, + // Block 0x86, offset 0x2180 + 0x2181: 0x00cc, 0x2182: 0x00cc, 0x2183: 0x00cc, 0x2184: 0x00cc, 0x2185: 0x00cc, + 0x2186: 0x00cc, 0x2187: 0x00cc, 0x2188: 0x00cc, 0x2189: 0x00cc, 0x218a: 0x00cc, 0x218b: 0x00cc, + 0x218c: 0x00cc, 0x218d: 0x00cc, 0x218e: 0x00cc, 0x218f: 0x00cc, 0x2190: 0x00cc, 0x2191: 0x00cc, + 0x2192: 0x00cc, 0x2193: 0x00cc, 0x2194: 0x00cc, 0x2195: 0x00cc, 0x2196: 0x00cc, 0x2197: 0x00cc, + 0x2198: 0x00cc, 0x2199: 0x00cc, 0x219a: 0x00cc, 0x219b: 0x00cc, 0x219c: 0x00cc, 0x219d: 0x00cc, + 0x219e: 0x00cc, 0x219f: 0x00cc, 0x21a0: 0x00cc, 0x21a1: 0x00cc, 0x21a2: 0x00cc, 0x21a3: 0x00cc, + 0x21a4: 0x00cc, 0x21a5: 0x00cc, 0x21a6: 0x00cc, 0x21a7: 0x00cc, 0x21a8: 0x00cc, 0x21a9: 0x00cc, + 0x21aa: 0x00cc, 0x21ab: 0x00cc, 0x21ac: 0x00cc, 0x21ad: 0x00cc, 0x21ae: 0x00cc, 0x21af: 0x00cc, + 0x21b0: 0x00cc, 0x21b1: 0x00cc, 0x21b2: 0x00cc, 0x21b3: 0x00cc, 0x21b4: 0x00cc, 0x21b5: 0x00cc, + 0x21b6: 0x00cc, 0x21b7: 0x00cc, 0x21b8: 0x00cc, 0x21b9: 0x00cc, 0x21ba: 0x00cc, 0x21bb: 0x00cc, + 0x21bc: 0x00cc, 0x21bd: 0x00cc, 0x21be: 0x00cc, 0x21bf: 0x00cc, + // Block 0x87, offset 0x21c0 + 0x21c0: 0x00cc, 0x21c1: 0x00cc, 0x21c2: 0x00cc, 0x21c3: 0x00cc, 0x21c4: 0x00cc, 0x21c5: 0x00cc, + 0x21c6: 0x00cc, 0x21c7: 0x00cc, 0x21c8: 0x00cc, 0x21c9: 0x00cc, 0x21ca: 0x00cc, 0x21cb: 0x00cc, + 0x21cc: 0x00cc, 0x21cd: 0x00cc, 0x21ce: 0x00cc, 0x21cf: 0x00cc, 0x21d0: 0x00cc, 0x21d1: 0x00cc, + 0x21d2: 0x00cc, 0x21d3: 0x00cc, 0x21d4: 0x00cc, 0x21d5: 0x00cc, 0x21d6: 0x00cc, + 0x21d9: 0x00c3, 0x21da: 0x00c3, 0x21db: 0x0080, 0x21dc: 0x0080, 0x21dd: 0x00cc, + 0x21de: 0x00cc, 0x21df: 0x008c, 0x21e0: 0x0080, 0x21e1: 0x00cc, 0x21e2: 0x00cc, 0x21e3: 0x00cc, + 0x21e4: 0x00cc, 0x21e5: 0x00cc, 0x21e6: 0x00cc, 0x21e7: 0x00cc, 0x21e8: 0x00cc, 0x21e9: 0x00cc, + 0x21ea: 0x00cc, 0x21eb: 0x00cc, 0x21ec: 0x00cc, 0x21ed: 0x00cc, 0x21ee: 0x00cc, 0x21ef: 0x00cc, + 0x21f0: 0x00cc, 0x21f1: 0x00cc, 0x21f2: 0x00cc, 0x21f3: 0x00cc, 0x21f4: 0x00cc, 0x21f5: 0x00cc, + 0x21f6: 0x00cc, 0x21f7: 0x00cc, 0x21f8: 0x00cc, 0x21f9: 0x00cc, 0x21fa: 0x00cc, 0x21fb: 0x00cc, + 0x21fc: 0x00cc, 0x21fd: 0x00cc, 0x21fe: 0x00cc, 0x21ff: 0x00cc, + // Block 0x88, offset 0x2200 + 0x2200: 0x00cc, 0x2201: 0x00cc, 0x2202: 0x00cc, 0x2203: 0x00cc, 0x2204: 0x00cc, 0x2205: 0x00cc, + 0x2206: 0x00cc, 0x2207: 0x00cc, 0x2208: 0x00cc, 0x2209: 0x00cc, 0x220a: 0x00cc, 0x220b: 0x00cc, + 0x220c: 0x00cc, 0x220d: 0x00cc, 0x220e: 0x00cc, 0x220f: 0x00cc, 0x2210: 0x00cc, 0x2211: 0x00cc, + 0x2212: 0x00cc, 0x2213: 0x00cc, 0x2214: 0x00cc, 0x2215: 0x00cc, 0x2216: 0x00cc, 0x2217: 0x00cc, + 0x2218: 0x00cc, 0x2219: 0x00cc, 0x221a: 0x00cc, 0x221b: 0x00cc, 0x221c: 0x00cc, 0x221d: 0x00cc, + 0x221e: 0x00cc, 0x221f: 0x00cc, 0x2220: 0x00cc, 0x2221: 0x00cc, 0x2222: 0x00cc, 0x2223: 0x00cc, + 0x2224: 0x00cc, 0x2225: 0x00cc, 0x2226: 0x00cc, 0x2227: 0x00cc, 0x2228: 0x00cc, 0x2229: 0x00cc, + 0x222a: 0x00cc, 0x222b: 0x00cc, 0x222c: 0x00cc, 0x222d: 0x00cc, 0x222e: 0x00cc, 0x222f: 0x00cc, + 0x2230: 0x00cc, 0x2231: 0x00cc, 0x2232: 0x00cc, 0x2233: 0x00cc, 0x2234: 0x00cc, 0x2235: 0x00cc, + 0x2236: 0x00cc, 0x2237: 0x00cc, 0x2238: 0x00cc, 0x2239: 0x00cc, 0x223a: 0x00cc, 0x223b: 0x00d2, + 0x223c: 0x00c0, 0x223d: 0x00cc, 0x223e: 0x00cc, 0x223f: 0x008c, + // Block 0x89, offset 0x2240 + 0x2245: 0x00c0, + 0x2246: 0x00c0, 0x2247: 0x00c0, 0x2248: 0x00c0, 0x2249: 0x00c0, 0x224a: 0x00c0, 0x224b: 0x00c0, + 0x224c: 0x00c0, 0x224d: 0x00c0, 0x224e: 0x00c0, 0x224f: 0x00c0, 0x2250: 0x00c0, 0x2251: 0x00c0, + 0x2252: 0x00c0, 0x2253: 0x00c0, 0x2254: 0x00c0, 0x2255: 0x00c0, 0x2256: 0x00c0, 0x2257: 0x00c0, + 0x2258: 0x00c0, 0x2259: 0x00c0, 0x225a: 0x00c0, 0x225b: 0x00c0, 0x225c: 0x00c0, 0x225d: 0x00c0, + 0x225e: 0x00c0, 0x225f: 0x00c0, 0x2260: 0x00c0, 0x2261: 0x00c0, 0x2262: 0x00c0, 0x2263: 0x00c0, + 0x2264: 0x00c0, 0x2265: 0x00c0, 0x2266: 0x00c0, 0x2267: 0x00c0, 0x2268: 0x00c0, 0x2269: 0x00c0, + 0x226a: 0x00c0, 0x226b: 0x00c0, 0x226c: 0x00c0, 0x226d: 0x00c0, 0x226e: 0x00c0, 0x226f: 0x00c0, + 0x2271: 0x0080, 0x2272: 0x0080, 0x2273: 0x0080, 0x2274: 0x0080, 0x2275: 0x0080, + 0x2276: 0x0080, 0x2277: 0x0080, 0x2278: 0x0080, 0x2279: 0x0080, 0x227a: 0x0080, 0x227b: 0x0080, + 0x227c: 0x0080, 0x227d: 0x0080, 0x227e: 0x0080, 0x227f: 0x0080, + // Block 0x8a, offset 0x2280 + 0x2280: 0x0080, 0x2281: 0x0080, 0x2282: 0x0080, 0x2283: 0x0080, 0x2284: 0x0080, 0x2285: 0x0080, + 0x2286: 0x0080, 0x2287: 0x0080, 0x2288: 0x0080, 0x2289: 0x0080, 0x228a: 0x0080, 0x228b: 0x0080, + 0x228c: 0x0080, 0x228d: 0x0080, 0x228e: 0x0080, 0x228f: 0x0080, 0x2290: 0x0080, 0x2291: 0x0080, + 0x2292: 0x0080, 0x2293: 0x0080, 0x2294: 0x0080, 0x2295: 0x0080, 0x2296: 0x0080, 0x2297: 0x0080, + 0x2298: 0x0080, 0x2299: 0x0080, 0x229a: 0x0080, 0x229b: 0x0080, 0x229c: 0x0080, 0x229d: 0x0080, + 0x229e: 0x0080, 0x229f: 0x0080, 0x22a0: 0x0080, 0x22a1: 0x0080, 0x22a2: 0x0080, 0x22a3: 0x0080, + 0x22a4: 0x0040, 0x22a5: 0x0080, 0x22a6: 0x0080, 0x22a7: 0x0080, 0x22a8: 0x0080, 0x22a9: 0x0080, + 0x22aa: 0x0080, 0x22ab: 0x0080, 0x22ac: 0x0080, 0x22ad: 0x0080, 0x22ae: 0x0080, 0x22af: 0x0080, + 0x22b0: 0x0080, 0x22b1: 0x0080, 0x22b2: 0x0080, 0x22b3: 0x0080, 0x22b4: 0x0080, 0x22b5: 0x0080, + 0x22b6: 0x0080, 0x22b7: 0x0080, 0x22b8: 0x0080, 0x22b9: 0x0080, 0x22ba: 0x0080, 0x22bb: 0x0080, + 0x22bc: 0x0080, 0x22bd: 0x0080, 0x22be: 0x0080, 0x22bf: 0x0080, + // Block 0x8b, offset 0x22c0 + 0x22c0: 0x0080, 0x22c1: 0x0080, 0x22c2: 0x0080, 0x22c3: 0x0080, 0x22c4: 0x0080, 0x22c5: 0x0080, + 0x22c6: 0x0080, 0x22c7: 0x0080, 0x22c8: 0x0080, 0x22c9: 0x0080, 0x22ca: 0x0080, 0x22cb: 0x0080, + 0x22cc: 0x0080, 0x22cd: 0x0080, 0x22ce: 0x0080, 0x22d0: 0x0080, 0x22d1: 0x0080, + 0x22d2: 0x0080, 0x22d3: 0x0080, 0x22d4: 0x0080, 0x22d5: 0x0080, 0x22d6: 0x0080, 0x22d7: 0x0080, + 0x22d8: 0x0080, 0x22d9: 0x0080, 0x22da: 0x0080, 0x22db: 0x0080, 0x22dc: 0x0080, 0x22dd: 0x0080, + 0x22de: 0x0080, 0x22df: 0x0080, 0x22e0: 0x00c0, 0x22e1: 0x00c0, 0x22e2: 0x00c0, 0x22e3: 0x00c0, + 0x22e4: 0x00c0, 0x22e5: 0x00c0, 0x22e6: 0x00c0, 0x22e7: 0x00c0, 0x22e8: 0x00c0, 0x22e9: 0x00c0, + 0x22ea: 0x00c0, 0x22eb: 0x00c0, 0x22ec: 0x00c0, 0x22ed: 0x00c0, 0x22ee: 0x00c0, 0x22ef: 0x00c0, + 0x22f0: 0x00c0, 0x22f1: 0x00c0, 0x22f2: 0x00c0, 0x22f3: 0x00c0, 0x22f4: 0x00c0, 0x22f5: 0x00c0, + 0x22f6: 0x00c0, 0x22f7: 0x00c0, 0x22f8: 0x00c0, 0x22f9: 0x00c0, 0x22fa: 0x00c0, + // Block 0x8c, offset 0x2300 + 0x2300: 0x0080, 0x2301: 0x0080, 0x2302: 0x0080, 0x2303: 0x0080, 0x2304: 0x0080, 0x2305: 0x0080, + 0x2306: 0x0080, 0x2307: 0x0080, 0x2308: 0x0080, 0x2309: 0x0080, 0x230a: 0x0080, 0x230b: 0x0080, + 0x230c: 0x0080, 0x230d: 0x0080, 0x230e: 0x0080, 0x230f: 0x0080, 0x2310: 0x0080, 0x2311: 0x0080, + 0x2312: 0x0080, 0x2313: 0x0080, 0x2314: 0x0080, 0x2315: 0x0080, 0x2316: 0x0080, 0x2317: 0x0080, + 0x2318: 0x0080, 0x2319: 0x0080, 0x231a: 0x0080, 0x231b: 0x0080, 0x231c: 0x0080, 0x231d: 0x0080, + 0x231e: 0x0080, 0x231f: 0x0080, 0x2320: 0x0080, 0x2321: 0x0080, 0x2322: 0x0080, 0x2323: 0x0080, + 0x2330: 0x00cc, 0x2331: 0x00cc, 0x2332: 0x00cc, 0x2333: 0x00cc, 0x2334: 0x00cc, 0x2335: 0x00cc, + 0x2336: 0x00cc, 0x2337: 0x00cc, 0x2338: 0x00cc, 0x2339: 0x00cc, 0x233a: 0x00cc, 0x233b: 0x00cc, + 0x233c: 0x00cc, 0x233d: 0x00cc, 0x233e: 0x00cc, 0x233f: 0x00cc, + // Block 0x8d, offset 0x2340 + 0x2340: 0x0080, 0x2341: 0x0080, 0x2342: 0x0080, 0x2343: 0x0080, 0x2344: 0x0080, 0x2345: 0x0080, + 0x2346: 0x0080, 0x2347: 0x0080, 0x2348: 0x0080, 0x2349: 0x0080, 0x234a: 0x0080, 0x234b: 0x0080, + 0x234c: 0x0080, 0x234d: 0x0080, 0x234e: 0x0080, 0x234f: 0x0080, 0x2350: 0x0080, 0x2351: 0x0080, + 0x2352: 0x0080, 0x2353: 0x0080, 0x2354: 0x0080, 0x2355: 0x0080, 0x2356: 0x0080, 0x2357: 0x0080, + 0x2358: 0x0080, 0x2359: 0x0080, 0x235a: 0x0080, 0x235b: 0x0080, 0x235c: 0x0080, 0x235d: 0x0080, + 0x235e: 0x0080, 0x2360: 0x0080, 0x2361: 0x0080, 0x2362: 0x0080, 0x2363: 0x0080, + 0x2364: 0x0080, 0x2365: 0x0080, 0x2366: 0x0080, 0x2367: 0x0080, 0x2368: 0x0080, 0x2369: 0x0080, + 0x236a: 0x0080, 0x236b: 0x0080, 0x236c: 0x0080, 0x236d: 0x0080, 0x236e: 0x0080, 0x236f: 0x0080, + 0x2370: 0x0080, 0x2371: 0x0080, 0x2372: 0x0080, 0x2373: 0x0080, 0x2374: 0x0080, 0x2375: 0x0080, + 0x2376: 0x0080, 0x2377: 0x0080, 0x2378: 0x0080, 0x2379: 0x0080, 0x237a: 0x0080, 0x237b: 0x0080, + 0x237c: 0x0080, 0x237d: 0x0080, 0x237e: 0x0080, 0x237f: 0x0080, + // Block 0x8e, offset 0x2380 + 0x2380: 0x0080, 0x2381: 0x0080, 0x2382: 0x0080, 0x2383: 0x0080, 0x2384: 0x0080, 0x2385: 0x0080, + 0x2386: 0x0080, 0x2387: 0x0080, 0x2388: 0x0080, 0x2389: 0x0080, 0x238a: 0x0080, 0x238b: 0x0080, + 0x238c: 0x0080, 0x238d: 0x0080, 0x238e: 0x0080, 0x238f: 0x0080, 0x2390: 0x008c, 0x2391: 0x008c, + 0x2392: 0x008c, 0x2393: 0x008c, 0x2394: 0x008c, 0x2395: 0x008c, 0x2396: 0x008c, 0x2397: 0x008c, + 0x2398: 0x008c, 0x2399: 0x008c, 0x239a: 0x008c, 0x239b: 0x008c, 0x239c: 0x008c, 0x239d: 0x008c, + 0x239e: 0x008c, 0x239f: 0x008c, 0x23a0: 0x008c, 0x23a1: 0x008c, 0x23a2: 0x008c, 0x23a3: 0x008c, + 0x23a4: 0x008c, 0x23a5: 0x008c, 0x23a6: 0x008c, 0x23a7: 0x008c, 0x23a8: 0x008c, 0x23a9: 0x008c, + 0x23aa: 0x008c, 0x23ab: 0x008c, 0x23ac: 0x008c, 0x23ad: 0x008c, 0x23ae: 0x008c, 0x23af: 0x008c, + 0x23b0: 0x008c, 0x23b1: 0x008c, 0x23b2: 0x008c, 0x23b3: 0x008c, 0x23b4: 0x008c, 0x23b5: 0x008c, + 0x23b6: 0x008c, 0x23b7: 0x008c, 0x23b8: 0x008c, 0x23b9: 0x008c, 0x23ba: 0x008c, 0x23bb: 0x008c, + 0x23bc: 0x008c, 0x23bd: 0x008c, 0x23be: 0x008c, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x008c, 0x23c1: 0x008c, 0x23c2: 0x008c, 0x23c3: 0x008c, 0x23c4: 0x008c, 0x23c5: 0x008c, + 0x23c6: 0x008c, 0x23c7: 0x008c, 0x23c8: 0x008c, 0x23c9: 0x008c, 0x23ca: 0x008c, 0x23cb: 0x008c, + 0x23cc: 0x008c, 0x23cd: 0x008c, 0x23ce: 0x008c, 0x23cf: 0x008c, 0x23d0: 0x008c, 0x23d1: 0x008c, + 0x23d2: 0x008c, 0x23d3: 0x008c, 0x23d4: 0x008c, 0x23d5: 0x008c, 0x23d6: 0x008c, 0x23d7: 0x008c, + 0x23d8: 0x0080, 0x23d9: 0x0080, 0x23da: 0x0080, 0x23db: 0x0080, 0x23dc: 0x0080, 0x23dd: 0x0080, + 0x23de: 0x0080, 0x23df: 0x0080, 0x23e0: 0x0080, 0x23e1: 0x0080, 0x23e2: 0x0080, 0x23e3: 0x0080, + 0x23e4: 0x0080, 0x23e5: 0x0080, 0x23e6: 0x0080, 0x23e7: 0x0080, 0x23e8: 0x0080, 0x23e9: 0x0080, + 0x23ea: 0x0080, 0x23eb: 0x0080, 0x23ec: 0x0080, 0x23ed: 0x0080, 0x23ee: 0x0080, 0x23ef: 0x0080, + 0x23f0: 0x0080, 0x23f1: 0x0080, 0x23f2: 0x0080, 0x23f3: 0x0080, 0x23f4: 0x0080, 0x23f5: 0x0080, + 0x23f6: 0x0080, 0x23f7: 0x0080, 0x23f8: 0x0080, 0x23f9: 0x0080, 0x23fa: 0x0080, 0x23fb: 0x0080, + 0x23fc: 0x0080, 0x23fd: 0x0080, 0x23fe: 0x0080, 0x23ff: 0x0080, + // Block 0x90, offset 0x2400 + 0x2400: 0x00cc, 0x2401: 0x00cc, 0x2402: 0x00cc, 0x2403: 0x00cc, 0x2404: 0x00cc, 0x2405: 0x00cc, + 0x2406: 0x00cc, 0x2407: 0x00cc, 0x2408: 0x00cc, 0x2409: 0x00cc, 0x240a: 0x00cc, 0x240b: 0x00cc, + 0x240c: 0x00cc, 0x240d: 0x00cc, 0x240e: 0x00cc, 0x240f: 0x00cc, 0x2410: 0x00cc, 0x2411: 0x00cc, + 0x2412: 0x00cc, 0x2413: 0x00cc, 0x2414: 0x00cc, 0x2415: 0x00cc, 0x2416: 0x00cc, 0x2417: 0x00cc, + 0x2418: 0x00cc, 0x2419: 0x00cc, 0x241a: 0x00cc, 0x241b: 0x00cc, 0x241c: 0x00cc, 0x241d: 0x00cc, + 0x241e: 0x00cc, 0x241f: 0x00cc, 0x2420: 0x00cc, 0x2421: 0x00cc, 0x2422: 0x00cc, 0x2423: 0x00cc, + 0x2424: 0x00cc, 0x2425: 0x00cc, 0x2426: 0x00cc, 0x2427: 0x00cc, 0x2428: 0x00cc, 0x2429: 0x00cc, + 0x242a: 0x00cc, 0x242b: 0x00cc, 0x242c: 0x00cc, 0x242d: 0x00cc, 0x242e: 0x00cc, 0x242f: 0x00cc, + 0x2430: 0x00cc, 0x2431: 0x00cc, 0x2432: 0x00cc, 0x2433: 0x00cc, 0x2434: 0x00cc, 0x2435: 0x00cc, + 0x2436: 0x00cc, 0x2437: 0x00cc, 0x2438: 0x00cc, 0x2439: 0x00cc, 0x243a: 0x00cc, 0x243b: 0x00cc, + 0x243c: 0x00cc, 0x243d: 0x00cc, 0x243e: 0x00cc, 0x243f: 0x00cc, + // Block 0x91, offset 0x2440 + 0x2440: 0x00cc, 0x2441: 0x00cc, 0x2442: 0x00cc, 0x2443: 0x00cc, 0x2444: 0x00cc, 0x2445: 0x00cc, + 0x2446: 0x00cc, 0x2447: 0x00cc, 0x2448: 0x00cc, 0x2449: 0x00cc, 0x244a: 0x00cc, 0x244b: 0x00cc, + 0x244c: 0x00cc, 0x244d: 0x00cc, 0x244e: 0x00cc, 0x244f: 0x00cc, 0x2450: 0x00cc, 0x2451: 0x00cc, + 0x2452: 0x00cc, 0x2453: 0x00cc, 0x2454: 0x00cc, 0x2455: 0x00cc, 0x2456: 0x00cc, 0x2457: 0x00cc, + 0x2458: 0x00cc, 0x2459: 0x00cc, 0x245a: 0x00cc, 0x245b: 0x00cc, 0x245c: 0x00cc, 0x245d: 0x00cc, + 0x245e: 0x00cc, 0x245f: 0x00cc, 0x2460: 0x00cc, 0x2461: 0x00cc, 0x2462: 0x00cc, 0x2463: 0x00cc, + 0x2464: 0x00cc, 0x2465: 0x00cc, 0x2466: 0x00cc, 0x2467: 0x00cc, 0x2468: 0x00cc, 0x2469: 0x00cc, + 0x246a: 0x00cc, 0x246b: 0x00cc, 0x246c: 0x00cc, 0x246d: 0x00cc, 0x246e: 0x00cc, 0x246f: 0x00cc, + 0x2470: 0x00cc, 0x2471: 0x00cc, 0x2472: 0x00cc, 0x2473: 0x00cc, 0x2474: 0x00cc, 0x2475: 0x00cc, + // Block 0x92, offset 0x2480 + 0x2480: 0x00cc, 0x2481: 0x00cc, 0x2482: 0x00cc, 0x2483: 0x00cc, 0x2484: 0x00cc, 0x2485: 0x00cc, + 0x2486: 0x00cc, 0x2487: 0x00cc, 0x2488: 0x00cc, 0x2489: 0x00cc, 0x248a: 0x00cc, 0x248b: 0x00cc, + 0x248c: 0x00cc, 0x248d: 0x00cc, 0x248e: 0x00cc, 0x248f: 0x00cc, 0x2490: 0x00cc, 0x2491: 0x00cc, + 0x2492: 0x00cc, 0x2493: 0x00cc, 0x2494: 0x00cc, 0x2495: 0x00cc, 0x2496: 0x00cc, 0x2497: 0x00cc, + 0x2498: 0x00cc, 0x2499: 0x00cc, 0x249a: 0x00cc, 0x249b: 0x00cc, 0x249c: 0x00cc, 0x249d: 0x00cc, + 0x249e: 0x00cc, 0x249f: 0x00cc, 0x24a0: 0x00cc, 0x24a1: 0x00cc, 0x24a2: 0x00cc, 0x24a3: 0x00cc, + 0x24a4: 0x00cc, 0x24a5: 0x00cc, 0x24a6: 0x00cc, 0x24a7: 0x00cc, 0x24a8: 0x00cc, 0x24a9: 0x00cc, + 0x24aa: 0x00cc, 0x24ab: 0x00cc, 0x24ac: 0x00cc, 0x24ad: 0x00cc, 0x24ae: 0x00cc, 0x24af: 0x00cc, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x00c0, 0x24c1: 0x00c0, 0x24c2: 0x00c0, 0x24c3: 0x00c0, 0x24c4: 0x00c0, 0x24c5: 0x00c0, + 0x24c6: 0x00c0, 0x24c7: 0x00c0, 0x24c8: 0x00c0, 0x24c9: 0x00c0, 0x24ca: 0x00c0, 0x24cb: 0x00c0, + 0x24cc: 0x00c0, 0x24d0: 0x0080, 0x24d1: 0x0080, + 0x24d2: 0x0080, 0x24d3: 0x0080, 0x24d4: 0x0080, 0x24d5: 0x0080, 0x24d6: 0x0080, 0x24d7: 0x0080, + 0x24d8: 0x0080, 0x24d9: 0x0080, 0x24da: 0x0080, 0x24db: 0x0080, 0x24dc: 0x0080, 0x24dd: 0x0080, + 0x24de: 0x0080, 0x24df: 0x0080, 0x24e0: 0x0080, 0x24e1: 0x0080, 0x24e2: 0x0080, 0x24e3: 0x0080, + 0x24e4: 0x0080, 0x24e5: 0x0080, 0x24e6: 0x0080, 0x24e7: 0x0080, 0x24e8: 0x0080, 0x24e9: 0x0080, + 0x24ea: 0x0080, 0x24eb: 0x0080, 0x24ec: 0x0080, 0x24ed: 0x0080, 0x24ee: 0x0080, 0x24ef: 0x0080, + 0x24f0: 0x0080, 0x24f1: 0x0080, 0x24f2: 0x0080, 0x24f3: 0x0080, 0x24f4: 0x0080, 0x24f5: 0x0080, + 0x24f6: 0x0080, 0x24f7: 0x0080, 0x24f8: 0x0080, 0x24f9: 0x0080, 0x24fa: 0x0080, 0x24fb: 0x0080, + 0x24fc: 0x0080, 0x24fd: 0x0080, 0x24fe: 0x0080, 0x24ff: 0x0080, + // Block 0x94, offset 0x2500 + 0x2500: 0x0080, 0x2501: 0x0080, 0x2502: 0x0080, 0x2503: 0x0080, 0x2504: 0x0080, 0x2505: 0x0080, + 0x2506: 0x0080, + 0x2510: 0x00c0, 0x2511: 0x00c0, + 0x2512: 0x00c0, 0x2513: 0x00c0, 0x2514: 0x00c0, 0x2515: 0x00c0, 0x2516: 0x00c0, 0x2517: 0x00c0, + 0x2518: 0x00c0, 0x2519: 0x00c0, 0x251a: 0x00c0, 0x251b: 0x00c0, 0x251c: 0x00c0, 0x251d: 0x00c0, + 0x251e: 0x00c0, 0x251f: 0x00c0, 0x2520: 0x00c0, 0x2521: 0x00c0, 0x2522: 0x00c0, 0x2523: 0x00c0, + 0x2524: 0x00c0, 0x2525: 0x00c0, 0x2526: 0x00c0, 0x2527: 0x00c0, 0x2528: 0x00c0, 0x2529: 0x00c0, + 0x252a: 0x00c0, 0x252b: 0x00c0, 0x252c: 0x00c0, 0x252d: 0x00c0, 0x252e: 0x00c0, 0x252f: 0x00c0, + 0x2530: 0x00c0, 0x2531: 0x00c0, 0x2532: 0x00c0, 0x2533: 0x00c0, 0x2534: 0x00c0, 0x2535: 0x00c0, + 0x2536: 0x00c0, 0x2537: 0x00c0, 0x2538: 0x00c0, 0x2539: 0x00c0, 0x253a: 0x00c0, 0x253b: 0x00c0, + 0x253c: 0x00c0, 0x253d: 0x00c0, 0x253e: 0x0080, 0x253f: 0x0080, + // Block 0x95, offset 0x2540 + 0x2540: 0x00c0, 0x2541: 0x00c0, 0x2542: 0x00c0, 0x2543: 0x00c0, 0x2544: 0x00c0, 0x2545: 0x00c0, + 0x2546: 0x00c0, 0x2547: 0x00c0, 0x2548: 0x00c0, 0x2549: 0x00c0, 0x254a: 0x00c0, 0x254b: 0x00c0, + 0x254c: 0x00c0, 0x254d: 0x0080, 0x254e: 0x0080, 0x254f: 0x0080, 0x2550: 0x00c0, 0x2551: 0x00c0, + 0x2552: 0x00c0, 0x2553: 0x00c0, 0x2554: 0x00c0, 0x2555: 0x00c0, 0x2556: 0x00c0, 0x2557: 0x00c0, + 0x2558: 0x00c0, 0x2559: 0x00c0, 0x255a: 0x00c0, 0x255b: 0x00c0, 0x255c: 0x00c0, 0x255d: 0x00c0, + 0x255e: 0x00c0, 0x255f: 0x00c0, 0x2560: 0x00c0, 0x2561: 0x00c0, 0x2562: 0x00c0, 0x2563: 0x00c0, + 0x2564: 0x00c0, 0x2565: 0x00c0, 0x2566: 0x00c0, 0x2567: 0x00c0, 0x2568: 0x00c0, 0x2569: 0x00c0, + 0x256a: 0x00c0, 0x256b: 0x00c0, + // Block 0x96, offset 0x2580 + 0x2580: 0x00c0, 0x2581: 0x00c0, 0x2582: 0x00c0, 0x2583: 0x00c0, 0x2584: 0x00c0, 0x2585: 0x00c0, + 0x2586: 0x00c0, 0x2587: 0x00c0, 0x2588: 0x00c0, 0x2589: 0x00c0, 0x258a: 0x00c0, 0x258b: 0x00c0, + 0x258c: 0x00c0, 0x258d: 0x00c0, 0x258e: 0x00c0, 0x258f: 0x00c0, 0x2590: 0x00c0, 0x2591: 0x00c0, + 0x2592: 0x00c0, 0x2593: 0x00c0, 0x2594: 0x00c0, 0x2595: 0x00c0, 0x2596: 0x00c0, 0x2597: 0x00c0, + 0x2598: 0x00c0, 0x2599: 0x00c0, 0x259a: 0x00c0, 0x259b: 0x00c0, 0x259c: 0x00c0, 0x259d: 0x00c0, + 0x259e: 0x00c0, 0x259f: 0x00c0, 0x25a0: 0x00c0, 0x25a1: 0x00c0, 0x25a2: 0x00c0, 0x25a3: 0x00c0, + 0x25a4: 0x00c0, 0x25a5: 0x00c0, 0x25a6: 0x00c0, 0x25a7: 0x00c0, 0x25a8: 0x00c0, 0x25a9: 0x00c0, + 0x25aa: 0x00c0, 0x25ab: 0x00c0, 0x25ac: 0x00c0, 0x25ad: 0x00c0, 0x25ae: 0x00c0, 0x25af: 0x00c3, + 0x25b0: 0x0083, 0x25b1: 0x0083, 0x25b2: 0x0083, 0x25b3: 0x0080, 0x25b4: 0x00c3, 0x25b5: 0x00c3, + 0x25b6: 0x00c3, 0x25b7: 0x00c3, 0x25b8: 0x00c3, 0x25b9: 0x00c3, 0x25ba: 0x00c3, 0x25bb: 0x00c3, + 0x25bc: 0x00c3, 0x25bd: 0x00c3, 0x25be: 0x0080, 0x25bf: 0x00c0, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x00c0, 0x25c1: 0x00c0, 0x25c2: 0x00c0, 0x25c3: 0x00c0, 0x25c4: 0x00c0, 0x25c5: 0x00c0, + 0x25c6: 0x00c0, 0x25c7: 0x00c0, 0x25c8: 0x00c0, 0x25c9: 0x00c0, 0x25ca: 0x00c0, 0x25cb: 0x00c0, + 0x25cc: 0x00c0, 0x25cd: 0x00c0, 0x25ce: 0x00c0, 0x25cf: 0x00c0, 0x25d0: 0x00c0, 0x25d1: 0x00c0, + 0x25d2: 0x00c0, 0x25d3: 0x00c0, 0x25d4: 0x00c0, 0x25d5: 0x00c0, 0x25d6: 0x00c0, 0x25d7: 0x00c0, + 0x25d8: 0x00c0, 0x25d9: 0x00c0, 0x25da: 0x00c0, 0x25db: 0x00c0, 0x25dc: 0x0080, 0x25dd: 0x0080, + 0x25de: 0x00c3, 0x25df: 0x00c3, 0x25e0: 0x00c0, 0x25e1: 0x00c0, 0x25e2: 0x00c0, 0x25e3: 0x00c0, + 0x25e4: 0x00c0, 0x25e5: 0x00c0, 0x25e6: 0x00c0, 0x25e7: 0x00c0, 0x25e8: 0x00c0, 0x25e9: 0x00c0, + 0x25ea: 0x00c0, 0x25eb: 0x00c0, 0x25ec: 0x00c0, 0x25ed: 0x00c0, 0x25ee: 0x00c0, 0x25ef: 0x00c0, + 0x25f0: 0x00c0, 0x25f1: 0x00c0, 0x25f2: 0x00c0, 0x25f3: 0x00c0, 0x25f4: 0x00c0, 0x25f5: 0x00c0, + 0x25f6: 0x00c0, 0x25f7: 0x00c0, 0x25f8: 0x00c0, 0x25f9: 0x00c0, 0x25fa: 0x00c0, 0x25fb: 0x00c0, + 0x25fc: 0x00c0, 0x25fd: 0x00c0, 0x25fe: 0x00c0, 0x25ff: 0x00c0, + // Block 0x98, offset 0x2600 + 0x2600: 0x00c0, 0x2601: 0x00c0, 0x2602: 0x00c0, 0x2603: 0x00c0, 0x2604: 0x00c0, 0x2605: 0x00c0, + 0x2606: 0x00c0, 0x2607: 0x00c0, 0x2608: 0x00c0, 0x2609: 0x00c0, 0x260a: 0x00c0, 0x260b: 0x00c0, + 0x260c: 0x00c0, 0x260d: 0x00c0, 0x260e: 0x00c0, 0x260f: 0x00c0, 0x2610: 0x00c0, 0x2611: 0x00c0, + 0x2612: 0x00c0, 0x2613: 0x00c0, 0x2614: 0x00c0, 0x2615: 0x00c0, 0x2616: 0x00c0, 0x2617: 0x00c0, + 0x2618: 0x00c0, 0x2619: 0x00c0, 0x261a: 0x00c0, 0x261b: 0x00c0, 0x261c: 0x00c0, 0x261d: 0x00c0, + 0x261e: 0x00c0, 0x261f: 0x00c0, 0x2620: 0x00c0, 0x2621: 0x00c0, 0x2622: 0x00c0, 0x2623: 0x00c0, + 0x2624: 0x00c0, 0x2625: 0x00c0, 0x2626: 0x0080, 0x2627: 0x0080, 0x2628: 0x0080, 0x2629: 0x0080, + 0x262a: 0x0080, 0x262b: 0x0080, 0x262c: 0x0080, 0x262d: 0x0080, 0x262e: 0x0080, 0x262f: 0x0080, + 0x2630: 0x00c3, 0x2631: 0x00c3, 0x2632: 0x0080, 0x2633: 0x0080, 0x2634: 0x0080, 0x2635: 0x0080, + 0x2636: 0x0080, 0x2637: 0x0080, + // Block 0x99, offset 0x2640 + 0x2640: 0x0080, 0x2641: 0x0080, 0x2642: 0x0080, 0x2643: 0x0080, 0x2644: 0x0080, 0x2645: 0x0080, + 0x2646: 0x0080, 0x2647: 0x0080, 0x2648: 0x0080, 0x2649: 0x0080, 0x264a: 0x0080, 0x264b: 0x0080, + 0x264c: 0x0080, 0x264d: 0x0080, 0x264e: 0x0080, 0x264f: 0x0080, 0x2650: 0x0080, 0x2651: 0x0080, + 0x2652: 0x0080, 0x2653: 0x0080, 0x2654: 0x0080, 0x2655: 0x0080, 0x2656: 0x0080, 0x2657: 0x00c0, + 0x2658: 0x00c0, 0x2659: 0x00c0, 0x265a: 0x00c0, 0x265b: 0x00c0, 0x265c: 0x00c0, 0x265d: 0x00c0, + 0x265e: 0x00c0, 0x265f: 0x00c0, 0x2660: 0x0080, 0x2661: 0x0080, 0x2662: 0x00c0, 0x2663: 0x00c0, + 0x2664: 0x00c0, 0x2665: 0x00c0, 0x2666: 0x00c0, 0x2667: 0x00c0, 0x2668: 0x00c0, 0x2669: 0x00c0, + 0x266a: 0x00c0, 0x266b: 0x00c0, 0x266c: 0x00c0, 0x266d: 0x00c0, 0x266e: 0x00c0, 0x266f: 0x00c0, + 0x2670: 0x00c0, 0x2671: 0x00c0, 0x2672: 0x00c0, 0x2673: 0x00c0, 0x2674: 0x00c0, 0x2675: 0x00c0, + 0x2676: 0x00c0, 0x2677: 0x00c0, 0x2678: 0x00c0, 0x2679: 0x00c0, 0x267a: 0x00c0, 0x267b: 0x00c0, + 0x267c: 0x00c0, 0x267d: 0x00c0, 0x267e: 0x00c0, 0x267f: 0x00c0, + // Block 0x9a, offset 0x2680 + 0x2680: 0x00c0, 0x2681: 0x00c0, 0x2682: 0x00c0, 0x2683: 0x00c0, 0x2684: 0x00c0, 0x2685: 0x00c0, + 0x2686: 0x00c0, 0x2687: 0x00c0, 0x2688: 0x00c0, 0x2689: 0x00c0, 0x268a: 0x00c0, 0x268b: 0x00c0, + 0x268c: 0x00c0, 0x268d: 0x00c0, 0x268e: 0x00c0, 0x268f: 0x00c0, 0x2690: 0x00c0, 0x2691: 0x00c0, + 0x2692: 0x00c0, 0x2693: 0x00c0, 0x2694: 0x00c0, 0x2695: 0x00c0, 0x2696: 0x00c0, 0x2697: 0x00c0, + 0x2698: 0x00c0, 0x2699: 0x00c0, 0x269a: 0x00c0, 0x269b: 0x00c0, 0x269c: 0x00c0, 0x269d: 0x00c0, + 0x269e: 0x00c0, 0x269f: 0x00c0, 0x26a0: 0x00c0, 0x26a1: 0x00c0, 0x26a2: 0x00c0, 0x26a3: 0x00c0, + 0x26a4: 0x00c0, 0x26a5: 0x00c0, 0x26a6: 0x00c0, 0x26a7: 0x00c0, 0x26a8: 0x00c0, 0x26a9: 0x00c0, + 0x26aa: 0x00c0, 0x26ab: 0x00c0, 0x26ac: 0x00c0, 0x26ad: 0x00c0, 0x26ae: 0x00c0, 0x26af: 0x00c0, + 0x26b0: 0x0080, 0x26b1: 0x00c0, 0x26b2: 0x00c0, 0x26b3: 0x00c0, 0x26b4: 0x00c0, 0x26b5: 0x00c0, + 0x26b6: 0x00c0, 0x26b7: 0x00c0, 0x26b8: 0x00c0, 0x26b9: 0x00c0, 0x26ba: 0x00c0, 0x26bb: 0x00c0, + 0x26bc: 0x00c0, 0x26bd: 0x00c0, 0x26be: 0x00c0, 0x26bf: 0x00c0, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x00c0, 0x26c1: 0x00c0, 0x26c2: 0x00c0, 0x26c3: 0x00c0, 0x26c4: 0x00c0, 0x26c5: 0x00c0, + 0x26c6: 0x00c0, 0x26c7: 0x00c0, 0x26c8: 0x00c0, 0x26c9: 0x0080, 0x26ca: 0x0080, 0x26cb: 0x00c0, + 0x26cc: 0x00c0, 0x26cd: 0x00c0, 0x26ce: 0x00c0, 0x26cf: 0x00c0, 0x26d0: 0x00c0, 0x26d1: 0x00c0, + 0x26d2: 0x00c0, 0x26d3: 0x00c0, 0x26d4: 0x00c0, 0x26d5: 0x00c0, 0x26d6: 0x00c0, 0x26d7: 0x00c0, + 0x26d8: 0x00c0, 0x26d9: 0x00c0, 0x26da: 0x00c0, 0x26db: 0x00c0, 0x26dc: 0x00c0, 0x26dd: 0x00c0, + 0x26de: 0x00c0, 0x26df: 0x00c0, 0x26e0: 0x00c0, 0x26e1: 0x00c0, 0x26e2: 0x00c0, 0x26e3: 0x00c0, + 0x26e4: 0x00c0, 0x26e5: 0x00c0, 0x26e6: 0x00c0, 0x26e7: 0x00c0, 0x26e8: 0x00c0, 0x26e9: 0x00c0, + 0x26ea: 0x00c0, 0x26eb: 0x00c0, 0x26ec: 0x00c0, 0x26ed: 0x00c0, 0x26ee: 0x00c0, 0x26ef: 0x00c0, + 0x26f0: 0x00c0, 0x26f1: 0x00c0, 0x26f2: 0x00c0, 0x26f3: 0x00c0, 0x26f4: 0x00c0, 0x26f5: 0x00c0, + 0x26f6: 0x00c0, 0x26f7: 0x00c0, 0x26f8: 0x00c0, 0x26f9: 0x00c0, 0x26fa: 0x00c0, 0x26fb: 0x00c0, + 0x26fc: 0x00c0, 0x26fd: 0x00c0, 0x26fe: 0x00c0, 0x26ff: 0x00c0, + // Block 0x9c, offset 0x2700 + 0x2702: 0x00c0, 0x2703: 0x00c0, 0x2704: 0x00c0, 0x2705: 0x00c0, + 0x2706: 0x00c0, + 0x2737: 0x00c0, 0x2738: 0x0080, 0x2739: 0x0080, 0x273a: 0x00c0, 0x273b: 0x00c0, + 0x273c: 0x00c0, 0x273d: 0x00c0, 0x273e: 0x00c0, 0x273f: 0x00c0, + // Block 0x9d, offset 0x2740 + 0x2740: 0x00c0, 0x2741: 0x00c0, 0x2742: 0x00c3, 0x2743: 0x00c0, 0x2744: 0x00c0, 0x2745: 0x00c0, + 0x2746: 0x00c6, 0x2747: 0x00c0, 0x2748: 0x00c0, 0x2749: 0x00c0, 0x274a: 0x00c0, 0x274b: 0x00c3, + 0x274c: 0x00c0, 0x274d: 0x00c0, 0x274e: 0x00c0, 0x274f: 0x00c0, 0x2750: 0x00c0, 0x2751: 0x00c0, + 0x2752: 0x00c0, 0x2753: 0x00c0, 0x2754: 0x00c0, 0x2755: 0x00c0, 0x2756: 0x00c0, 0x2757: 0x00c0, + 0x2758: 0x00c0, 0x2759: 0x00c0, 0x275a: 0x00c0, 0x275b: 0x00c0, 0x275c: 0x00c0, 0x275d: 0x00c0, + 0x275e: 0x00c0, 0x275f: 0x00c0, 0x2760: 0x00c0, 0x2761: 0x00c0, 0x2762: 0x00c0, 0x2763: 0x00c0, + 0x2764: 0x00c0, 0x2765: 0x00c3, 0x2766: 0x00c3, 0x2767: 0x00c0, 0x2768: 0x0080, 0x2769: 0x0080, + 0x276a: 0x0080, 0x276b: 0x0080, + 0x2770: 0x0080, 0x2771: 0x0080, 0x2772: 0x0080, 0x2773: 0x0080, 0x2774: 0x0080, 0x2775: 0x0080, + 0x2776: 0x0080, 0x2777: 0x0080, 0x2778: 0x0080, 0x2779: 0x0080, + // Block 0x9e, offset 0x2780 + 0x2780: 0x00c2, 0x2781: 0x00c2, 0x2782: 0x00c2, 0x2783: 0x00c2, 0x2784: 0x00c2, 0x2785: 0x00c2, + 0x2786: 0x00c2, 0x2787: 0x00c2, 0x2788: 0x00c2, 0x2789: 0x00c2, 0x278a: 0x00c2, 0x278b: 0x00c2, + 0x278c: 0x00c2, 0x278d: 0x00c2, 0x278e: 0x00c2, 0x278f: 0x00c2, 0x2790: 0x00c2, 0x2791: 0x00c2, + 0x2792: 0x00c2, 0x2793: 0x00c2, 0x2794: 0x00c2, 0x2795: 0x00c2, 0x2796: 0x00c2, 0x2797: 0x00c2, + 0x2798: 0x00c2, 0x2799: 0x00c2, 0x279a: 0x00c2, 0x279b: 0x00c2, 0x279c: 0x00c2, 0x279d: 0x00c2, + 0x279e: 0x00c2, 0x279f: 0x00c2, 0x27a0: 0x00c2, 0x27a1: 0x00c2, 0x27a2: 0x00c2, 0x27a3: 0x00c2, + 0x27a4: 0x00c2, 0x27a5: 0x00c2, 0x27a6: 0x00c2, 0x27a7: 0x00c2, 0x27a8: 0x00c2, 0x27a9: 0x00c2, + 0x27aa: 0x00c2, 0x27ab: 0x00c2, 0x27ac: 0x00c2, 0x27ad: 0x00c2, 0x27ae: 0x00c2, 0x27af: 0x00c2, + 0x27b0: 0x00c2, 0x27b1: 0x00c2, 0x27b2: 0x00c1, 0x27b3: 0x00c0, 0x27b4: 0x0080, 0x27b5: 0x0080, + 0x27b6: 0x0080, 0x27b7: 0x0080, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x00c0, 0x27c1: 0x00c0, 0x27c2: 0x00c0, 0x27c3: 0x00c0, 0x27c4: 0x00c6, 0x27c5: 0x00c3, + 0x27ce: 0x0080, 0x27cf: 0x0080, 0x27d0: 0x00c0, 0x27d1: 0x00c0, + 0x27d2: 0x00c0, 0x27d3: 0x00c0, 0x27d4: 0x00c0, 0x27d5: 0x00c0, 0x27d6: 0x00c0, 0x27d7: 0x00c0, + 0x27d8: 0x00c0, 0x27d9: 0x00c0, + 0x27e0: 0x00c3, 0x27e1: 0x00c3, 0x27e2: 0x00c3, 0x27e3: 0x00c3, + 0x27e4: 0x00c3, 0x27e5: 0x00c3, 0x27e6: 0x00c3, 0x27e7: 0x00c3, 0x27e8: 0x00c3, 0x27e9: 0x00c3, + 0x27ea: 0x00c3, 0x27eb: 0x00c3, 0x27ec: 0x00c3, 0x27ed: 0x00c3, 0x27ee: 0x00c3, 0x27ef: 0x00c3, + 0x27f0: 0x00c3, 0x27f1: 0x00c3, 0x27f2: 0x00c0, 0x27f3: 0x00c0, 0x27f4: 0x00c0, 0x27f5: 0x00c0, + 0x27f6: 0x00c0, 0x27f7: 0x00c0, 0x27f8: 0x0080, 0x27f9: 0x0080, 0x27fa: 0x0080, 0x27fb: 0x00c0, + 0x27fc: 0x0080, 0x27fd: 0x00c0, 0x27fe: 0x00c0, 0x27ff: 0x00c3, + // Block 0xa0, offset 0x2800 + 0x2800: 0x00c0, 0x2801: 0x00c0, 0x2802: 0x00c0, 0x2803: 0x00c0, 0x2804: 0x00c0, 0x2805: 0x00c0, + 0x2806: 0x00c0, 0x2807: 0x00c0, 0x2808: 0x00c0, 0x2809: 0x00c0, 0x280a: 0x00c0, 0x280b: 0x00c0, + 0x280c: 0x00c0, 0x280d: 0x00c0, 0x280e: 0x00c0, 0x280f: 0x00c0, 0x2810: 0x00c0, 0x2811: 0x00c0, + 0x2812: 0x00c0, 0x2813: 0x00c0, 0x2814: 0x00c0, 0x2815: 0x00c0, 0x2816: 0x00c0, 0x2817: 0x00c0, + 0x2818: 0x00c0, 0x2819: 0x00c0, 0x281a: 0x00c0, 0x281b: 0x00c0, 0x281c: 0x00c0, 0x281d: 0x00c0, + 0x281e: 0x00c0, 0x281f: 0x00c0, 0x2820: 0x00c0, 0x2821: 0x00c0, 0x2822: 0x00c0, 0x2823: 0x00c0, + 0x2824: 0x00c0, 0x2825: 0x00c0, 0x2826: 0x00c3, 0x2827: 0x00c3, 0x2828: 0x00c3, 0x2829: 0x00c3, + 0x282a: 0x00c3, 0x282b: 0x00c3, 0x282c: 0x00c3, 0x282d: 0x00c3, 0x282e: 0x0080, 0x282f: 0x0080, + 0x2830: 0x00c0, 0x2831: 0x00c0, 0x2832: 0x00c0, 0x2833: 0x00c0, 0x2834: 0x00c0, 0x2835: 0x00c0, + 0x2836: 0x00c0, 0x2837: 0x00c0, 0x2838: 0x00c0, 0x2839: 0x00c0, 0x283a: 0x00c0, 0x283b: 0x00c0, + 0x283c: 0x00c0, 0x283d: 0x00c0, 0x283e: 0x00c0, 0x283f: 0x00c0, + // Block 0xa1, offset 0x2840 + 0x2840: 0x00c0, 0x2841: 0x00c0, 0x2842: 0x00c0, 0x2843: 0x00c0, 0x2844: 0x00c0, 0x2845: 0x00c0, + 0x2846: 0x00c0, 0x2847: 0x00c3, 0x2848: 0x00c3, 0x2849: 0x00c3, 0x284a: 0x00c3, 0x284b: 0x00c3, + 0x284c: 0x00c3, 0x284d: 0x00c3, 0x284e: 0x00c3, 0x284f: 0x00c3, 0x2850: 0x00c3, 0x2851: 0x00c3, + 0x2852: 0x00c0, 0x2853: 0x00c5, + 0x285f: 0x0080, 0x2860: 0x0040, 0x2861: 0x0040, 0x2862: 0x0040, 0x2863: 0x0040, + 0x2864: 0x0040, 0x2865: 0x0040, 0x2866: 0x0040, 0x2867: 0x0040, 0x2868: 0x0040, 0x2869: 0x0040, + 0x286a: 0x0040, 0x286b: 0x0040, 0x286c: 0x0040, 0x286d: 0x0040, 0x286e: 0x0040, 0x286f: 0x0040, + 0x2870: 0x0040, 0x2871: 0x0040, 0x2872: 0x0040, 0x2873: 0x0040, 0x2874: 0x0040, 0x2875: 0x0040, + 0x2876: 0x0040, 0x2877: 0x0040, 0x2878: 0x0040, 0x2879: 0x0040, 0x287a: 0x0040, 0x287b: 0x0040, + 0x287c: 0x0040, + // Block 0xa2, offset 0x2880 + 0x2880: 0x00c3, 0x2881: 0x00c3, 0x2882: 0x00c3, 0x2883: 0x00c0, 0x2884: 0x00c0, 0x2885: 0x00c0, + 0x2886: 0x00c0, 0x2887: 0x00c0, 0x2888: 0x00c0, 0x2889: 0x00c0, 0x288a: 0x00c0, 0x288b: 0x00c0, + 0x288c: 0x00c0, 0x288d: 0x00c0, 0x288e: 0x00c0, 0x288f: 0x00c0, 0x2890: 0x00c0, 0x2891: 0x00c0, + 0x2892: 0x00c0, 0x2893: 0x00c0, 0x2894: 0x00c0, 0x2895: 0x00c0, 0x2896: 0x00c0, 0x2897: 0x00c0, + 0x2898: 0x00c0, 0x2899: 0x00c0, 0x289a: 0x00c0, 0x289b: 0x00c0, 0x289c: 0x00c0, 0x289d: 0x00c0, + 0x289e: 0x00c0, 0x289f: 0x00c0, 0x28a0: 0x00c0, 0x28a1: 0x00c0, 0x28a2: 0x00c0, 0x28a3: 0x00c0, + 0x28a4: 0x00c0, 0x28a5: 0x00c0, 0x28a6: 0x00c0, 0x28a7: 0x00c0, 0x28a8: 0x00c0, 0x28a9: 0x00c0, + 0x28aa: 0x00c0, 0x28ab: 0x00c0, 0x28ac: 0x00c0, 0x28ad: 0x00c0, 0x28ae: 0x00c0, 0x28af: 0x00c0, + 0x28b0: 0x00c0, 0x28b1: 0x00c0, 0x28b2: 0x00c0, 0x28b3: 0x00c3, 0x28b4: 0x00c0, 0x28b5: 0x00c0, + 0x28b6: 0x00c3, 0x28b7: 0x00c3, 0x28b8: 0x00c3, 0x28b9: 0x00c3, 0x28ba: 0x00c0, 0x28bb: 0x00c0, + 0x28bc: 0x00c3, 0x28bd: 0x00c3, 0x28be: 0x00c0, 0x28bf: 0x00c0, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x00c5, 0x28c1: 0x0080, 0x28c2: 0x0080, 0x28c3: 0x0080, 0x28c4: 0x0080, 0x28c5: 0x0080, + 0x28c6: 0x0080, 0x28c7: 0x0080, 0x28c8: 0x0080, 0x28c9: 0x0080, 0x28ca: 0x0080, 0x28cb: 0x0080, + 0x28cc: 0x0080, 0x28cd: 0x0080, 0x28cf: 0x00c0, 0x28d0: 0x00c0, 0x28d1: 0x00c0, + 0x28d2: 0x00c0, 0x28d3: 0x00c0, 0x28d4: 0x00c0, 0x28d5: 0x00c0, 0x28d6: 0x00c0, 0x28d7: 0x00c0, + 0x28d8: 0x00c0, 0x28d9: 0x00c0, + 0x28de: 0x0080, 0x28df: 0x0080, 0x28e0: 0x00c0, 0x28e1: 0x00c0, 0x28e2: 0x00c0, 0x28e3: 0x00c0, + 0x28e4: 0x00c0, 0x28e5: 0x00c3, 0x28e6: 0x00c0, 0x28e7: 0x00c0, 0x28e8: 0x00c0, 0x28e9: 0x00c0, + 0x28ea: 0x00c0, 0x28eb: 0x00c0, 0x28ec: 0x00c0, 0x28ed: 0x00c0, 0x28ee: 0x00c0, 0x28ef: 0x00c0, + 0x28f0: 0x00c0, 0x28f1: 0x00c0, 0x28f2: 0x00c0, 0x28f3: 0x00c0, 0x28f4: 0x00c0, 0x28f5: 0x00c0, + 0x28f6: 0x00c0, 0x28f7: 0x00c0, 0x28f8: 0x00c0, 0x28f9: 0x00c0, 0x28fa: 0x00c0, 0x28fb: 0x00c0, + 0x28fc: 0x00c0, 0x28fd: 0x00c0, 0x28fe: 0x00c0, + // Block 0xa4, offset 0x2900 + 0x2900: 0x00c0, 0x2901: 0x00c0, 0x2902: 0x00c0, 0x2903: 0x00c0, 0x2904: 0x00c0, 0x2905: 0x00c0, + 0x2906: 0x00c0, 0x2907: 0x00c0, 0x2908: 0x00c0, 0x2909: 0x00c0, 0x290a: 0x00c0, 0x290b: 0x00c0, + 0x290c: 0x00c0, 0x290d: 0x00c0, 0x290e: 0x00c0, 0x290f: 0x00c0, 0x2910: 0x00c0, 0x2911: 0x00c0, + 0x2912: 0x00c0, 0x2913: 0x00c0, 0x2914: 0x00c0, 0x2915: 0x00c0, 0x2916: 0x00c0, 0x2917: 0x00c0, + 0x2918: 0x00c0, 0x2919: 0x00c0, 0x291a: 0x00c0, 0x291b: 0x00c0, 0x291c: 0x00c0, 0x291d: 0x00c0, + 0x291e: 0x00c0, 0x291f: 0x00c0, 0x2920: 0x00c0, 0x2921: 0x00c0, 0x2922: 0x00c0, 0x2923: 0x00c0, + 0x2924: 0x00c0, 0x2925: 0x00c0, 0x2926: 0x00c0, 0x2927: 0x00c0, 0x2928: 0x00c0, 0x2929: 0x00c3, + 0x292a: 0x00c3, 0x292b: 0x00c3, 0x292c: 0x00c3, 0x292d: 0x00c3, 0x292e: 0x00c3, 0x292f: 0x00c0, + 0x2930: 0x00c0, 0x2931: 0x00c3, 0x2932: 0x00c3, 0x2933: 0x00c0, 0x2934: 0x00c0, 0x2935: 0x00c3, + 0x2936: 0x00c3, + // Block 0xa5, offset 0x2940 + 0x2940: 0x00c0, 0x2941: 0x00c0, 0x2942: 0x00c0, 0x2943: 0x00c3, 0x2944: 0x00c0, 0x2945: 0x00c0, + 0x2946: 0x00c0, 0x2947: 0x00c0, 0x2948: 0x00c0, 0x2949: 0x00c0, 0x294a: 0x00c0, 0x294b: 0x00c0, + 0x294c: 0x00c3, 0x294d: 0x00c0, 0x2950: 0x00c0, 0x2951: 0x00c0, + 0x2952: 0x00c0, 0x2953: 0x00c0, 0x2954: 0x00c0, 0x2955: 0x00c0, 0x2956: 0x00c0, 0x2957: 0x00c0, + 0x2958: 0x00c0, 0x2959: 0x00c0, 0x295c: 0x0080, 0x295d: 0x0080, + 0x295e: 0x0080, 0x295f: 0x0080, 0x2960: 0x00c0, 0x2961: 0x00c0, 0x2962: 0x00c0, 0x2963: 0x00c0, + 0x2964: 0x00c0, 0x2965: 0x00c0, 0x2966: 0x00c0, 0x2967: 0x00c0, 0x2968: 0x00c0, 0x2969: 0x00c0, + 0x296a: 0x00c0, 0x296b: 0x00c0, 0x296c: 0x00c0, 0x296d: 0x00c0, 0x296e: 0x00c0, 0x296f: 0x00c0, + 0x2970: 0x00c0, 0x2971: 0x00c0, 0x2972: 0x00c0, 0x2973: 0x00c0, 0x2974: 0x00c0, 0x2975: 0x00c0, + 0x2976: 0x00c0, 0x2977: 0x0080, 0x2978: 0x0080, 0x2979: 0x0080, 0x297a: 0x00c0, 0x297b: 0x00c0, + 0x297c: 0x00c3, 0x297d: 0x00c0, 0x297e: 0x00c0, 0x297f: 0x00c0, + // Block 0xa6, offset 0x2980 + 0x2980: 0x00c0, 0x2981: 0x00c0, 0x2982: 0x00c0, 0x2983: 0x00c0, 0x2984: 0x00c0, 0x2985: 0x00c0, + 0x2986: 0x00c0, 0x2987: 0x00c0, 0x2988: 0x00c0, 0x2989: 0x00c0, 0x298a: 0x00c0, 0x298b: 0x00c0, + 0x298c: 0x00c0, 0x298d: 0x00c0, 0x298e: 0x00c0, 0x298f: 0x00c0, 0x2990: 0x00c0, 0x2991: 0x00c0, + 0x2992: 0x00c0, 0x2993: 0x00c0, 0x2994: 0x00c0, 0x2995: 0x00c0, 0x2996: 0x00c0, 0x2997: 0x00c0, + 0x2998: 0x00c0, 0x2999: 0x00c0, 0x299a: 0x00c0, 0x299b: 0x00c0, 0x299c: 0x00c0, 0x299d: 0x00c0, + 0x299e: 0x00c0, 0x299f: 0x00c0, 0x29a0: 0x00c0, 0x29a1: 0x00c0, 0x29a2: 0x00c0, 0x29a3: 0x00c0, + 0x29a4: 0x00c0, 0x29a5: 0x00c0, 0x29a6: 0x00c0, 0x29a7: 0x00c0, 0x29a8: 0x00c0, 0x29a9: 0x00c0, + 0x29aa: 0x00c0, 0x29ab: 0x00c0, 0x29ac: 0x00c0, 0x29ad: 0x00c0, 0x29ae: 0x00c0, 0x29af: 0x00c0, + 0x29b0: 0x00c3, 0x29b1: 0x00c0, 0x29b2: 0x00c3, 0x29b3: 0x00c3, 0x29b4: 0x00c3, 0x29b5: 0x00c0, + 0x29b6: 0x00c0, 0x29b7: 0x00c3, 0x29b8: 0x00c3, 0x29b9: 0x00c0, 0x29ba: 0x00c0, 0x29bb: 0x00c0, + 0x29bc: 0x00c0, 0x29bd: 0x00c0, 0x29be: 0x00c3, 0x29bf: 0x00c3, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x00c0, 0x29c1: 0x00c3, 0x29c2: 0x00c0, + 0x29db: 0x00c0, 0x29dc: 0x00c0, 0x29dd: 0x00c0, + 0x29de: 0x0080, 0x29df: 0x0080, 0x29e0: 0x00c0, 0x29e1: 0x00c0, 0x29e2: 0x00c0, 0x29e3: 0x00c0, + 0x29e4: 0x00c0, 0x29e5: 0x00c0, 0x29e6: 0x00c0, 0x29e7: 0x00c0, 0x29e8: 0x00c0, 0x29e9: 0x00c0, + 0x29ea: 0x00c0, 0x29eb: 0x00c0, 0x29ec: 0x00c3, 0x29ed: 0x00c3, 0x29ee: 0x00c0, 0x29ef: 0x00c0, + 0x29f0: 0x0080, 0x29f1: 0x0080, 0x29f2: 0x00c0, 0x29f3: 0x00c0, 0x29f4: 0x00c0, 0x29f5: 0x00c0, + 0x29f6: 0x00c6, + // Block 0xa8, offset 0x2a00 + 0x2a01: 0x00c0, 0x2a02: 0x00c0, 0x2a03: 0x00c0, 0x2a04: 0x00c0, 0x2a05: 0x00c0, + 0x2a06: 0x00c0, 0x2a09: 0x00c0, 0x2a0a: 0x00c0, 0x2a0b: 0x00c0, + 0x2a0c: 0x00c0, 0x2a0d: 0x00c0, 0x2a0e: 0x00c0, 0x2a11: 0x00c0, + 0x2a12: 0x00c0, 0x2a13: 0x00c0, 0x2a14: 0x00c0, 0x2a15: 0x00c0, 0x2a16: 0x00c0, + 0x2a20: 0x00c0, 0x2a21: 0x00c0, 0x2a22: 0x00c0, 0x2a23: 0x00c0, + 0x2a24: 0x00c0, 0x2a25: 0x00c0, 0x2a26: 0x00c0, 0x2a28: 0x00c0, 0x2a29: 0x00c0, + 0x2a2a: 0x00c0, 0x2a2b: 0x00c0, 0x2a2c: 0x00c0, 0x2a2d: 0x00c0, 0x2a2e: 0x00c0, + 0x2a30: 0x00c0, 0x2a31: 0x00c0, 0x2a32: 0x00c0, 0x2a33: 0x00c0, 0x2a34: 0x00c0, 0x2a35: 0x00c0, + 0x2a36: 0x00c0, 0x2a37: 0x00c0, 0x2a38: 0x00c0, 0x2a39: 0x00c0, 0x2a3a: 0x00c0, 0x2a3b: 0x00c0, + 0x2a3c: 0x00c0, 0x2a3d: 0x00c0, 0x2a3e: 0x00c0, 0x2a3f: 0x00c0, + // Block 0xa9, offset 0x2a40 + 0x2a40: 0x00c0, 0x2a41: 0x00c0, 0x2a42: 0x00c0, 0x2a43: 0x00c0, 0x2a44: 0x00c0, 0x2a45: 0x00c0, + 0x2a46: 0x00c0, 0x2a47: 0x00c0, 0x2a48: 0x00c0, 0x2a49: 0x00c0, 0x2a4a: 0x00c0, 0x2a4b: 0x00c0, + 0x2a4c: 0x00c0, 0x2a4d: 0x00c0, 0x2a4e: 0x00c0, 0x2a4f: 0x00c0, 0x2a50: 0x00c0, 0x2a51: 0x00c0, + 0x2a52: 0x00c0, 0x2a53: 0x00c0, 0x2a54: 0x00c0, 0x2a55: 0x00c0, 0x2a56: 0x00c0, 0x2a57: 0x00c0, + 0x2a58: 0x00c0, 0x2a59: 0x00c0, 0x2a5a: 0x00c0, 0x2a5b: 0x0080, 0x2a5c: 0x0080, 0x2a5d: 0x0080, + 0x2a5e: 0x0080, 0x2a5f: 0x0080, 0x2a60: 0x00c0, 0x2a61: 0x00c0, 0x2a62: 0x00c0, 0x2a63: 0x00c0, + 0x2a64: 0x00c0, 0x2a65: 0x00c8, 0x2a66: 0x00c0, 0x2a67: 0x00c0, + 0x2a70: 0x00c0, 0x2a71: 0x00c0, 0x2a72: 0x00c0, 0x2a73: 0x00c0, 0x2a74: 0x00c0, 0x2a75: 0x00c0, + 0x2a76: 0x00c0, 0x2a77: 0x00c0, 0x2a78: 0x00c0, 0x2a79: 0x00c0, 0x2a7a: 0x00c0, 0x2a7b: 0x00c0, + 0x2a7c: 0x00c0, 0x2a7d: 0x00c0, 0x2a7e: 0x00c0, 0x2a7f: 0x00c0, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x00c0, 0x2a81: 0x00c0, 0x2a82: 0x00c0, 0x2a83: 0x00c0, 0x2a84: 0x00c0, 0x2a85: 0x00c0, + 0x2a86: 0x00c0, 0x2a87: 0x00c0, 0x2a88: 0x00c0, 0x2a89: 0x00c0, 0x2a8a: 0x00c0, 0x2a8b: 0x00c0, + 0x2a8c: 0x00c0, 0x2a8d: 0x00c0, 0x2a8e: 0x00c0, 0x2a8f: 0x00c0, 0x2a90: 0x00c0, 0x2a91: 0x00c0, + 0x2a92: 0x00c0, 0x2a93: 0x00c0, 0x2a94: 0x00c0, 0x2a95: 0x00c0, 0x2a96: 0x00c0, 0x2a97: 0x00c0, + 0x2a98: 0x00c0, 0x2a99: 0x00c0, 0x2a9a: 0x00c0, 0x2a9b: 0x00c0, 0x2a9c: 0x00c0, 0x2a9d: 0x00c0, + 0x2a9e: 0x00c0, 0x2a9f: 0x00c0, 0x2aa0: 0x00c0, 0x2aa1: 0x00c0, 0x2aa2: 0x00c0, 0x2aa3: 0x00c0, + 0x2aa4: 0x00c0, 0x2aa5: 0x00c3, 0x2aa6: 0x00c0, 0x2aa7: 0x00c0, 0x2aa8: 0x00c3, 0x2aa9: 0x00c0, + 0x2aaa: 0x00c0, 0x2aab: 0x0080, 0x2aac: 0x00c0, 0x2aad: 0x00c6, + 0x2ab0: 0x00c0, 0x2ab1: 0x00c0, 0x2ab2: 0x00c0, 0x2ab3: 0x00c0, 0x2ab4: 0x00c0, 0x2ab5: 0x00c0, + 0x2ab6: 0x00c0, 0x2ab7: 0x00c0, 0x2ab8: 0x00c0, 0x2ab9: 0x00c0, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x00c0, 0x2ac1: 0x00c0, 0x2ac2: 0x00c0, 0x2ac3: 0x00c0, 0x2ac4: 0x00c0, 0x2ac5: 0x00c0, + 0x2ac6: 0x00c0, 0x2ac7: 0x00c0, 0x2ac8: 0x00c0, 0x2ac9: 0x00c0, 0x2aca: 0x00c0, 0x2acb: 0x00c0, + 0x2acc: 0x00c0, 0x2acd: 0x00c0, 0x2ace: 0x00c0, 0x2acf: 0x00c0, 0x2ad0: 0x00c0, 0x2ad1: 0x00c0, + 0x2ad2: 0x00c0, 0x2ad3: 0x00c0, 0x2ad4: 0x00c0, 0x2ad5: 0x00c0, 0x2ad6: 0x00c0, 0x2ad7: 0x00c0, + 0x2ad8: 0x00c0, 0x2ad9: 0x00c0, 0x2ada: 0x00c0, 0x2adb: 0x00c0, 0x2adc: 0x00c0, 0x2add: 0x00c0, + 0x2ade: 0x00c0, 0x2adf: 0x00c0, 0x2ae0: 0x00c0, 0x2ae1: 0x00c0, 0x2ae2: 0x00c0, 0x2ae3: 0x00c0, + 0x2af0: 0x0040, 0x2af1: 0x0040, 0x2af2: 0x0040, 0x2af3: 0x0040, 0x2af4: 0x0040, 0x2af5: 0x0040, + 0x2af6: 0x0040, 0x2af7: 0x0040, 0x2af8: 0x0040, 0x2af9: 0x0040, 0x2afa: 0x0040, 0x2afb: 0x0040, + 0x2afc: 0x0040, 0x2afd: 0x0040, 0x2afe: 0x0040, 0x2aff: 0x0040, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x0040, 0x2b01: 0x0040, 0x2b02: 0x0040, 0x2b03: 0x0040, 0x2b04: 0x0040, 0x2b05: 0x0040, + 0x2b06: 0x0040, 0x2b0b: 0x0040, + 0x2b0c: 0x0040, 0x2b0d: 0x0040, 0x2b0e: 0x0040, 0x2b0f: 0x0040, 0x2b10: 0x0040, 0x2b11: 0x0040, + 0x2b12: 0x0040, 0x2b13: 0x0040, 0x2b14: 0x0040, 0x2b15: 0x0040, 0x2b16: 0x0040, 0x2b17: 0x0040, + 0x2b18: 0x0040, 0x2b19: 0x0040, 0x2b1a: 0x0040, 0x2b1b: 0x0040, 0x2b1c: 0x0040, 0x2b1d: 0x0040, + 0x2b1e: 0x0040, 0x2b1f: 0x0040, 0x2b20: 0x0040, 0x2b21: 0x0040, 0x2b22: 0x0040, 0x2b23: 0x0040, + 0x2b24: 0x0040, 0x2b25: 0x0040, 0x2b26: 0x0040, 0x2b27: 0x0040, 0x2b28: 0x0040, 0x2b29: 0x0040, + 0x2b2a: 0x0040, 0x2b2b: 0x0040, 0x2b2c: 0x0040, 0x2b2d: 0x0040, 0x2b2e: 0x0040, 0x2b2f: 0x0040, + 0x2b30: 0x0040, 0x2b31: 0x0040, 0x2b32: 0x0040, 0x2b33: 0x0040, 0x2b34: 0x0040, 0x2b35: 0x0040, + 0x2b36: 0x0040, 0x2b37: 0x0040, 0x2b38: 0x0040, 0x2b39: 0x0040, 0x2b3a: 0x0040, 0x2b3b: 0x0040, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x008c, 0x2b41: 0x008c, 0x2b42: 0x008c, 0x2b43: 0x008c, 0x2b44: 0x008c, 0x2b45: 0x008c, + 0x2b46: 0x008c, 0x2b47: 0x008c, 0x2b48: 0x008c, 0x2b49: 0x008c, 0x2b4a: 0x008c, 0x2b4b: 0x008c, + 0x2b4c: 0x008c, 0x2b4d: 0x008c, 0x2b4e: 0x00cc, 0x2b4f: 0x00cc, 0x2b50: 0x008c, 0x2b51: 0x00cc, + 0x2b52: 0x008c, 0x2b53: 0x00cc, 0x2b54: 0x00cc, 0x2b55: 0x008c, 0x2b56: 0x008c, 0x2b57: 0x008c, + 0x2b58: 0x008c, 0x2b59: 0x008c, 0x2b5a: 0x008c, 0x2b5b: 0x008c, 0x2b5c: 0x008c, 0x2b5d: 0x008c, + 0x2b5e: 0x008c, 0x2b5f: 0x00cc, 0x2b60: 0x008c, 0x2b61: 0x00cc, 0x2b62: 0x008c, 0x2b63: 0x00cc, + 0x2b64: 0x00cc, 0x2b65: 0x008c, 0x2b66: 0x008c, 0x2b67: 0x00cc, 0x2b68: 0x00cc, 0x2b69: 0x00cc, + 0x2b6a: 0x008c, 0x2b6b: 0x008c, 0x2b6c: 0x008c, 0x2b6d: 0x008c, 0x2b6e: 0x008c, 0x2b6f: 0x008c, + 0x2b70: 0x008c, 0x2b71: 0x008c, 0x2b72: 0x008c, 0x2b73: 0x008c, 0x2b74: 0x008c, 0x2b75: 0x008c, + 0x2b76: 0x008c, 0x2b77: 0x008c, 0x2b78: 0x008c, 0x2b79: 0x008c, 0x2b7a: 0x008c, 0x2b7b: 0x008c, + 0x2b7c: 0x008c, 0x2b7d: 0x008c, 0x2b7e: 0x008c, 0x2b7f: 0x008c, + // Block 0xae, offset 0x2b80 + 0x2b80: 0x008c, 0x2b81: 0x008c, 0x2b82: 0x008c, 0x2b83: 0x008c, 0x2b84: 0x008c, 0x2b85: 0x008c, + 0x2b86: 0x008c, 0x2b87: 0x008c, 0x2b88: 0x008c, 0x2b89: 0x008c, 0x2b8a: 0x008c, 0x2b8b: 0x008c, + 0x2b8c: 0x008c, 0x2b8d: 0x008c, 0x2b8e: 0x008c, 0x2b8f: 0x008c, 0x2b90: 0x008c, 0x2b91: 0x008c, + 0x2b92: 0x008c, 0x2b93: 0x008c, 0x2b94: 0x008c, 0x2b95: 0x008c, 0x2b96: 0x008c, 0x2b97: 0x008c, + 0x2b98: 0x008c, 0x2b99: 0x008c, 0x2b9a: 0x008c, 0x2b9b: 0x008c, 0x2b9c: 0x008c, 0x2b9d: 0x008c, + 0x2b9e: 0x008c, 0x2b9f: 0x008c, 0x2ba0: 0x008c, 0x2ba1: 0x008c, 0x2ba2: 0x008c, 0x2ba3: 0x008c, + 0x2ba4: 0x008c, 0x2ba5: 0x008c, 0x2ba6: 0x008c, 0x2ba7: 0x008c, 0x2ba8: 0x008c, 0x2ba9: 0x008c, + 0x2baa: 0x008c, 0x2bab: 0x008c, 0x2bac: 0x008c, 0x2bad: 0x008c, + 0x2bb0: 0x008c, 0x2bb1: 0x008c, 0x2bb2: 0x008c, 0x2bb3: 0x008c, 0x2bb4: 0x008c, 0x2bb5: 0x008c, + 0x2bb6: 0x008c, 0x2bb7: 0x008c, 0x2bb8: 0x008c, 0x2bb9: 0x008c, 0x2bba: 0x008c, 0x2bbb: 0x008c, + 0x2bbc: 0x008c, 0x2bbd: 0x008c, 0x2bbe: 0x008c, 0x2bbf: 0x008c, + // Block 0xaf, offset 0x2bc0 + 0x2bc0: 0x008c, 0x2bc1: 0x008c, 0x2bc2: 0x008c, 0x2bc3: 0x008c, 0x2bc4: 0x008c, 0x2bc5: 0x008c, + 0x2bc6: 0x008c, 0x2bc7: 0x008c, 0x2bc8: 0x008c, 0x2bc9: 0x008c, 0x2bca: 0x008c, 0x2bcb: 0x008c, + 0x2bcc: 0x008c, 0x2bcd: 0x008c, 0x2bce: 0x008c, 0x2bcf: 0x008c, 0x2bd0: 0x008c, 0x2bd1: 0x008c, + 0x2bd2: 0x008c, 0x2bd3: 0x008c, 0x2bd4: 0x008c, 0x2bd5: 0x008c, 0x2bd6: 0x008c, 0x2bd7: 0x008c, + 0x2bd8: 0x008c, 0x2bd9: 0x008c, + // Block 0xb0, offset 0x2c00 + 0x2c00: 0x0080, 0x2c01: 0x0080, 0x2c02: 0x0080, 0x2c03: 0x0080, 0x2c04: 0x0080, 0x2c05: 0x0080, + 0x2c06: 0x0080, + 0x2c13: 0x0080, 0x2c14: 0x0080, 0x2c15: 0x0080, 0x2c16: 0x0080, 0x2c17: 0x0080, + 0x2c1d: 0x008a, + 0x2c1e: 0x00cb, 0x2c1f: 0x008a, 0x2c20: 0x008a, 0x2c21: 0x008a, 0x2c22: 0x008a, 0x2c23: 0x008a, + 0x2c24: 0x008a, 0x2c25: 0x008a, 0x2c26: 0x008a, 0x2c27: 0x008a, 0x2c28: 0x008a, 0x2c29: 0x008a, + 0x2c2a: 0x008a, 0x2c2b: 0x008a, 0x2c2c: 0x008a, 0x2c2d: 0x008a, 0x2c2e: 0x008a, 0x2c2f: 0x008a, + 0x2c30: 0x008a, 0x2c31: 0x008a, 0x2c32: 0x008a, 0x2c33: 0x008a, 0x2c34: 0x008a, 0x2c35: 0x008a, + 0x2c36: 0x008a, 0x2c38: 0x008a, 0x2c39: 0x008a, 0x2c3a: 0x008a, 0x2c3b: 0x008a, + 0x2c3c: 0x008a, 0x2c3e: 0x008a, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x008a, 0x2c41: 0x008a, 0x2c43: 0x008a, 0x2c44: 0x008a, + 0x2c46: 0x008a, 0x2c47: 0x008a, 0x2c48: 0x008a, 0x2c49: 0x008a, 0x2c4a: 0x008a, 0x2c4b: 0x008a, + 0x2c4c: 0x008a, 0x2c4d: 0x008a, 0x2c4e: 0x008a, 0x2c4f: 0x008a, 0x2c50: 0x0080, 0x2c51: 0x0080, + 0x2c52: 0x0080, 0x2c53: 0x0080, 0x2c54: 0x0080, 0x2c55: 0x0080, 0x2c56: 0x0080, 0x2c57: 0x0080, + 0x2c58: 0x0080, 0x2c59: 0x0080, 0x2c5a: 0x0080, 0x2c5b: 0x0080, 0x2c5c: 0x0080, 0x2c5d: 0x0080, + 0x2c5e: 0x0080, 0x2c5f: 0x0080, 0x2c60: 0x0080, 0x2c61: 0x0080, 0x2c62: 0x0080, 0x2c63: 0x0080, + 0x2c64: 0x0080, 0x2c65: 0x0080, 0x2c66: 0x0080, 0x2c67: 0x0080, 0x2c68: 0x0080, 0x2c69: 0x0080, + 0x2c6a: 0x0080, 0x2c6b: 0x0080, 0x2c6c: 0x0080, 0x2c6d: 0x0080, 0x2c6e: 0x0080, 0x2c6f: 0x0080, + 0x2c70: 0x0080, 0x2c71: 0x0080, 0x2c72: 0x0080, 0x2c73: 0x0080, 0x2c74: 0x0080, 0x2c75: 0x0080, + 0x2c76: 0x0080, 0x2c77: 0x0080, 0x2c78: 0x0080, 0x2c79: 0x0080, 0x2c7a: 0x0080, 0x2c7b: 0x0080, + 0x2c7c: 0x0080, 0x2c7d: 0x0080, 0x2c7e: 0x0080, 0x2c7f: 0x0080, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0x0080, 0x2c81: 0x0080, + 0x2c93: 0x0080, 0x2c94: 0x0080, 0x2c95: 0x0080, 0x2c96: 0x0080, 0x2c97: 0x0080, + 0x2c98: 0x0080, 0x2c99: 0x0080, 0x2c9a: 0x0080, 0x2c9b: 0x0080, 0x2c9c: 0x0080, 0x2c9d: 0x0080, + 0x2c9e: 0x0080, 0x2c9f: 0x0080, 0x2ca0: 0x0080, 0x2ca1: 0x0080, 0x2ca2: 0x0080, 0x2ca3: 0x0080, + 0x2ca4: 0x0080, 0x2ca5: 0x0080, 0x2ca6: 0x0080, 0x2ca7: 0x0080, 0x2ca8: 0x0080, 0x2ca9: 0x0080, + 0x2caa: 0x0080, 0x2cab: 0x0080, 0x2cac: 0x0080, 0x2cad: 0x0080, 0x2cae: 0x0080, 0x2caf: 0x0080, + 0x2cb0: 0x0080, 0x2cb1: 0x0080, 0x2cb2: 0x0080, 0x2cb3: 0x0080, 0x2cb4: 0x0080, 0x2cb5: 0x0080, + 0x2cb6: 0x0080, 0x2cb7: 0x0080, 0x2cb8: 0x0080, 0x2cb9: 0x0080, 0x2cba: 0x0080, 0x2cbb: 0x0080, + 0x2cbc: 0x0080, 0x2cbd: 0x0080, 0x2cbe: 0x0080, 0x2cbf: 0x0080, + // Block 0xb3, offset 0x2cc0 + 0x2cd0: 0x0080, 0x2cd1: 0x0080, + 0x2cd2: 0x0080, 0x2cd3: 0x0080, 0x2cd4: 0x0080, 0x2cd5: 0x0080, 0x2cd6: 0x0080, 0x2cd7: 0x0080, + 0x2cd8: 0x0080, 0x2cd9: 0x0080, 0x2cda: 0x0080, 0x2cdb: 0x0080, 0x2cdc: 0x0080, 0x2cdd: 0x0080, + 0x2cde: 0x0080, 0x2cdf: 0x0080, 0x2ce0: 0x0080, 0x2ce1: 0x0080, 0x2ce2: 0x0080, 0x2ce3: 0x0080, + 0x2ce4: 0x0080, 0x2ce5: 0x0080, 0x2ce6: 0x0080, 0x2ce7: 0x0080, 0x2ce8: 0x0080, 0x2ce9: 0x0080, + 0x2cea: 0x0080, 0x2ceb: 0x0080, 0x2cec: 0x0080, 0x2ced: 0x0080, 0x2cee: 0x0080, 0x2cef: 0x0080, + 0x2cf0: 0x0080, 0x2cf1: 0x0080, 0x2cf2: 0x0080, 0x2cf3: 0x0080, 0x2cf4: 0x0080, 0x2cf5: 0x0080, + 0x2cf6: 0x0080, 0x2cf7: 0x0080, 0x2cf8: 0x0080, 0x2cf9: 0x0080, 0x2cfa: 0x0080, 0x2cfb: 0x0080, + 0x2cfc: 0x0080, 0x2cfd: 0x0080, 0x2cfe: 0x0080, 0x2cff: 0x0080, + // Block 0xb4, offset 0x2d00 + 0x2d00: 0x0080, 0x2d01: 0x0080, 0x2d02: 0x0080, 0x2d03: 0x0080, 0x2d04: 0x0080, 0x2d05: 0x0080, + 0x2d06: 0x0080, 0x2d07: 0x0080, 0x2d08: 0x0080, 0x2d09: 0x0080, 0x2d0a: 0x0080, 0x2d0b: 0x0080, + 0x2d0c: 0x0080, 0x2d0d: 0x0080, 0x2d0e: 0x0080, 0x2d0f: 0x0080, + 0x2d12: 0x0080, 0x2d13: 0x0080, 0x2d14: 0x0080, 0x2d15: 0x0080, 0x2d16: 0x0080, 0x2d17: 0x0080, + 0x2d18: 0x0080, 0x2d19: 0x0080, 0x2d1a: 0x0080, 0x2d1b: 0x0080, 0x2d1c: 0x0080, 0x2d1d: 0x0080, + 0x2d1e: 0x0080, 0x2d1f: 0x0080, 0x2d20: 0x0080, 0x2d21: 0x0080, 0x2d22: 0x0080, 0x2d23: 0x0080, + 0x2d24: 0x0080, 0x2d25: 0x0080, 0x2d26: 0x0080, 0x2d27: 0x0080, 0x2d28: 0x0080, 0x2d29: 0x0080, + 0x2d2a: 0x0080, 0x2d2b: 0x0080, 0x2d2c: 0x0080, 0x2d2d: 0x0080, 0x2d2e: 0x0080, 0x2d2f: 0x0080, + 0x2d30: 0x0080, 0x2d31: 0x0080, 0x2d32: 0x0080, 0x2d33: 0x0080, 0x2d34: 0x0080, 0x2d35: 0x0080, + 0x2d36: 0x0080, 0x2d37: 0x0080, 0x2d38: 0x0080, 0x2d39: 0x0080, 0x2d3a: 0x0080, 0x2d3b: 0x0080, + 0x2d3c: 0x0080, 0x2d3d: 0x0080, 0x2d3e: 0x0080, 0x2d3f: 0x0080, + // Block 0xb5, offset 0x2d40 + 0x2d40: 0x0080, 0x2d41: 0x0080, 0x2d42: 0x0080, 0x2d43: 0x0080, 0x2d44: 0x0080, 0x2d45: 0x0080, + 0x2d46: 0x0080, 0x2d47: 0x0080, + 0x2d70: 0x0080, 0x2d71: 0x0080, 0x2d72: 0x0080, 0x2d73: 0x0080, 0x2d74: 0x0080, 0x2d75: 0x0080, + 0x2d76: 0x0080, 0x2d77: 0x0080, 0x2d78: 0x0080, 0x2d79: 0x0080, 0x2d7a: 0x0080, 0x2d7b: 0x0080, + 0x2d7c: 0x0080, 0x2d7d: 0x0080, + // Block 0xb6, offset 0x2d80 + 0x2d80: 0x0040, 0x2d81: 0x0040, 0x2d82: 0x0040, 0x2d83: 0x0040, 0x2d84: 0x0040, 0x2d85: 0x0040, + 0x2d86: 0x0040, 0x2d87: 0x0040, 0x2d88: 0x0040, 0x2d89: 0x0040, 0x2d8a: 0x0040, 0x2d8b: 0x0040, + 0x2d8c: 0x0040, 0x2d8d: 0x0040, 0x2d8e: 0x0040, 0x2d8f: 0x0040, 0x2d90: 0x0080, 0x2d91: 0x0080, + 0x2d92: 0x0080, 0x2d93: 0x0080, 0x2d94: 0x0080, 0x2d95: 0x0080, 0x2d96: 0x0080, 0x2d97: 0x0080, + 0x2d98: 0x0080, 0x2d99: 0x0080, + 0x2da0: 0x00c3, 0x2da1: 0x00c3, 0x2da2: 0x00c3, 0x2da3: 0x00c3, + 0x2da4: 0x00c3, 0x2da5: 0x00c3, 0x2da6: 0x00c3, 0x2da7: 0x00c3, 0x2da8: 0x00c3, 0x2da9: 0x00c3, + 0x2daa: 0x00c3, 0x2dab: 0x00c3, 0x2dac: 0x00c3, 0x2dad: 0x00c3, 0x2dae: 0x00c3, 0x2daf: 0x00c3, + 0x2db0: 0x0080, 0x2db1: 0x0080, 0x2db2: 0x0080, 0x2db3: 0x0080, 0x2db4: 0x0080, 0x2db5: 0x0080, + 0x2db6: 0x0080, 0x2db7: 0x0080, 0x2db8: 0x0080, 0x2db9: 0x0080, 0x2dba: 0x0080, 0x2dbb: 0x0080, + 0x2dbc: 0x0080, 0x2dbd: 0x0080, 0x2dbe: 0x0080, 0x2dbf: 0x0080, + // Block 0xb7, offset 0x2dc0 + 0x2dc0: 0x0080, 0x2dc1: 0x0080, 0x2dc2: 0x0080, 0x2dc3: 0x0080, 0x2dc4: 0x0080, 0x2dc5: 0x0080, + 0x2dc6: 0x0080, 0x2dc7: 0x0080, 0x2dc8: 0x0080, 0x2dc9: 0x0080, 0x2dca: 0x0080, 0x2dcb: 0x0080, + 0x2dcc: 0x0080, 0x2dcd: 0x0080, 0x2dce: 0x0080, 0x2dcf: 0x0080, 0x2dd0: 0x0080, 0x2dd1: 0x0080, + 0x2dd2: 0x0080, 0x2dd4: 0x0080, 0x2dd5: 0x0080, 0x2dd6: 0x0080, 0x2dd7: 0x0080, + 0x2dd8: 0x0080, 0x2dd9: 0x0080, 0x2dda: 0x0080, 0x2ddb: 0x0080, 0x2ddc: 0x0080, 0x2ddd: 0x0080, + 0x2dde: 0x0080, 0x2ddf: 0x0080, 0x2de0: 0x0080, 0x2de1: 0x0080, 0x2de2: 0x0080, 0x2de3: 0x0080, + 0x2de4: 0x0080, 0x2de5: 0x0080, 0x2de6: 0x0080, 0x2de8: 0x0080, 0x2de9: 0x0080, + 0x2dea: 0x0080, 0x2deb: 0x0080, + 0x2df0: 0x0080, 0x2df1: 0x0080, 0x2df2: 0x0080, 0x2df3: 0x00c0, 0x2df4: 0x0080, + 0x2df6: 0x0080, 0x2df7: 0x0080, 0x2df8: 0x0080, 0x2df9: 0x0080, 0x2dfa: 0x0080, 0x2dfb: 0x0080, + 0x2dfc: 0x0080, 0x2dfd: 0x0080, 0x2dfe: 0x0080, 0x2dff: 0x0080, + // Block 0xb8, offset 0x2e00 + 0x2e00: 0x0080, 0x2e01: 0x0080, 0x2e02: 0x0080, 0x2e03: 0x0080, 0x2e04: 0x0080, 0x2e05: 0x0080, + 0x2e06: 0x0080, 0x2e07: 0x0080, 0x2e08: 0x0080, 0x2e09: 0x0080, 0x2e0a: 0x0080, 0x2e0b: 0x0080, + 0x2e0c: 0x0080, 0x2e0d: 0x0080, 0x2e0e: 0x0080, 0x2e0f: 0x0080, 0x2e10: 0x0080, 0x2e11: 0x0080, + 0x2e12: 0x0080, 0x2e13: 0x0080, 0x2e14: 0x0080, 0x2e15: 0x0080, 0x2e16: 0x0080, 0x2e17: 0x0080, + 0x2e18: 0x0080, 0x2e19: 0x0080, 0x2e1a: 0x0080, 0x2e1b: 0x0080, 0x2e1c: 0x0080, 0x2e1d: 0x0080, + 0x2e1e: 0x0080, 0x2e1f: 0x0080, 0x2e20: 0x0080, 0x2e21: 0x0080, 0x2e22: 0x0080, 0x2e23: 0x0080, + 0x2e24: 0x0080, 0x2e25: 0x0080, 0x2e26: 0x0080, 0x2e27: 0x0080, 0x2e28: 0x0080, 0x2e29: 0x0080, + 0x2e2a: 0x0080, 0x2e2b: 0x0080, 0x2e2c: 0x0080, 0x2e2d: 0x0080, 0x2e2e: 0x0080, 0x2e2f: 0x0080, + 0x2e30: 0x0080, 0x2e31: 0x0080, 0x2e32: 0x0080, 0x2e33: 0x0080, 0x2e34: 0x0080, 0x2e35: 0x0080, + 0x2e36: 0x0080, 0x2e37: 0x0080, 0x2e38: 0x0080, 0x2e39: 0x0080, 0x2e3a: 0x0080, 0x2e3b: 0x0080, + 0x2e3c: 0x0080, 0x2e3f: 0x0040, + // Block 0xb9, offset 0x2e40 + 0x2e41: 0x0080, 0x2e42: 0x0080, 0x2e43: 0x0080, 0x2e44: 0x0080, 0x2e45: 0x0080, + 0x2e46: 0x0080, 0x2e47: 0x0080, 0x2e48: 0x0080, 0x2e49: 0x0080, 0x2e4a: 0x0080, 0x2e4b: 0x0080, + 0x2e4c: 0x0080, 0x2e4d: 0x0080, 0x2e4e: 0x0080, 0x2e4f: 0x0080, 0x2e50: 0x0080, 0x2e51: 0x0080, + 0x2e52: 0x0080, 0x2e53: 0x0080, 0x2e54: 0x0080, 0x2e55: 0x0080, 0x2e56: 0x0080, 0x2e57: 0x0080, + 0x2e58: 0x0080, 0x2e59: 0x0080, 0x2e5a: 0x0080, 0x2e5b: 0x0080, 0x2e5c: 0x0080, 0x2e5d: 0x0080, + 0x2e5e: 0x0080, 0x2e5f: 0x0080, 0x2e60: 0x0080, 0x2e61: 0x0080, 0x2e62: 0x0080, 0x2e63: 0x0080, + 0x2e64: 0x0080, 0x2e65: 0x0080, 0x2e66: 0x0080, 0x2e67: 0x0080, 0x2e68: 0x0080, 0x2e69: 0x0080, + 0x2e6a: 0x0080, 0x2e6b: 0x0080, 0x2e6c: 0x0080, 0x2e6d: 0x0080, 0x2e6e: 0x0080, 0x2e6f: 0x0080, + 0x2e70: 0x0080, 0x2e71: 0x0080, 0x2e72: 0x0080, 0x2e73: 0x0080, 0x2e74: 0x0080, 0x2e75: 0x0080, + 0x2e76: 0x0080, 0x2e77: 0x0080, 0x2e78: 0x0080, 0x2e79: 0x0080, 0x2e7a: 0x0080, 0x2e7b: 0x0080, + 0x2e7c: 0x0080, 0x2e7d: 0x0080, 0x2e7e: 0x0080, 0x2e7f: 0x0080, + // Block 0xba, offset 0x2e80 + 0x2e80: 0x0080, 0x2e81: 0x0080, 0x2e82: 0x0080, 0x2e83: 0x0080, 0x2e84: 0x0080, 0x2e85: 0x0080, + 0x2e86: 0x0080, 0x2e87: 0x0080, 0x2e88: 0x0080, 0x2e89: 0x0080, 0x2e8a: 0x0080, 0x2e8b: 0x0080, + 0x2e8c: 0x0080, 0x2e8d: 0x0080, 0x2e8e: 0x0080, 0x2e8f: 0x0080, 0x2e90: 0x0080, 0x2e91: 0x0080, + 0x2e92: 0x0080, 0x2e93: 0x0080, 0x2e94: 0x0080, 0x2e95: 0x0080, 0x2e96: 0x0080, 0x2e97: 0x0080, + 0x2e98: 0x0080, 0x2e99: 0x0080, 0x2e9a: 0x0080, 0x2e9b: 0x0080, 0x2e9c: 0x0080, 0x2e9d: 0x0080, + 0x2e9e: 0x0080, 0x2e9f: 0x0080, 0x2ea0: 0x0080, 0x2ea1: 0x0080, 0x2ea2: 0x0080, 0x2ea3: 0x0080, + 0x2ea4: 0x0080, 0x2ea5: 0x0080, 0x2ea6: 0x008c, 0x2ea7: 0x008c, 0x2ea8: 0x008c, 0x2ea9: 0x008c, + 0x2eaa: 0x008c, 0x2eab: 0x008c, 0x2eac: 0x008c, 0x2ead: 0x008c, 0x2eae: 0x008c, 0x2eaf: 0x008c, + 0x2eb0: 0x0080, 0x2eb1: 0x008c, 0x2eb2: 0x008c, 0x2eb3: 0x008c, 0x2eb4: 0x008c, 0x2eb5: 0x008c, + 0x2eb6: 0x008c, 0x2eb7: 0x008c, 0x2eb8: 0x008c, 0x2eb9: 0x008c, 0x2eba: 0x008c, 0x2ebb: 0x008c, + 0x2ebc: 0x008c, 0x2ebd: 0x008c, 0x2ebe: 0x008c, 0x2ebf: 0x008c, + // Block 0xbb, offset 0x2ec0 + 0x2ec0: 0x008c, 0x2ec1: 0x008c, 0x2ec2: 0x008c, 0x2ec3: 0x008c, 0x2ec4: 0x008c, 0x2ec5: 0x008c, + 0x2ec6: 0x008c, 0x2ec7: 0x008c, 0x2ec8: 0x008c, 0x2ec9: 0x008c, 0x2eca: 0x008c, 0x2ecb: 0x008c, + 0x2ecc: 0x008c, 0x2ecd: 0x008c, 0x2ece: 0x008c, 0x2ecf: 0x008c, 0x2ed0: 0x008c, 0x2ed1: 0x008c, + 0x2ed2: 0x008c, 0x2ed3: 0x008c, 0x2ed4: 0x008c, 0x2ed5: 0x008c, 0x2ed6: 0x008c, 0x2ed7: 0x008c, + 0x2ed8: 0x008c, 0x2ed9: 0x008c, 0x2eda: 0x008c, 0x2edb: 0x008c, 0x2edc: 0x008c, 0x2edd: 0x008c, + 0x2ede: 0x0080, 0x2edf: 0x0080, 0x2ee0: 0x0040, 0x2ee1: 0x0080, 0x2ee2: 0x0080, 0x2ee3: 0x0080, + 0x2ee4: 0x0080, 0x2ee5: 0x0080, 0x2ee6: 0x0080, 0x2ee7: 0x0080, 0x2ee8: 0x0080, 0x2ee9: 0x0080, + 0x2eea: 0x0080, 0x2eeb: 0x0080, 0x2eec: 0x0080, 0x2eed: 0x0080, 0x2eee: 0x0080, 0x2eef: 0x0080, + 0x2ef0: 0x0080, 0x2ef1: 0x0080, 0x2ef2: 0x0080, 0x2ef3: 0x0080, 0x2ef4: 0x0080, 0x2ef5: 0x0080, + 0x2ef6: 0x0080, 0x2ef7: 0x0080, 0x2ef8: 0x0080, 0x2ef9: 0x0080, 0x2efa: 0x0080, 0x2efb: 0x0080, + 0x2efc: 0x0080, 0x2efd: 0x0080, 0x2efe: 0x0080, + // Block 0xbc, offset 0x2f00 + 0x2f02: 0x0080, 0x2f03: 0x0080, 0x2f04: 0x0080, 0x2f05: 0x0080, + 0x2f06: 0x0080, 0x2f07: 0x0080, 0x2f0a: 0x0080, 0x2f0b: 0x0080, + 0x2f0c: 0x0080, 0x2f0d: 0x0080, 0x2f0e: 0x0080, 0x2f0f: 0x0080, + 0x2f12: 0x0080, 0x2f13: 0x0080, 0x2f14: 0x0080, 0x2f15: 0x0080, 0x2f16: 0x0080, 0x2f17: 0x0080, + 0x2f1a: 0x0080, 0x2f1b: 0x0080, 0x2f1c: 0x0080, + 0x2f20: 0x0080, 0x2f21: 0x0080, 0x2f22: 0x0080, 0x2f23: 0x0080, + 0x2f24: 0x0080, 0x2f25: 0x0080, 0x2f26: 0x0080, 0x2f28: 0x0080, 0x2f29: 0x0080, + 0x2f2a: 0x0080, 0x2f2b: 0x0080, 0x2f2c: 0x0080, 0x2f2d: 0x0080, 0x2f2e: 0x0080, + 0x2f39: 0x0040, 0x2f3a: 0x0040, 0x2f3b: 0x0040, + 0x2f3c: 0x0080, 0x2f3d: 0x0080, + // Block 0xbd, offset 0x2f40 + 0x2f40: 0x00c0, 0x2f41: 0x00c0, 0x2f42: 0x00c0, 0x2f43: 0x00c0, 0x2f44: 0x00c0, 0x2f45: 0x00c0, + 0x2f46: 0x00c0, 0x2f47: 0x00c0, 0x2f48: 0x00c0, 0x2f49: 0x00c0, 0x2f4a: 0x00c0, 0x2f4b: 0x00c0, + 0x2f4d: 0x00c0, 0x2f4e: 0x00c0, 0x2f4f: 0x00c0, 0x2f50: 0x00c0, 0x2f51: 0x00c0, + 0x2f52: 0x00c0, 0x2f53: 0x00c0, 0x2f54: 0x00c0, 0x2f55: 0x00c0, 0x2f56: 0x00c0, 0x2f57: 0x00c0, + 0x2f58: 0x00c0, 0x2f59: 0x00c0, 0x2f5a: 0x00c0, 0x2f5b: 0x00c0, 0x2f5c: 0x00c0, 0x2f5d: 0x00c0, + 0x2f5e: 0x00c0, 0x2f5f: 0x00c0, 0x2f60: 0x00c0, 0x2f61: 0x00c0, 0x2f62: 0x00c0, 0x2f63: 0x00c0, + 0x2f64: 0x00c0, 0x2f65: 0x00c0, 0x2f66: 0x00c0, 0x2f68: 0x00c0, 0x2f69: 0x00c0, + 0x2f6a: 0x00c0, 0x2f6b: 0x00c0, 0x2f6c: 0x00c0, 0x2f6d: 0x00c0, 0x2f6e: 0x00c0, 0x2f6f: 0x00c0, + 0x2f70: 0x00c0, 0x2f71: 0x00c0, 0x2f72: 0x00c0, 0x2f73: 0x00c0, 0x2f74: 0x00c0, 0x2f75: 0x00c0, + 0x2f76: 0x00c0, 0x2f77: 0x00c0, 0x2f78: 0x00c0, 0x2f79: 0x00c0, 0x2f7a: 0x00c0, + 0x2f7c: 0x00c0, 0x2f7d: 0x00c0, 0x2f7f: 0x00c0, + // Block 0xbe, offset 0x2f80 + 0x2f80: 0x00c0, 0x2f81: 0x00c0, 0x2f82: 0x00c0, 0x2f83: 0x00c0, 0x2f84: 0x00c0, 0x2f85: 0x00c0, + 0x2f86: 0x00c0, 0x2f87: 0x00c0, 0x2f88: 0x00c0, 0x2f89: 0x00c0, 0x2f8a: 0x00c0, 0x2f8b: 0x00c0, + 0x2f8c: 0x00c0, 0x2f8d: 0x00c0, 0x2f90: 0x00c0, 0x2f91: 0x00c0, + 0x2f92: 0x00c0, 0x2f93: 0x00c0, 0x2f94: 0x00c0, 0x2f95: 0x00c0, 0x2f96: 0x00c0, 0x2f97: 0x00c0, + 0x2f98: 0x00c0, 0x2f99: 0x00c0, 0x2f9a: 0x00c0, 0x2f9b: 0x00c0, 0x2f9c: 0x00c0, 0x2f9d: 0x00c0, + // Block 0xbf, offset 0x2fc0 + 0x2fc0: 0x00c0, 0x2fc1: 0x00c0, 0x2fc2: 0x00c0, 0x2fc3: 0x00c0, 0x2fc4: 0x00c0, 0x2fc5: 0x00c0, + 0x2fc6: 0x00c0, 0x2fc7: 0x00c0, 0x2fc8: 0x00c0, 0x2fc9: 0x00c0, 0x2fca: 0x00c0, 0x2fcb: 0x00c0, + 0x2fcc: 0x00c0, 0x2fcd: 0x00c0, 0x2fce: 0x00c0, 0x2fcf: 0x00c0, 0x2fd0: 0x00c0, 0x2fd1: 0x00c0, + 0x2fd2: 0x00c0, 0x2fd3: 0x00c0, 0x2fd4: 0x00c0, 0x2fd5: 0x00c0, 0x2fd6: 0x00c0, 0x2fd7: 0x00c0, + 0x2fd8: 0x00c0, 0x2fd9: 0x00c0, 0x2fda: 0x00c0, 0x2fdb: 0x00c0, 0x2fdc: 0x00c0, 0x2fdd: 0x00c0, + 0x2fde: 0x00c0, 0x2fdf: 0x00c0, 0x2fe0: 0x00c0, 0x2fe1: 0x00c0, 0x2fe2: 0x00c0, 0x2fe3: 0x00c0, + 0x2fe4: 0x00c0, 0x2fe5: 0x00c0, 0x2fe6: 0x00c0, 0x2fe7: 0x00c0, 0x2fe8: 0x00c0, 0x2fe9: 0x00c0, + 0x2fea: 0x00c0, 0x2feb: 0x00c0, 0x2fec: 0x00c0, 0x2fed: 0x00c0, 0x2fee: 0x00c0, 0x2fef: 0x00c0, + 0x2ff0: 0x00c0, 0x2ff1: 0x00c0, 0x2ff2: 0x00c0, 0x2ff3: 0x00c0, 0x2ff4: 0x00c0, 0x2ff5: 0x00c0, + 0x2ff6: 0x00c0, 0x2ff7: 0x00c0, 0x2ff8: 0x00c0, 0x2ff9: 0x00c0, 0x2ffa: 0x00c0, + // Block 0xc0, offset 0x3000 + 0x3000: 0x0080, 0x3001: 0x0080, 0x3002: 0x0080, + 0x3007: 0x0080, 0x3008: 0x0080, 0x3009: 0x0080, 0x300a: 0x0080, 0x300b: 0x0080, + 0x300c: 0x0080, 0x300d: 0x0080, 0x300e: 0x0080, 0x300f: 0x0080, 0x3010: 0x0080, 0x3011: 0x0080, + 0x3012: 0x0080, 0x3013: 0x0080, 0x3014: 0x0080, 0x3015: 0x0080, 0x3016: 0x0080, 0x3017: 0x0080, + 0x3018: 0x0080, 0x3019: 0x0080, 0x301a: 0x0080, 0x301b: 0x0080, 0x301c: 0x0080, 0x301d: 0x0080, + 0x301e: 0x0080, 0x301f: 0x0080, 0x3020: 0x0080, 0x3021: 0x0080, 0x3022: 0x0080, 0x3023: 0x0080, + 0x3024: 0x0080, 0x3025: 0x0080, 0x3026: 0x0080, 0x3027: 0x0080, 0x3028: 0x0080, 0x3029: 0x0080, + 0x302a: 0x0080, 0x302b: 0x0080, 0x302c: 0x0080, 0x302d: 0x0080, 0x302e: 0x0080, 0x302f: 0x0080, + 0x3030: 0x0080, 0x3031: 0x0080, 0x3032: 0x0080, 0x3033: 0x0080, + 0x3037: 0x0080, 0x3038: 0x0080, 0x3039: 0x0080, 0x303a: 0x0080, 0x303b: 0x0080, + 0x303c: 0x0080, 0x303d: 0x0080, 0x303e: 0x0080, 0x303f: 0x0080, + // Block 0xc1, offset 0x3040 + 0x3040: 0x0088, 0x3041: 0x0088, 0x3042: 0x0088, 0x3043: 0x0088, 0x3044: 0x0088, 0x3045: 0x0088, + 0x3046: 0x0088, 0x3047: 0x0088, 0x3048: 0x0088, 0x3049: 0x0088, 0x304a: 0x0088, 0x304b: 0x0088, + 0x304c: 0x0088, 0x304d: 0x0088, 0x304e: 0x0088, 0x304f: 0x0088, 0x3050: 0x0088, 0x3051: 0x0088, + 0x3052: 0x0088, 0x3053: 0x0088, 0x3054: 0x0088, 0x3055: 0x0088, 0x3056: 0x0088, 0x3057: 0x0088, + 0x3058: 0x0088, 0x3059: 0x0088, 0x305a: 0x0088, 0x305b: 0x0088, 0x305c: 0x0088, 0x305d: 0x0088, + 0x305e: 0x0088, 0x305f: 0x0088, 0x3060: 0x0088, 0x3061: 0x0088, 0x3062: 0x0088, 0x3063: 0x0088, + 0x3064: 0x0088, 0x3065: 0x0088, 0x3066: 0x0088, 0x3067: 0x0088, 0x3068: 0x0088, 0x3069: 0x0088, + 0x306a: 0x0088, 0x306b: 0x0088, 0x306c: 0x0088, 0x306d: 0x0088, 0x306e: 0x0088, 0x306f: 0x0088, + 0x3070: 0x0088, 0x3071: 0x0088, 0x3072: 0x0088, 0x3073: 0x0088, 0x3074: 0x0088, 0x3075: 0x0088, + 0x3076: 0x0088, 0x3077: 0x0088, 0x3078: 0x0088, 0x3079: 0x0088, 0x307a: 0x0088, 0x307b: 0x0088, + 0x307c: 0x0088, 0x307d: 0x0088, 0x307e: 0x0088, 0x307f: 0x0088, + // Block 0xc2, offset 0x3080 + 0x3080: 0x0088, 0x3081: 0x0088, 0x3082: 0x0088, 0x3083: 0x0088, 0x3084: 0x0088, 0x3085: 0x0088, + 0x3086: 0x0088, 0x3087: 0x0088, 0x3088: 0x0088, 0x3089: 0x0088, 0x308a: 0x0088, 0x308b: 0x0088, + 0x308c: 0x0088, 0x308d: 0x0088, 0x308e: 0x0088, 0x3090: 0x0080, 0x3091: 0x0080, + 0x3092: 0x0080, 0x3093: 0x0080, 0x3094: 0x0080, 0x3095: 0x0080, 0x3096: 0x0080, 0x3097: 0x0080, + 0x3098: 0x0080, 0x3099: 0x0080, 0x309a: 0x0080, 0x309b: 0x0080, + 0x30a0: 0x0088, + // Block 0xc3, offset 0x30c0 + 0x30d0: 0x0080, 0x30d1: 0x0080, + 0x30d2: 0x0080, 0x30d3: 0x0080, 0x30d4: 0x0080, 0x30d5: 0x0080, 0x30d6: 0x0080, 0x30d7: 0x0080, + 0x30d8: 0x0080, 0x30d9: 0x0080, 0x30da: 0x0080, 0x30db: 0x0080, 0x30dc: 0x0080, 0x30dd: 0x0080, + 0x30de: 0x0080, 0x30df: 0x0080, 0x30e0: 0x0080, 0x30e1: 0x0080, 0x30e2: 0x0080, 0x30e3: 0x0080, + 0x30e4: 0x0080, 0x30e5: 0x0080, 0x30e6: 0x0080, 0x30e7: 0x0080, 0x30e8: 0x0080, 0x30e9: 0x0080, + 0x30ea: 0x0080, 0x30eb: 0x0080, 0x30ec: 0x0080, 0x30ed: 0x0080, 0x30ee: 0x0080, 0x30ef: 0x0080, + 0x30f0: 0x0080, 0x30f1: 0x0080, 0x30f2: 0x0080, 0x30f3: 0x0080, 0x30f4: 0x0080, 0x30f5: 0x0080, + 0x30f6: 0x0080, 0x30f7: 0x0080, 0x30f8: 0x0080, 0x30f9: 0x0080, 0x30fa: 0x0080, 0x30fb: 0x0080, + 0x30fc: 0x0080, 0x30fd: 0x00c3, + // Block 0xc4, offset 0x3100 + 0x3100: 0x00c0, 0x3101: 0x00c0, 0x3102: 0x00c0, 0x3103: 0x00c0, 0x3104: 0x00c0, 0x3105: 0x00c0, + 0x3106: 0x00c0, 0x3107: 0x00c0, 0x3108: 0x00c0, 0x3109: 0x00c0, 0x310a: 0x00c0, 0x310b: 0x00c0, + 0x310c: 0x00c0, 0x310d: 0x00c0, 0x310e: 0x00c0, 0x310f: 0x00c0, 0x3110: 0x00c0, 0x3111: 0x00c0, + 0x3112: 0x00c0, 0x3113: 0x00c0, 0x3114: 0x00c0, 0x3115: 0x00c0, 0x3116: 0x00c0, 0x3117: 0x00c0, + 0x3118: 0x00c0, 0x3119: 0x00c0, 0x311a: 0x00c0, 0x311b: 0x00c0, 0x311c: 0x00c0, + 0x3120: 0x00c0, 0x3121: 0x00c0, 0x3122: 0x00c0, 0x3123: 0x00c0, + 0x3124: 0x00c0, 0x3125: 0x00c0, 0x3126: 0x00c0, 0x3127: 0x00c0, 0x3128: 0x00c0, 0x3129: 0x00c0, + 0x312a: 0x00c0, 0x312b: 0x00c0, 0x312c: 0x00c0, 0x312d: 0x00c0, 0x312e: 0x00c0, 0x312f: 0x00c0, + 0x3130: 0x00c0, 0x3131: 0x00c0, 0x3132: 0x00c0, 0x3133: 0x00c0, 0x3134: 0x00c0, 0x3135: 0x00c0, + 0x3136: 0x00c0, 0x3137: 0x00c0, 0x3138: 0x00c0, 0x3139: 0x00c0, 0x313a: 0x00c0, 0x313b: 0x00c0, + 0x313c: 0x00c0, 0x313d: 0x00c0, 0x313e: 0x00c0, 0x313f: 0x00c0, + // Block 0xc5, offset 0x3140 + 0x3140: 0x00c0, 0x3141: 0x00c0, 0x3142: 0x00c0, 0x3143: 0x00c0, 0x3144: 0x00c0, 0x3145: 0x00c0, + 0x3146: 0x00c0, 0x3147: 0x00c0, 0x3148: 0x00c0, 0x3149: 0x00c0, 0x314a: 0x00c0, 0x314b: 0x00c0, + 0x314c: 0x00c0, 0x314d: 0x00c0, 0x314e: 0x00c0, 0x314f: 0x00c0, 0x3150: 0x00c0, + 0x3160: 0x00c3, 0x3161: 0x0080, 0x3162: 0x0080, 0x3163: 0x0080, + 0x3164: 0x0080, 0x3165: 0x0080, 0x3166: 0x0080, 0x3167: 0x0080, 0x3168: 0x0080, 0x3169: 0x0080, + 0x316a: 0x0080, 0x316b: 0x0080, 0x316c: 0x0080, 0x316d: 0x0080, 0x316e: 0x0080, 0x316f: 0x0080, + 0x3170: 0x0080, 0x3171: 0x0080, 0x3172: 0x0080, 0x3173: 0x0080, 0x3174: 0x0080, 0x3175: 0x0080, + 0x3176: 0x0080, 0x3177: 0x0080, 0x3178: 0x0080, 0x3179: 0x0080, 0x317a: 0x0080, 0x317b: 0x0080, + // Block 0xc6, offset 0x3180 + 0x3180: 0x00c0, 0x3181: 0x00c0, 0x3182: 0x00c0, 0x3183: 0x00c0, 0x3184: 0x00c0, 0x3185: 0x00c0, + 0x3186: 0x00c0, 0x3187: 0x00c0, 0x3188: 0x00c0, 0x3189: 0x00c0, 0x318a: 0x00c0, 0x318b: 0x00c0, + 0x318c: 0x00c0, 0x318d: 0x00c0, 0x318e: 0x00c0, 0x318f: 0x00c0, 0x3190: 0x00c0, 0x3191: 0x00c0, + 0x3192: 0x00c0, 0x3193: 0x00c0, 0x3194: 0x00c0, 0x3195: 0x00c0, 0x3196: 0x00c0, 0x3197: 0x00c0, + 0x3198: 0x00c0, 0x3199: 0x00c0, 0x319a: 0x00c0, 0x319b: 0x00c0, 0x319c: 0x00c0, 0x319d: 0x00c0, + 0x319e: 0x00c0, 0x319f: 0x00c0, 0x31a0: 0x0080, 0x31a1: 0x0080, 0x31a2: 0x0080, 0x31a3: 0x0080, + 0x31ad: 0x00c0, 0x31ae: 0x00c0, 0x31af: 0x00c0, + 0x31b0: 0x00c0, 0x31b1: 0x00c0, 0x31b2: 0x00c0, 0x31b3: 0x00c0, 0x31b4: 0x00c0, 0x31b5: 0x00c0, + 0x31b6: 0x00c0, 0x31b7: 0x00c0, 0x31b8: 0x00c0, 0x31b9: 0x00c0, 0x31ba: 0x00c0, 0x31bb: 0x00c0, + 0x31bc: 0x00c0, 0x31bd: 0x00c0, 0x31be: 0x00c0, 0x31bf: 0x00c0, + // Block 0xc7, offset 0x31c0 + 0x31c0: 0x00c0, 0x31c1: 0x0080, 0x31c2: 0x00c0, 0x31c3: 0x00c0, 0x31c4: 0x00c0, 0x31c5: 0x00c0, + 0x31c6: 0x00c0, 0x31c7: 0x00c0, 0x31c8: 0x00c0, 0x31c9: 0x00c0, 0x31ca: 0x0080, + 0x31d0: 0x00c0, 0x31d1: 0x00c0, + 0x31d2: 0x00c0, 0x31d3: 0x00c0, 0x31d4: 0x00c0, 0x31d5: 0x00c0, 0x31d6: 0x00c0, 0x31d7: 0x00c0, + 0x31d8: 0x00c0, 0x31d9: 0x00c0, 0x31da: 0x00c0, 0x31db: 0x00c0, 0x31dc: 0x00c0, 0x31dd: 0x00c0, + 0x31de: 0x00c0, 0x31df: 0x00c0, 0x31e0: 0x00c0, 0x31e1: 0x00c0, 0x31e2: 0x00c0, 0x31e3: 0x00c0, + 0x31e4: 0x00c0, 0x31e5: 0x00c0, 0x31e6: 0x00c0, 0x31e7: 0x00c0, 0x31e8: 0x00c0, 0x31e9: 0x00c0, + 0x31ea: 0x00c0, 0x31eb: 0x00c0, 0x31ec: 0x00c0, 0x31ed: 0x00c0, 0x31ee: 0x00c0, 0x31ef: 0x00c0, + 0x31f0: 0x00c0, 0x31f1: 0x00c0, 0x31f2: 0x00c0, 0x31f3: 0x00c0, 0x31f4: 0x00c0, 0x31f5: 0x00c0, + 0x31f6: 0x00c3, 0x31f7: 0x00c3, 0x31f8: 0x00c3, 0x31f9: 0x00c3, 0x31fa: 0x00c3, + // Block 0xc8, offset 0x3200 + 0x3200: 0x00c0, 0x3201: 0x00c0, 0x3202: 0x00c0, 0x3203: 0x00c0, 0x3204: 0x00c0, 0x3205: 0x00c0, + 0x3206: 0x00c0, 0x3207: 0x00c0, 0x3208: 0x00c0, 0x3209: 0x00c0, 0x320a: 0x00c0, 0x320b: 0x00c0, + 0x320c: 0x00c0, 0x320d: 0x00c0, 0x320e: 0x00c0, 0x320f: 0x00c0, 0x3210: 0x00c0, 0x3211: 0x00c0, + 0x3212: 0x00c0, 0x3213: 0x00c0, 0x3214: 0x00c0, 0x3215: 0x00c0, 0x3216: 0x00c0, 0x3217: 0x00c0, + 0x3218: 0x00c0, 0x3219: 0x00c0, 0x321a: 0x00c0, 0x321b: 0x00c0, 0x321c: 0x00c0, 0x321d: 0x00c0, + 0x321f: 0x0080, 0x3220: 0x00c0, 0x3221: 0x00c0, 0x3222: 0x00c0, 0x3223: 0x00c0, + 0x3224: 0x00c0, 0x3225: 0x00c0, 0x3226: 0x00c0, 0x3227: 0x00c0, 0x3228: 0x00c0, 0x3229: 0x00c0, + 0x322a: 0x00c0, 0x322b: 0x00c0, 0x322c: 0x00c0, 0x322d: 0x00c0, 0x322e: 0x00c0, 0x322f: 0x00c0, + 0x3230: 0x00c0, 0x3231: 0x00c0, 0x3232: 0x00c0, 0x3233: 0x00c0, 0x3234: 0x00c0, 0x3235: 0x00c0, + 0x3236: 0x00c0, 0x3237: 0x00c0, 0x3238: 0x00c0, 0x3239: 0x00c0, 0x323a: 0x00c0, 0x323b: 0x00c0, + 0x323c: 0x00c0, 0x323d: 0x00c0, 0x323e: 0x00c0, 0x323f: 0x00c0, + // Block 0xc9, offset 0x3240 + 0x3240: 0x00c0, 0x3241: 0x00c0, 0x3242: 0x00c0, 0x3243: 0x00c0, + 0x3248: 0x00c0, 0x3249: 0x00c0, 0x324a: 0x00c0, 0x324b: 0x00c0, + 0x324c: 0x00c0, 0x324d: 0x00c0, 0x324e: 0x00c0, 0x324f: 0x00c0, 0x3250: 0x0080, 0x3251: 0x0080, + 0x3252: 0x0080, 0x3253: 0x0080, 0x3254: 0x0080, 0x3255: 0x0080, + // Block 0xca, offset 0x3280 + 0x3280: 0x00c0, 0x3281: 0x00c0, 0x3282: 0x00c0, 0x3283: 0x00c0, 0x3284: 0x00c0, 0x3285: 0x00c0, + 0x3286: 0x00c0, 0x3287: 0x00c0, 0x3288: 0x00c0, 0x3289: 0x00c0, 0x328a: 0x00c0, 0x328b: 0x00c0, + 0x328c: 0x00c0, 0x328d: 0x00c0, 0x328e: 0x00c0, 0x328f: 0x00c0, 0x3290: 0x00c0, 0x3291: 0x00c0, + 0x3292: 0x00c0, 0x3293: 0x00c0, 0x3294: 0x00c0, 0x3295: 0x00c0, 0x3296: 0x00c0, 0x3297: 0x00c0, + 0x3298: 0x00c0, 0x3299: 0x00c0, 0x329a: 0x00c0, 0x329b: 0x00c0, 0x329c: 0x00c0, 0x329d: 0x00c0, + 0x32a0: 0x00c0, 0x32a1: 0x00c0, 0x32a2: 0x00c0, 0x32a3: 0x00c0, + 0x32a4: 0x00c0, 0x32a5: 0x00c0, 0x32a6: 0x00c0, 0x32a7: 0x00c0, 0x32a8: 0x00c0, 0x32a9: 0x00c0, + 0x32b0: 0x00c0, 0x32b1: 0x00c0, 0x32b2: 0x00c0, 0x32b3: 0x00c0, 0x32b4: 0x00c0, 0x32b5: 0x00c0, + 0x32b6: 0x00c0, 0x32b7: 0x00c0, 0x32b8: 0x00c0, 0x32b9: 0x00c0, 0x32ba: 0x00c0, 0x32bb: 0x00c0, + 0x32bc: 0x00c0, 0x32bd: 0x00c0, 0x32be: 0x00c0, 0x32bf: 0x00c0, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x00c0, 0x32c1: 0x00c0, 0x32c2: 0x00c0, 0x32c3: 0x00c0, 0x32c4: 0x00c0, 0x32c5: 0x00c0, + 0x32c6: 0x00c0, 0x32c7: 0x00c0, 0x32c8: 0x00c0, 0x32c9: 0x00c0, 0x32ca: 0x00c0, 0x32cb: 0x00c0, + 0x32cc: 0x00c0, 0x32cd: 0x00c0, 0x32ce: 0x00c0, 0x32cf: 0x00c0, 0x32d0: 0x00c0, 0x32d1: 0x00c0, + 0x32d2: 0x00c0, 0x32d3: 0x00c0, + 0x32d8: 0x00c0, 0x32d9: 0x00c0, 0x32da: 0x00c0, 0x32db: 0x00c0, 0x32dc: 0x00c0, 0x32dd: 0x00c0, + 0x32de: 0x00c0, 0x32df: 0x00c0, 0x32e0: 0x00c0, 0x32e1: 0x00c0, 0x32e2: 0x00c0, 0x32e3: 0x00c0, + 0x32e4: 0x00c0, 0x32e5: 0x00c0, 0x32e6: 0x00c0, 0x32e7: 0x00c0, 0x32e8: 0x00c0, 0x32e9: 0x00c0, + 0x32ea: 0x00c0, 0x32eb: 0x00c0, 0x32ec: 0x00c0, 0x32ed: 0x00c0, 0x32ee: 0x00c0, 0x32ef: 0x00c0, + 0x32f0: 0x00c0, 0x32f1: 0x00c0, 0x32f2: 0x00c0, 0x32f3: 0x00c0, 0x32f4: 0x00c0, 0x32f5: 0x00c0, + 0x32f6: 0x00c0, 0x32f7: 0x00c0, 0x32f8: 0x00c0, 0x32f9: 0x00c0, 0x32fa: 0x00c0, 0x32fb: 0x00c0, + // Block 0xcc, offset 0x3300 + 0x3300: 0x00c0, 0x3301: 0x00c0, 0x3302: 0x00c0, 0x3303: 0x00c0, 0x3304: 0x00c0, 0x3305: 0x00c0, + 0x3306: 0x00c0, 0x3307: 0x00c0, 0x3308: 0x00c0, 0x3309: 0x00c0, 0x330a: 0x00c0, 0x330b: 0x00c0, + 0x330c: 0x00c0, 0x330d: 0x00c0, 0x330e: 0x00c0, 0x330f: 0x00c0, 0x3310: 0x00c0, 0x3311: 0x00c0, + 0x3312: 0x00c0, 0x3313: 0x00c0, 0x3314: 0x00c0, 0x3315: 0x00c0, 0x3316: 0x00c0, 0x3317: 0x00c0, + 0x3318: 0x00c0, 0x3319: 0x00c0, 0x331a: 0x00c0, 0x331b: 0x00c0, 0x331c: 0x00c0, 0x331d: 0x00c0, + 0x331e: 0x00c0, 0x331f: 0x00c0, 0x3320: 0x00c0, 0x3321: 0x00c0, 0x3322: 0x00c0, 0x3323: 0x00c0, + 0x3324: 0x00c0, 0x3325: 0x00c0, 0x3326: 0x00c0, 0x3327: 0x00c0, + 0x3330: 0x00c0, 0x3331: 0x00c0, 0x3332: 0x00c0, 0x3333: 0x00c0, 0x3334: 0x00c0, 0x3335: 0x00c0, + 0x3336: 0x00c0, 0x3337: 0x00c0, 0x3338: 0x00c0, 0x3339: 0x00c0, 0x333a: 0x00c0, 0x333b: 0x00c0, + 0x333c: 0x00c0, 0x333d: 0x00c0, 0x333e: 0x00c0, 0x333f: 0x00c0, + // Block 0xcd, offset 0x3340 + 0x3340: 0x00c0, 0x3341: 0x00c0, 0x3342: 0x00c0, 0x3343: 0x00c0, 0x3344: 0x00c0, 0x3345: 0x00c0, + 0x3346: 0x00c0, 0x3347: 0x00c0, 0x3348: 0x00c0, 0x3349: 0x00c0, 0x334a: 0x00c0, 0x334b: 0x00c0, + 0x334c: 0x00c0, 0x334d: 0x00c0, 0x334e: 0x00c0, 0x334f: 0x00c0, 0x3350: 0x00c0, 0x3351: 0x00c0, + 0x3352: 0x00c0, 0x3353: 0x00c0, 0x3354: 0x00c0, 0x3355: 0x00c0, 0x3356: 0x00c0, 0x3357: 0x00c0, + 0x3358: 0x00c0, 0x3359: 0x00c0, 0x335a: 0x00c0, 0x335b: 0x00c0, 0x335c: 0x00c0, 0x335d: 0x00c0, + 0x335e: 0x00c0, 0x335f: 0x00c0, 0x3360: 0x00c0, 0x3361: 0x00c0, 0x3362: 0x00c0, 0x3363: 0x00c0, + 0x336f: 0x0080, + // Block 0xce, offset 0x3380 + 0x3380: 0x00c0, 0x3381: 0x00c0, 0x3382: 0x00c0, 0x3383: 0x00c0, 0x3384: 0x00c0, 0x3385: 0x00c0, + 0x3386: 0x00c0, 0x3387: 0x00c0, 0x3388: 0x00c0, 0x3389: 0x00c0, 0x338a: 0x00c0, 0x338b: 0x00c0, + 0x338c: 0x00c0, 0x338d: 0x00c0, 0x338e: 0x00c0, 0x338f: 0x00c0, 0x3390: 0x00c0, 0x3391: 0x00c0, + 0x3392: 0x00c0, 0x3393: 0x00c0, 0x3394: 0x00c0, 0x3395: 0x00c0, 0x3396: 0x00c0, 0x3397: 0x00c0, + 0x3398: 0x00c0, 0x3399: 0x00c0, 0x339a: 0x00c0, 0x339b: 0x00c0, 0x339c: 0x00c0, 0x339d: 0x00c0, + 0x339e: 0x00c0, 0x339f: 0x00c0, 0x33a0: 0x00c0, 0x33a1: 0x00c0, 0x33a2: 0x00c0, 0x33a3: 0x00c0, + 0x33a4: 0x00c0, 0x33a5: 0x00c0, 0x33a6: 0x00c0, 0x33a7: 0x00c0, 0x33a8: 0x00c0, 0x33a9: 0x00c0, + 0x33aa: 0x00c0, 0x33ab: 0x00c0, 0x33ac: 0x00c0, 0x33ad: 0x00c0, 0x33ae: 0x00c0, 0x33af: 0x00c0, + 0x33b0: 0x00c0, 0x33b1: 0x00c0, 0x33b2: 0x00c0, 0x33b3: 0x00c0, 0x33b4: 0x00c0, 0x33b5: 0x00c0, + 0x33b6: 0x00c0, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x00c0, 0x33c1: 0x00c0, 0x33c2: 0x00c0, 0x33c3: 0x00c0, 0x33c4: 0x00c0, 0x33c5: 0x00c0, + 0x33c6: 0x00c0, 0x33c7: 0x00c0, 0x33c8: 0x00c0, 0x33c9: 0x00c0, 0x33ca: 0x00c0, 0x33cb: 0x00c0, + 0x33cc: 0x00c0, 0x33cd: 0x00c0, 0x33ce: 0x00c0, 0x33cf: 0x00c0, 0x33d0: 0x00c0, 0x33d1: 0x00c0, + 0x33d2: 0x00c0, 0x33d3: 0x00c0, 0x33d4: 0x00c0, 0x33d5: 0x00c0, + 0x33e0: 0x00c0, 0x33e1: 0x00c0, 0x33e2: 0x00c0, 0x33e3: 0x00c0, + 0x33e4: 0x00c0, 0x33e5: 0x00c0, 0x33e6: 0x00c0, 0x33e7: 0x00c0, + // Block 0xd0, offset 0x3400 + 0x3400: 0x00c0, 0x3401: 0x00c0, 0x3402: 0x00c0, 0x3403: 0x00c0, 0x3404: 0x00c0, 0x3405: 0x00c0, + 0x3408: 0x00c0, 0x340a: 0x00c0, 0x340b: 0x00c0, + 0x340c: 0x00c0, 0x340d: 0x00c0, 0x340e: 0x00c0, 0x340f: 0x00c0, 0x3410: 0x00c0, 0x3411: 0x00c0, + 0x3412: 0x00c0, 0x3413: 0x00c0, 0x3414: 0x00c0, 0x3415: 0x00c0, 0x3416: 0x00c0, 0x3417: 0x00c0, + 0x3418: 0x00c0, 0x3419: 0x00c0, 0x341a: 0x00c0, 0x341b: 0x00c0, 0x341c: 0x00c0, 0x341d: 0x00c0, + 0x341e: 0x00c0, 0x341f: 0x00c0, 0x3420: 0x00c0, 0x3421: 0x00c0, 0x3422: 0x00c0, 0x3423: 0x00c0, + 0x3424: 0x00c0, 0x3425: 0x00c0, 0x3426: 0x00c0, 0x3427: 0x00c0, 0x3428: 0x00c0, 0x3429: 0x00c0, + 0x342a: 0x00c0, 0x342b: 0x00c0, 0x342c: 0x00c0, 0x342d: 0x00c0, 0x342e: 0x00c0, 0x342f: 0x00c0, + 0x3430: 0x00c0, 0x3431: 0x00c0, 0x3432: 0x00c0, 0x3433: 0x00c0, 0x3434: 0x00c0, 0x3435: 0x00c0, + 0x3437: 0x00c0, 0x3438: 0x00c0, + 0x343c: 0x00c0, 0x343f: 0x00c0, + // Block 0xd1, offset 0x3440 + 0x3440: 0x00c0, 0x3441: 0x00c0, 0x3442: 0x00c0, 0x3443: 0x00c0, 0x3444: 0x00c0, 0x3445: 0x00c0, + 0x3446: 0x00c0, 0x3447: 0x00c0, 0x3448: 0x00c0, 0x3449: 0x00c0, 0x344a: 0x00c0, 0x344b: 0x00c0, + 0x344c: 0x00c0, 0x344d: 0x00c0, 0x344e: 0x00c0, 0x344f: 0x00c0, 0x3450: 0x00c0, 0x3451: 0x00c0, + 0x3452: 0x00c0, 0x3453: 0x00c0, 0x3454: 0x00c0, 0x3455: 0x00c0, 0x3457: 0x0080, + 0x3458: 0x0080, 0x3459: 0x0080, 0x345a: 0x0080, 0x345b: 0x0080, 0x345c: 0x0080, 0x345d: 0x0080, + 0x345e: 0x0080, 0x345f: 0x0080, 0x3460: 0x00c0, 0x3461: 0x00c0, 0x3462: 0x00c0, 0x3463: 0x00c0, + 0x3464: 0x00c0, 0x3465: 0x00c0, 0x3466: 0x00c0, 0x3467: 0x00c0, 0x3468: 0x00c0, 0x3469: 0x00c0, + 0x346a: 0x00c0, 0x346b: 0x00c0, 0x346c: 0x00c0, 0x346d: 0x00c0, 0x346e: 0x00c0, 0x346f: 0x00c0, + 0x3470: 0x00c0, 0x3471: 0x00c0, 0x3472: 0x00c0, 0x3473: 0x00c0, 0x3474: 0x00c0, 0x3475: 0x00c0, + 0x3476: 0x00c0, 0x3477: 0x0080, 0x3478: 0x0080, 0x3479: 0x0080, 0x347a: 0x0080, 0x347b: 0x0080, + 0x347c: 0x0080, 0x347d: 0x0080, 0x347e: 0x0080, 0x347f: 0x0080, + // Block 0xd2, offset 0x3480 + 0x3480: 0x00c0, 0x3481: 0x00c0, 0x3482: 0x00c0, 0x3483: 0x00c0, 0x3484: 0x00c0, 0x3485: 0x00c0, + 0x3486: 0x00c0, 0x3487: 0x00c0, 0x3488: 0x00c0, 0x3489: 0x00c0, 0x348a: 0x00c0, 0x348b: 0x00c0, + 0x348c: 0x00c0, 0x348d: 0x00c0, 0x348e: 0x00c0, 0x348f: 0x00c0, 0x3490: 0x00c0, 0x3491: 0x00c0, + 0x3492: 0x00c0, 0x3493: 0x00c0, 0x3494: 0x00c0, 0x3495: 0x00c0, 0x3496: 0x00c0, 0x3497: 0x00c0, + 0x3498: 0x00c0, 0x3499: 0x00c0, 0x349a: 0x00c0, 0x349b: 0x00c0, 0x349c: 0x00c0, 0x349d: 0x00c0, + 0x349e: 0x00c0, + 0x34a7: 0x0080, 0x34a8: 0x0080, 0x34a9: 0x0080, + 0x34aa: 0x0080, 0x34ab: 0x0080, 0x34ac: 0x0080, 0x34ad: 0x0080, 0x34ae: 0x0080, 0x34af: 0x0080, + // Block 0xd3, offset 0x34c0 + 0x34e0: 0x00c0, 0x34e1: 0x00c0, 0x34e2: 0x00c0, 0x34e3: 0x00c0, + 0x34e4: 0x00c0, 0x34e5: 0x00c0, 0x34e6: 0x00c0, 0x34e7: 0x00c0, 0x34e8: 0x00c0, 0x34e9: 0x00c0, + 0x34ea: 0x00c0, 0x34eb: 0x00c0, 0x34ec: 0x00c0, 0x34ed: 0x00c0, 0x34ee: 0x00c0, 0x34ef: 0x00c0, + 0x34f0: 0x00c0, 0x34f1: 0x00c0, 0x34f2: 0x00c0, 0x34f4: 0x00c0, 0x34f5: 0x00c0, + 0x34fb: 0x0080, + 0x34fc: 0x0080, 0x34fd: 0x0080, 0x34fe: 0x0080, 0x34ff: 0x0080, + // Block 0xd4, offset 0x3500 + 0x3500: 0x00c0, 0x3501: 0x00c0, 0x3502: 0x00c0, 0x3503: 0x00c0, 0x3504: 0x00c0, 0x3505: 0x00c0, + 0x3506: 0x00c0, 0x3507: 0x00c0, 0x3508: 0x00c0, 0x3509: 0x00c0, 0x350a: 0x00c0, 0x350b: 0x00c0, + 0x350c: 0x00c0, 0x350d: 0x00c0, 0x350e: 0x00c0, 0x350f: 0x00c0, 0x3510: 0x00c0, 0x3511: 0x00c0, + 0x3512: 0x00c0, 0x3513: 0x00c0, 0x3514: 0x00c0, 0x3515: 0x00c0, 0x3516: 0x0080, 0x3517: 0x0080, + 0x3518: 0x0080, 0x3519: 0x0080, 0x351a: 0x0080, 0x351b: 0x0080, + 0x351f: 0x0080, 0x3520: 0x00c0, 0x3521: 0x00c0, 0x3522: 0x00c0, 0x3523: 0x00c0, + 0x3524: 0x00c0, 0x3525: 0x00c0, 0x3526: 0x00c0, 0x3527: 0x00c0, 0x3528: 0x00c0, 0x3529: 0x00c0, + 0x352a: 0x00c0, 0x352b: 0x00c0, 0x352c: 0x00c0, 0x352d: 0x00c0, 0x352e: 0x00c0, 0x352f: 0x00c0, + 0x3530: 0x00c0, 0x3531: 0x00c0, 0x3532: 0x00c0, 0x3533: 0x00c0, 0x3534: 0x00c0, 0x3535: 0x00c0, + 0x3536: 0x00c0, 0x3537: 0x00c0, 0x3538: 0x00c0, 0x3539: 0x00c0, + 0x353f: 0x0080, + // Block 0xd5, offset 0x3540 + 0x3540: 0x00c0, 0x3541: 0x00c0, 0x3542: 0x00c0, 0x3543: 0x00c0, 0x3544: 0x00c0, 0x3545: 0x00c0, + 0x3546: 0x00c0, 0x3547: 0x00c0, 0x3548: 0x00c0, 0x3549: 0x00c0, 0x354a: 0x00c0, 0x354b: 0x00c0, + 0x354c: 0x00c0, 0x354d: 0x00c0, 0x354e: 0x00c0, 0x354f: 0x00c0, 0x3550: 0x00c0, 0x3551: 0x00c0, + 0x3552: 0x00c0, 0x3553: 0x00c0, 0x3554: 0x00c0, 0x3555: 0x00c0, 0x3556: 0x00c0, 0x3557: 0x00c0, + 0x3558: 0x00c0, 0x3559: 0x00c0, 0x355a: 0x00c0, 0x355b: 0x00c0, 0x355c: 0x00c0, 0x355d: 0x00c0, + 0x355e: 0x00c0, 0x355f: 0x00c0, 0x3560: 0x00c0, 0x3561: 0x00c0, 0x3562: 0x00c0, 0x3563: 0x00c0, + 0x3564: 0x00c0, 0x3565: 0x00c0, 0x3566: 0x00c0, 0x3567: 0x00c0, 0x3568: 0x00c0, 0x3569: 0x00c0, + 0x356a: 0x00c0, 0x356b: 0x00c0, 0x356c: 0x00c0, 0x356d: 0x00c0, 0x356e: 0x00c0, 0x356f: 0x00c0, + 0x3570: 0x00c0, 0x3571: 0x00c0, 0x3572: 0x00c0, 0x3573: 0x00c0, 0x3574: 0x00c0, 0x3575: 0x00c0, + 0x3576: 0x00c0, 0x3577: 0x00c0, + 0x357c: 0x0080, 0x357d: 0x0080, 0x357e: 0x00c0, 0x357f: 0x00c0, + // Block 0xd6, offset 0x3580 + 0x3580: 0x00c0, 0x3581: 0x00c3, 0x3582: 0x00c3, 0x3583: 0x00c3, 0x3585: 0x00c3, + 0x3586: 0x00c3, + 0x358c: 0x00c3, 0x358d: 0x00c3, 0x358e: 0x00c3, 0x358f: 0x00c3, 0x3590: 0x00c0, 0x3591: 0x00c0, + 0x3592: 0x00c0, 0x3593: 0x00c0, 0x3595: 0x00c0, 0x3596: 0x00c0, 0x3597: 0x00c0, + 0x3599: 0x00c0, 0x359a: 0x00c0, 0x359b: 0x00c0, 0x359c: 0x00c0, 0x359d: 0x00c0, + 0x359e: 0x00c0, 0x359f: 0x00c0, 0x35a0: 0x00c0, 0x35a1: 0x00c0, 0x35a2: 0x00c0, 0x35a3: 0x00c0, + 0x35a4: 0x00c0, 0x35a5: 0x00c0, 0x35a6: 0x00c0, 0x35a7: 0x00c0, 0x35a8: 0x00c0, 0x35a9: 0x00c0, + 0x35aa: 0x00c0, 0x35ab: 0x00c0, 0x35ac: 0x00c0, 0x35ad: 0x00c0, 0x35ae: 0x00c0, 0x35af: 0x00c0, + 0x35b0: 0x00c0, 0x35b1: 0x00c0, 0x35b2: 0x00c0, 0x35b3: 0x00c0, 0x35b4: 0x00c0, 0x35b5: 0x00c0, + 0x35b8: 0x00c3, 0x35b9: 0x00c3, 0x35ba: 0x00c3, + 0x35bf: 0x00c6, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x0080, 0x35c1: 0x0080, 0x35c2: 0x0080, 0x35c3: 0x0080, 0x35c4: 0x0080, 0x35c5: 0x0080, + 0x35c6: 0x0080, 0x35c7: 0x0080, 0x35c8: 0x0080, + 0x35d0: 0x0080, 0x35d1: 0x0080, + 0x35d2: 0x0080, 0x35d3: 0x0080, 0x35d4: 0x0080, 0x35d5: 0x0080, 0x35d6: 0x0080, 0x35d7: 0x0080, + 0x35d8: 0x0080, + 0x35e0: 0x00c0, 0x35e1: 0x00c0, 0x35e2: 0x00c0, 0x35e3: 0x00c0, + 0x35e4: 0x00c0, 0x35e5: 0x00c0, 0x35e6: 0x00c0, 0x35e7: 0x00c0, 0x35e8: 0x00c0, 0x35e9: 0x00c0, + 0x35ea: 0x00c0, 0x35eb: 0x00c0, 0x35ec: 0x00c0, 0x35ed: 0x00c0, 0x35ee: 0x00c0, 0x35ef: 0x00c0, + 0x35f0: 0x00c0, 0x35f1: 0x00c0, 0x35f2: 0x00c0, 0x35f3: 0x00c0, 0x35f4: 0x00c0, 0x35f5: 0x00c0, + 0x35f6: 0x00c0, 0x35f7: 0x00c0, 0x35f8: 0x00c0, 0x35f9: 0x00c0, 0x35fa: 0x00c0, 0x35fb: 0x00c0, + 0x35fc: 0x00c0, 0x35fd: 0x0080, 0x35fe: 0x0080, 0x35ff: 0x0080, + // Block 0xd8, offset 0x3600 + 0x3600: 0x00c0, 0x3601: 0x00c0, 0x3602: 0x00c0, 0x3603: 0x00c0, 0x3604: 0x00c0, 0x3605: 0x00c0, + 0x3606: 0x00c0, 0x3607: 0x00c0, 0x3608: 0x00c0, 0x3609: 0x00c0, 0x360a: 0x00c0, 0x360b: 0x00c0, + 0x360c: 0x00c0, 0x360d: 0x00c0, 0x360e: 0x00c0, 0x360f: 0x00c0, 0x3610: 0x00c0, 0x3611: 0x00c0, + 0x3612: 0x00c0, 0x3613: 0x00c0, 0x3614: 0x00c0, 0x3615: 0x00c0, 0x3616: 0x00c0, 0x3617: 0x00c0, + 0x3618: 0x00c0, 0x3619: 0x00c0, 0x361a: 0x00c0, 0x361b: 0x00c0, 0x361c: 0x00c0, 0x361d: 0x0080, + 0x361e: 0x0080, 0x361f: 0x0080, + // Block 0xd9, offset 0x3640 + 0x3640: 0x00c2, 0x3641: 0x00c2, 0x3642: 0x00c2, 0x3643: 0x00c2, 0x3644: 0x00c2, 0x3645: 0x00c4, + 0x3646: 0x00c0, 0x3647: 0x00c4, 0x3648: 0x0080, 0x3649: 0x00c4, 0x364a: 0x00c4, 0x364b: 0x00c0, + 0x364c: 0x00c0, 0x364d: 0x00c1, 0x364e: 0x00c4, 0x364f: 0x00c4, 0x3650: 0x00c4, 0x3651: 0x00c4, + 0x3652: 0x00c4, 0x3653: 0x00c2, 0x3654: 0x00c2, 0x3655: 0x00c2, 0x3656: 0x00c2, 0x3657: 0x00c1, + 0x3658: 0x00c2, 0x3659: 0x00c2, 0x365a: 0x00c2, 0x365b: 0x00c2, 0x365c: 0x00c2, 0x365d: 0x00c4, + 0x365e: 0x00c2, 0x365f: 0x00c2, 0x3660: 0x00c2, 0x3661: 0x00c4, 0x3662: 0x00c0, 0x3663: 0x00c0, + 0x3664: 0x00c4, 0x3665: 0x00c3, 0x3666: 0x00c3, + 0x366b: 0x0082, 0x366c: 0x0082, 0x366d: 0x0082, 0x366e: 0x0082, 0x366f: 0x0084, + 0x3670: 0x0080, 0x3671: 0x0080, 0x3672: 0x0080, 0x3673: 0x0080, 0x3674: 0x0080, 0x3675: 0x0080, + 0x3676: 0x0080, + // Block 0xda, offset 0x3680 + 0x3680: 0x00c0, 0x3681: 0x00c0, 0x3682: 0x00c0, 0x3683: 0x00c0, 0x3684: 0x00c0, 0x3685: 0x00c0, + 0x3686: 0x00c0, 0x3687: 0x00c0, 0x3688: 0x00c0, 0x3689: 0x00c0, 0x368a: 0x00c0, 0x368b: 0x00c0, + 0x368c: 0x00c0, 0x368d: 0x00c0, 0x368e: 0x00c0, 0x368f: 0x00c0, 0x3690: 0x00c0, 0x3691: 0x00c0, + 0x3692: 0x00c0, 0x3693: 0x00c0, 0x3694: 0x00c0, 0x3695: 0x00c0, 0x3696: 0x00c0, 0x3697: 0x00c0, + 0x3698: 0x00c0, 0x3699: 0x00c0, 0x369a: 0x00c0, 0x369b: 0x00c0, 0x369c: 0x00c0, 0x369d: 0x00c0, + 0x369e: 0x00c0, 0x369f: 0x00c0, 0x36a0: 0x00c0, 0x36a1: 0x00c0, 0x36a2: 0x00c0, 0x36a3: 0x00c0, + 0x36a4: 0x00c0, 0x36a5: 0x00c0, 0x36a6: 0x00c0, 0x36a7: 0x00c0, 0x36a8: 0x00c0, 0x36a9: 0x00c0, + 0x36aa: 0x00c0, 0x36ab: 0x00c0, 0x36ac: 0x00c0, 0x36ad: 0x00c0, 0x36ae: 0x00c0, 0x36af: 0x00c0, + 0x36b0: 0x00c0, 0x36b1: 0x00c0, 0x36b2: 0x00c0, 0x36b3: 0x00c0, 0x36b4: 0x00c0, 0x36b5: 0x00c0, + 0x36b9: 0x0080, 0x36ba: 0x0080, 0x36bb: 0x0080, + 0x36bc: 0x0080, 0x36bd: 0x0080, 0x36be: 0x0080, 0x36bf: 0x0080, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x00c0, 0x36c1: 0x00c0, 0x36c2: 0x00c0, 0x36c3: 0x00c0, 0x36c4: 0x00c0, 0x36c5: 0x00c0, + 0x36c6: 0x00c0, 0x36c7: 0x00c0, 0x36c8: 0x00c0, 0x36c9: 0x00c0, 0x36ca: 0x00c0, 0x36cb: 0x00c0, + 0x36cc: 0x00c0, 0x36cd: 0x00c0, 0x36ce: 0x00c0, 0x36cf: 0x00c0, 0x36d0: 0x00c0, 0x36d1: 0x00c0, + 0x36d2: 0x00c0, 0x36d3: 0x00c0, 0x36d4: 0x00c0, 0x36d5: 0x00c0, + 0x36d8: 0x0080, 0x36d9: 0x0080, 0x36da: 0x0080, 0x36db: 0x0080, 0x36dc: 0x0080, 0x36dd: 0x0080, + 0x36de: 0x0080, 0x36df: 0x0080, 0x36e0: 0x00c0, 0x36e1: 0x00c0, 0x36e2: 0x00c0, 0x36e3: 0x00c0, + 0x36e4: 0x00c0, 0x36e5: 0x00c0, 0x36e6: 0x00c0, 0x36e7: 0x00c0, 0x36e8: 0x00c0, 0x36e9: 0x00c0, + 0x36ea: 0x00c0, 0x36eb: 0x00c0, 0x36ec: 0x00c0, 0x36ed: 0x00c0, 0x36ee: 0x00c0, 0x36ef: 0x00c0, + 0x36f0: 0x00c0, 0x36f1: 0x00c0, 0x36f2: 0x00c0, + 0x36f8: 0x0080, 0x36f9: 0x0080, 0x36fa: 0x0080, 0x36fb: 0x0080, + 0x36fc: 0x0080, 0x36fd: 0x0080, 0x36fe: 0x0080, 0x36ff: 0x0080, + // Block 0xdc, offset 0x3700 + 0x3700: 0x00c2, 0x3701: 0x00c4, 0x3702: 0x00c2, 0x3703: 0x00c4, 0x3704: 0x00c4, 0x3705: 0x00c4, + 0x3706: 0x00c2, 0x3707: 0x00c2, 0x3708: 0x00c2, 0x3709: 0x00c4, 0x370a: 0x00c2, 0x370b: 0x00c2, + 0x370c: 0x00c4, 0x370d: 0x00c2, 0x370e: 0x00c4, 0x370f: 0x00c4, 0x3710: 0x00c2, 0x3711: 0x00c4, + 0x3719: 0x0080, 0x371a: 0x0080, 0x371b: 0x0080, 0x371c: 0x0080, + 0x3729: 0x0084, + 0x372a: 0x0084, 0x372b: 0x0084, 0x372c: 0x0084, 0x372d: 0x0082, 0x372e: 0x0082, 0x372f: 0x0080, + // Block 0xdd, offset 0x3740 + 0x3740: 0x00c0, 0x3741: 0x00c0, 0x3742: 0x00c0, 0x3743: 0x00c0, 0x3744: 0x00c0, 0x3745: 0x00c0, + 0x3746: 0x00c0, 0x3747: 0x00c0, 0x3748: 0x00c0, + // Block 0xde, offset 0x3780 + 0x3780: 0x00c0, 0x3781: 0x00c0, 0x3782: 0x00c0, 0x3783: 0x00c0, 0x3784: 0x00c0, 0x3785: 0x00c0, + 0x3786: 0x00c0, 0x3787: 0x00c0, 0x3788: 0x00c0, 0x3789: 0x00c0, 0x378a: 0x00c0, 0x378b: 0x00c0, + 0x378c: 0x00c0, 0x378d: 0x00c0, 0x378e: 0x00c0, 0x378f: 0x00c0, 0x3790: 0x00c0, 0x3791: 0x00c0, + 0x3792: 0x00c0, 0x3793: 0x00c0, 0x3794: 0x00c0, 0x3795: 0x00c0, 0x3796: 0x00c0, 0x3797: 0x00c0, + 0x3798: 0x00c0, 0x3799: 0x00c0, 0x379a: 0x00c0, 0x379b: 0x00c0, 0x379c: 0x00c0, 0x379d: 0x00c0, + 0x379e: 0x00c0, 0x379f: 0x00c0, 0x37a0: 0x00c0, 0x37a1: 0x00c0, 0x37a2: 0x00c0, 0x37a3: 0x00c0, + 0x37a4: 0x00c0, 0x37a5: 0x00c0, 0x37a6: 0x00c0, 0x37a7: 0x00c0, 0x37a8: 0x00c0, 0x37a9: 0x00c0, + 0x37aa: 0x00c0, 0x37ab: 0x00c0, 0x37ac: 0x00c0, 0x37ad: 0x00c0, 0x37ae: 0x00c0, 0x37af: 0x00c0, + 0x37b0: 0x00c0, 0x37b1: 0x00c0, 0x37b2: 0x00c0, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x00c0, 0x37c1: 0x00c0, 0x37c2: 0x00c0, 0x37c3: 0x00c0, 0x37c4: 0x00c0, 0x37c5: 0x00c0, + 0x37c6: 0x00c0, 0x37c7: 0x00c0, 0x37c8: 0x00c0, 0x37c9: 0x00c0, 0x37ca: 0x00c0, 0x37cb: 0x00c0, + 0x37cc: 0x00c0, 0x37cd: 0x00c0, 0x37ce: 0x00c0, 0x37cf: 0x00c0, 0x37d0: 0x00c0, 0x37d1: 0x00c0, + 0x37d2: 0x00c0, 0x37d3: 0x00c0, 0x37d4: 0x00c0, 0x37d5: 0x00c0, 0x37d6: 0x00c0, 0x37d7: 0x00c0, + 0x37d8: 0x00c0, 0x37d9: 0x00c0, 0x37da: 0x00c0, 0x37db: 0x00c0, 0x37dc: 0x00c0, 0x37dd: 0x00c0, + 0x37de: 0x00c0, 0x37df: 0x00c0, 0x37e0: 0x00c0, 0x37e1: 0x00c0, 0x37e2: 0x00c0, 0x37e3: 0x00c0, + 0x37e4: 0x00c0, 0x37e5: 0x00c0, 0x37e6: 0x00c0, 0x37e7: 0x00c0, 0x37e8: 0x00c0, 0x37e9: 0x00c0, + 0x37ea: 0x00c0, 0x37eb: 0x00c0, 0x37ec: 0x00c0, 0x37ed: 0x00c0, 0x37ee: 0x00c0, 0x37ef: 0x00c0, + 0x37f0: 0x00c0, 0x37f1: 0x00c0, 0x37f2: 0x00c0, + 0x37fa: 0x0080, 0x37fb: 0x0080, + 0x37fc: 0x0080, 0x37fd: 0x0080, 0x37fe: 0x0080, 0x37ff: 0x0080, + // Block 0xe0, offset 0x3800 + 0x3800: 0x00c1, 0x3801: 0x00c2, 0x3802: 0x00c2, 0x3803: 0x00c2, 0x3804: 0x00c2, 0x3805: 0x00c2, + 0x3806: 0x00c2, 0x3807: 0x00c2, 0x3808: 0x00c2, 0x3809: 0x00c2, 0x380a: 0x00c2, 0x380b: 0x00c2, + 0x380c: 0x00c2, 0x380d: 0x00c2, 0x380e: 0x00c2, 0x380f: 0x00c2, 0x3810: 0x00c2, 0x3811: 0x00c2, + 0x3812: 0x00c2, 0x3813: 0x00c2, 0x3814: 0x00c2, 0x3815: 0x00c2, 0x3816: 0x00c2, 0x3817: 0x00c2, + 0x3818: 0x00c2, 0x3819: 0x00c2, 0x381a: 0x00c2, 0x381b: 0x00c2, 0x381c: 0x00c2, 0x381d: 0x00c2, + 0x381e: 0x00c2, 0x381f: 0x00c2, 0x3820: 0x00c2, 0x3821: 0x00c2, 0x3822: 0x00c4, 0x3823: 0x00c2, + 0x3824: 0x00c3, 0x3825: 0x00c3, 0x3826: 0x00c3, 0x3827: 0x00c3, + 0x3830: 0x00c0, 0x3831: 0x00c0, 0x3832: 0x00c0, 0x3833: 0x00c0, 0x3834: 0x00c0, 0x3835: 0x00c0, + 0x3836: 0x00c0, 0x3837: 0x00c0, 0x3838: 0x00c0, 0x3839: 0x00c0, + // Block 0xe1, offset 0x3840 + 0x3860: 0x0080, 0x3861: 0x0080, 0x3862: 0x0080, 0x3863: 0x0080, + 0x3864: 0x0080, 0x3865: 0x0080, 0x3866: 0x0080, 0x3867: 0x0080, 0x3868: 0x0080, 0x3869: 0x0080, + 0x386a: 0x0080, 0x386b: 0x0080, 0x386c: 0x0080, 0x386d: 0x0080, 0x386e: 0x0080, 0x386f: 0x0080, + 0x3870: 0x0080, 0x3871: 0x0080, 0x3872: 0x0080, 0x3873: 0x0080, 0x3874: 0x0080, 0x3875: 0x0080, + 0x3876: 0x0080, 0x3877: 0x0080, 0x3878: 0x0080, 0x3879: 0x0080, 0x387a: 0x0080, 0x387b: 0x0080, + 0x387c: 0x0080, 0x387d: 0x0080, 0x387e: 0x0080, + // Block 0xe2, offset 0x3880 + 0x3880: 0x00c0, 0x3881: 0x00c0, 0x3882: 0x00c0, 0x3883: 0x00c0, 0x3884: 0x00c0, 0x3885: 0x00c0, + 0x3886: 0x00c0, 0x3887: 0x00c0, 0x3888: 0x00c0, 0x3889: 0x00c0, 0x388a: 0x00c0, 0x388b: 0x00c0, + 0x388c: 0x00c0, 0x388d: 0x00c0, 0x388e: 0x00c0, 0x388f: 0x00c0, 0x3890: 0x00c0, 0x3891: 0x00c0, + 0x3892: 0x00c0, 0x3893: 0x00c0, 0x3894: 0x00c0, 0x3895: 0x00c0, 0x3896: 0x00c0, 0x3897: 0x00c0, + 0x3898: 0x00c0, 0x3899: 0x00c0, 0x389a: 0x00c0, 0x389b: 0x00c0, 0x389c: 0x00c0, 0x389d: 0x0080, + 0x389e: 0x0080, 0x389f: 0x0080, 0x38a0: 0x0080, 0x38a1: 0x0080, 0x38a2: 0x0080, 0x38a3: 0x0080, + 0x38a4: 0x0080, 0x38a5: 0x0080, 0x38a6: 0x0080, 0x38a7: 0x00c0, + 0x38b0: 0x00c2, 0x38b1: 0x00c2, 0x38b2: 0x00c2, 0x38b3: 0x00c4, 0x38b4: 0x00c2, 0x38b5: 0x00c2, + 0x38b6: 0x00c2, 0x38b7: 0x00c2, 0x38b8: 0x00c2, 0x38b9: 0x00c2, 0x38ba: 0x00c2, 0x38bb: 0x00c2, + 0x38bc: 0x00c2, 0x38bd: 0x00c2, 0x38be: 0x00c2, 0x38bf: 0x00c2, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x00c2, 0x38c1: 0x00c2, 0x38c2: 0x00c2, 0x38c3: 0x00c2, 0x38c4: 0x00c2, 0x38c5: 0x00c0, + 0x38c6: 0x00c3, 0x38c7: 0x00c3, 0x38c8: 0x00c3, 0x38c9: 0x00c3, 0x38ca: 0x00c3, 0x38cb: 0x00c3, + 0x38cc: 0x00c3, 0x38cd: 0x00c3, 0x38ce: 0x00c3, 0x38cf: 0x00c3, 0x38d0: 0x00c3, 0x38d1: 0x0082, + 0x38d2: 0x0082, 0x38d3: 0x0082, 0x38d4: 0x0084, 0x38d5: 0x0080, 0x38d6: 0x0080, 0x38d7: 0x0080, + 0x38d8: 0x0080, 0x38d9: 0x0080, + // Block 0xe4, offset 0x3900 + 0x3920: 0x00c0, 0x3921: 0x00c0, 0x3922: 0x00c0, 0x3923: 0x00c0, + 0x3924: 0x00c0, 0x3925: 0x00c0, 0x3926: 0x00c0, 0x3927: 0x00c0, 0x3928: 0x00c0, 0x3929: 0x00c0, + 0x392a: 0x00c0, 0x392b: 0x00c0, 0x392c: 0x00c0, 0x392d: 0x00c0, 0x392e: 0x00c0, 0x392f: 0x00c0, + 0x3930: 0x00c0, 0x3931: 0x00c0, 0x3932: 0x00c0, 0x3933: 0x00c0, 0x3934: 0x00c0, 0x3935: 0x00c0, + 0x3936: 0x00c0, + // Block 0xe5, offset 0x3940 + 0x3940: 0x00c0, 0x3941: 0x00c3, 0x3942: 0x00c0, 0x3943: 0x00c0, 0x3944: 0x00c0, 0x3945: 0x00c0, + 0x3946: 0x00c0, 0x3947: 0x00c0, 0x3948: 0x00c0, 0x3949: 0x00c0, 0x394a: 0x00c0, 0x394b: 0x00c0, + 0x394c: 0x00c0, 0x394d: 0x00c0, 0x394e: 0x00c0, 0x394f: 0x00c0, 0x3950: 0x00c0, 0x3951: 0x00c0, + 0x3952: 0x00c0, 0x3953: 0x00c0, 0x3954: 0x00c0, 0x3955: 0x00c0, 0x3956: 0x00c0, 0x3957: 0x00c0, + 0x3958: 0x00c0, 0x3959: 0x00c0, 0x395a: 0x00c0, 0x395b: 0x00c0, 0x395c: 0x00c0, 0x395d: 0x00c0, + 0x395e: 0x00c0, 0x395f: 0x00c0, 0x3960: 0x00c0, 0x3961: 0x00c0, 0x3962: 0x00c0, 0x3963: 0x00c0, + 0x3964: 0x00c0, 0x3965: 0x00c0, 0x3966: 0x00c0, 0x3967: 0x00c0, 0x3968: 0x00c0, 0x3969: 0x00c0, + 0x396a: 0x00c0, 0x396b: 0x00c0, 0x396c: 0x00c0, 0x396d: 0x00c0, 0x396e: 0x00c0, 0x396f: 0x00c0, + 0x3970: 0x00c0, 0x3971: 0x00c0, 0x3972: 0x00c0, 0x3973: 0x00c0, 0x3974: 0x00c0, 0x3975: 0x00c0, + 0x3976: 0x00c0, 0x3977: 0x00c0, 0x3978: 0x00c3, 0x3979: 0x00c3, 0x397a: 0x00c3, 0x397b: 0x00c3, + 0x397c: 0x00c3, 0x397d: 0x00c3, 0x397e: 0x00c3, 0x397f: 0x00c3, + // Block 0xe6, offset 0x3980 + 0x3980: 0x00c3, 0x3981: 0x00c3, 0x3982: 0x00c3, 0x3983: 0x00c3, 0x3984: 0x00c3, 0x3985: 0x00c3, + 0x3986: 0x00c6, 0x3987: 0x0080, 0x3988: 0x0080, 0x3989: 0x0080, 0x398a: 0x0080, 0x398b: 0x0080, + 0x398c: 0x0080, 0x398d: 0x0080, + 0x3992: 0x0080, 0x3993: 0x0080, 0x3994: 0x0080, 0x3995: 0x0080, 0x3996: 0x0080, 0x3997: 0x0080, + 0x3998: 0x0080, 0x3999: 0x0080, 0x399a: 0x0080, 0x399b: 0x0080, 0x399c: 0x0080, 0x399d: 0x0080, + 0x399e: 0x0080, 0x399f: 0x0080, 0x39a0: 0x0080, 0x39a1: 0x0080, 0x39a2: 0x0080, 0x39a3: 0x0080, + 0x39a4: 0x0080, 0x39a5: 0x0080, 0x39a6: 0x00c0, 0x39a7: 0x00c0, 0x39a8: 0x00c0, 0x39a9: 0x00c0, + 0x39aa: 0x00c0, 0x39ab: 0x00c0, 0x39ac: 0x00c0, 0x39ad: 0x00c0, 0x39ae: 0x00c0, 0x39af: 0x00c0, + 0x39bf: 0x00c6, + // Block 0xe7, offset 0x39c0 + 0x39c0: 0x00c3, 0x39c1: 0x00c3, 0x39c2: 0x00c0, 0x39c3: 0x00c0, 0x39c4: 0x00c0, 0x39c5: 0x00c0, + 0x39c6: 0x00c0, 0x39c7: 0x00c0, 0x39c8: 0x00c0, 0x39c9: 0x00c0, 0x39ca: 0x00c0, 0x39cb: 0x00c0, + 0x39cc: 0x00c0, 0x39cd: 0x00c0, 0x39ce: 0x00c0, 0x39cf: 0x00c0, 0x39d0: 0x00c0, 0x39d1: 0x00c0, + 0x39d2: 0x00c0, 0x39d3: 0x00c0, 0x39d4: 0x00c0, 0x39d5: 0x00c0, 0x39d6: 0x00c0, 0x39d7: 0x00c0, + 0x39d8: 0x00c0, 0x39d9: 0x00c0, 0x39da: 0x00c0, 0x39db: 0x00c0, 0x39dc: 0x00c0, 0x39dd: 0x00c0, + 0x39de: 0x00c0, 0x39df: 0x00c0, 0x39e0: 0x00c0, 0x39e1: 0x00c0, 0x39e2: 0x00c0, 0x39e3: 0x00c0, + 0x39e4: 0x00c0, 0x39e5: 0x00c0, 0x39e6: 0x00c0, 0x39e7: 0x00c0, 0x39e8: 0x00c0, 0x39e9: 0x00c0, + 0x39ea: 0x00c0, 0x39eb: 0x00c0, 0x39ec: 0x00c0, 0x39ed: 0x00c0, 0x39ee: 0x00c0, 0x39ef: 0x00c0, + 0x39f0: 0x00c0, 0x39f1: 0x00c0, 0x39f2: 0x00c0, 0x39f3: 0x00c3, 0x39f4: 0x00c3, 0x39f5: 0x00c3, + 0x39f6: 0x00c3, 0x39f7: 0x00c0, 0x39f8: 0x00c0, 0x39f9: 0x00c6, 0x39fa: 0x00c3, 0x39fb: 0x0080, + 0x39fc: 0x0080, 0x39fd: 0x0040, 0x39fe: 0x0080, 0x39ff: 0x0080, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0x0080, 0x3a01: 0x0080, + 0x3a0d: 0x0040, 0x3a10: 0x00c0, 0x3a11: 0x00c0, + 0x3a12: 0x00c0, 0x3a13: 0x00c0, 0x3a14: 0x00c0, 0x3a15: 0x00c0, 0x3a16: 0x00c0, 0x3a17: 0x00c0, + 0x3a18: 0x00c0, 0x3a19: 0x00c0, 0x3a1a: 0x00c0, 0x3a1b: 0x00c0, 0x3a1c: 0x00c0, 0x3a1d: 0x00c0, + 0x3a1e: 0x00c0, 0x3a1f: 0x00c0, 0x3a20: 0x00c0, 0x3a21: 0x00c0, 0x3a22: 0x00c0, 0x3a23: 0x00c0, + 0x3a24: 0x00c0, 0x3a25: 0x00c0, 0x3a26: 0x00c0, 0x3a27: 0x00c0, 0x3a28: 0x00c0, + 0x3a30: 0x00c0, 0x3a31: 0x00c0, 0x3a32: 0x00c0, 0x3a33: 0x00c0, 0x3a34: 0x00c0, 0x3a35: 0x00c0, + 0x3a36: 0x00c0, 0x3a37: 0x00c0, 0x3a38: 0x00c0, 0x3a39: 0x00c0, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x00c3, 0x3a41: 0x00c3, 0x3a42: 0x00c3, 0x3a43: 0x00c0, 0x3a44: 0x00c0, 0x3a45: 0x00c0, + 0x3a46: 0x00c0, 0x3a47: 0x00c0, 0x3a48: 0x00c0, 0x3a49: 0x00c0, 0x3a4a: 0x00c0, 0x3a4b: 0x00c0, + 0x3a4c: 0x00c0, 0x3a4d: 0x00c0, 0x3a4e: 0x00c0, 0x3a4f: 0x00c0, 0x3a50: 0x00c0, 0x3a51: 0x00c0, + 0x3a52: 0x00c0, 0x3a53: 0x00c0, 0x3a54: 0x00c0, 0x3a55: 0x00c0, 0x3a56: 0x00c0, 0x3a57: 0x00c0, + 0x3a58: 0x00c0, 0x3a59: 0x00c0, 0x3a5a: 0x00c0, 0x3a5b: 0x00c0, 0x3a5c: 0x00c0, 0x3a5d: 0x00c0, + 0x3a5e: 0x00c0, 0x3a5f: 0x00c0, 0x3a60: 0x00c0, 0x3a61: 0x00c0, 0x3a62: 0x00c0, 0x3a63: 0x00c0, + 0x3a64: 0x00c0, 0x3a65: 0x00c0, 0x3a66: 0x00c0, 0x3a67: 0x00c3, 0x3a68: 0x00c3, 0x3a69: 0x00c3, + 0x3a6a: 0x00c3, 0x3a6b: 0x00c3, 0x3a6c: 0x00c0, 0x3a6d: 0x00c3, 0x3a6e: 0x00c3, 0x3a6f: 0x00c3, + 0x3a70: 0x00c3, 0x3a71: 0x00c3, 0x3a72: 0x00c3, 0x3a73: 0x00c6, 0x3a74: 0x00c6, + 0x3a76: 0x00c0, 0x3a77: 0x00c0, 0x3a78: 0x00c0, 0x3a79: 0x00c0, 0x3a7a: 0x00c0, 0x3a7b: 0x00c0, + 0x3a7c: 0x00c0, 0x3a7d: 0x00c0, 0x3a7e: 0x00c0, 0x3a7f: 0x00c0, + // Block 0xea, offset 0x3a80 + 0x3a80: 0x0080, 0x3a81: 0x0080, 0x3a82: 0x0080, 0x3a83: 0x0080, 0x3a84: 0x00c0, 0x3a85: 0x00c0, + 0x3a86: 0x00c0, + 0x3a90: 0x00c0, 0x3a91: 0x00c0, + 0x3a92: 0x00c0, 0x3a93: 0x00c0, 0x3a94: 0x00c0, 0x3a95: 0x00c0, 0x3a96: 0x00c0, 0x3a97: 0x00c0, + 0x3a98: 0x00c0, 0x3a99: 0x00c0, 0x3a9a: 0x00c0, 0x3a9b: 0x00c0, 0x3a9c: 0x00c0, 0x3a9d: 0x00c0, + 0x3a9e: 0x00c0, 0x3a9f: 0x00c0, 0x3aa0: 0x00c0, 0x3aa1: 0x00c0, 0x3aa2: 0x00c0, 0x3aa3: 0x00c0, + 0x3aa4: 0x00c0, 0x3aa5: 0x00c0, 0x3aa6: 0x00c0, 0x3aa7: 0x00c0, 0x3aa8: 0x00c0, 0x3aa9: 0x00c0, + 0x3aaa: 0x00c0, 0x3aab: 0x00c0, 0x3aac: 0x00c0, 0x3aad: 0x00c0, 0x3aae: 0x00c0, 0x3aaf: 0x00c0, + 0x3ab0: 0x00c0, 0x3ab1: 0x00c0, 0x3ab2: 0x00c0, 0x3ab3: 0x00c3, 0x3ab4: 0x0080, 0x3ab5: 0x0080, + 0x3ab6: 0x00c0, + // Block 0xeb, offset 0x3ac0 + 0x3ac0: 0x00c3, 0x3ac1: 0x00c3, 0x3ac2: 0x00c0, 0x3ac3: 0x00c0, 0x3ac4: 0x00c0, 0x3ac5: 0x00c0, + 0x3ac6: 0x00c0, 0x3ac7: 0x00c0, 0x3ac8: 0x00c0, 0x3ac9: 0x00c0, 0x3aca: 0x00c0, 0x3acb: 0x00c0, + 0x3acc: 0x00c0, 0x3acd: 0x00c0, 0x3ace: 0x00c0, 0x3acf: 0x00c0, 0x3ad0: 0x00c0, 0x3ad1: 0x00c0, + 0x3ad2: 0x00c0, 0x3ad3: 0x00c0, 0x3ad4: 0x00c0, 0x3ad5: 0x00c0, 0x3ad6: 0x00c0, 0x3ad7: 0x00c0, + 0x3ad8: 0x00c0, 0x3ad9: 0x00c0, 0x3ada: 0x00c0, 0x3adb: 0x00c0, 0x3adc: 0x00c0, 0x3add: 0x00c0, + 0x3ade: 0x00c0, 0x3adf: 0x00c0, 0x3ae0: 0x00c0, 0x3ae1: 0x00c0, 0x3ae2: 0x00c0, 0x3ae3: 0x00c0, + 0x3ae4: 0x00c0, 0x3ae5: 0x00c0, 0x3ae6: 0x00c0, 0x3ae7: 0x00c0, 0x3ae8: 0x00c0, 0x3ae9: 0x00c0, + 0x3aea: 0x00c0, 0x3aeb: 0x00c0, 0x3aec: 0x00c0, 0x3aed: 0x00c0, 0x3aee: 0x00c0, 0x3aef: 0x00c0, + 0x3af0: 0x00c0, 0x3af1: 0x00c0, 0x3af2: 0x00c0, 0x3af3: 0x00c0, 0x3af4: 0x00c0, 0x3af5: 0x00c0, + 0x3af6: 0x00c3, 0x3af7: 0x00c3, 0x3af8: 0x00c3, 0x3af9: 0x00c3, 0x3afa: 0x00c3, 0x3afb: 0x00c3, + 0x3afc: 0x00c3, 0x3afd: 0x00c3, 0x3afe: 0x00c3, 0x3aff: 0x00c0, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x00c5, 0x3b01: 0x00c0, 0x3b02: 0x00c0, 0x3b03: 0x00c0, 0x3b04: 0x00c0, 0x3b05: 0x0080, + 0x3b06: 0x0080, 0x3b07: 0x0080, 0x3b08: 0x0080, 0x3b09: 0x00c3, 0x3b0a: 0x00c3, 0x3b0b: 0x00c3, + 0x3b0c: 0x00c3, 0x3b0d: 0x0080, 0x3b10: 0x00c0, 0x3b11: 0x00c0, + 0x3b12: 0x00c0, 0x3b13: 0x00c0, 0x3b14: 0x00c0, 0x3b15: 0x00c0, 0x3b16: 0x00c0, 0x3b17: 0x00c0, + 0x3b18: 0x00c0, 0x3b19: 0x00c0, 0x3b1a: 0x00c0, 0x3b1b: 0x0080, 0x3b1c: 0x00c0, 0x3b1d: 0x0080, + 0x3b1e: 0x0080, 0x3b1f: 0x0080, 0x3b21: 0x0080, 0x3b22: 0x0080, 0x3b23: 0x0080, + 0x3b24: 0x0080, 0x3b25: 0x0080, 0x3b26: 0x0080, 0x3b27: 0x0080, 0x3b28: 0x0080, 0x3b29: 0x0080, + 0x3b2a: 0x0080, 0x3b2b: 0x0080, 0x3b2c: 0x0080, 0x3b2d: 0x0080, 0x3b2e: 0x0080, 0x3b2f: 0x0080, + 0x3b30: 0x0080, 0x3b31: 0x0080, 0x3b32: 0x0080, 0x3b33: 0x0080, 0x3b34: 0x0080, + // Block 0xed, offset 0x3b40 + 0x3b40: 0x00c0, 0x3b41: 0x00c0, 0x3b42: 0x00c0, 0x3b43: 0x00c0, 0x3b44: 0x00c0, 0x3b45: 0x00c0, + 0x3b46: 0x00c0, 0x3b47: 0x00c0, 0x3b48: 0x00c0, 0x3b49: 0x00c0, 0x3b4a: 0x00c0, 0x3b4b: 0x00c0, + 0x3b4c: 0x00c0, 0x3b4d: 0x00c0, 0x3b4e: 0x00c0, 0x3b4f: 0x00c0, 0x3b50: 0x00c0, 0x3b51: 0x00c0, + 0x3b53: 0x00c0, 0x3b54: 0x00c0, 0x3b55: 0x00c0, 0x3b56: 0x00c0, 0x3b57: 0x00c0, + 0x3b58: 0x00c0, 0x3b59: 0x00c0, 0x3b5a: 0x00c0, 0x3b5b: 0x00c0, 0x3b5c: 0x00c0, 0x3b5d: 0x00c0, + 0x3b5e: 0x00c0, 0x3b5f: 0x00c0, 0x3b60: 0x00c0, 0x3b61: 0x00c0, 0x3b62: 0x00c0, 0x3b63: 0x00c0, + 0x3b64: 0x00c0, 0x3b65: 0x00c0, 0x3b66: 0x00c0, 0x3b67: 0x00c0, 0x3b68: 0x00c0, 0x3b69: 0x00c0, + 0x3b6a: 0x00c0, 0x3b6b: 0x00c0, 0x3b6c: 0x00c0, 0x3b6d: 0x00c0, 0x3b6e: 0x00c0, 0x3b6f: 0x00c3, + 0x3b70: 0x00c3, 0x3b71: 0x00c3, 0x3b72: 0x00c0, 0x3b73: 0x00c0, 0x3b74: 0x00c3, 0x3b75: 0x00c5, + 0x3b76: 0x00c3, 0x3b77: 0x00c3, 0x3b78: 0x0080, 0x3b79: 0x0080, 0x3b7a: 0x0080, 0x3b7b: 0x0080, + 0x3b7c: 0x0080, 0x3b7d: 0x0080, 0x3b7e: 0x00c3, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x00c0, 0x3b81: 0x00c0, 0x3b82: 0x00c0, 0x3b83: 0x00c0, 0x3b84: 0x00c0, 0x3b85: 0x00c0, + 0x3b86: 0x00c0, 0x3b88: 0x00c0, 0x3b8a: 0x00c0, 0x3b8b: 0x00c0, + 0x3b8c: 0x00c0, 0x3b8d: 0x00c0, 0x3b8f: 0x00c0, 0x3b90: 0x00c0, 0x3b91: 0x00c0, + 0x3b92: 0x00c0, 0x3b93: 0x00c0, 0x3b94: 0x00c0, 0x3b95: 0x00c0, 0x3b96: 0x00c0, 0x3b97: 0x00c0, + 0x3b98: 0x00c0, 0x3b99: 0x00c0, 0x3b9a: 0x00c0, 0x3b9b: 0x00c0, 0x3b9c: 0x00c0, 0x3b9d: 0x00c0, + 0x3b9f: 0x00c0, 0x3ba0: 0x00c0, 0x3ba1: 0x00c0, 0x3ba2: 0x00c0, 0x3ba3: 0x00c0, + 0x3ba4: 0x00c0, 0x3ba5: 0x00c0, 0x3ba6: 0x00c0, 0x3ba7: 0x00c0, 0x3ba8: 0x00c0, 0x3ba9: 0x0080, + 0x3bb0: 0x00c0, 0x3bb1: 0x00c0, 0x3bb2: 0x00c0, 0x3bb3: 0x00c0, 0x3bb4: 0x00c0, 0x3bb5: 0x00c0, + 0x3bb6: 0x00c0, 0x3bb7: 0x00c0, 0x3bb8: 0x00c0, 0x3bb9: 0x00c0, 0x3bba: 0x00c0, 0x3bbb: 0x00c0, + 0x3bbc: 0x00c0, 0x3bbd: 0x00c0, 0x3bbe: 0x00c0, 0x3bbf: 0x00c0, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x00c0, 0x3bc1: 0x00c0, 0x3bc2: 0x00c0, 0x3bc3: 0x00c0, 0x3bc4: 0x00c0, 0x3bc5: 0x00c0, + 0x3bc6: 0x00c0, 0x3bc7: 0x00c0, 0x3bc8: 0x00c0, 0x3bc9: 0x00c0, 0x3bca: 0x00c0, 0x3bcb: 0x00c0, + 0x3bcc: 0x00c0, 0x3bcd: 0x00c0, 0x3bce: 0x00c0, 0x3bcf: 0x00c0, 0x3bd0: 0x00c0, 0x3bd1: 0x00c0, + 0x3bd2: 0x00c0, 0x3bd3: 0x00c0, 0x3bd4: 0x00c0, 0x3bd5: 0x00c0, 0x3bd6: 0x00c0, 0x3bd7: 0x00c0, + 0x3bd8: 0x00c0, 0x3bd9: 0x00c0, 0x3bda: 0x00c0, 0x3bdb: 0x00c0, 0x3bdc: 0x00c0, 0x3bdd: 0x00c0, + 0x3bde: 0x00c0, 0x3bdf: 0x00c3, 0x3be0: 0x00c0, 0x3be1: 0x00c0, 0x3be2: 0x00c0, 0x3be3: 0x00c3, + 0x3be4: 0x00c3, 0x3be5: 0x00c3, 0x3be6: 0x00c3, 0x3be7: 0x00c3, 0x3be8: 0x00c3, 0x3be9: 0x00c3, + 0x3bea: 0x00c6, + 0x3bf0: 0x00c0, 0x3bf1: 0x00c0, 0x3bf2: 0x00c0, 0x3bf3: 0x00c0, 0x3bf4: 0x00c0, 0x3bf5: 0x00c0, + 0x3bf6: 0x00c0, 0x3bf7: 0x00c0, 0x3bf8: 0x00c0, 0x3bf9: 0x00c0, + // Block 0xf0, offset 0x3c00 + 0x3c00: 0x00c3, 0x3c01: 0x00c3, 0x3c02: 0x00c0, 0x3c03: 0x00c0, 0x3c05: 0x00c0, + 0x3c06: 0x00c0, 0x3c07: 0x00c0, 0x3c08: 0x00c0, 0x3c09: 0x00c0, 0x3c0a: 0x00c0, 0x3c0b: 0x00c0, + 0x3c0c: 0x00c0, 0x3c0f: 0x00c0, 0x3c10: 0x00c0, + 0x3c13: 0x00c0, 0x3c14: 0x00c0, 0x3c15: 0x00c0, 0x3c16: 0x00c0, 0x3c17: 0x00c0, + 0x3c18: 0x00c0, 0x3c19: 0x00c0, 0x3c1a: 0x00c0, 0x3c1b: 0x00c0, 0x3c1c: 0x00c0, 0x3c1d: 0x00c0, + 0x3c1e: 0x00c0, 0x3c1f: 0x00c0, 0x3c20: 0x00c0, 0x3c21: 0x00c0, 0x3c22: 0x00c0, 0x3c23: 0x00c0, + 0x3c24: 0x00c0, 0x3c25: 0x00c0, 0x3c26: 0x00c0, 0x3c27: 0x00c0, 0x3c28: 0x00c0, + 0x3c2a: 0x00c0, 0x3c2b: 0x00c0, 0x3c2c: 0x00c0, 0x3c2d: 0x00c0, 0x3c2e: 0x00c0, 0x3c2f: 0x00c0, + 0x3c30: 0x00c0, 0x3c32: 0x00c0, 0x3c33: 0x00c0, 0x3c35: 0x00c0, + 0x3c36: 0x00c0, 0x3c37: 0x00c0, 0x3c38: 0x00c0, 0x3c39: 0x00c0, 0x3c3b: 0x00c3, + 0x3c3c: 0x00c3, 0x3c3d: 0x00c0, 0x3c3e: 0x00c0, 0x3c3f: 0x00c0, + // Block 0xf1, offset 0x3c40 + 0x3c40: 0x00c3, 0x3c41: 0x00c0, 0x3c42: 0x00c0, 0x3c43: 0x00c0, 0x3c44: 0x00c0, + 0x3c47: 0x00c0, 0x3c48: 0x00c0, 0x3c4b: 0x00c0, + 0x3c4c: 0x00c0, 0x3c4d: 0x00c5, 0x3c50: 0x00c0, + 0x3c57: 0x00c0, + 0x3c5d: 0x00c0, + 0x3c5e: 0x00c0, 0x3c5f: 0x00c0, 0x3c60: 0x00c0, 0x3c61: 0x00c0, 0x3c62: 0x00c0, 0x3c63: 0x00c0, + 0x3c66: 0x00c3, 0x3c67: 0x00c3, 0x3c68: 0x00c3, 0x3c69: 0x00c3, + 0x3c6a: 0x00c3, 0x3c6b: 0x00c3, 0x3c6c: 0x00c3, + 0x3c70: 0x00c3, 0x3c71: 0x00c3, 0x3c72: 0x00c3, 0x3c73: 0x00c3, 0x3c74: 0x00c3, + // Block 0xf2, offset 0x3c80 + 0x3c80: 0x00c0, 0x3c81: 0x00c0, 0x3c82: 0x00c0, 0x3c83: 0x00c0, 0x3c84: 0x00c0, 0x3c85: 0x00c0, + 0x3c86: 0x00c0, 0x3c87: 0x00c0, 0x3c88: 0x00c0, 0x3c89: 0x00c0, 0x3c8a: 0x00c0, 0x3c8b: 0x00c0, + 0x3c8c: 0x00c0, 0x3c8d: 0x00c0, 0x3c8e: 0x00c0, 0x3c8f: 0x00c0, 0x3c90: 0x00c0, 0x3c91: 0x00c0, + 0x3c92: 0x00c0, 0x3c93: 0x00c0, 0x3c94: 0x00c0, 0x3c95: 0x00c0, 0x3c96: 0x00c0, 0x3c97: 0x00c0, + 0x3c98: 0x00c0, 0x3c99: 0x00c0, 0x3c9a: 0x00c0, 0x3c9b: 0x00c0, 0x3c9c: 0x00c0, 0x3c9d: 0x00c0, + 0x3c9e: 0x00c0, 0x3c9f: 0x00c0, 0x3ca0: 0x00c0, 0x3ca1: 0x00c0, 0x3ca2: 0x00c0, 0x3ca3: 0x00c0, + 0x3ca4: 0x00c0, 0x3ca5: 0x00c0, 0x3ca6: 0x00c0, 0x3ca7: 0x00c0, 0x3ca8: 0x00c0, 0x3ca9: 0x00c0, + 0x3caa: 0x00c0, 0x3cab: 0x00c0, 0x3cac: 0x00c0, 0x3cad: 0x00c0, 0x3cae: 0x00c0, 0x3caf: 0x00c0, + 0x3cb0: 0x00c0, 0x3cb1: 0x00c0, 0x3cb2: 0x00c0, 0x3cb3: 0x00c0, 0x3cb4: 0x00c0, 0x3cb5: 0x00c0, + 0x3cb6: 0x00c0, 0x3cb7: 0x00c0, 0x3cb8: 0x00c3, 0x3cb9: 0x00c3, 0x3cba: 0x00c3, 0x3cbb: 0x00c3, + 0x3cbc: 0x00c3, 0x3cbd: 0x00c3, 0x3cbe: 0x00c3, 0x3cbf: 0x00c3, + // Block 0xf3, offset 0x3cc0 + 0x3cc0: 0x00c0, 0x3cc1: 0x00c0, 0x3cc2: 0x00c6, 0x3cc3: 0x00c3, 0x3cc4: 0x00c3, 0x3cc5: 0x00c0, + 0x3cc6: 0x00c3, 0x3cc7: 0x00c0, 0x3cc8: 0x00c0, 0x3cc9: 0x00c0, 0x3cca: 0x00c0, 0x3ccb: 0x0080, + 0x3ccc: 0x0080, 0x3ccd: 0x0080, 0x3cce: 0x0080, 0x3ccf: 0x0080, 0x3cd0: 0x00c0, 0x3cd1: 0x00c0, + 0x3cd2: 0x00c0, 0x3cd3: 0x00c0, 0x3cd4: 0x00c0, 0x3cd5: 0x00c0, 0x3cd6: 0x00c0, 0x3cd7: 0x00c0, + 0x3cd8: 0x00c0, 0x3cd9: 0x00c0, 0x3cdb: 0x0080, 0x3cdd: 0x0080, + 0x3cde: 0x00c3, 0x3cdf: 0x00c0, + // Block 0xf4, offset 0x3d00 + 0x3d00: 0x00c0, 0x3d01: 0x00c0, 0x3d02: 0x00c0, 0x3d03: 0x00c0, 0x3d04: 0x00c0, 0x3d05: 0x00c0, + 0x3d06: 0x00c0, 0x3d07: 0x00c0, 0x3d08: 0x00c0, 0x3d09: 0x00c0, 0x3d0a: 0x00c0, 0x3d0b: 0x00c0, + 0x3d0c: 0x00c0, 0x3d0d: 0x00c0, 0x3d0e: 0x00c0, 0x3d0f: 0x00c0, 0x3d10: 0x00c0, 0x3d11: 0x00c0, + 0x3d12: 0x00c0, 0x3d13: 0x00c0, 0x3d14: 0x00c0, 0x3d15: 0x00c0, 0x3d16: 0x00c0, 0x3d17: 0x00c0, + 0x3d18: 0x00c0, 0x3d19: 0x00c0, 0x3d1a: 0x00c0, 0x3d1b: 0x00c0, 0x3d1c: 0x00c0, 0x3d1d: 0x00c0, + 0x3d1e: 0x00c0, 0x3d1f: 0x00c0, 0x3d20: 0x00c0, 0x3d21: 0x00c0, 0x3d22: 0x00c0, 0x3d23: 0x00c0, + 0x3d24: 0x00c0, 0x3d25: 0x00c0, 0x3d26: 0x00c0, 0x3d27: 0x00c0, 0x3d28: 0x00c0, 0x3d29: 0x00c0, + 0x3d2a: 0x00c0, 0x3d2b: 0x00c0, 0x3d2c: 0x00c0, 0x3d2d: 0x00c0, 0x3d2e: 0x00c0, 0x3d2f: 0x00c0, + 0x3d30: 0x00c0, 0x3d31: 0x00c0, 0x3d32: 0x00c0, 0x3d33: 0x00c3, 0x3d34: 0x00c3, 0x3d35: 0x00c3, + 0x3d36: 0x00c3, 0x3d37: 0x00c3, 0x3d38: 0x00c3, 0x3d39: 0x00c0, 0x3d3a: 0x00c3, 0x3d3b: 0x00c0, + 0x3d3c: 0x00c0, 0x3d3d: 0x00c0, 0x3d3e: 0x00c0, 0x3d3f: 0x00c3, + // Block 0xf5, offset 0x3d40 + 0x3d40: 0x00c3, 0x3d41: 0x00c0, 0x3d42: 0x00c6, 0x3d43: 0x00c3, 0x3d44: 0x00c0, 0x3d45: 0x00c0, + 0x3d46: 0x0080, 0x3d47: 0x00c0, + 0x3d50: 0x00c0, 0x3d51: 0x00c0, + 0x3d52: 0x00c0, 0x3d53: 0x00c0, 0x3d54: 0x00c0, 0x3d55: 0x00c0, 0x3d56: 0x00c0, 0x3d57: 0x00c0, + 0x3d58: 0x00c0, 0x3d59: 0x00c0, + // Block 0xf6, offset 0x3d80 + 0x3d80: 0x00c0, 0x3d81: 0x00c0, 0x3d82: 0x00c0, 0x3d83: 0x00c0, 0x3d84: 0x00c0, 0x3d85: 0x00c0, + 0x3d86: 0x00c0, 0x3d87: 0x00c0, 0x3d88: 0x00c0, 0x3d89: 0x00c0, 0x3d8a: 0x00c0, 0x3d8b: 0x00c0, + 0x3d8c: 0x00c0, 0x3d8d: 0x00c0, 0x3d8e: 0x00c0, 0x3d8f: 0x00c0, 0x3d90: 0x00c0, 0x3d91: 0x00c0, + 0x3d92: 0x00c0, 0x3d93: 0x00c0, 0x3d94: 0x00c0, 0x3d95: 0x00c0, 0x3d96: 0x00c0, 0x3d97: 0x00c0, + 0x3d98: 0x00c0, 0x3d99: 0x00c0, 0x3d9a: 0x00c0, 0x3d9b: 0x00c0, 0x3d9c: 0x00c0, 0x3d9d: 0x00c0, + 0x3d9e: 0x00c0, 0x3d9f: 0x00c0, 0x3da0: 0x00c0, 0x3da1: 0x00c0, 0x3da2: 0x00c0, 0x3da3: 0x00c0, + 0x3da4: 0x00c0, 0x3da5: 0x00c0, 0x3da6: 0x00c0, 0x3da7: 0x00c0, 0x3da8: 0x00c0, 0x3da9: 0x00c0, + 0x3daa: 0x00c0, 0x3dab: 0x00c0, 0x3dac: 0x00c0, 0x3dad: 0x00c0, 0x3dae: 0x00c0, 0x3daf: 0x00c0, + 0x3db0: 0x00c0, 0x3db1: 0x00c0, 0x3db2: 0x00c3, 0x3db3: 0x00c3, 0x3db4: 0x00c3, 0x3db5: 0x00c3, + 0x3db8: 0x00c0, 0x3db9: 0x00c0, 0x3dba: 0x00c0, 0x3dbb: 0x00c0, + 0x3dbc: 0x00c3, 0x3dbd: 0x00c3, 0x3dbe: 0x00c0, 0x3dbf: 0x00c6, + // Block 0xf7, offset 0x3dc0 + 0x3dc0: 0x00c3, 0x3dc1: 0x0080, 0x3dc2: 0x0080, 0x3dc3: 0x0080, 0x3dc4: 0x0080, 0x3dc5: 0x0080, + 0x3dc6: 0x0080, 0x3dc7: 0x0080, 0x3dc8: 0x0080, 0x3dc9: 0x0080, 0x3dca: 0x0080, 0x3dcb: 0x0080, + 0x3dcc: 0x0080, 0x3dcd: 0x0080, 0x3dce: 0x0080, 0x3dcf: 0x0080, 0x3dd0: 0x0080, 0x3dd1: 0x0080, + 0x3dd2: 0x0080, 0x3dd3: 0x0080, 0x3dd4: 0x0080, 0x3dd5: 0x0080, 0x3dd6: 0x0080, 0x3dd7: 0x0080, + 0x3dd8: 0x00c0, 0x3dd9: 0x00c0, 0x3dda: 0x00c0, 0x3ddb: 0x00c0, 0x3ddc: 0x00c3, 0x3ddd: 0x00c3, + // Block 0xf8, offset 0x3e00 + 0x3e00: 0x00c0, 0x3e01: 0x00c0, 0x3e02: 0x00c0, 0x3e03: 0x00c0, 0x3e04: 0x00c0, 0x3e05: 0x00c0, + 0x3e06: 0x00c0, 0x3e07: 0x00c0, 0x3e08: 0x00c0, 0x3e09: 0x00c0, 0x3e0a: 0x00c0, 0x3e0b: 0x00c0, + 0x3e0c: 0x00c0, 0x3e0d: 0x00c0, 0x3e0e: 0x00c0, 0x3e0f: 0x00c0, 0x3e10: 0x00c0, 0x3e11: 0x00c0, + 0x3e12: 0x00c0, 0x3e13: 0x00c0, 0x3e14: 0x00c0, 0x3e15: 0x00c0, 0x3e16: 0x00c0, 0x3e17: 0x00c0, + 0x3e18: 0x00c0, 0x3e19: 0x00c0, 0x3e1a: 0x00c0, 0x3e1b: 0x00c0, 0x3e1c: 0x00c0, 0x3e1d: 0x00c0, + 0x3e1e: 0x00c0, 0x3e1f: 0x00c0, 0x3e20: 0x00c0, 0x3e21: 0x00c0, 0x3e22: 0x00c0, 0x3e23: 0x00c0, + 0x3e24: 0x00c0, 0x3e25: 0x00c0, 0x3e26: 0x00c0, 0x3e27: 0x00c0, 0x3e28: 0x00c0, 0x3e29: 0x00c0, + 0x3e2a: 0x00c0, 0x3e2b: 0x00c0, 0x3e2c: 0x00c0, 0x3e2d: 0x00c0, 0x3e2e: 0x00c0, 0x3e2f: 0x00c0, + 0x3e30: 0x00c0, 0x3e31: 0x00c0, 0x3e32: 0x00c0, 0x3e33: 0x00c3, 0x3e34: 0x00c3, 0x3e35: 0x00c3, + 0x3e36: 0x00c3, 0x3e37: 0x00c3, 0x3e38: 0x00c3, 0x3e39: 0x00c3, 0x3e3a: 0x00c3, 0x3e3b: 0x00c0, + 0x3e3c: 0x00c0, 0x3e3d: 0x00c3, 0x3e3e: 0x00c0, 0x3e3f: 0x00c6, + // Block 0xf9, offset 0x3e40 + 0x3e40: 0x00c3, 0x3e41: 0x0080, 0x3e42: 0x0080, 0x3e43: 0x0080, 0x3e44: 0x00c0, + 0x3e50: 0x00c0, 0x3e51: 0x00c0, + 0x3e52: 0x00c0, 0x3e53: 0x00c0, 0x3e54: 0x00c0, 0x3e55: 0x00c0, 0x3e56: 0x00c0, 0x3e57: 0x00c0, + 0x3e58: 0x00c0, 0x3e59: 0x00c0, + 0x3e60: 0x0080, 0x3e61: 0x0080, 0x3e62: 0x0080, 0x3e63: 0x0080, + 0x3e64: 0x0080, 0x3e65: 0x0080, 0x3e66: 0x0080, 0x3e67: 0x0080, 0x3e68: 0x0080, 0x3e69: 0x0080, + 0x3e6a: 0x0080, 0x3e6b: 0x0080, 0x3e6c: 0x0080, + // Block 0xfa, offset 0x3e80 + 0x3e80: 0x00c0, 0x3e81: 0x00c0, 0x3e82: 0x00c0, 0x3e83: 0x00c0, 0x3e84: 0x00c0, 0x3e85: 0x00c0, + 0x3e86: 0x00c0, 0x3e87: 0x00c0, 0x3e88: 0x00c0, 0x3e89: 0x00c0, 0x3e8a: 0x00c0, 0x3e8b: 0x00c0, + 0x3e8c: 0x00c0, 0x3e8d: 0x00c0, 0x3e8e: 0x00c0, 0x3e8f: 0x00c0, 0x3e90: 0x00c0, 0x3e91: 0x00c0, + 0x3e92: 0x00c0, 0x3e93: 0x00c0, 0x3e94: 0x00c0, 0x3e95: 0x00c0, 0x3e96: 0x00c0, 0x3e97: 0x00c0, + 0x3e98: 0x00c0, 0x3e99: 0x00c0, 0x3e9a: 0x00c0, 0x3e9b: 0x00c0, 0x3e9c: 0x00c0, 0x3e9d: 0x00c0, + 0x3e9e: 0x00c0, 0x3e9f: 0x00c0, 0x3ea0: 0x00c0, 0x3ea1: 0x00c0, 0x3ea2: 0x00c0, 0x3ea3: 0x00c0, + 0x3ea4: 0x00c0, 0x3ea5: 0x00c0, 0x3ea6: 0x00c0, 0x3ea7: 0x00c0, 0x3ea8: 0x00c0, 0x3ea9: 0x00c0, + 0x3eaa: 0x00c0, 0x3eab: 0x00c3, 0x3eac: 0x00c0, 0x3ead: 0x00c3, 0x3eae: 0x00c0, 0x3eaf: 0x00c0, + 0x3eb0: 0x00c3, 0x3eb1: 0x00c3, 0x3eb2: 0x00c3, 0x3eb3: 0x00c3, 0x3eb4: 0x00c3, 0x3eb5: 0x00c3, + 0x3eb6: 0x00c5, 0x3eb7: 0x00c3, 0x3eb8: 0x00c0, + // Block 0xfb, offset 0x3ec0 + 0x3ec0: 0x00c0, 0x3ec1: 0x00c0, 0x3ec2: 0x00c0, 0x3ec3: 0x00c0, 0x3ec4: 0x00c0, 0x3ec5: 0x00c0, + 0x3ec6: 0x00c0, 0x3ec7: 0x00c0, 0x3ec8: 0x00c0, 0x3ec9: 0x00c0, + // Block 0xfc, offset 0x3f00 + 0x3f00: 0x00c0, 0x3f01: 0x00c0, 0x3f02: 0x00c0, 0x3f03: 0x00c0, 0x3f04: 0x00c0, 0x3f05: 0x00c0, + 0x3f06: 0x00c0, 0x3f07: 0x00c0, 0x3f08: 0x00c0, 0x3f09: 0x00c0, 0x3f0a: 0x00c0, 0x3f0b: 0x00c0, + 0x3f0c: 0x00c0, 0x3f0d: 0x00c0, 0x3f0e: 0x00c0, 0x3f0f: 0x00c0, 0x3f10: 0x00c0, 0x3f11: 0x00c0, + 0x3f12: 0x00c0, 0x3f13: 0x00c0, 0x3f14: 0x00c0, 0x3f15: 0x00c0, 0x3f16: 0x00c0, 0x3f17: 0x00c0, + 0x3f18: 0x00c0, 0x3f19: 0x00c0, 0x3f1a: 0x00c0, 0x3f1d: 0x00c3, + 0x3f1e: 0x00c3, 0x3f1f: 0x00c3, 0x3f20: 0x00c0, 0x3f21: 0x00c0, 0x3f22: 0x00c3, 0x3f23: 0x00c3, + 0x3f24: 0x00c3, 0x3f25: 0x00c3, 0x3f26: 0x00c0, 0x3f27: 0x00c3, 0x3f28: 0x00c3, 0x3f29: 0x00c3, + 0x3f2a: 0x00c3, 0x3f2b: 0x00c6, + 0x3f30: 0x00c0, 0x3f31: 0x00c0, 0x3f32: 0x00c0, 0x3f33: 0x00c0, 0x3f34: 0x00c0, 0x3f35: 0x00c0, + 0x3f36: 0x00c0, 0x3f37: 0x00c0, 0x3f38: 0x00c0, 0x3f39: 0x00c0, 0x3f3a: 0x0080, 0x3f3b: 0x0080, + 0x3f3c: 0x0080, 0x3f3d: 0x0080, 0x3f3e: 0x0080, 0x3f3f: 0x0080, + // Block 0xfd, offset 0x3f40 + 0x3f40: 0x00c0, 0x3f41: 0x00c0, 0x3f42: 0x00c0, 0x3f43: 0x00c0, 0x3f44: 0x00c0, 0x3f45: 0x00c0, + 0x3f46: 0x00c0, 0x3f47: 0x00c0, 0x3f48: 0x00c0, 0x3f49: 0x00c0, 0x3f4a: 0x00c0, 0x3f4b: 0x00c0, + 0x3f4c: 0x00c0, 0x3f4d: 0x00c0, 0x3f4e: 0x00c0, 0x3f4f: 0x00c0, 0x3f50: 0x00c0, 0x3f51: 0x00c0, + 0x3f52: 0x00c0, 0x3f53: 0x00c0, 0x3f54: 0x00c0, 0x3f55: 0x00c0, 0x3f56: 0x00c0, 0x3f57: 0x00c0, + 0x3f58: 0x00c0, 0x3f59: 0x00c0, 0x3f5a: 0x00c0, 0x3f5b: 0x00c0, 0x3f5c: 0x00c0, 0x3f5d: 0x00c0, + 0x3f5e: 0x00c0, 0x3f5f: 0x00c0, 0x3f60: 0x00c0, 0x3f61: 0x00c0, 0x3f62: 0x00c0, 0x3f63: 0x00c0, + 0x3f64: 0x00c0, 0x3f65: 0x00c0, 0x3f66: 0x00c0, 0x3f67: 0x00c0, 0x3f68: 0x00c0, 0x3f69: 0x00c0, + 0x3f6a: 0x00c0, 0x3f6b: 0x00c0, 0x3f6c: 0x00c0, 0x3f6d: 0x00c0, 0x3f6e: 0x00c0, 0x3f6f: 0x00c3, + 0x3f70: 0x00c3, 0x3f71: 0x00c3, 0x3f72: 0x00c3, 0x3f73: 0x00c3, 0x3f74: 0x00c3, 0x3f75: 0x00c3, + 0x3f76: 0x00c3, 0x3f77: 0x00c3, 0x3f78: 0x00c0, 0x3f79: 0x00c6, 0x3f7a: 0x00c3, 0x3f7b: 0x0080, + // Block 0xfe, offset 0x3f80 + 0x3fa0: 0x00c0, 0x3fa1: 0x00c0, 0x3fa2: 0x00c0, 0x3fa3: 0x00c0, + 0x3fa4: 0x00c0, 0x3fa5: 0x00c0, 0x3fa6: 0x00c0, 0x3fa7: 0x00c0, 0x3fa8: 0x00c0, 0x3fa9: 0x00c0, + 0x3faa: 0x00c0, 0x3fab: 0x00c0, 0x3fac: 0x00c0, 0x3fad: 0x00c0, 0x3fae: 0x00c0, 0x3faf: 0x00c0, + 0x3fb0: 0x00c0, 0x3fb1: 0x00c0, 0x3fb2: 0x00c0, 0x3fb3: 0x00c0, 0x3fb4: 0x00c0, 0x3fb5: 0x00c0, + 0x3fb6: 0x00c0, 0x3fb7: 0x00c0, 0x3fb8: 0x00c0, 0x3fb9: 0x00c0, 0x3fba: 0x00c0, 0x3fbb: 0x00c0, + 0x3fbc: 0x00c0, 0x3fbd: 0x00c0, 0x3fbe: 0x00c0, 0x3fbf: 0x00c0, + // Block 0xff, offset 0x3fc0 + 0x3fc0: 0x00c0, 0x3fc1: 0x00c0, 0x3fc2: 0x00c0, 0x3fc3: 0x00c0, 0x3fc4: 0x00c0, 0x3fc5: 0x00c0, + 0x3fc6: 0x00c0, 0x3fc7: 0x00c0, 0x3fc8: 0x00c0, 0x3fc9: 0x00c0, 0x3fca: 0x00c0, 0x3fcb: 0x00c0, + 0x3fcc: 0x00c0, 0x3fcd: 0x00c0, 0x3fce: 0x00c0, 0x3fcf: 0x00c0, 0x3fd0: 0x00c0, 0x3fd1: 0x00c0, + 0x3fd2: 0x00c0, 0x3fd3: 0x00c0, 0x3fd4: 0x00c0, 0x3fd5: 0x00c0, 0x3fd6: 0x00c0, 0x3fd7: 0x00c0, + 0x3fd8: 0x00c0, 0x3fd9: 0x00c0, 0x3fda: 0x00c0, 0x3fdb: 0x00c0, 0x3fdc: 0x00c0, 0x3fdd: 0x00c0, + 0x3fde: 0x00c0, 0x3fdf: 0x00c0, 0x3fe0: 0x00c0, 0x3fe1: 0x00c0, 0x3fe2: 0x00c0, 0x3fe3: 0x00c0, + 0x3fe4: 0x00c0, 0x3fe5: 0x00c0, 0x3fe6: 0x00c0, 0x3fe7: 0x00c0, 0x3fe8: 0x00c0, 0x3fe9: 0x00c0, + 0x3fea: 0x0080, 0x3feb: 0x0080, 0x3fec: 0x0080, 0x3fed: 0x0080, 0x3fee: 0x0080, 0x3fef: 0x0080, + 0x3ff0: 0x0080, 0x3ff1: 0x0080, 0x3ff2: 0x0080, + 0x3fff: 0x00c0, + // Block 0x100, offset 0x4000 + 0x4020: 0x00c0, 0x4021: 0x00c0, 0x4022: 0x00c0, 0x4023: 0x00c0, + 0x4024: 0x00c0, 0x4025: 0x00c0, 0x4026: 0x00c0, 0x4027: 0x00c0, + 0x402a: 0x00c0, 0x402b: 0x00c0, 0x402c: 0x00c0, 0x402d: 0x00c0, 0x402e: 0x00c0, 0x402f: 0x00c0, + 0x4030: 0x00c0, 0x4031: 0x00c0, 0x4032: 0x00c0, 0x4033: 0x00c0, 0x4034: 0x00c0, 0x4035: 0x00c0, + 0x4036: 0x00c0, 0x4037: 0x00c0, 0x4038: 0x00c0, 0x4039: 0x00c0, 0x403a: 0x00c0, 0x403b: 0x00c0, + 0x403c: 0x00c0, 0x403d: 0x00c0, 0x403e: 0x00c0, 0x403f: 0x00c0, + // Block 0x101, offset 0x4040 + 0x4040: 0x00c0, 0x4041: 0x00c0, 0x4042: 0x00c0, 0x4043: 0x00c0, 0x4044: 0x00c0, 0x4045: 0x00c0, + 0x4046: 0x00c0, 0x4047: 0x00c0, 0x4048: 0x00c0, 0x4049: 0x00c0, 0x404a: 0x00c0, 0x404b: 0x00c0, + 0x404c: 0x00c0, 0x404d: 0x00c0, 0x404e: 0x00c0, 0x404f: 0x00c0, 0x4050: 0x00c0, 0x4051: 0x00c0, + 0x4052: 0x00c0, 0x4053: 0x00c0, 0x4054: 0x00c3, 0x4055: 0x00c3, 0x4056: 0x00c3, 0x4057: 0x00c3, + 0x405a: 0x00c3, 0x405b: 0x00c3, 0x405c: 0x00c0, 0x405d: 0x00c0, + 0x405e: 0x00c0, 0x405f: 0x00c0, 0x4060: 0x00c6, 0x4061: 0x00c0, 0x4062: 0x0080, 0x4063: 0x00c0, + 0x4064: 0x00c0, + // Block 0x102, offset 0x4080 + 0x4080: 0x00c0, 0x4081: 0x00c3, 0x4082: 0x00c3, 0x4083: 0x00c3, 0x4084: 0x00c3, 0x4085: 0x00c3, + 0x4086: 0x00c3, 0x4087: 0x00c3, 0x4088: 0x00c3, 0x4089: 0x00c3, 0x408a: 0x00c3, 0x408b: 0x00c0, + 0x408c: 0x00c0, 0x408d: 0x00c0, 0x408e: 0x00c0, 0x408f: 0x00c0, 0x4090: 0x00c0, 0x4091: 0x00c0, + 0x4092: 0x00c0, 0x4093: 0x00c0, 0x4094: 0x00c0, 0x4095: 0x00c0, 0x4096: 0x00c0, 0x4097: 0x00c0, + 0x4098: 0x00c0, 0x4099: 0x00c0, 0x409a: 0x00c0, 0x409b: 0x00c0, 0x409c: 0x00c0, 0x409d: 0x00c0, + 0x409e: 0x00c0, 0x409f: 0x00c0, 0x40a0: 0x00c0, 0x40a1: 0x00c0, 0x40a2: 0x00c0, 0x40a3: 0x00c0, + 0x40a4: 0x00c0, 0x40a5: 0x00c0, 0x40a6: 0x00c0, 0x40a7: 0x00c0, 0x40a8: 0x00c0, 0x40a9: 0x00c0, + 0x40aa: 0x00c0, 0x40ab: 0x00c0, 0x40ac: 0x00c0, 0x40ad: 0x00c0, 0x40ae: 0x00c0, 0x40af: 0x00c0, + 0x40b0: 0x00c0, 0x40b1: 0x00c0, 0x40b2: 0x00c0, 0x40b3: 0x00c3, 0x40b4: 0x00c6, 0x40b5: 0x00c3, + 0x40b6: 0x00c3, 0x40b7: 0x00c3, 0x40b8: 0x00c3, 0x40b9: 0x00c0, 0x40ba: 0x00c0, 0x40bb: 0x00c3, + 0x40bc: 0x00c3, 0x40bd: 0x00c3, 0x40be: 0x00c3, 0x40bf: 0x0080, + // Block 0x103, offset 0x40c0 + 0x40c0: 0x0080, 0x40c1: 0x0080, 0x40c2: 0x0080, 0x40c3: 0x0080, 0x40c4: 0x0080, 0x40c5: 0x0080, + 0x40c6: 0x0080, 0x40c7: 0x00c6, + 0x40d0: 0x00c0, 0x40d1: 0x00c3, + 0x40d2: 0x00c3, 0x40d3: 0x00c3, 0x40d4: 0x00c3, 0x40d5: 0x00c3, 0x40d6: 0x00c3, 0x40d7: 0x00c0, + 0x40d8: 0x00c0, 0x40d9: 0x00c3, 0x40da: 0x00c3, 0x40db: 0x00c3, 0x40dc: 0x00c0, 0x40dd: 0x00c0, + 0x40de: 0x00c0, 0x40df: 0x00c0, 0x40e0: 0x00c0, 0x40e1: 0x00c0, 0x40e2: 0x00c0, 0x40e3: 0x00c0, + 0x40e4: 0x00c0, 0x40e5: 0x00c0, 0x40e6: 0x00c0, 0x40e7: 0x00c0, 0x40e8: 0x00c0, 0x40e9: 0x00c0, + 0x40ea: 0x00c0, 0x40eb: 0x00c0, 0x40ec: 0x00c0, 0x40ed: 0x00c0, 0x40ee: 0x00c0, 0x40ef: 0x00c0, + 0x40f0: 0x00c0, 0x40f1: 0x00c0, 0x40f2: 0x00c0, 0x40f3: 0x00c0, 0x40f4: 0x00c0, 0x40f5: 0x00c0, + 0x40f6: 0x00c0, 0x40f7: 0x00c0, 0x40f8: 0x00c0, 0x40f9: 0x00c0, 0x40fa: 0x00c0, 0x40fb: 0x00c0, + 0x40fc: 0x00c0, 0x40fd: 0x00c0, 0x40fe: 0x00c0, 0x40ff: 0x00c0, + // Block 0x104, offset 0x4100 + 0x4100: 0x00c0, 0x4101: 0x00c0, 0x4102: 0x00c0, 0x4103: 0x00c0, 0x4104: 0x00c0, 0x4105: 0x00c0, + 0x4106: 0x00c0, 0x4107: 0x00c0, 0x4108: 0x00c0, 0x4109: 0x00c0, 0x410a: 0x00c3, 0x410b: 0x00c3, + 0x410c: 0x00c3, 0x410d: 0x00c3, 0x410e: 0x00c3, 0x410f: 0x00c3, 0x4110: 0x00c3, 0x4111: 0x00c3, + 0x4112: 0x00c3, 0x4113: 0x00c3, 0x4114: 0x00c3, 0x4115: 0x00c3, 0x4116: 0x00c3, 0x4117: 0x00c0, + 0x4118: 0x00c3, 0x4119: 0x00c6, 0x411a: 0x0080, 0x411b: 0x0080, 0x411c: 0x0080, 0x411d: 0x00c0, + 0x411e: 0x0080, 0x411f: 0x0080, 0x4120: 0x0080, 0x4121: 0x0080, 0x4122: 0x0080, + // Block 0x105, offset 0x4140 + 0x4140: 0x00c0, 0x4141: 0x00c0, 0x4142: 0x00c0, 0x4143: 0x00c0, 0x4144: 0x00c0, 0x4145: 0x00c0, + 0x4146: 0x00c0, 0x4147: 0x00c0, 0x4148: 0x00c0, 0x4149: 0x00c0, 0x414a: 0x00c0, 0x414b: 0x00c0, + 0x414c: 0x00c0, 0x414d: 0x00c0, 0x414e: 0x00c0, 0x414f: 0x00c0, 0x4150: 0x00c0, 0x4151: 0x00c0, + 0x4152: 0x00c0, 0x4153: 0x00c0, 0x4154: 0x00c0, 0x4155: 0x00c0, 0x4156: 0x00c0, 0x4157: 0x00c0, + 0x4158: 0x00c0, 0x4159: 0x00c0, 0x415a: 0x00c0, 0x415b: 0x00c0, 0x415c: 0x00c0, 0x415d: 0x00c0, + 0x415e: 0x00c0, 0x415f: 0x00c0, 0x4160: 0x00c0, 0x4161: 0x00c0, 0x4162: 0x00c0, 0x4163: 0x00c0, + 0x4164: 0x00c0, 0x4165: 0x00c0, 0x4166: 0x00c0, 0x4167: 0x00c0, 0x4168: 0x00c0, 0x4169: 0x00c0, + 0x416a: 0x00c0, 0x416b: 0x00c0, 0x416c: 0x00c0, 0x416d: 0x00c0, 0x416e: 0x00c0, 0x416f: 0x00c0, + 0x4170: 0x00c0, 0x4171: 0x00c0, 0x4172: 0x00c0, 0x4173: 0x00c0, 0x4174: 0x00c0, 0x4175: 0x00c0, + 0x4176: 0x00c0, 0x4177: 0x00c0, 0x4178: 0x00c0, + // Block 0x106, offset 0x4180 + 0x4180: 0x00c0, 0x4181: 0x00c0, 0x4182: 0x00c0, 0x4183: 0x00c0, 0x4184: 0x00c0, 0x4185: 0x00c0, + 0x4186: 0x00c0, 0x4187: 0x00c0, 0x4188: 0x00c0, 0x418a: 0x00c0, 0x418b: 0x00c0, + 0x418c: 0x00c0, 0x418d: 0x00c0, 0x418e: 0x00c0, 0x418f: 0x00c0, 0x4190: 0x00c0, 0x4191: 0x00c0, + 0x4192: 0x00c0, 0x4193: 0x00c0, 0x4194: 0x00c0, 0x4195: 0x00c0, 0x4196: 0x00c0, 0x4197: 0x00c0, + 0x4198: 0x00c0, 0x4199: 0x00c0, 0x419a: 0x00c0, 0x419b: 0x00c0, 0x419c: 0x00c0, 0x419d: 0x00c0, + 0x419e: 0x00c0, 0x419f: 0x00c0, 0x41a0: 0x00c0, 0x41a1: 0x00c0, 0x41a2: 0x00c0, 0x41a3: 0x00c0, + 0x41a4: 0x00c0, 0x41a5: 0x00c0, 0x41a6: 0x00c0, 0x41a7: 0x00c0, 0x41a8: 0x00c0, 0x41a9: 0x00c0, + 0x41aa: 0x00c0, 0x41ab: 0x00c0, 0x41ac: 0x00c0, 0x41ad: 0x00c0, 0x41ae: 0x00c0, 0x41af: 0x00c0, + 0x41b0: 0x00c3, 0x41b1: 0x00c3, 0x41b2: 0x00c3, 0x41b3: 0x00c3, 0x41b4: 0x00c3, 0x41b5: 0x00c3, + 0x41b6: 0x00c3, 0x41b8: 0x00c3, 0x41b9: 0x00c3, 0x41ba: 0x00c3, 0x41bb: 0x00c3, + 0x41bc: 0x00c3, 0x41bd: 0x00c3, 0x41be: 0x00c0, 0x41bf: 0x00c6, + // Block 0x107, offset 0x41c0 + 0x41c0: 0x00c0, 0x41c1: 0x0080, 0x41c2: 0x0080, 0x41c3: 0x0080, 0x41c4: 0x0080, 0x41c5: 0x0080, + 0x41d0: 0x00c0, 0x41d1: 0x00c0, + 0x41d2: 0x00c0, 0x41d3: 0x00c0, 0x41d4: 0x00c0, 0x41d5: 0x00c0, 0x41d6: 0x00c0, 0x41d7: 0x00c0, + 0x41d8: 0x00c0, 0x41d9: 0x00c0, 0x41da: 0x0080, 0x41db: 0x0080, 0x41dc: 0x0080, 0x41dd: 0x0080, + 0x41de: 0x0080, 0x41df: 0x0080, 0x41e0: 0x0080, 0x41e1: 0x0080, 0x41e2: 0x0080, 0x41e3: 0x0080, + 0x41e4: 0x0080, 0x41e5: 0x0080, 0x41e6: 0x0080, 0x41e7: 0x0080, 0x41e8: 0x0080, 0x41e9: 0x0080, + 0x41ea: 0x0080, 0x41eb: 0x0080, 0x41ec: 0x0080, + 0x41f0: 0x0080, 0x41f1: 0x0080, 0x41f2: 0x00c0, 0x41f3: 0x00c0, 0x41f4: 0x00c0, 0x41f5: 0x00c0, + 0x41f6: 0x00c0, 0x41f7: 0x00c0, 0x41f8: 0x00c0, 0x41f9: 0x00c0, 0x41fa: 0x00c0, 0x41fb: 0x00c0, + 0x41fc: 0x00c0, 0x41fd: 0x00c0, 0x41fe: 0x00c0, 0x41ff: 0x00c0, + // Block 0x108, offset 0x4200 + 0x4200: 0x00c0, 0x4201: 0x00c0, 0x4202: 0x00c0, 0x4203: 0x00c0, 0x4204: 0x00c0, 0x4205: 0x00c0, + 0x4206: 0x00c0, 0x4207: 0x00c0, 0x4208: 0x00c0, 0x4209: 0x00c0, 0x420a: 0x00c0, 0x420b: 0x00c0, + 0x420c: 0x00c0, 0x420d: 0x00c0, 0x420e: 0x00c0, 0x420f: 0x00c0, + 0x4212: 0x00c3, 0x4213: 0x00c3, 0x4214: 0x00c3, 0x4215: 0x00c3, 0x4216: 0x00c3, 0x4217: 0x00c3, + 0x4218: 0x00c3, 0x4219: 0x00c3, 0x421a: 0x00c3, 0x421b: 0x00c3, 0x421c: 0x00c3, 0x421d: 0x00c3, + 0x421e: 0x00c3, 0x421f: 0x00c3, 0x4220: 0x00c3, 0x4221: 0x00c3, 0x4222: 0x00c3, 0x4223: 0x00c3, + 0x4224: 0x00c3, 0x4225: 0x00c3, 0x4226: 0x00c3, 0x4227: 0x00c3, 0x4229: 0x00c0, + 0x422a: 0x00c3, 0x422b: 0x00c3, 0x422c: 0x00c3, 0x422d: 0x00c3, 0x422e: 0x00c3, 0x422f: 0x00c3, + 0x4230: 0x00c3, 0x4231: 0x00c0, 0x4232: 0x00c3, 0x4233: 0x00c3, 0x4234: 0x00c0, 0x4235: 0x00c3, + 0x4236: 0x00c3, + // Block 0x109, offset 0x4240 + 0x4240: 0x00c0, 0x4241: 0x00c0, 0x4242: 0x00c0, 0x4243: 0x00c0, 0x4244: 0x00c0, 0x4245: 0x00c0, + 0x4246: 0x00c0, 0x4248: 0x00c0, 0x4249: 0x00c0, 0x424b: 0x00c0, + 0x424c: 0x00c0, 0x424d: 0x00c0, 0x424e: 0x00c0, 0x424f: 0x00c0, 0x4250: 0x00c0, 0x4251: 0x00c0, + 0x4252: 0x00c0, 0x4253: 0x00c0, 0x4254: 0x00c0, 0x4255: 0x00c0, 0x4256: 0x00c0, 0x4257: 0x00c0, + 0x4258: 0x00c0, 0x4259: 0x00c0, 0x425a: 0x00c0, 0x425b: 0x00c0, 0x425c: 0x00c0, 0x425d: 0x00c0, + 0x425e: 0x00c0, 0x425f: 0x00c0, 0x4260: 0x00c0, 0x4261: 0x00c0, 0x4262: 0x00c0, 0x4263: 0x00c0, + 0x4264: 0x00c0, 0x4265: 0x00c0, 0x4266: 0x00c0, 0x4267: 0x00c0, 0x4268: 0x00c0, 0x4269: 0x00c0, + 0x426a: 0x00c0, 0x426b: 0x00c0, 0x426c: 0x00c0, 0x426d: 0x00c0, 0x426e: 0x00c0, 0x426f: 0x00c0, + 0x4270: 0x00c0, 0x4271: 0x00c3, 0x4272: 0x00c3, 0x4273: 0x00c3, 0x4274: 0x00c3, 0x4275: 0x00c3, + 0x4276: 0x00c3, 0x427a: 0x00c3, + 0x427c: 0x00c3, 0x427d: 0x00c3, 0x427f: 0x00c3, + // Block 0x10a, offset 0x4280 + 0x4280: 0x00c3, 0x4281: 0x00c3, 0x4282: 0x00c3, 0x4283: 0x00c3, 0x4284: 0x00c6, 0x4285: 0x00c6, + 0x4286: 0x00c0, 0x4287: 0x00c3, + 0x4290: 0x00c0, 0x4291: 0x00c0, + 0x4292: 0x00c0, 0x4293: 0x00c0, 0x4294: 0x00c0, 0x4295: 0x00c0, 0x4296: 0x00c0, 0x4297: 0x00c0, + 0x4298: 0x00c0, 0x4299: 0x00c0, + 0x42a0: 0x00c0, 0x42a1: 0x00c0, 0x42a2: 0x00c0, 0x42a3: 0x00c0, + 0x42a4: 0x00c0, 0x42a5: 0x00c0, 0x42a7: 0x00c0, 0x42a8: 0x00c0, + 0x42aa: 0x00c0, 0x42ab: 0x00c0, 0x42ac: 0x00c0, 0x42ad: 0x00c0, 0x42ae: 0x00c0, 0x42af: 0x00c0, + 0x42b0: 0x00c0, 0x42b1: 0x00c0, 0x42b2: 0x00c0, 0x42b3: 0x00c0, 0x42b4: 0x00c0, 0x42b5: 0x00c0, + 0x42b6: 0x00c0, 0x42b7: 0x00c0, 0x42b8: 0x00c0, 0x42b9: 0x00c0, 0x42ba: 0x00c0, 0x42bb: 0x00c0, + 0x42bc: 0x00c0, 0x42bd: 0x00c0, 0x42be: 0x00c0, 0x42bf: 0x00c0, + // Block 0x10b, offset 0x42c0 + 0x42c0: 0x00c0, 0x42c1: 0x00c0, 0x42c2: 0x00c0, 0x42c3: 0x00c0, 0x42c4: 0x00c0, 0x42c5: 0x00c0, + 0x42c6: 0x00c0, 0x42c7: 0x00c0, 0x42c8: 0x00c0, 0x42c9: 0x00c0, 0x42ca: 0x00c0, 0x42cb: 0x00c0, + 0x42cc: 0x00c0, 0x42cd: 0x00c0, 0x42ce: 0x00c0, 0x42d0: 0x00c3, 0x42d1: 0x00c3, + 0x42d3: 0x00c0, 0x42d4: 0x00c0, 0x42d5: 0x00c3, 0x42d6: 0x00c0, 0x42d7: 0x00c6, + 0x42d8: 0x00c0, + 0x42e0: 0x00c0, 0x42e1: 0x00c0, 0x42e2: 0x00c0, 0x42e3: 0x00c0, + 0x42e4: 0x00c0, 0x42e5: 0x00c0, 0x42e6: 0x00c0, 0x42e7: 0x00c0, 0x42e8: 0x00c0, 0x42e9: 0x00c0, + // Block 0x10c, offset 0x4300 + 0x4320: 0x00c0, 0x4321: 0x00c0, 0x4322: 0x00c0, 0x4323: 0x00c0, + 0x4324: 0x00c0, 0x4325: 0x00c0, 0x4326: 0x00c0, 0x4327: 0x00c0, 0x4328: 0x00c0, 0x4329: 0x00c0, + 0x432a: 0x00c0, 0x432b: 0x00c0, 0x432c: 0x00c0, 0x432d: 0x00c0, 0x432e: 0x00c0, 0x432f: 0x00c0, + 0x4330: 0x00c0, 0x4331: 0x00c0, 0x4332: 0x00c0, 0x4333: 0x00c3, 0x4334: 0x00c3, 0x4335: 0x00c0, + 0x4336: 0x00c0, 0x4337: 0x0080, 0x4338: 0x0080, + // Block 0x10d, offset 0x4340 + 0x4340: 0x0080, 0x4341: 0x0080, 0x4342: 0x0080, 0x4343: 0x0080, 0x4344: 0x0080, 0x4345: 0x0080, + 0x4346: 0x0080, 0x4347: 0x0080, 0x4348: 0x0080, 0x4349: 0x0080, 0x434a: 0x0080, 0x434b: 0x0080, + 0x434c: 0x0080, 0x434d: 0x0080, 0x434e: 0x0080, 0x434f: 0x0080, 0x4350: 0x0080, 0x4351: 0x0080, + 0x4352: 0x0080, 0x4353: 0x0080, 0x4354: 0x0080, 0x4355: 0x0080, 0x4356: 0x0080, 0x4357: 0x0080, + 0x4358: 0x0080, 0x4359: 0x0080, 0x435a: 0x0080, 0x435b: 0x0080, 0x435c: 0x0080, 0x435d: 0x0080, + 0x435e: 0x0080, 0x435f: 0x0080, 0x4360: 0x0080, 0x4361: 0x0080, 0x4362: 0x0080, 0x4363: 0x0080, + 0x4364: 0x0080, 0x4365: 0x0080, 0x4366: 0x0080, 0x4367: 0x0080, 0x4368: 0x0080, 0x4369: 0x0080, + 0x436a: 0x0080, 0x436b: 0x0080, 0x436c: 0x0080, 0x436d: 0x0080, 0x436e: 0x0080, 0x436f: 0x0080, + 0x4370: 0x0080, 0x4371: 0x0080, + 0x437f: 0x0080, + // Block 0x10e, offset 0x4380 + 0x4380: 0x00c0, 0x4381: 0x00c0, 0x4382: 0x00c0, 0x4383: 0x00c0, 0x4384: 0x00c0, 0x4385: 0x00c0, + 0x4386: 0x00c0, 0x4387: 0x00c0, 0x4388: 0x00c0, 0x4389: 0x00c0, 0x438a: 0x00c0, 0x438b: 0x00c0, + 0x438c: 0x00c0, 0x438d: 0x00c0, 0x438e: 0x00c0, 0x438f: 0x00c0, 0x4390: 0x00c0, 0x4391: 0x00c0, + 0x4392: 0x00c0, 0x4393: 0x00c0, 0x4394: 0x00c0, 0x4395: 0x00c0, 0x4396: 0x00c0, 0x4397: 0x00c0, + 0x4398: 0x00c0, 0x4399: 0x00c0, + // Block 0x10f, offset 0x43c0 + 0x43c0: 0x0080, 0x43c1: 0x0080, 0x43c2: 0x0080, 0x43c3: 0x0080, 0x43c4: 0x0080, 0x43c5: 0x0080, + 0x43c6: 0x0080, 0x43c7: 0x0080, 0x43c8: 0x0080, 0x43c9: 0x0080, 0x43ca: 0x0080, 0x43cb: 0x0080, + 0x43cc: 0x0080, 0x43cd: 0x0080, 0x43ce: 0x0080, 0x43cf: 0x0080, 0x43d0: 0x0080, 0x43d1: 0x0080, + 0x43d2: 0x0080, 0x43d3: 0x0080, 0x43d4: 0x0080, 0x43d5: 0x0080, 0x43d6: 0x0080, 0x43d7: 0x0080, + 0x43d8: 0x0080, 0x43d9: 0x0080, 0x43da: 0x0080, 0x43db: 0x0080, 0x43dc: 0x0080, 0x43dd: 0x0080, + 0x43de: 0x0080, 0x43df: 0x0080, 0x43e0: 0x0080, 0x43e1: 0x0080, 0x43e2: 0x0080, 0x43e3: 0x0080, + 0x43e4: 0x0080, 0x43e5: 0x0080, 0x43e6: 0x0080, 0x43e7: 0x0080, 0x43e8: 0x0080, 0x43e9: 0x0080, + 0x43ea: 0x0080, 0x43eb: 0x0080, 0x43ec: 0x0080, 0x43ed: 0x0080, 0x43ee: 0x0080, + 0x43f0: 0x0080, 0x43f1: 0x0080, 0x43f2: 0x0080, 0x43f3: 0x0080, 0x43f4: 0x0080, + // Block 0x110, offset 0x4400 + 0x4400: 0x00c0, 0x4401: 0x00c0, 0x4402: 0x00c0, 0x4403: 0x00c0, + // Block 0x111, offset 0x4440 + 0x4440: 0x00c0, 0x4441: 0x00c0, 0x4442: 0x00c0, 0x4443: 0x00c0, 0x4444: 0x00c0, 0x4445: 0x00c0, + 0x4446: 0x00c0, 0x4447: 0x00c0, 0x4448: 0x00c0, 0x4449: 0x00c0, 0x444a: 0x00c0, 0x444b: 0x00c0, + 0x444c: 0x00c0, 0x444d: 0x00c0, 0x444e: 0x00c0, 0x444f: 0x00c0, 0x4450: 0x00c0, 0x4451: 0x00c0, + 0x4452: 0x00c0, 0x4453: 0x00c0, 0x4454: 0x00c0, 0x4455: 0x00c0, 0x4456: 0x00c0, 0x4457: 0x00c0, + 0x4458: 0x00c0, 0x4459: 0x00c0, 0x445a: 0x00c0, 0x445b: 0x00c0, 0x445c: 0x00c0, 0x445d: 0x00c0, + 0x445e: 0x00c0, 0x445f: 0x00c0, 0x4460: 0x00c0, 0x4461: 0x00c0, 0x4462: 0x00c0, 0x4463: 0x00c0, + 0x4464: 0x00c0, 0x4465: 0x00c0, 0x4466: 0x00c0, 0x4467: 0x00c0, 0x4468: 0x00c0, 0x4469: 0x00c0, + 0x446a: 0x00c0, 0x446b: 0x00c0, 0x446c: 0x00c0, 0x446d: 0x00c0, 0x446e: 0x00c0, + 0x4470: 0x0040, 0x4471: 0x0040, 0x4472: 0x0040, 0x4473: 0x0040, 0x4474: 0x0040, 0x4475: 0x0040, + 0x4476: 0x0040, 0x4477: 0x0040, 0x4478: 0x0040, + // Block 0x112, offset 0x4480 + 0x4480: 0x00c0, 0x4481: 0x00c0, 0x4482: 0x00c0, 0x4483: 0x00c0, 0x4484: 0x00c0, 0x4485: 0x00c0, + 0x4486: 0x00c0, + // Block 0x113, offset 0x44c0 + 0x44c0: 0x00c0, 0x44c1: 0x00c0, 0x44c2: 0x00c0, 0x44c3: 0x00c0, 0x44c4: 0x00c0, 0x44c5: 0x00c0, + 0x44c6: 0x00c0, 0x44c7: 0x00c0, 0x44c8: 0x00c0, 0x44c9: 0x00c0, 0x44ca: 0x00c0, 0x44cb: 0x00c0, + 0x44cc: 0x00c0, 0x44cd: 0x00c0, 0x44ce: 0x00c0, 0x44cf: 0x00c0, 0x44d0: 0x00c0, 0x44d1: 0x00c0, + 0x44d2: 0x00c0, 0x44d3: 0x00c0, 0x44d4: 0x00c0, 0x44d5: 0x00c0, 0x44d6: 0x00c0, 0x44d7: 0x00c0, + 0x44d8: 0x00c0, 0x44d9: 0x00c0, 0x44da: 0x00c0, 0x44db: 0x00c0, 0x44dc: 0x00c0, 0x44dd: 0x00c0, + 0x44de: 0x00c0, 0x44e0: 0x00c0, 0x44e1: 0x00c0, 0x44e2: 0x00c0, 0x44e3: 0x00c0, + 0x44e4: 0x00c0, 0x44e5: 0x00c0, 0x44e6: 0x00c0, 0x44e7: 0x00c0, 0x44e8: 0x00c0, 0x44e9: 0x00c0, + 0x44ee: 0x0080, 0x44ef: 0x0080, + // Block 0x114, offset 0x4500 + 0x4510: 0x00c0, 0x4511: 0x00c0, + 0x4512: 0x00c0, 0x4513: 0x00c0, 0x4514: 0x00c0, 0x4515: 0x00c0, 0x4516: 0x00c0, 0x4517: 0x00c0, + 0x4518: 0x00c0, 0x4519: 0x00c0, 0x451a: 0x00c0, 0x451b: 0x00c0, 0x451c: 0x00c0, 0x451d: 0x00c0, + 0x451e: 0x00c0, 0x451f: 0x00c0, 0x4520: 0x00c0, 0x4521: 0x00c0, 0x4522: 0x00c0, 0x4523: 0x00c0, + 0x4524: 0x00c0, 0x4525: 0x00c0, 0x4526: 0x00c0, 0x4527: 0x00c0, 0x4528: 0x00c0, 0x4529: 0x00c0, + 0x452a: 0x00c0, 0x452b: 0x00c0, 0x452c: 0x00c0, 0x452d: 0x00c0, + 0x4530: 0x00c3, 0x4531: 0x00c3, 0x4532: 0x00c3, 0x4533: 0x00c3, 0x4534: 0x00c3, 0x4535: 0x0080, + // Block 0x115, offset 0x4540 + 0x4540: 0x00c0, 0x4541: 0x00c0, 0x4542: 0x00c0, 0x4543: 0x00c0, 0x4544: 0x00c0, 0x4545: 0x00c0, + 0x4546: 0x00c0, 0x4547: 0x00c0, 0x4548: 0x00c0, 0x4549: 0x00c0, 0x454a: 0x00c0, 0x454b: 0x00c0, + 0x454c: 0x00c0, 0x454d: 0x00c0, 0x454e: 0x00c0, 0x454f: 0x00c0, 0x4550: 0x00c0, 0x4551: 0x00c0, + 0x4552: 0x00c0, 0x4553: 0x00c0, 0x4554: 0x00c0, 0x4555: 0x00c0, 0x4556: 0x00c0, 0x4557: 0x00c0, + 0x4558: 0x00c0, 0x4559: 0x00c0, 0x455a: 0x00c0, 0x455b: 0x00c0, 0x455c: 0x00c0, 0x455d: 0x00c0, + 0x455e: 0x00c0, 0x455f: 0x00c0, 0x4560: 0x00c0, 0x4561: 0x00c0, 0x4562: 0x00c0, 0x4563: 0x00c0, + 0x4564: 0x00c0, 0x4565: 0x00c0, 0x4566: 0x00c0, 0x4567: 0x00c0, 0x4568: 0x00c0, 0x4569: 0x00c0, + 0x456a: 0x00c0, 0x456b: 0x00c0, 0x456c: 0x00c0, 0x456d: 0x00c0, 0x456e: 0x00c0, 0x456f: 0x00c0, + 0x4570: 0x00c3, 0x4571: 0x00c3, 0x4572: 0x00c3, 0x4573: 0x00c3, 0x4574: 0x00c3, 0x4575: 0x00c3, + 0x4576: 0x00c3, 0x4577: 0x0080, 0x4578: 0x0080, 0x4579: 0x0080, 0x457a: 0x0080, 0x457b: 0x0080, + 0x457c: 0x0080, 0x457d: 0x0080, 0x457e: 0x0080, 0x457f: 0x0080, + // Block 0x116, offset 0x4580 + 0x4580: 0x00c0, 0x4581: 0x00c0, 0x4582: 0x00c0, 0x4583: 0x00c0, 0x4584: 0x0080, 0x4585: 0x0080, + 0x4590: 0x00c0, 0x4591: 0x00c0, + 0x4592: 0x00c0, 0x4593: 0x00c0, 0x4594: 0x00c0, 0x4595: 0x00c0, 0x4596: 0x00c0, 0x4597: 0x00c0, + 0x4598: 0x00c0, 0x4599: 0x00c0, 0x459b: 0x0080, 0x459c: 0x0080, 0x459d: 0x0080, + 0x459e: 0x0080, 0x459f: 0x0080, 0x45a0: 0x0080, 0x45a1: 0x0080, 0x45a3: 0x00c0, + 0x45a4: 0x00c0, 0x45a5: 0x00c0, 0x45a6: 0x00c0, 0x45a7: 0x00c0, 0x45a8: 0x00c0, 0x45a9: 0x00c0, + 0x45aa: 0x00c0, 0x45ab: 0x00c0, 0x45ac: 0x00c0, 0x45ad: 0x00c0, 0x45ae: 0x00c0, 0x45af: 0x00c0, + 0x45b0: 0x00c0, 0x45b1: 0x00c0, 0x45b2: 0x00c0, 0x45b3: 0x00c0, 0x45b4: 0x00c0, 0x45b5: 0x00c0, + 0x45b6: 0x00c0, 0x45b7: 0x00c0, + 0x45bd: 0x00c0, 0x45be: 0x00c0, 0x45bf: 0x00c0, + // Block 0x117, offset 0x45c0 + 0x45c0: 0x00c0, 0x45c1: 0x00c0, 0x45c2: 0x00c0, 0x45c3: 0x00c0, 0x45c4: 0x00c0, 0x45c5: 0x00c0, + 0x45c6: 0x00c0, 0x45c7: 0x00c0, 0x45c8: 0x00c0, 0x45c9: 0x00c0, 0x45ca: 0x00c0, 0x45cb: 0x00c0, + 0x45cc: 0x00c0, 0x45cd: 0x00c0, 0x45ce: 0x00c0, 0x45cf: 0x00c0, + // Block 0x118, offset 0x4600 + 0x4600: 0x0080, 0x4601: 0x0080, 0x4602: 0x0080, 0x4603: 0x0080, 0x4604: 0x0080, 0x4605: 0x0080, + 0x4606: 0x0080, 0x4607: 0x0080, 0x4608: 0x0080, 0x4609: 0x0080, 0x460a: 0x0080, 0x460b: 0x0080, + 0x460c: 0x0080, 0x460d: 0x0080, 0x460e: 0x0080, 0x460f: 0x0080, 0x4610: 0x0080, 0x4611: 0x0080, + 0x4612: 0x0080, 0x4613: 0x0080, 0x4614: 0x0080, 0x4615: 0x0080, 0x4616: 0x0080, 0x4617: 0x0080, + 0x4618: 0x0080, 0x4619: 0x0080, 0x461a: 0x0080, + // Block 0x119, offset 0x4640 + 0x4640: 0x00c0, 0x4641: 0x00c0, 0x4642: 0x00c0, 0x4643: 0x00c0, 0x4644: 0x00c0, 0x4645: 0x00c0, + 0x4646: 0x00c0, 0x4647: 0x00c0, 0x4648: 0x00c0, 0x4649: 0x00c0, 0x464a: 0x00c0, + 0x464f: 0x00c3, 0x4650: 0x00c0, 0x4651: 0x00c0, + 0x4652: 0x00c0, 0x4653: 0x00c0, 0x4654: 0x00c0, 0x4655: 0x00c0, 0x4656: 0x00c0, 0x4657: 0x00c0, + 0x4658: 0x00c0, 0x4659: 0x00c0, 0x465a: 0x00c0, 0x465b: 0x00c0, 0x465c: 0x00c0, 0x465d: 0x00c0, + 0x465e: 0x00c0, 0x465f: 0x00c0, 0x4660: 0x00c0, 0x4661: 0x00c0, 0x4662: 0x00c0, 0x4663: 0x00c0, + 0x4664: 0x00c0, 0x4665: 0x00c0, 0x4666: 0x00c0, 0x4667: 0x00c0, 0x4668: 0x00c0, 0x4669: 0x00c0, + 0x466a: 0x00c0, 0x466b: 0x00c0, 0x466c: 0x00c0, 0x466d: 0x00c0, 0x466e: 0x00c0, 0x466f: 0x00c0, + 0x4670: 0x00c0, 0x4671: 0x00c0, 0x4672: 0x00c0, 0x4673: 0x00c0, 0x4674: 0x00c0, 0x4675: 0x00c0, + 0x4676: 0x00c0, 0x4677: 0x00c0, 0x4678: 0x00c0, 0x4679: 0x00c0, 0x467a: 0x00c0, 0x467b: 0x00c0, + 0x467c: 0x00c0, 0x467d: 0x00c0, 0x467e: 0x00c0, 0x467f: 0x00c0, + // Block 0x11a, offset 0x4680 + 0x4680: 0x00c0, 0x4681: 0x00c0, 0x4682: 0x00c0, 0x4683: 0x00c0, 0x4684: 0x00c0, 0x4685: 0x00c0, + 0x4686: 0x00c0, 0x4687: 0x00c0, + 0x468f: 0x00c3, 0x4690: 0x00c3, 0x4691: 0x00c3, + 0x4692: 0x00c3, 0x4693: 0x00c0, 0x4694: 0x00c0, 0x4695: 0x00c0, 0x4696: 0x00c0, 0x4697: 0x00c0, + 0x4698: 0x00c0, 0x4699: 0x00c0, 0x469a: 0x00c0, 0x469b: 0x00c0, 0x469c: 0x00c0, 0x469d: 0x00c0, + 0x469e: 0x00c0, 0x469f: 0x00c0, + // Block 0x11b, offset 0x46c0 + 0x46e0: 0x00c0, 0x46e1: 0x00c0, 0x46e2: 0x0080, 0x46e3: 0x00c0, + // Block 0x11c, offset 0x4700 + 0x4700: 0x00c0, 0x4701: 0x00c0, 0x4702: 0x00c0, 0x4703: 0x00c0, 0x4704: 0x00c0, 0x4705: 0x00c0, + 0x4706: 0x00c0, 0x4707: 0x00c0, 0x4708: 0x00c0, 0x4709: 0x00c0, 0x470a: 0x00c0, 0x470b: 0x00c0, + 0x470c: 0x00c0, 0x470d: 0x00c0, 0x470e: 0x00c0, 0x470f: 0x00c0, 0x4710: 0x00c0, 0x4711: 0x00c0, + 0x4712: 0x00c0, 0x4713: 0x00c0, 0x4714: 0x00c0, 0x4715: 0x00c0, 0x4716: 0x00c0, 0x4717: 0x00c0, + 0x4718: 0x00c0, 0x4719: 0x00c0, 0x471a: 0x00c0, 0x471b: 0x00c0, 0x471c: 0x00c0, 0x471d: 0x00c0, + 0x471e: 0x00c0, 0x471f: 0x00c0, 0x4720: 0x00c0, 0x4721: 0x00c0, 0x4722: 0x00c0, 0x4723: 0x00c0, + 0x4724: 0x00c0, 0x4725: 0x00c0, 0x4726: 0x00c0, 0x4727: 0x00c0, 0x4728: 0x00c0, 0x4729: 0x00c0, + 0x472a: 0x00c0, 0x472b: 0x00c0, 0x472c: 0x00c0, 0x472d: 0x00c0, 0x472e: 0x00c0, 0x472f: 0x00c0, + 0x4730: 0x00c0, 0x4731: 0x00c0, 0x4732: 0x00c0, 0x4733: 0x00c0, 0x4734: 0x00c0, 0x4735: 0x00c0, + 0x4736: 0x00c0, 0x4737: 0x00c0, + // Block 0x11d, offset 0x4740 + 0x4740: 0x00cc, 0x4741: 0x00cc, 0x4742: 0x00cc, 0x4743: 0x00cc, 0x4744: 0x00cc, 0x4745: 0x00cc, + 0x4746: 0x00cc, 0x4747: 0x00cc, 0x4748: 0x00cc, 0x4749: 0x00cc, 0x474a: 0x00cc, 0x474b: 0x00cc, + 0x474c: 0x00cc, 0x474d: 0x00cc, 0x474e: 0x00cc, 0x474f: 0x00cc, 0x4750: 0x00cc, 0x4751: 0x00cc, + 0x4752: 0x00cc, 0x4753: 0x00cc, 0x4754: 0x00cc, 0x4755: 0x00cc, 0x4756: 0x00cc, 0x4757: 0x00cc, + 0x4758: 0x00cc, 0x4759: 0x00cc, 0x475a: 0x00cc, 0x475b: 0x00cc, 0x475c: 0x00cc, 0x475d: 0x00cc, + 0x475e: 0x00cc, + // Block 0x11e, offset 0x4780 + 0x4790: 0x00cc, 0x4791: 0x00cc, + 0x4792: 0x00cc, + 0x47a4: 0x00cc, 0x47a5: 0x00cc, 0x47a6: 0x00cc, 0x47a7: 0x00cc, + 0x47b0: 0x00c0, 0x47b1: 0x00c0, 0x47b2: 0x00c0, 0x47b3: 0x00c0, 0x47b4: 0x00c0, 0x47b5: 0x00c0, + 0x47b6: 0x00c0, 0x47b7: 0x00c0, 0x47b8: 0x00c0, 0x47b9: 0x00c0, 0x47ba: 0x00c0, 0x47bb: 0x00c0, + 0x47bc: 0x00c0, 0x47bd: 0x00c0, 0x47be: 0x00c0, 0x47bf: 0x00c0, + // Block 0x11f, offset 0x47c0 + 0x47c0: 0x00c0, 0x47c1: 0x00c0, 0x47c2: 0x00c0, 0x47c3: 0x00c0, 0x47c4: 0x00c0, 0x47c5: 0x00c0, + 0x47c6: 0x00c0, 0x47c7: 0x00c0, 0x47c8: 0x00c0, 0x47c9: 0x00c0, 0x47ca: 0x00c0, 0x47cb: 0x00c0, + 0x47cc: 0x00c0, 0x47cd: 0x00c0, 0x47ce: 0x00c0, 0x47cf: 0x00c0, 0x47d0: 0x00c0, 0x47d1: 0x00c0, + 0x47d2: 0x00c0, 0x47d3: 0x00c0, 0x47d4: 0x00c0, 0x47d5: 0x00c0, 0x47d6: 0x00c0, 0x47d7: 0x00c0, + 0x47d8: 0x00c0, 0x47d9: 0x00c0, 0x47da: 0x00c0, 0x47db: 0x00c0, 0x47dc: 0x00c0, 0x47dd: 0x00c0, + 0x47de: 0x00c0, 0x47df: 0x00c0, 0x47e0: 0x00c0, 0x47e1: 0x00c0, 0x47e2: 0x00c0, 0x47e3: 0x00c0, + 0x47e4: 0x00c0, 0x47e5: 0x00c0, 0x47e6: 0x00c0, 0x47e7: 0x00c0, 0x47e8: 0x00c0, 0x47e9: 0x00c0, + 0x47ea: 0x00c0, 0x47eb: 0x00c0, 0x47ec: 0x00c0, 0x47ed: 0x00c0, 0x47ee: 0x00c0, 0x47ef: 0x00c0, + 0x47f0: 0x00c0, 0x47f1: 0x00c0, 0x47f2: 0x00c0, 0x47f3: 0x00c0, 0x47f4: 0x00c0, 0x47f5: 0x00c0, + 0x47f6: 0x00c0, 0x47f7: 0x00c0, 0x47f8: 0x00c0, 0x47f9: 0x00c0, 0x47fa: 0x00c0, 0x47fb: 0x00c0, + // Block 0x120, offset 0x4800 + 0x4800: 0x00c0, 0x4801: 0x00c0, 0x4802: 0x00c0, 0x4803: 0x00c0, 0x4804: 0x00c0, 0x4805: 0x00c0, + 0x4806: 0x00c0, 0x4807: 0x00c0, 0x4808: 0x00c0, 0x4809: 0x00c0, 0x480a: 0x00c0, 0x480b: 0x00c0, + 0x480c: 0x00c0, 0x480d: 0x00c0, 0x480e: 0x00c0, 0x480f: 0x00c0, 0x4810: 0x00c0, 0x4811: 0x00c0, + 0x4812: 0x00c0, 0x4813: 0x00c0, 0x4814: 0x00c0, 0x4815: 0x00c0, 0x4816: 0x00c0, 0x4817: 0x00c0, + 0x4818: 0x00c0, 0x4819: 0x00c0, 0x481a: 0x00c0, 0x481b: 0x00c0, 0x481c: 0x00c0, 0x481d: 0x00c0, + 0x481e: 0x00c0, 0x481f: 0x00c0, 0x4820: 0x00c0, 0x4821: 0x00c0, 0x4822: 0x00c0, 0x4823: 0x00c0, + 0x4824: 0x00c0, 0x4825: 0x00c0, 0x4826: 0x00c0, 0x4827: 0x00c0, 0x4828: 0x00c0, 0x4829: 0x00c0, + 0x482a: 0x00c0, + 0x4830: 0x00c0, 0x4831: 0x00c0, 0x4832: 0x00c0, 0x4833: 0x00c0, 0x4834: 0x00c0, 0x4835: 0x00c0, + 0x4836: 0x00c0, 0x4837: 0x00c0, 0x4838: 0x00c0, 0x4839: 0x00c0, 0x483a: 0x00c0, 0x483b: 0x00c0, + 0x483c: 0x00c0, + // Block 0x121, offset 0x4840 + 0x4840: 0x00c0, 0x4841: 0x00c0, 0x4842: 0x00c0, 0x4843: 0x00c0, 0x4844: 0x00c0, 0x4845: 0x00c0, + 0x4846: 0x00c0, 0x4847: 0x00c0, 0x4848: 0x00c0, + 0x4850: 0x00c0, 0x4851: 0x00c0, + 0x4852: 0x00c0, 0x4853: 0x00c0, 0x4854: 0x00c0, 0x4855: 0x00c0, 0x4856: 0x00c0, 0x4857: 0x00c0, + 0x4858: 0x00c0, 0x4859: 0x00c0, 0x485c: 0x0080, 0x485d: 0x00c3, + 0x485e: 0x00c3, 0x485f: 0x0080, 0x4860: 0x0040, 0x4861: 0x0040, 0x4862: 0x0040, 0x4863: 0x0040, + // Block 0x122, offset 0x4880 + 0x4880: 0x0080, 0x4881: 0x0080, 0x4882: 0x0080, 0x4883: 0x0080, 0x4884: 0x0080, 0x4885: 0x0080, + 0x4886: 0x0080, 0x4887: 0x0080, 0x4888: 0x0080, 0x4889: 0x0080, 0x488a: 0x0080, 0x488b: 0x0080, + 0x488c: 0x0080, 0x488d: 0x0080, 0x488e: 0x0080, 0x488f: 0x0080, 0x4890: 0x0080, 0x4891: 0x0080, + 0x4892: 0x0080, 0x4893: 0x0080, 0x4894: 0x0080, 0x4895: 0x0080, 0x4896: 0x0080, 0x4897: 0x0080, + 0x4898: 0x0080, 0x4899: 0x0080, 0x489a: 0x0080, 0x489b: 0x0080, 0x489c: 0x0080, 0x489d: 0x0080, + 0x489e: 0x0080, 0x489f: 0x0080, 0x48a0: 0x0080, 0x48a1: 0x0080, 0x48a2: 0x0080, 0x48a3: 0x0080, + 0x48a4: 0x0080, 0x48a5: 0x0080, 0x48a6: 0x0080, 0x48a7: 0x0080, 0x48a8: 0x0080, 0x48a9: 0x0080, + 0x48aa: 0x0080, 0x48ab: 0x0080, 0x48ac: 0x0080, 0x48ad: 0x0080, 0x48ae: 0x0080, 0x48af: 0x0080, + 0x48b0: 0x0080, 0x48b1: 0x0080, 0x48b2: 0x0080, 0x48b3: 0x0080, 0x48b4: 0x0080, 0x48b5: 0x0080, + // Block 0x123, offset 0x48c0 + 0x48c0: 0x0080, 0x48c1: 0x0080, 0x48c2: 0x0080, 0x48c3: 0x0080, 0x48c4: 0x0080, 0x48c5: 0x0080, + 0x48c6: 0x0080, 0x48c7: 0x0080, 0x48c8: 0x0080, 0x48c9: 0x0080, 0x48ca: 0x0080, 0x48cb: 0x0080, + 0x48cc: 0x0080, 0x48cd: 0x0080, 0x48ce: 0x0080, 0x48cf: 0x0080, 0x48d0: 0x0080, 0x48d1: 0x0080, + 0x48d2: 0x0080, 0x48d3: 0x0080, 0x48d4: 0x0080, 0x48d5: 0x0080, 0x48d6: 0x0080, 0x48d7: 0x0080, + 0x48d8: 0x0080, 0x48d9: 0x0080, 0x48da: 0x0080, 0x48db: 0x0080, 0x48dc: 0x0080, 0x48dd: 0x0080, + 0x48de: 0x0080, 0x48df: 0x0080, 0x48e0: 0x0080, 0x48e1: 0x0080, 0x48e2: 0x0080, 0x48e3: 0x0080, + 0x48e4: 0x0080, 0x48e5: 0x0080, 0x48e6: 0x0080, 0x48e9: 0x0080, + 0x48ea: 0x0080, 0x48eb: 0x0080, 0x48ec: 0x0080, 0x48ed: 0x0080, 0x48ee: 0x0080, 0x48ef: 0x0080, + 0x48f0: 0x0080, 0x48f1: 0x0080, 0x48f2: 0x0080, 0x48f3: 0x0080, 0x48f4: 0x0080, 0x48f5: 0x0080, + 0x48f6: 0x0080, 0x48f7: 0x0080, 0x48f8: 0x0080, 0x48f9: 0x0080, 0x48fa: 0x0080, 0x48fb: 0x0080, + 0x48fc: 0x0080, 0x48fd: 0x0080, 0x48fe: 0x0080, 0x48ff: 0x0080, + // Block 0x124, offset 0x4900 + 0x4900: 0x0080, 0x4901: 0x0080, 0x4902: 0x0080, 0x4903: 0x0080, 0x4904: 0x0080, 0x4905: 0x0080, + 0x4906: 0x0080, 0x4907: 0x0080, 0x4908: 0x0080, 0x4909: 0x0080, 0x490a: 0x0080, 0x490b: 0x0080, + 0x490c: 0x0080, 0x490d: 0x0080, 0x490e: 0x0080, 0x490f: 0x0080, 0x4910: 0x0080, 0x4911: 0x0080, + 0x4912: 0x0080, 0x4913: 0x0080, 0x4914: 0x0080, 0x4915: 0x0080, 0x4916: 0x0080, 0x4917: 0x0080, + 0x4918: 0x0080, 0x4919: 0x0080, 0x491a: 0x0080, 0x491b: 0x0080, 0x491c: 0x0080, 0x491d: 0x0080, + 0x491e: 0x0080, 0x491f: 0x0080, 0x4920: 0x0080, 0x4921: 0x0080, 0x4922: 0x0080, 0x4923: 0x0080, + 0x4924: 0x0080, 0x4925: 0x00c0, 0x4926: 0x00c0, 0x4927: 0x00c3, 0x4928: 0x00c3, 0x4929: 0x00c3, + 0x492a: 0x0080, 0x492b: 0x0080, 0x492c: 0x0080, 0x492d: 0x00c0, 0x492e: 0x00c0, 0x492f: 0x00c0, + 0x4930: 0x00c0, 0x4931: 0x00c0, 0x4932: 0x00c0, 0x4933: 0x0040, 0x4934: 0x0040, 0x4935: 0x0040, + 0x4936: 0x0040, 0x4937: 0x0040, 0x4938: 0x0040, 0x4939: 0x0040, 0x493a: 0x0040, 0x493b: 0x00c3, + 0x493c: 0x00c3, 0x493d: 0x00c3, 0x493e: 0x00c3, 0x493f: 0x00c3, + // Block 0x125, offset 0x4940 + 0x4940: 0x00c3, 0x4941: 0x00c3, 0x4942: 0x00c3, 0x4943: 0x0080, 0x4944: 0x0080, 0x4945: 0x00c3, + 0x4946: 0x00c3, 0x4947: 0x00c3, 0x4948: 0x00c3, 0x4949: 0x00c3, 0x494a: 0x00c3, 0x494b: 0x00c3, + 0x494c: 0x0080, 0x494d: 0x0080, 0x494e: 0x0080, 0x494f: 0x0080, 0x4950: 0x0080, 0x4951: 0x0080, + 0x4952: 0x0080, 0x4953: 0x0080, 0x4954: 0x0080, 0x4955: 0x0080, 0x4956: 0x0080, 0x4957: 0x0080, + 0x4958: 0x0080, 0x4959: 0x0080, 0x495a: 0x0080, 0x495b: 0x0080, 0x495c: 0x0080, 0x495d: 0x0080, + 0x495e: 0x0080, 0x495f: 0x0080, 0x4960: 0x0080, 0x4961: 0x0080, 0x4962: 0x0080, 0x4963: 0x0080, + 0x4964: 0x0080, 0x4965: 0x0080, 0x4966: 0x0080, 0x4967: 0x0080, 0x4968: 0x0080, 0x4969: 0x0080, + 0x496a: 0x00c3, 0x496b: 0x00c3, 0x496c: 0x00c3, 0x496d: 0x00c3, 0x496e: 0x0080, 0x496f: 0x0080, + 0x4970: 0x0080, 0x4971: 0x0080, 0x4972: 0x0080, 0x4973: 0x0080, 0x4974: 0x0080, 0x4975: 0x0080, + 0x4976: 0x0080, 0x4977: 0x0080, 0x4978: 0x0080, 0x4979: 0x0080, 0x497a: 0x0080, 0x497b: 0x0080, + 0x497c: 0x0080, 0x497d: 0x0080, 0x497e: 0x0080, 0x497f: 0x0080, + // Block 0x126, offset 0x4980 + 0x4980: 0x0080, 0x4981: 0x0080, 0x4982: 0x0080, 0x4983: 0x0080, 0x4984: 0x0080, 0x4985: 0x0080, + 0x4986: 0x0080, 0x4987: 0x0080, 0x4988: 0x0080, 0x4989: 0x0080, 0x498a: 0x0080, 0x498b: 0x0080, + 0x498c: 0x0080, 0x498d: 0x0080, 0x498e: 0x0080, 0x498f: 0x0080, 0x4990: 0x0080, 0x4991: 0x0080, + 0x4992: 0x0080, 0x4993: 0x0080, 0x4994: 0x0080, 0x4995: 0x0080, 0x4996: 0x0080, 0x4997: 0x0080, + 0x4998: 0x0080, 0x4999: 0x0080, 0x499a: 0x0080, 0x499b: 0x0080, 0x499c: 0x0080, 0x499d: 0x0080, + 0x499e: 0x0080, 0x499f: 0x0080, 0x49a0: 0x0080, 0x49a1: 0x0080, 0x49a2: 0x0080, 0x49a3: 0x0080, + 0x49a4: 0x0080, 0x49a5: 0x0080, 0x49a6: 0x0080, 0x49a7: 0x0080, 0x49a8: 0x0080, + // Block 0x127, offset 0x49c0 + 0x49c0: 0x0088, 0x49c1: 0x0088, 0x49c2: 0x00c9, 0x49c3: 0x00c9, 0x49c4: 0x00c9, 0x49c5: 0x0088, + // Block 0x128, offset 0x4a00 + 0x4a20: 0x0080, 0x4a21: 0x0080, 0x4a22: 0x0080, 0x4a23: 0x0080, + 0x4a24: 0x0080, 0x4a25: 0x0080, 0x4a26: 0x0080, 0x4a27: 0x0080, 0x4a28: 0x0080, 0x4a29: 0x0080, + 0x4a2a: 0x0080, 0x4a2b: 0x0080, 0x4a2c: 0x0080, 0x4a2d: 0x0080, 0x4a2e: 0x0080, 0x4a2f: 0x0080, + 0x4a30: 0x0080, 0x4a31: 0x0080, 0x4a32: 0x0080, 0x4a33: 0x0080, + // Block 0x129, offset 0x4a40 + 0x4a40: 0x0080, 0x4a41: 0x0080, 0x4a42: 0x0080, 0x4a43: 0x0080, 0x4a44: 0x0080, 0x4a45: 0x0080, + 0x4a46: 0x0080, 0x4a47: 0x0080, 0x4a48: 0x0080, 0x4a49: 0x0080, 0x4a4a: 0x0080, 0x4a4b: 0x0080, + 0x4a4c: 0x0080, 0x4a4d: 0x0080, 0x4a4e: 0x0080, 0x4a4f: 0x0080, 0x4a50: 0x0080, 0x4a51: 0x0080, + 0x4a52: 0x0080, 0x4a53: 0x0080, 0x4a54: 0x0080, 0x4a55: 0x0080, 0x4a56: 0x0080, + 0x4a60: 0x0080, 0x4a61: 0x0080, 0x4a62: 0x0080, 0x4a63: 0x0080, + 0x4a64: 0x0080, 0x4a65: 0x0080, 0x4a66: 0x0080, 0x4a67: 0x0080, 0x4a68: 0x0080, 0x4a69: 0x0080, + 0x4a6a: 0x0080, 0x4a6b: 0x0080, 0x4a6c: 0x0080, 0x4a6d: 0x0080, 0x4a6e: 0x0080, 0x4a6f: 0x0080, + 0x4a70: 0x0080, 0x4a71: 0x0080, 0x4a72: 0x0080, 0x4a73: 0x0080, 0x4a74: 0x0080, 0x4a75: 0x0080, + 0x4a76: 0x0080, 0x4a77: 0x0080, 0x4a78: 0x0080, + // Block 0x12a, offset 0x4a80 + 0x4a80: 0x0080, 0x4a81: 0x0080, 0x4a82: 0x0080, 0x4a83: 0x0080, 0x4a84: 0x0080, 0x4a85: 0x0080, + 0x4a86: 0x0080, 0x4a87: 0x0080, 0x4a88: 0x0080, 0x4a89: 0x0080, 0x4a8a: 0x0080, 0x4a8b: 0x0080, + 0x4a8c: 0x0080, 0x4a8d: 0x0080, 0x4a8e: 0x0080, 0x4a8f: 0x0080, 0x4a90: 0x0080, 0x4a91: 0x0080, + 0x4a92: 0x0080, 0x4a93: 0x0080, 0x4a94: 0x0080, 0x4a96: 0x0080, 0x4a97: 0x0080, + 0x4a98: 0x0080, 0x4a99: 0x0080, 0x4a9a: 0x0080, 0x4a9b: 0x0080, 0x4a9c: 0x0080, 0x4a9d: 0x0080, + 0x4a9e: 0x0080, 0x4a9f: 0x0080, 0x4aa0: 0x0080, 0x4aa1: 0x0080, 0x4aa2: 0x0080, 0x4aa3: 0x0080, + 0x4aa4: 0x0080, 0x4aa5: 0x0080, 0x4aa6: 0x0080, 0x4aa7: 0x0080, 0x4aa8: 0x0080, 0x4aa9: 0x0080, + 0x4aaa: 0x0080, 0x4aab: 0x0080, 0x4aac: 0x0080, 0x4aad: 0x0080, 0x4aae: 0x0080, 0x4aaf: 0x0080, + 0x4ab0: 0x0080, 0x4ab1: 0x0080, 0x4ab2: 0x0080, 0x4ab3: 0x0080, 0x4ab4: 0x0080, 0x4ab5: 0x0080, + 0x4ab6: 0x0080, 0x4ab7: 0x0080, 0x4ab8: 0x0080, 0x4ab9: 0x0080, 0x4aba: 0x0080, 0x4abb: 0x0080, + 0x4abc: 0x0080, 0x4abd: 0x0080, 0x4abe: 0x0080, 0x4abf: 0x0080, + // Block 0x12b, offset 0x4ac0 + 0x4ac0: 0x0080, 0x4ac1: 0x0080, 0x4ac2: 0x0080, 0x4ac3: 0x0080, 0x4ac4: 0x0080, 0x4ac5: 0x0080, + 0x4ac6: 0x0080, 0x4ac7: 0x0080, 0x4ac8: 0x0080, 0x4ac9: 0x0080, 0x4aca: 0x0080, 0x4acb: 0x0080, + 0x4acc: 0x0080, 0x4acd: 0x0080, 0x4ace: 0x0080, 0x4acf: 0x0080, 0x4ad0: 0x0080, 0x4ad1: 0x0080, + 0x4ad2: 0x0080, 0x4ad3: 0x0080, 0x4ad4: 0x0080, 0x4ad5: 0x0080, 0x4ad6: 0x0080, 0x4ad7: 0x0080, + 0x4ad8: 0x0080, 0x4ad9: 0x0080, 0x4ada: 0x0080, 0x4adb: 0x0080, 0x4adc: 0x0080, + 0x4ade: 0x0080, 0x4adf: 0x0080, 0x4ae2: 0x0080, + 0x4ae5: 0x0080, 0x4ae6: 0x0080, 0x4ae9: 0x0080, + 0x4aea: 0x0080, 0x4aeb: 0x0080, 0x4aec: 0x0080, 0x4aee: 0x0080, 0x4aef: 0x0080, + 0x4af0: 0x0080, 0x4af1: 0x0080, 0x4af2: 0x0080, 0x4af3: 0x0080, 0x4af4: 0x0080, 0x4af5: 0x0080, + 0x4af6: 0x0080, 0x4af7: 0x0080, 0x4af8: 0x0080, 0x4af9: 0x0080, 0x4afb: 0x0080, + 0x4afd: 0x0080, 0x4afe: 0x0080, 0x4aff: 0x0080, + // Block 0x12c, offset 0x4b00 + 0x4b00: 0x0080, 0x4b01: 0x0080, 0x4b02: 0x0080, 0x4b03: 0x0080, 0x4b05: 0x0080, + 0x4b06: 0x0080, 0x4b07: 0x0080, 0x4b08: 0x0080, 0x4b09: 0x0080, 0x4b0a: 0x0080, 0x4b0b: 0x0080, + 0x4b0c: 0x0080, 0x4b0d: 0x0080, 0x4b0e: 0x0080, 0x4b0f: 0x0080, 0x4b10: 0x0080, 0x4b11: 0x0080, + 0x4b12: 0x0080, 0x4b13: 0x0080, 0x4b14: 0x0080, 0x4b15: 0x0080, 0x4b16: 0x0080, 0x4b17: 0x0080, + 0x4b18: 0x0080, 0x4b19: 0x0080, 0x4b1a: 0x0080, 0x4b1b: 0x0080, 0x4b1c: 0x0080, 0x4b1d: 0x0080, + 0x4b1e: 0x0080, 0x4b1f: 0x0080, 0x4b20: 0x0080, 0x4b21: 0x0080, 0x4b22: 0x0080, 0x4b23: 0x0080, + 0x4b24: 0x0080, 0x4b25: 0x0080, 0x4b26: 0x0080, 0x4b27: 0x0080, 0x4b28: 0x0080, 0x4b29: 0x0080, + 0x4b2a: 0x0080, 0x4b2b: 0x0080, 0x4b2c: 0x0080, 0x4b2d: 0x0080, 0x4b2e: 0x0080, 0x4b2f: 0x0080, + 0x4b30: 0x0080, 0x4b31: 0x0080, 0x4b32: 0x0080, 0x4b33: 0x0080, 0x4b34: 0x0080, 0x4b35: 0x0080, + 0x4b36: 0x0080, 0x4b37: 0x0080, 0x4b38: 0x0080, 0x4b39: 0x0080, 0x4b3a: 0x0080, 0x4b3b: 0x0080, + 0x4b3c: 0x0080, 0x4b3d: 0x0080, 0x4b3e: 0x0080, 0x4b3f: 0x0080, + // Block 0x12d, offset 0x4b40 + 0x4b40: 0x0080, 0x4b41: 0x0080, 0x4b42: 0x0080, 0x4b43: 0x0080, 0x4b44: 0x0080, 0x4b45: 0x0080, + 0x4b47: 0x0080, 0x4b48: 0x0080, 0x4b49: 0x0080, 0x4b4a: 0x0080, + 0x4b4d: 0x0080, 0x4b4e: 0x0080, 0x4b4f: 0x0080, 0x4b50: 0x0080, 0x4b51: 0x0080, + 0x4b52: 0x0080, 0x4b53: 0x0080, 0x4b54: 0x0080, 0x4b56: 0x0080, 0x4b57: 0x0080, + 0x4b58: 0x0080, 0x4b59: 0x0080, 0x4b5a: 0x0080, 0x4b5b: 0x0080, 0x4b5c: 0x0080, + 0x4b5e: 0x0080, 0x4b5f: 0x0080, 0x4b60: 0x0080, 0x4b61: 0x0080, 0x4b62: 0x0080, 0x4b63: 0x0080, + 0x4b64: 0x0080, 0x4b65: 0x0080, 0x4b66: 0x0080, 0x4b67: 0x0080, 0x4b68: 0x0080, 0x4b69: 0x0080, + 0x4b6a: 0x0080, 0x4b6b: 0x0080, 0x4b6c: 0x0080, 0x4b6d: 0x0080, 0x4b6e: 0x0080, 0x4b6f: 0x0080, + 0x4b70: 0x0080, 0x4b71: 0x0080, 0x4b72: 0x0080, 0x4b73: 0x0080, 0x4b74: 0x0080, 0x4b75: 0x0080, + 0x4b76: 0x0080, 0x4b77: 0x0080, 0x4b78: 0x0080, 0x4b79: 0x0080, 0x4b7b: 0x0080, + 0x4b7c: 0x0080, 0x4b7d: 0x0080, 0x4b7e: 0x0080, + // Block 0x12e, offset 0x4b80 + 0x4b80: 0x0080, 0x4b81: 0x0080, 0x4b82: 0x0080, 0x4b83: 0x0080, 0x4b84: 0x0080, + 0x4b86: 0x0080, 0x4b8a: 0x0080, 0x4b8b: 0x0080, + 0x4b8c: 0x0080, 0x4b8d: 0x0080, 0x4b8e: 0x0080, 0x4b8f: 0x0080, 0x4b90: 0x0080, + 0x4b92: 0x0080, 0x4b93: 0x0080, 0x4b94: 0x0080, 0x4b95: 0x0080, 0x4b96: 0x0080, 0x4b97: 0x0080, + 0x4b98: 0x0080, 0x4b99: 0x0080, 0x4b9a: 0x0080, 0x4b9b: 0x0080, 0x4b9c: 0x0080, 0x4b9d: 0x0080, + 0x4b9e: 0x0080, 0x4b9f: 0x0080, 0x4ba0: 0x0080, 0x4ba1: 0x0080, 0x4ba2: 0x0080, 0x4ba3: 0x0080, + 0x4ba4: 0x0080, 0x4ba5: 0x0080, 0x4ba6: 0x0080, 0x4ba7: 0x0080, 0x4ba8: 0x0080, 0x4ba9: 0x0080, + 0x4baa: 0x0080, 0x4bab: 0x0080, 0x4bac: 0x0080, 0x4bad: 0x0080, 0x4bae: 0x0080, 0x4baf: 0x0080, + 0x4bb0: 0x0080, 0x4bb1: 0x0080, 0x4bb2: 0x0080, 0x4bb3: 0x0080, 0x4bb4: 0x0080, 0x4bb5: 0x0080, + 0x4bb6: 0x0080, 0x4bb7: 0x0080, 0x4bb8: 0x0080, 0x4bb9: 0x0080, 0x4bba: 0x0080, 0x4bbb: 0x0080, + 0x4bbc: 0x0080, 0x4bbd: 0x0080, 0x4bbe: 0x0080, 0x4bbf: 0x0080, + // Block 0x12f, offset 0x4bc0 + 0x4bc0: 0x0080, 0x4bc1: 0x0080, 0x4bc2: 0x0080, 0x4bc3: 0x0080, 0x4bc4: 0x0080, 0x4bc5: 0x0080, + 0x4bc6: 0x0080, 0x4bc7: 0x0080, 0x4bc8: 0x0080, 0x4bc9: 0x0080, 0x4bca: 0x0080, 0x4bcb: 0x0080, + 0x4bcc: 0x0080, 0x4bcd: 0x0080, 0x4bce: 0x0080, 0x4bcf: 0x0080, 0x4bd0: 0x0080, 0x4bd1: 0x0080, + 0x4bd2: 0x0080, 0x4bd3: 0x0080, 0x4bd4: 0x0080, 0x4bd5: 0x0080, 0x4bd6: 0x0080, 0x4bd7: 0x0080, + 0x4bd8: 0x0080, 0x4bd9: 0x0080, 0x4bda: 0x0080, 0x4bdb: 0x0080, 0x4bdc: 0x0080, 0x4bdd: 0x0080, + 0x4bde: 0x0080, 0x4bdf: 0x0080, 0x4be0: 0x0080, 0x4be1: 0x0080, 0x4be2: 0x0080, 0x4be3: 0x0080, + 0x4be4: 0x0080, 0x4be5: 0x0080, 0x4be8: 0x0080, 0x4be9: 0x0080, + 0x4bea: 0x0080, 0x4beb: 0x0080, 0x4bec: 0x0080, 0x4bed: 0x0080, 0x4bee: 0x0080, 0x4bef: 0x0080, + 0x4bf0: 0x0080, 0x4bf1: 0x0080, 0x4bf2: 0x0080, 0x4bf3: 0x0080, 0x4bf4: 0x0080, 0x4bf5: 0x0080, + 0x4bf6: 0x0080, 0x4bf7: 0x0080, 0x4bf8: 0x0080, 0x4bf9: 0x0080, 0x4bfa: 0x0080, 0x4bfb: 0x0080, + 0x4bfc: 0x0080, 0x4bfd: 0x0080, 0x4bfe: 0x0080, 0x4bff: 0x0080, + // Block 0x130, offset 0x4c00 + 0x4c00: 0x0080, 0x4c01: 0x0080, 0x4c02: 0x0080, 0x4c03: 0x0080, 0x4c04: 0x0080, 0x4c05: 0x0080, + 0x4c06: 0x0080, 0x4c07: 0x0080, 0x4c08: 0x0080, 0x4c09: 0x0080, 0x4c0a: 0x0080, 0x4c0b: 0x0080, + 0x4c0e: 0x0080, 0x4c0f: 0x0080, 0x4c10: 0x0080, 0x4c11: 0x0080, + 0x4c12: 0x0080, 0x4c13: 0x0080, 0x4c14: 0x0080, 0x4c15: 0x0080, 0x4c16: 0x0080, 0x4c17: 0x0080, + 0x4c18: 0x0080, 0x4c19: 0x0080, 0x4c1a: 0x0080, 0x4c1b: 0x0080, 0x4c1c: 0x0080, 0x4c1d: 0x0080, + 0x4c1e: 0x0080, 0x4c1f: 0x0080, 0x4c20: 0x0080, 0x4c21: 0x0080, 0x4c22: 0x0080, 0x4c23: 0x0080, + 0x4c24: 0x0080, 0x4c25: 0x0080, 0x4c26: 0x0080, 0x4c27: 0x0080, 0x4c28: 0x0080, 0x4c29: 0x0080, + 0x4c2a: 0x0080, 0x4c2b: 0x0080, 0x4c2c: 0x0080, 0x4c2d: 0x0080, 0x4c2e: 0x0080, 0x4c2f: 0x0080, + 0x4c30: 0x0080, 0x4c31: 0x0080, 0x4c32: 0x0080, 0x4c33: 0x0080, 0x4c34: 0x0080, 0x4c35: 0x0080, + 0x4c36: 0x0080, 0x4c37: 0x0080, 0x4c38: 0x0080, 0x4c39: 0x0080, 0x4c3a: 0x0080, 0x4c3b: 0x0080, + 0x4c3c: 0x0080, 0x4c3d: 0x0080, 0x4c3e: 0x0080, 0x4c3f: 0x0080, + // Block 0x131, offset 0x4c40 + 0x4c40: 0x00c3, 0x4c41: 0x00c3, 0x4c42: 0x00c3, 0x4c43: 0x00c3, 0x4c44: 0x00c3, 0x4c45: 0x00c3, + 0x4c46: 0x00c3, 0x4c47: 0x00c3, 0x4c48: 0x00c3, 0x4c49: 0x00c3, 0x4c4a: 0x00c3, 0x4c4b: 0x00c3, + 0x4c4c: 0x00c3, 0x4c4d: 0x00c3, 0x4c4e: 0x00c3, 0x4c4f: 0x00c3, 0x4c50: 0x00c3, 0x4c51: 0x00c3, + 0x4c52: 0x00c3, 0x4c53: 0x00c3, 0x4c54: 0x00c3, 0x4c55: 0x00c3, 0x4c56: 0x00c3, 0x4c57: 0x00c3, + 0x4c58: 0x00c3, 0x4c59: 0x00c3, 0x4c5a: 0x00c3, 0x4c5b: 0x00c3, 0x4c5c: 0x00c3, 0x4c5d: 0x00c3, + 0x4c5e: 0x00c3, 0x4c5f: 0x00c3, 0x4c60: 0x00c3, 0x4c61: 0x00c3, 0x4c62: 0x00c3, 0x4c63: 0x00c3, + 0x4c64: 0x00c3, 0x4c65: 0x00c3, 0x4c66: 0x00c3, 0x4c67: 0x00c3, 0x4c68: 0x00c3, 0x4c69: 0x00c3, + 0x4c6a: 0x00c3, 0x4c6b: 0x00c3, 0x4c6c: 0x00c3, 0x4c6d: 0x00c3, 0x4c6e: 0x00c3, 0x4c6f: 0x00c3, + 0x4c70: 0x00c3, 0x4c71: 0x00c3, 0x4c72: 0x00c3, 0x4c73: 0x00c3, 0x4c74: 0x00c3, 0x4c75: 0x00c3, + 0x4c76: 0x00c3, 0x4c77: 0x0080, 0x4c78: 0x0080, 0x4c79: 0x0080, 0x4c7a: 0x0080, 0x4c7b: 0x00c3, + 0x4c7c: 0x00c3, 0x4c7d: 0x00c3, 0x4c7e: 0x00c3, 0x4c7f: 0x00c3, + // Block 0x132, offset 0x4c80 + 0x4c80: 0x00c3, 0x4c81: 0x00c3, 0x4c82: 0x00c3, 0x4c83: 0x00c3, 0x4c84: 0x00c3, 0x4c85: 0x00c3, + 0x4c86: 0x00c3, 0x4c87: 0x00c3, 0x4c88: 0x00c3, 0x4c89: 0x00c3, 0x4c8a: 0x00c3, 0x4c8b: 0x00c3, + 0x4c8c: 0x00c3, 0x4c8d: 0x00c3, 0x4c8e: 0x00c3, 0x4c8f: 0x00c3, 0x4c90: 0x00c3, 0x4c91: 0x00c3, + 0x4c92: 0x00c3, 0x4c93: 0x00c3, 0x4c94: 0x00c3, 0x4c95: 0x00c3, 0x4c96: 0x00c3, 0x4c97: 0x00c3, + 0x4c98: 0x00c3, 0x4c99: 0x00c3, 0x4c9a: 0x00c3, 0x4c9b: 0x00c3, 0x4c9c: 0x00c3, 0x4c9d: 0x00c3, + 0x4c9e: 0x00c3, 0x4c9f: 0x00c3, 0x4ca0: 0x00c3, 0x4ca1: 0x00c3, 0x4ca2: 0x00c3, 0x4ca3: 0x00c3, + 0x4ca4: 0x00c3, 0x4ca5: 0x00c3, 0x4ca6: 0x00c3, 0x4ca7: 0x00c3, 0x4ca8: 0x00c3, 0x4ca9: 0x00c3, + 0x4caa: 0x00c3, 0x4cab: 0x00c3, 0x4cac: 0x00c3, 0x4cad: 0x0080, 0x4cae: 0x0080, 0x4caf: 0x0080, + 0x4cb0: 0x0080, 0x4cb1: 0x0080, 0x4cb2: 0x0080, 0x4cb3: 0x0080, 0x4cb4: 0x0080, 0x4cb5: 0x00c3, + 0x4cb6: 0x0080, 0x4cb7: 0x0080, 0x4cb8: 0x0080, 0x4cb9: 0x0080, 0x4cba: 0x0080, 0x4cbb: 0x0080, + 0x4cbc: 0x0080, 0x4cbd: 0x0080, 0x4cbe: 0x0080, 0x4cbf: 0x0080, + // Block 0x133, offset 0x4cc0 + 0x4cc0: 0x0080, 0x4cc1: 0x0080, 0x4cc2: 0x0080, 0x4cc3: 0x0080, 0x4cc4: 0x00c3, 0x4cc5: 0x0080, + 0x4cc6: 0x0080, 0x4cc7: 0x0080, 0x4cc8: 0x0080, 0x4cc9: 0x0080, 0x4cca: 0x0080, 0x4ccb: 0x0080, + 0x4cdb: 0x00c3, 0x4cdc: 0x00c3, 0x4cdd: 0x00c3, + 0x4cde: 0x00c3, 0x4cdf: 0x00c3, 0x4ce1: 0x00c3, 0x4ce2: 0x00c3, 0x4ce3: 0x00c3, + 0x4ce4: 0x00c3, 0x4ce5: 0x00c3, 0x4ce6: 0x00c3, 0x4ce7: 0x00c3, 0x4ce8: 0x00c3, 0x4ce9: 0x00c3, + 0x4cea: 0x00c3, 0x4ceb: 0x00c3, 0x4cec: 0x00c3, 0x4ced: 0x00c3, 0x4cee: 0x00c3, 0x4cef: 0x00c3, + // Block 0x134, offset 0x4d00 + 0x4d00: 0x00c3, 0x4d01: 0x00c3, 0x4d02: 0x00c3, 0x4d03: 0x00c3, 0x4d04: 0x00c3, 0x4d05: 0x00c3, + 0x4d06: 0x00c3, 0x4d08: 0x00c3, 0x4d09: 0x00c3, 0x4d0a: 0x00c3, 0x4d0b: 0x00c3, + 0x4d0c: 0x00c3, 0x4d0d: 0x00c3, 0x4d0e: 0x00c3, 0x4d0f: 0x00c3, 0x4d10: 0x00c3, 0x4d11: 0x00c3, + 0x4d12: 0x00c3, 0x4d13: 0x00c3, 0x4d14: 0x00c3, 0x4d15: 0x00c3, 0x4d16: 0x00c3, 0x4d17: 0x00c3, + 0x4d18: 0x00c3, 0x4d1b: 0x00c3, 0x4d1c: 0x00c3, 0x4d1d: 0x00c3, + 0x4d1e: 0x00c3, 0x4d1f: 0x00c3, 0x4d20: 0x00c3, 0x4d21: 0x00c3, 0x4d23: 0x00c3, + 0x4d24: 0x00c3, 0x4d26: 0x00c3, 0x4d27: 0x00c3, 0x4d28: 0x00c3, 0x4d29: 0x00c3, + 0x4d2a: 0x00c3, + // Block 0x135, offset 0x4d40 + 0x4d40: 0x00c0, 0x4d41: 0x00c0, 0x4d42: 0x00c0, 0x4d43: 0x00c0, 0x4d44: 0x00c0, 0x4d45: 0x00c0, + 0x4d46: 0x00c0, 0x4d47: 0x00c0, 0x4d48: 0x00c0, 0x4d49: 0x00c0, 0x4d4a: 0x00c0, 0x4d4b: 0x00c0, + 0x4d4c: 0x00c0, 0x4d4d: 0x00c0, 0x4d4e: 0x00c0, 0x4d4f: 0x00c0, 0x4d50: 0x00c0, 0x4d51: 0x00c0, + 0x4d52: 0x00c0, 0x4d53: 0x00c0, 0x4d54: 0x00c0, 0x4d55: 0x00c0, 0x4d56: 0x00c0, 0x4d57: 0x00c0, + 0x4d58: 0x00c0, 0x4d59: 0x00c0, 0x4d5a: 0x00c0, 0x4d5b: 0x00c0, 0x4d5c: 0x00c0, 0x4d5d: 0x00c0, + 0x4d5e: 0x00c0, 0x4d5f: 0x00c0, 0x4d60: 0x00c0, 0x4d61: 0x00c0, 0x4d62: 0x00c0, 0x4d63: 0x00c0, + 0x4d64: 0x00c0, 0x4d65: 0x00c0, 0x4d66: 0x00c0, 0x4d67: 0x00c0, 0x4d68: 0x00c0, 0x4d69: 0x00c0, + 0x4d6a: 0x00c0, 0x4d6b: 0x00c0, 0x4d6c: 0x00c0, + 0x4d70: 0x00c3, 0x4d71: 0x00c3, 0x4d72: 0x00c3, 0x4d73: 0x00c3, 0x4d74: 0x00c3, 0x4d75: 0x00c3, + 0x4d76: 0x00c3, 0x4d77: 0x00c0, 0x4d78: 0x00c0, 0x4d79: 0x00c0, 0x4d7a: 0x00c0, 0x4d7b: 0x00c0, + 0x4d7c: 0x00c0, 0x4d7d: 0x00c0, + // Block 0x136, offset 0x4d80 + 0x4d80: 0x00c0, 0x4d81: 0x00c0, 0x4d82: 0x00c0, 0x4d83: 0x00c0, 0x4d84: 0x00c0, 0x4d85: 0x00c0, + 0x4d86: 0x00c0, 0x4d87: 0x00c0, 0x4d88: 0x00c0, 0x4d89: 0x00c0, + 0x4d8e: 0x00c0, 0x4d8f: 0x0080, + // Block 0x137, offset 0x4dc0 + 0x4dc0: 0x00c0, 0x4dc1: 0x00c0, 0x4dc2: 0x00c0, 0x4dc3: 0x00c0, 0x4dc4: 0x00c0, 0x4dc5: 0x00c0, + 0x4dc6: 0x00c0, 0x4dc7: 0x00c0, 0x4dc8: 0x00c0, 0x4dc9: 0x00c0, 0x4dca: 0x00c0, 0x4dcb: 0x00c0, + 0x4dcc: 0x00c0, 0x4dcd: 0x00c0, 0x4dce: 0x00c0, 0x4dcf: 0x00c0, 0x4dd0: 0x00c0, 0x4dd1: 0x00c0, + 0x4dd2: 0x00c0, 0x4dd3: 0x00c0, 0x4dd4: 0x00c0, 0x4dd5: 0x00c0, 0x4dd6: 0x00c0, 0x4dd7: 0x00c0, + 0x4dd8: 0x00c0, 0x4dd9: 0x00c0, 0x4dda: 0x00c0, 0x4ddb: 0x00c0, 0x4ddc: 0x00c0, 0x4ddd: 0x00c0, + 0x4dde: 0x00c0, 0x4ddf: 0x00c0, 0x4de0: 0x00c0, 0x4de1: 0x00c0, 0x4de2: 0x00c0, 0x4de3: 0x00c0, + 0x4de4: 0x00c0, 0x4de5: 0x00c0, 0x4de6: 0x00c0, 0x4de7: 0x00c0, 0x4de8: 0x00c0, 0x4de9: 0x00c0, + 0x4dea: 0x00c0, 0x4deb: 0x00c0, 0x4dec: 0x00c3, 0x4ded: 0x00c3, 0x4dee: 0x00c3, 0x4def: 0x00c3, + 0x4df0: 0x00c0, 0x4df1: 0x00c0, 0x4df2: 0x00c0, 0x4df3: 0x00c0, 0x4df4: 0x00c0, 0x4df5: 0x00c0, + 0x4df6: 0x00c0, 0x4df7: 0x00c0, 0x4df8: 0x00c0, 0x4df9: 0x00c0, + 0x4dff: 0x0080, + // Block 0x138, offset 0x4e00 + 0x4e00: 0x00c0, 0x4e01: 0x00c0, 0x4e02: 0x00c0, 0x4e03: 0x00c0, 0x4e04: 0x00c0, + 0x4e07: 0x0080, 0x4e08: 0x0080, 0x4e09: 0x0080, 0x4e0a: 0x0080, 0x4e0b: 0x0080, + 0x4e0c: 0x0080, 0x4e0d: 0x0080, 0x4e0e: 0x0080, 0x4e0f: 0x0080, 0x4e10: 0x00c3, 0x4e11: 0x00c3, + 0x4e12: 0x00c3, 0x4e13: 0x00c3, 0x4e14: 0x00c3, 0x4e15: 0x00c3, 0x4e16: 0x00c3, + // Block 0x139, offset 0x4e40 + 0x4e40: 0x00c2, 0x4e41: 0x00c2, 0x4e42: 0x00c2, 0x4e43: 0x00c2, 0x4e44: 0x00c2, 0x4e45: 0x00c2, + 0x4e46: 0x00c2, 0x4e47: 0x00c2, 0x4e48: 0x00c2, 0x4e49: 0x00c2, 0x4e4a: 0x00c2, 0x4e4b: 0x00c2, + 0x4e4c: 0x00c2, 0x4e4d: 0x00c2, 0x4e4e: 0x00c2, 0x4e4f: 0x00c2, 0x4e50: 0x00c2, 0x4e51: 0x00c2, + 0x4e52: 0x00c2, 0x4e53: 0x00c2, 0x4e54: 0x00c2, 0x4e55: 0x00c2, 0x4e56: 0x00c2, 0x4e57: 0x00c2, + 0x4e58: 0x00c2, 0x4e59: 0x00c2, 0x4e5a: 0x00c2, 0x4e5b: 0x00c2, 0x4e5c: 0x00c2, 0x4e5d: 0x00c2, + 0x4e5e: 0x00c2, 0x4e5f: 0x00c2, 0x4e60: 0x00c2, 0x4e61: 0x00c2, 0x4e62: 0x00c2, 0x4e63: 0x00c2, + 0x4e64: 0x00c2, 0x4e65: 0x00c2, 0x4e66: 0x00c2, 0x4e67: 0x00c2, 0x4e68: 0x00c2, 0x4e69: 0x00c2, + 0x4e6a: 0x00c2, 0x4e6b: 0x00c2, 0x4e6c: 0x00c2, 0x4e6d: 0x00c2, 0x4e6e: 0x00c2, 0x4e6f: 0x00c2, + 0x4e70: 0x00c2, 0x4e71: 0x00c2, 0x4e72: 0x00c2, 0x4e73: 0x00c2, 0x4e74: 0x00c2, 0x4e75: 0x00c2, + 0x4e76: 0x00c2, 0x4e77: 0x00c2, 0x4e78: 0x00c2, 0x4e79: 0x00c2, 0x4e7a: 0x00c2, 0x4e7b: 0x00c2, + 0x4e7c: 0x00c2, 0x4e7d: 0x00c2, 0x4e7e: 0x00c2, 0x4e7f: 0x00c2, + // Block 0x13a, offset 0x4e80 + 0x4e80: 0x00c2, 0x4e81: 0x00c2, 0x4e82: 0x00c2, 0x4e83: 0x00c2, 0x4e84: 0x00c3, 0x4e85: 0x00c3, + 0x4e86: 0x00c3, 0x4e87: 0x00c3, 0x4e88: 0x00c3, 0x4e89: 0x00c3, 0x4e8a: 0x00c3, 0x4e8b: 0x00c3, + 0x4e90: 0x00c0, 0x4e91: 0x00c0, + 0x4e92: 0x00c0, 0x4e93: 0x00c0, 0x4e94: 0x00c0, 0x4e95: 0x00c0, 0x4e96: 0x00c0, 0x4e97: 0x00c0, + 0x4e98: 0x00c0, 0x4e99: 0x00c0, + 0x4e9e: 0x0080, 0x4e9f: 0x0080, + // Block 0x13b, offset 0x4ec0 + 0x4ef1: 0x0080, 0x4ef2: 0x0080, 0x4ef3: 0x0080, 0x4ef4: 0x0080, 0x4ef5: 0x0080, + 0x4ef6: 0x0080, 0x4ef7: 0x0080, 0x4ef8: 0x0080, 0x4ef9: 0x0080, 0x4efa: 0x0080, 0x4efb: 0x0080, + 0x4efc: 0x0080, 0x4efd: 0x0080, 0x4efe: 0x0080, 0x4eff: 0x0080, + // Block 0x13c, offset 0x4f00 + 0x4f00: 0x0080, 0x4f01: 0x0080, 0x4f02: 0x0080, 0x4f03: 0x0080, 0x4f04: 0x0080, 0x4f05: 0x0080, + 0x4f06: 0x0080, 0x4f07: 0x0080, 0x4f08: 0x0080, 0x4f09: 0x0080, 0x4f0a: 0x0080, 0x4f0b: 0x0080, + 0x4f0c: 0x0080, 0x4f0d: 0x0080, 0x4f0e: 0x0080, 0x4f0f: 0x0080, 0x4f10: 0x0080, 0x4f11: 0x0080, + 0x4f12: 0x0080, 0x4f13: 0x0080, 0x4f14: 0x0080, 0x4f15: 0x0080, 0x4f16: 0x0080, 0x4f17: 0x0080, + 0x4f18: 0x0080, 0x4f19: 0x0080, 0x4f1a: 0x0080, 0x4f1b: 0x0080, 0x4f1c: 0x0080, 0x4f1d: 0x0080, + 0x4f1e: 0x0080, 0x4f1f: 0x0080, 0x4f20: 0x0080, 0x4f21: 0x0080, 0x4f22: 0x0080, 0x4f23: 0x0080, + 0x4f24: 0x0080, 0x4f25: 0x0080, 0x4f26: 0x0080, 0x4f27: 0x0080, 0x4f28: 0x0080, 0x4f29: 0x0080, + 0x4f2a: 0x0080, 0x4f2b: 0x0080, 0x4f2c: 0x0080, 0x4f2d: 0x0080, 0x4f2e: 0x0080, 0x4f2f: 0x0080, + 0x4f30: 0x0080, 0x4f31: 0x0080, 0x4f32: 0x0080, 0x4f33: 0x0080, 0x4f34: 0x0080, + // Block 0x13d, offset 0x4f40 + 0x4f41: 0x0080, 0x4f42: 0x0080, 0x4f43: 0x0080, 0x4f44: 0x0080, 0x4f45: 0x0080, + 0x4f46: 0x0080, 0x4f47: 0x0080, 0x4f48: 0x0080, 0x4f49: 0x0080, 0x4f4a: 0x0080, 0x4f4b: 0x0080, + 0x4f4c: 0x0080, 0x4f4d: 0x0080, 0x4f4e: 0x0080, 0x4f4f: 0x0080, 0x4f50: 0x0080, 0x4f51: 0x0080, + 0x4f52: 0x0080, 0x4f53: 0x0080, 0x4f54: 0x0080, 0x4f55: 0x0080, 0x4f56: 0x0080, 0x4f57: 0x0080, + 0x4f58: 0x0080, 0x4f59: 0x0080, 0x4f5a: 0x0080, 0x4f5b: 0x0080, 0x4f5c: 0x0080, 0x4f5d: 0x0080, + 0x4f5e: 0x0080, 0x4f5f: 0x0080, 0x4f60: 0x0080, 0x4f61: 0x0080, 0x4f62: 0x0080, 0x4f63: 0x0080, + 0x4f64: 0x0080, 0x4f65: 0x0080, 0x4f66: 0x0080, 0x4f67: 0x0080, 0x4f68: 0x0080, 0x4f69: 0x0080, + 0x4f6a: 0x0080, 0x4f6b: 0x0080, 0x4f6c: 0x0080, 0x4f6d: 0x0080, 0x4f6e: 0x0080, 0x4f6f: 0x0080, + 0x4f70: 0x0080, 0x4f71: 0x0080, 0x4f72: 0x0080, 0x4f73: 0x0080, 0x4f74: 0x0080, 0x4f75: 0x0080, + 0x4f76: 0x0080, 0x4f77: 0x0080, 0x4f78: 0x0080, 0x4f79: 0x0080, 0x4f7a: 0x0080, 0x4f7b: 0x0080, + 0x4f7c: 0x0080, 0x4f7d: 0x0080, + // Block 0x13e, offset 0x4f80 + 0x4f80: 0x0080, 0x4f81: 0x0080, 0x4f82: 0x0080, 0x4f83: 0x0080, 0x4f85: 0x0080, + 0x4f86: 0x0080, 0x4f87: 0x0080, 0x4f88: 0x0080, 0x4f89: 0x0080, 0x4f8a: 0x0080, 0x4f8b: 0x0080, + 0x4f8c: 0x0080, 0x4f8d: 0x0080, 0x4f8e: 0x0080, 0x4f8f: 0x0080, 0x4f90: 0x0080, 0x4f91: 0x0080, + 0x4f92: 0x0080, 0x4f93: 0x0080, 0x4f94: 0x0080, 0x4f95: 0x0080, 0x4f96: 0x0080, 0x4f97: 0x0080, + 0x4f98: 0x0080, 0x4f99: 0x0080, 0x4f9a: 0x0080, 0x4f9b: 0x0080, 0x4f9c: 0x0080, 0x4f9d: 0x0080, + 0x4f9e: 0x0080, 0x4f9f: 0x0080, 0x4fa1: 0x0080, 0x4fa2: 0x0080, + 0x4fa4: 0x0080, 0x4fa7: 0x0080, 0x4fa9: 0x0080, + 0x4faa: 0x0080, 0x4fab: 0x0080, 0x4fac: 0x0080, 0x4fad: 0x0080, 0x4fae: 0x0080, 0x4faf: 0x0080, + 0x4fb0: 0x0080, 0x4fb1: 0x0080, 0x4fb2: 0x0080, 0x4fb4: 0x0080, 0x4fb5: 0x0080, + 0x4fb6: 0x0080, 0x4fb7: 0x0080, 0x4fb9: 0x0080, 0x4fbb: 0x0080, + // Block 0x13f, offset 0x4fc0 + 0x4fc2: 0x0080, + 0x4fc7: 0x0080, 0x4fc9: 0x0080, 0x4fcb: 0x0080, + 0x4fcd: 0x0080, 0x4fce: 0x0080, 0x4fcf: 0x0080, 0x4fd1: 0x0080, + 0x4fd2: 0x0080, 0x4fd4: 0x0080, 0x4fd7: 0x0080, + 0x4fd9: 0x0080, 0x4fdb: 0x0080, 0x4fdd: 0x0080, + 0x4fdf: 0x0080, 0x4fe1: 0x0080, 0x4fe2: 0x0080, + 0x4fe4: 0x0080, 0x4fe7: 0x0080, 0x4fe8: 0x0080, 0x4fe9: 0x0080, + 0x4fea: 0x0080, 0x4fec: 0x0080, 0x4fed: 0x0080, 0x4fee: 0x0080, 0x4fef: 0x0080, + 0x4ff0: 0x0080, 0x4ff1: 0x0080, 0x4ff2: 0x0080, 0x4ff4: 0x0080, 0x4ff5: 0x0080, + 0x4ff6: 0x0080, 0x4ff7: 0x0080, 0x4ff9: 0x0080, 0x4ffa: 0x0080, 0x4ffb: 0x0080, + 0x4ffc: 0x0080, 0x4ffe: 0x0080, + // Block 0x140, offset 0x5000 + 0x5000: 0x0080, 0x5001: 0x0080, 0x5002: 0x0080, 0x5003: 0x0080, 0x5004: 0x0080, 0x5005: 0x0080, + 0x5006: 0x0080, 0x5007: 0x0080, 0x5008: 0x0080, 0x5009: 0x0080, 0x500b: 0x0080, + 0x500c: 0x0080, 0x500d: 0x0080, 0x500e: 0x0080, 0x500f: 0x0080, 0x5010: 0x0080, 0x5011: 0x0080, + 0x5012: 0x0080, 0x5013: 0x0080, 0x5014: 0x0080, 0x5015: 0x0080, 0x5016: 0x0080, 0x5017: 0x0080, + 0x5018: 0x0080, 0x5019: 0x0080, 0x501a: 0x0080, 0x501b: 0x0080, + 0x5021: 0x0080, 0x5022: 0x0080, 0x5023: 0x0080, + 0x5025: 0x0080, 0x5026: 0x0080, 0x5027: 0x0080, 0x5028: 0x0080, 0x5029: 0x0080, + 0x502b: 0x0080, 0x502c: 0x0080, 0x502d: 0x0080, 0x502e: 0x0080, 0x502f: 0x0080, + 0x5030: 0x0080, 0x5031: 0x0080, 0x5032: 0x0080, 0x5033: 0x0080, 0x5034: 0x0080, 0x5035: 0x0080, + 0x5036: 0x0080, 0x5037: 0x0080, 0x5038: 0x0080, 0x5039: 0x0080, 0x503a: 0x0080, 0x503b: 0x0080, + // Block 0x141, offset 0x5040 + 0x5070: 0x0080, 0x5071: 0x0080, + // Block 0x142, offset 0x5080 + 0x5080: 0x0080, 0x5081: 0x0080, 0x5082: 0x0080, 0x5083: 0x0080, 0x5084: 0x0080, 0x5085: 0x0080, + 0x5086: 0x0080, 0x5087: 0x0080, 0x5088: 0x0080, 0x5089: 0x0080, 0x508a: 0x0080, 0x508b: 0x0080, + 0x508c: 0x0080, 0x508d: 0x0080, 0x508e: 0x0080, 0x508f: 0x0080, 0x5090: 0x0080, 0x5091: 0x0080, + 0x5092: 0x0080, 0x5093: 0x0080, 0x5094: 0x0080, 0x5095: 0x0080, 0x5096: 0x0080, 0x5097: 0x0080, + 0x5098: 0x0080, 0x5099: 0x0080, 0x509a: 0x0080, 0x509b: 0x0080, 0x509c: 0x0080, 0x509d: 0x0080, + 0x509e: 0x0080, 0x509f: 0x0080, 0x50a0: 0x0080, 0x50a1: 0x0080, 0x50a2: 0x0080, 0x50a3: 0x0080, + 0x50a4: 0x0080, 0x50a5: 0x0080, 0x50a6: 0x0080, 0x50a7: 0x0080, 0x50a8: 0x0080, 0x50a9: 0x0080, + 0x50aa: 0x0080, 0x50ab: 0x0080, + 0x50b0: 0x0080, 0x50b1: 0x0080, 0x50b2: 0x0080, 0x50b3: 0x0080, 0x50b4: 0x0080, 0x50b5: 0x0080, + 0x50b6: 0x0080, 0x50b7: 0x0080, 0x50b8: 0x0080, 0x50b9: 0x0080, 0x50ba: 0x0080, 0x50bb: 0x0080, + 0x50bc: 0x0080, 0x50bd: 0x0080, 0x50be: 0x0080, 0x50bf: 0x0080, + // Block 0x143, offset 0x50c0 + 0x50c0: 0x0080, 0x50c1: 0x0080, 0x50c2: 0x0080, 0x50c3: 0x0080, 0x50c4: 0x0080, 0x50c5: 0x0080, + 0x50c6: 0x0080, 0x50c7: 0x0080, 0x50c8: 0x0080, 0x50c9: 0x0080, 0x50ca: 0x0080, 0x50cb: 0x0080, + 0x50cc: 0x0080, 0x50cd: 0x0080, 0x50ce: 0x0080, 0x50cf: 0x0080, 0x50d0: 0x0080, 0x50d1: 0x0080, + 0x50d2: 0x0080, 0x50d3: 0x0080, + 0x50e0: 0x0080, 0x50e1: 0x0080, 0x50e2: 0x0080, 0x50e3: 0x0080, + 0x50e4: 0x0080, 0x50e5: 0x0080, 0x50e6: 0x0080, 0x50e7: 0x0080, 0x50e8: 0x0080, 0x50e9: 0x0080, + 0x50ea: 0x0080, 0x50eb: 0x0080, 0x50ec: 0x0080, 0x50ed: 0x0080, 0x50ee: 0x0080, + 0x50f1: 0x0080, 0x50f2: 0x0080, 0x50f3: 0x0080, 0x50f4: 0x0080, 0x50f5: 0x0080, + 0x50f6: 0x0080, 0x50f7: 0x0080, 0x50f8: 0x0080, 0x50f9: 0x0080, 0x50fa: 0x0080, 0x50fb: 0x0080, + 0x50fc: 0x0080, 0x50fd: 0x0080, 0x50fe: 0x0080, 0x50ff: 0x0080, + // Block 0x144, offset 0x5100 + 0x5101: 0x0080, 0x5102: 0x0080, 0x5103: 0x0080, 0x5104: 0x0080, 0x5105: 0x0080, + 0x5106: 0x0080, 0x5107: 0x0080, 0x5108: 0x0080, 0x5109: 0x0080, 0x510a: 0x0080, 0x510b: 0x0080, + 0x510c: 0x0080, 0x510d: 0x0080, 0x510e: 0x0080, 0x510f: 0x0080, 0x5111: 0x0080, + 0x5112: 0x0080, 0x5113: 0x0080, 0x5114: 0x0080, 0x5115: 0x0080, 0x5116: 0x0080, 0x5117: 0x0080, + 0x5118: 0x0080, 0x5119: 0x0080, 0x511a: 0x0080, 0x511b: 0x0080, 0x511c: 0x0080, 0x511d: 0x0080, + 0x511e: 0x0080, 0x511f: 0x0080, 0x5120: 0x0080, 0x5121: 0x0080, 0x5122: 0x0080, 0x5123: 0x0080, + 0x5124: 0x0080, 0x5125: 0x0080, 0x5126: 0x0080, 0x5127: 0x0080, 0x5128: 0x0080, 0x5129: 0x0080, + 0x512a: 0x0080, 0x512b: 0x0080, 0x512c: 0x0080, 0x512d: 0x0080, 0x512e: 0x0080, 0x512f: 0x0080, + 0x5130: 0x0080, 0x5131: 0x0080, 0x5132: 0x0080, 0x5133: 0x0080, 0x5134: 0x0080, 0x5135: 0x0080, + // Block 0x145, offset 0x5140 + 0x5140: 0x0080, 0x5141: 0x0080, 0x5142: 0x0080, 0x5143: 0x0080, 0x5144: 0x0080, 0x5145: 0x0080, + 0x5146: 0x0080, 0x5147: 0x0080, 0x5148: 0x0080, 0x5149: 0x0080, 0x514a: 0x0080, 0x514b: 0x0080, + 0x514c: 0x0080, 0x5150: 0x0080, 0x5151: 0x0080, + 0x5152: 0x0080, 0x5153: 0x0080, 0x5154: 0x0080, 0x5155: 0x0080, 0x5156: 0x0080, 0x5157: 0x0080, + 0x5158: 0x0080, 0x5159: 0x0080, 0x515a: 0x0080, 0x515b: 0x0080, 0x515c: 0x0080, 0x515d: 0x0080, + 0x515e: 0x0080, 0x515f: 0x0080, 0x5160: 0x0080, 0x5161: 0x0080, 0x5162: 0x0080, 0x5163: 0x0080, + 0x5164: 0x0080, 0x5165: 0x0080, 0x5166: 0x0080, 0x5167: 0x0080, 0x5168: 0x0080, 0x5169: 0x0080, + 0x516a: 0x0080, 0x516b: 0x0080, 0x516c: 0x0080, 0x516d: 0x0080, 0x516e: 0x0080, 0x516f: 0x0080, + 0x5170: 0x0080, 0x5171: 0x0080, 0x5172: 0x0080, 0x5173: 0x0080, 0x5174: 0x0080, 0x5175: 0x0080, + 0x5176: 0x0080, 0x5177: 0x0080, 0x5178: 0x0080, 0x5179: 0x0080, 0x517a: 0x0080, 0x517b: 0x0080, + 0x517c: 0x0080, 0x517d: 0x0080, 0x517e: 0x0080, 0x517f: 0x0080, + // Block 0x146, offset 0x5180 + 0x5180: 0x0080, 0x5181: 0x0080, 0x5182: 0x0080, 0x5183: 0x0080, 0x5184: 0x0080, 0x5185: 0x0080, + 0x5186: 0x0080, 0x5187: 0x0080, 0x5188: 0x0080, 0x5189: 0x0080, 0x518a: 0x0080, 0x518b: 0x0080, + 0x518c: 0x0080, 0x518d: 0x0080, 0x518e: 0x0080, 0x518f: 0x0080, 0x5190: 0x0080, 0x5191: 0x0080, + 0x5192: 0x0080, 0x5193: 0x0080, 0x5194: 0x0080, 0x5195: 0x0080, 0x5196: 0x0080, 0x5197: 0x0080, + 0x5198: 0x0080, 0x5199: 0x0080, 0x519a: 0x0080, 0x519b: 0x0080, 0x519c: 0x0080, 0x519d: 0x0080, + 0x519e: 0x0080, 0x519f: 0x0080, 0x51a0: 0x0080, 0x51a1: 0x0080, 0x51a2: 0x0080, 0x51a3: 0x0080, + 0x51a4: 0x0080, 0x51a5: 0x0080, 0x51a6: 0x0080, 0x51a7: 0x0080, 0x51a8: 0x0080, 0x51a9: 0x0080, + 0x51aa: 0x0080, 0x51ab: 0x0080, 0x51ac: 0x0080, + 0x51b0: 0x0080, 0x51b1: 0x0080, 0x51b2: 0x0080, 0x51b3: 0x0080, 0x51b4: 0x0080, 0x51b5: 0x0080, + 0x51b6: 0x0080, 0x51b7: 0x0080, 0x51b8: 0x0080, 0x51b9: 0x0080, 0x51ba: 0x0080, 0x51bb: 0x0080, + 0x51bc: 0x0080, 0x51bd: 0x0080, 0x51be: 0x0080, 0x51bf: 0x0080, + // Block 0x147, offset 0x51c0 + 0x51c0: 0x0080, 0x51c1: 0x0080, 0x51c2: 0x0080, 0x51c3: 0x0080, 0x51c4: 0x0080, 0x51c5: 0x0080, + 0x51c6: 0x0080, 0x51c7: 0x0080, 0x51c8: 0x0080, 0x51c9: 0x0080, 0x51ca: 0x0080, 0x51cb: 0x0080, + 0x51cc: 0x0080, 0x51cd: 0x0080, 0x51ce: 0x0080, 0x51cf: 0x0080, 0x51d0: 0x0080, 0x51d1: 0x0080, + 0x51d2: 0x0080, 0x51d3: 0x0080, 0x51d4: 0x0080, 0x51d5: 0x0080, 0x51d6: 0x0080, 0x51d7: 0x0080, + 0x51d8: 0x0080, 0x51d9: 0x0080, 0x51da: 0x0080, 0x51db: 0x0080, 0x51dc: 0x0080, 0x51dd: 0x0080, + 0x51de: 0x0080, 0x51df: 0x0080, 0x51e0: 0x0080, 0x51e1: 0x0080, 0x51e2: 0x0080, 0x51e3: 0x0080, + 0x51e4: 0x0080, 0x51e5: 0x0080, 0x51e6: 0x0080, 0x51e7: 0x0080, 0x51e8: 0x0080, 0x51e9: 0x0080, + 0x51ea: 0x0080, 0x51eb: 0x0080, 0x51ec: 0x0080, + // Block 0x148, offset 0x5200 + 0x5226: 0x0080, 0x5227: 0x0080, 0x5228: 0x0080, 0x5229: 0x0080, + 0x522a: 0x0080, 0x522b: 0x0080, 0x522c: 0x0080, 0x522d: 0x0080, 0x522e: 0x0080, 0x522f: 0x0080, + 0x5230: 0x0080, 0x5231: 0x0080, 0x5232: 0x0080, 0x5233: 0x0080, 0x5234: 0x0080, 0x5235: 0x0080, + 0x5236: 0x0080, 0x5237: 0x0080, 0x5238: 0x0080, 0x5239: 0x0080, 0x523a: 0x0080, 0x523b: 0x0080, + 0x523c: 0x0080, 0x523d: 0x0080, 0x523e: 0x0080, 0x523f: 0x0080, + // Block 0x149, offset 0x5240 + 0x5240: 0x008c, 0x5241: 0x0080, 0x5242: 0x0080, + 0x5250: 0x0080, 0x5251: 0x0080, + 0x5252: 0x0080, 0x5253: 0x0080, 0x5254: 0x0080, 0x5255: 0x0080, 0x5256: 0x0080, 0x5257: 0x0080, + 0x5258: 0x0080, 0x5259: 0x0080, 0x525a: 0x0080, 0x525b: 0x0080, 0x525c: 0x0080, 0x525d: 0x0080, + 0x525e: 0x0080, 0x525f: 0x0080, 0x5260: 0x0080, 0x5261: 0x0080, 0x5262: 0x0080, 0x5263: 0x0080, + 0x5264: 0x0080, 0x5265: 0x0080, 0x5266: 0x0080, 0x5267: 0x0080, 0x5268: 0x0080, 0x5269: 0x0080, + 0x526a: 0x0080, 0x526b: 0x0080, 0x526c: 0x0080, 0x526d: 0x0080, 0x526e: 0x0080, 0x526f: 0x0080, + 0x5270: 0x0080, 0x5271: 0x0080, 0x5272: 0x0080, 0x5273: 0x0080, 0x5274: 0x0080, 0x5275: 0x0080, + 0x5276: 0x0080, 0x5277: 0x0080, 0x5278: 0x0080, 0x5279: 0x0080, 0x527a: 0x0080, 0x527b: 0x0080, + // Block 0x14a, offset 0x5280 + 0x5280: 0x0080, 0x5281: 0x0080, 0x5282: 0x0080, 0x5283: 0x0080, 0x5284: 0x0080, 0x5285: 0x0080, + 0x5286: 0x0080, 0x5287: 0x0080, 0x5288: 0x0080, + 0x5290: 0x0080, 0x5291: 0x0080, + 0x52a0: 0x0080, 0x52a1: 0x0080, 0x52a2: 0x0080, 0x52a3: 0x0080, + 0x52a4: 0x0080, 0x52a5: 0x0080, + // Block 0x14b, offset 0x52c0 + 0x52c0: 0x0080, 0x52c1: 0x0080, 0x52c2: 0x0080, 0x52c3: 0x0080, 0x52c4: 0x0080, 0x52c5: 0x0080, + 0x52c6: 0x0080, 0x52c7: 0x0080, 0x52c8: 0x0080, 0x52c9: 0x0080, 0x52ca: 0x0080, 0x52cb: 0x0080, + 0x52cc: 0x0080, 0x52cd: 0x0080, 0x52ce: 0x0080, 0x52cf: 0x0080, 0x52d0: 0x0080, 0x52d1: 0x0080, + 0x52d2: 0x0080, 0x52d3: 0x0080, 0x52d4: 0x0080, 0x52d5: 0x0080, + 0x52e0: 0x0080, 0x52e1: 0x0080, 0x52e2: 0x0080, 0x52e3: 0x0080, + 0x52e4: 0x0080, 0x52e5: 0x0080, 0x52e6: 0x0080, 0x52e7: 0x0080, 0x52e8: 0x0080, 0x52e9: 0x0080, + 0x52ea: 0x0080, 0x52eb: 0x0080, 0x52ec: 0x0080, + 0x52f0: 0x0080, 0x52f1: 0x0080, 0x52f2: 0x0080, 0x52f3: 0x0080, 0x52f4: 0x0080, 0x52f5: 0x0080, + 0x52f6: 0x0080, 0x52f7: 0x0080, 0x52f8: 0x0080, 0x52f9: 0x0080, 0x52fa: 0x0080, + // Block 0x14c, offset 0x5300 + 0x5300: 0x0080, 0x5301: 0x0080, 0x5302: 0x0080, 0x5303: 0x0080, 0x5304: 0x0080, 0x5305: 0x0080, + 0x5306: 0x0080, 0x5307: 0x0080, 0x5308: 0x0080, 0x5309: 0x0080, 0x530a: 0x0080, 0x530b: 0x0080, + 0x530c: 0x0080, 0x530d: 0x0080, 0x530e: 0x0080, 0x530f: 0x0080, 0x5310: 0x0080, 0x5311: 0x0080, + 0x5312: 0x0080, 0x5313: 0x0080, 0x5314: 0x0080, 0x5315: 0x0080, 0x5316: 0x0080, 0x5317: 0x0080, + 0x5318: 0x0080, 0x5319: 0x0080, 0x531a: 0x0080, 0x531b: 0x0080, 0x531c: 0x0080, 0x531d: 0x0080, + 0x531e: 0x0080, 0x531f: 0x0080, 0x5320: 0x0080, 0x5321: 0x0080, 0x5322: 0x0080, 0x5323: 0x0080, + 0x5324: 0x0080, 0x5325: 0x0080, 0x5326: 0x0080, 0x5327: 0x0080, 0x5328: 0x0080, 0x5329: 0x0080, + 0x532a: 0x0080, 0x532b: 0x0080, 0x532c: 0x0080, 0x532d: 0x0080, 0x532e: 0x0080, 0x532f: 0x0080, + 0x5330: 0x0080, 0x5331: 0x0080, 0x5332: 0x0080, 0x5333: 0x0080, + // Block 0x14d, offset 0x5340 + 0x5340: 0x0080, 0x5341: 0x0080, 0x5342: 0x0080, 0x5343: 0x0080, 0x5344: 0x0080, 0x5345: 0x0080, + 0x5346: 0x0080, 0x5347: 0x0080, 0x5348: 0x0080, 0x5349: 0x0080, 0x534a: 0x0080, 0x534b: 0x0080, + 0x534c: 0x0080, 0x534d: 0x0080, 0x534e: 0x0080, 0x534f: 0x0080, 0x5350: 0x0080, 0x5351: 0x0080, + 0x5352: 0x0080, 0x5353: 0x0080, 0x5354: 0x0080, 0x5355: 0x0080, 0x5356: 0x0080, 0x5357: 0x0080, + 0x5358: 0x0080, + 0x5360: 0x0080, 0x5361: 0x0080, 0x5362: 0x0080, 0x5363: 0x0080, + 0x5364: 0x0080, 0x5365: 0x0080, 0x5366: 0x0080, 0x5367: 0x0080, 0x5368: 0x0080, 0x5369: 0x0080, + 0x536a: 0x0080, 0x536b: 0x0080, + // Block 0x14e, offset 0x5380 + 0x5380: 0x0080, 0x5381: 0x0080, 0x5382: 0x0080, 0x5383: 0x0080, 0x5384: 0x0080, 0x5385: 0x0080, + 0x5386: 0x0080, 0x5387: 0x0080, 0x5388: 0x0080, 0x5389: 0x0080, 0x538a: 0x0080, 0x538b: 0x0080, + 0x5390: 0x0080, 0x5391: 0x0080, + 0x5392: 0x0080, 0x5393: 0x0080, 0x5394: 0x0080, 0x5395: 0x0080, 0x5396: 0x0080, 0x5397: 0x0080, + 0x5398: 0x0080, 0x5399: 0x0080, 0x539a: 0x0080, 0x539b: 0x0080, 0x539c: 0x0080, 0x539d: 0x0080, + 0x539e: 0x0080, 0x539f: 0x0080, 0x53a0: 0x0080, 0x53a1: 0x0080, 0x53a2: 0x0080, 0x53a3: 0x0080, + 0x53a4: 0x0080, 0x53a5: 0x0080, 0x53a6: 0x0080, 0x53a7: 0x0080, 0x53a8: 0x0080, 0x53a9: 0x0080, + 0x53aa: 0x0080, 0x53ab: 0x0080, 0x53ac: 0x0080, 0x53ad: 0x0080, 0x53ae: 0x0080, 0x53af: 0x0080, + 0x53b0: 0x0080, 0x53b1: 0x0080, 0x53b2: 0x0080, 0x53b3: 0x0080, 0x53b4: 0x0080, 0x53b5: 0x0080, + 0x53b6: 0x0080, 0x53b7: 0x0080, 0x53b8: 0x0080, 0x53b9: 0x0080, 0x53ba: 0x0080, 0x53bb: 0x0080, + 0x53bc: 0x0080, 0x53bd: 0x0080, 0x53be: 0x0080, 0x53bf: 0x0080, + // Block 0x14f, offset 0x53c0 + 0x53c0: 0x0080, 0x53c1: 0x0080, 0x53c2: 0x0080, 0x53c3: 0x0080, 0x53c4: 0x0080, 0x53c5: 0x0080, + 0x53c6: 0x0080, 0x53c7: 0x0080, + 0x53d0: 0x0080, 0x53d1: 0x0080, + 0x53d2: 0x0080, 0x53d3: 0x0080, 0x53d4: 0x0080, 0x53d5: 0x0080, 0x53d6: 0x0080, 0x53d7: 0x0080, + 0x53d8: 0x0080, 0x53d9: 0x0080, + 0x53e0: 0x0080, 0x53e1: 0x0080, 0x53e2: 0x0080, 0x53e3: 0x0080, + 0x53e4: 0x0080, 0x53e5: 0x0080, 0x53e6: 0x0080, 0x53e7: 0x0080, 0x53e8: 0x0080, 0x53e9: 0x0080, + 0x53ea: 0x0080, 0x53eb: 0x0080, 0x53ec: 0x0080, 0x53ed: 0x0080, 0x53ee: 0x0080, 0x53ef: 0x0080, + 0x53f0: 0x0080, 0x53f1: 0x0080, 0x53f2: 0x0080, 0x53f3: 0x0080, 0x53f4: 0x0080, 0x53f5: 0x0080, + 0x53f6: 0x0080, 0x53f7: 0x0080, 0x53f8: 0x0080, 0x53f9: 0x0080, 0x53fa: 0x0080, 0x53fb: 0x0080, + 0x53fc: 0x0080, 0x53fd: 0x0080, 0x53fe: 0x0080, 0x53ff: 0x0080, + // Block 0x150, offset 0x5400 + 0x5400: 0x0080, 0x5401: 0x0080, 0x5402: 0x0080, 0x5403: 0x0080, 0x5404: 0x0080, 0x5405: 0x0080, + 0x5406: 0x0080, 0x5407: 0x0080, + 0x5410: 0x0080, 0x5411: 0x0080, + 0x5412: 0x0080, 0x5413: 0x0080, 0x5414: 0x0080, 0x5415: 0x0080, 0x5416: 0x0080, 0x5417: 0x0080, + 0x5418: 0x0080, 0x5419: 0x0080, 0x541a: 0x0080, 0x541b: 0x0080, 0x541c: 0x0080, 0x541d: 0x0080, + 0x541e: 0x0080, 0x541f: 0x0080, 0x5420: 0x0080, 0x5421: 0x0080, 0x5422: 0x0080, 0x5423: 0x0080, + 0x5424: 0x0080, 0x5425: 0x0080, 0x5426: 0x0080, 0x5427: 0x0080, 0x5428: 0x0080, 0x5429: 0x0080, + 0x542a: 0x0080, 0x542b: 0x0080, 0x542c: 0x0080, 0x542d: 0x0080, + // Block 0x151, offset 0x5440 + 0x5440: 0x0080, 0x5441: 0x0080, 0x5442: 0x0080, 0x5443: 0x0080, 0x5444: 0x0080, 0x5445: 0x0080, + 0x5446: 0x0080, 0x5447: 0x0080, 0x5448: 0x0080, 0x5449: 0x0080, 0x544a: 0x0080, 0x544b: 0x0080, + 0x544d: 0x0080, 0x544e: 0x0080, 0x544f: 0x0080, 0x5450: 0x0080, 0x5451: 0x0080, + 0x5452: 0x0080, 0x5453: 0x0080, 0x5454: 0x0080, 0x5455: 0x0080, 0x5456: 0x0080, 0x5457: 0x0080, + 0x5458: 0x0080, 0x5459: 0x0080, 0x545a: 0x0080, 0x545b: 0x0080, 0x545c: 0x0080, 0x545d: 0x0080, + 0x545e: 0x0080, 0x545f: 0x0080, 0x5460: 0x0080, 0x5461: 0x0080, 0x5462: 0x0080, 0x5463: 0x0080, + 0x5464: 0x0080, 0x5465: 0x0080, 0x5466: 0x0080, 0x5467: 0x0080, 0x5468: 0x0080, 0x5469: 0x0080, + 0x546a: 0x0080, 0x546b: 0x0080, 0x546c: 0x0080, 0x546d: 0x0080, 0x546e: 0x0080, 0x546f: 0x0080, + 0x5470: 0x0080, 0x5471: 0x0080, 0x5472: 0x0080, 0x5473: 0x0080, 0x5474: 0x0080, 0x5475: 0x0080, + 0x5476: 0x0080, 0x5477: 0x0080, 0x5478: 0x0080, 0x5479: 0x0080, 0x547a: 0x0080, 0x547b: 0x0080, + 0x547c: 0x0080, 0x547d: 0x0080, 0x547e: 0x0080, 0x547f: 0x0080, + // Block 0x152, offset 0x5480 + 0x5480: 0x0080, 0x5481: 0x0080, 0x5482: 0x0080, 0x5483: 0x0080, 0x5484: 0x0080, 0x5485: 0x0080, + 0x5486: 0x0080, 0x5487: 0x0080, 0x5488: 0x0080, 0x5489: 0x0080, 0x548a: 0x0080, 0x548b: 0x0080, + 0x548c: 0x0080, 0x548d: 0x0080, 0x548e: 0x0080, 0x548f: 0x0080, 0x5490: 0x0080, 0x5491: 0x0080, + 0x5492: 0x0080, 0x5493: 0x0080, 0x5494: 0x0080, 0x5495: 0x0080, 0x5496: 0x0080, 0x5497: 0x0080, + 0x5498: 0x0080, 0x5499: 0x0080, 0x549a: 0x0080, 0x549b: 0x0080, 0x549c: 0x0080, 0x549d: 0x0080, + 0x549e: 0x0080, 0x549f: 0x0080, 0x54a0: 0x0080, 0x54a1: 0x0080, 0x54a2: 0x0080, 0x54a3: 0x0080, + 0x54a4: 0x0080, 0x54a5: 0x0080, 0x54a6: 0x0080, 0x54a7: 0x0080, 0x54a8: 0x0080, 0x54a9: 0x0080, + 0x54aa: 0x0080, 0x54ab: 0x0080, 0x54ac: 0x0080, 0x54ad: 0x0080, 0x54ae: 0x0080, 0x54af: 0x0080, + 0x54b0: 0x0080, 0x54b1: 0x0080, 0x54b3: 0x0080, 0x54b4: 0x0080, 0x54b5: 0x0080, + 0x54b6: 0x0080, 0x54ba: 0x0080, 0x54bb: 0x0080, + 0x54bc: 0x0080, 0x54bd: 0x0080, 0x54be: 0x0080, 0x54bf: 0x0080, + // Block 0x153, offset 0x54c0 + 0x54c0: 0x0080, 0x54c1: 0x0080, 0x54c2: 0x0080, 0x54c3: 0x0080, 0x54c4: 0x0080, 0x54c5: 0x0080, + 0x54c6: 0x0080, 0x54c7: 0x0080, 0x54c8: 0x0080, 0x54c9: 0x0080, 0x54ca: 0x0080, 0x54cb: 0x0080, + 0x54cc: 0x0080, 0x54cd: 0x0080, 0x54ce: 0x0080, 0x54cf: 0x0080, 0x54d0: 0x0080, 0x54d1: 0x0080, + 0x54d2: 0x0080, 0x54d3: 0x0080, 0x54d4: 0x0080, 0x54d5: 0x0080, 0x54d6: 0x0080, 0x54d7: 0x0080, + 0x54d8: 0x0080, 0x54d9: 0x0080, 0x54da: 0x0080, 0x54db: 0x0080, 0x54dc: 0x0080, 0x54dd: 0x0080, + 0x54de: 0x0080, 0x54df: 0x0080, 0x54e0: 0x0080, 0x54e1: 0x0080, 0x54e2: 0x0080, + 0x54e5: 0x0080, 0x54e6: 0x0080, 0x54e7: 0x0080, 0x54e8: 0x0080, 0x54e9: 0x0080, + 0x54ea: 0x0080, 0x54ee: 0x0080, 0x54ef: 0x0080, + 0x54f0: 0x0080, 0x54f1: 0x0080, 0x54f2: 0x0080, 0x54f3: 0x0080, 0x54f4: 0x0080, 0x54f5: 0x0080, + 0x54f6: 0x0080, 0x54f7: 0x0080, 0x54f8: 0x0080, 0x54f9: 0x0080, 0x54fa: 0x0080, 0x54fb: 0x0080, + 0x54fc: 0x0080, 0x54fd: 0x0080, 0x54fe: 0x0080, 0x54ff: 0x0080, + // Block 0x154, offset 0x5500 + 0x5500: 0x0080, 0x5501: 0x0080, 0x5502: 0x0080, 0x5503: 0x0080, 0x5504: 0x0080, 0x5505: 0x0080, + 0x5506: 0x0080, 0x5507: 0x0080, 0x5508: 0x0080, 0x5509: 0x0080, 0x550a: 0x0080, + 0x550d: 0x0080, 0x550e: 0x0080, 0x550f: 0x0080, 0x5510: 0x0080, 0x5511: 0x0080, + 0x5512: 0x0080, 0x5513: 0x0080, 0x5514: 0x0080, 0x5515: 0x0080, 0x5516: 0x0080, 0x5517: 0x0080, + 0x5518: 0x0080, 0x5519: 0x0080, 0x551a: 0x0080, 0x551b: 0x0080, 0x551c: 0x0080, 0x551d: 0x0080, + 0x551e: 0x0080, 0x551f: 0x0080, 0x5520: 0x0080, 0x5521: 0x0080, 0x5522: 0x0080, 0x5523: 0x0080, + 0x5524: 0x0080, 0x5525: 0x0080, 0x5526: 0x0080, 0x5527: 0x0080, 0x5528: 0x0080, 0x5529: 0x0080, + 0x552a: 0x0080, 0x552b: 0x0080, 0x552c: 0x0080, 0x552d: 0x0080, 0x552e: 0x0080, 0x552f: 0x0080, + 0x5530: 0x0080, 0x5531: 0x0080, 0x5532: 0x0080, 0x5533: 0x0080, 0x5534: 0x0080, 0x5535: 0x0080, + 0x5536: 0x0080, 0x5537: 0x0080, 0x5538: 0x0080, 0x5539: 0x0080, 0x553a: 0x0080, 0x553b: 0x0080, + 0x553c: 0x0080, 0x553d: 0x0080, 0x553e: 0x0080, 0x553f: 0x0080, + // Block 0x155, offset 0x5540 + 0x5540: 0x0080, 0x5541: 0x0080, 0x5542: 0x0080, 0x5543: 0x0080, 0x5544: 0x0080, 0x5545: 0x0080, + 0x5546: 0x0080, 0x5547: 0x0080, 0x5548: 0x0080, 0x5549: 0x0080, 0x554a: 0x0080, 0x554b: 0x0080, + 0x554c: 0x0080, 0x554d: 0x0080, 0x554e: 0x0080, 0x554f: 0x0080, 0x5550: 0x0080, 0x5551: 0x0080, + 0x5552: 0x0080, 0x5553: 0x0080, + 0x5560: 0x0080, 0x5561: 0x0080, 0x5562: 0x0080, 0x5563: 0x0080, + 0x5564: 0x0080, 0x5565: 0x0080, 0x5566: 0x0080, 0x5567: 0x0080, 0x5568: 0x0080, 0x5569: 0x0080, + 0x556a: 0x0080, 0x556b: 0x0080, 0x556c: 0x0080, 0x556d: 0x0080, + 0x5570: 0x0080, 0x5571: 0x0080, 0x5572: 0x0080, 0x5573: 0x0080, + 0x5578: 0x0080, 0x5579: 0x0080, 0x557a: 0x0080, + // Block 0x156, offset 0x5580 + 0x5580: 0x0080, 0x5581: 0x0080, 0x5582: 0x0080, + 0x5590: 0x0080, 0x5591: 0x0080, + 0x5592: 0x0080, 0x5593: 0x0080, 0x5594: 0x0080, 0x5595: 0x0080, + // Block 0x157, offset 0x55c0 + 0x55c0: 0x00cc, 0x55c1: 0x00cc, 0x55c2: 0x00cc, 0x55c3: 0x00cc, 0x55c4: 0x00cc, 0x55c5: 0x00cc, + 0x55c6: 0x00cc, 0x55c7: 0x00cc, 0x55c8: 0x00cc, 0x55c9: 0x00cc, 0x55ca: 0x00cc, 0x55cb: 0x00cc, + 0x55cc: 0x00cc, 0x55cd: 0x00cc, 0x55ce: 0x00cc, 0x55cf: 0x00cc, 0x55d0: 0x00cc, 0x55d1: 0x00cc, + 0x55d2: 0x00cc, 0x55d3: 0x00cc, 0x55d4: 0x00cc, 0x55d5: 0x00cc, 0x55d6: 0x00cc, + // Block 0x158, offset 0x5600 + 0x5600: 0x00cc, 0x5601: 0x00cc, 0x5602: 0x00cc, 0x5603: 0x00cc, 0x5604: 0x00cc, 0x5605: 0x00cc, + 0x5606: 0x00cc, 0x5607: 0x00cc, 0x5608: 0x00cc, 0x5609: 0x00cc, 0x560a: 0x00cc, 0x560b: 0x00cc, + 0x560c: 0x00cc, 0x560d: 0x00cc, 0x560e: 0x00cc, 0x560f: 0x00cc, 0x5610: 0x00cc, 0x5611: 0x00cc, + 0x5612: 0x00cc, 0x5613: 0x00cc, 0x5614: 0x00cc, 0x5615: 0x00cc, 0x5616: 0x00cc, 0x5617: 0x00cc, + 0x5618: 0x00cc, 0x5619: 0x00cc, 0x561a: 0x00cc, 0x561b: 0x00cc, 0x561c: 0x00cc, 0x561d: 0x00cc, + 0x561e: 0x00cc, 0x561f: 0x00cc, 0x5620: 0x00cc, 0x5621: 0x00cc, 0x5622: 0x00cc, 0x5623: 0x00cc, + 0x5624: 0x00cc, 0x5625: 0x00cc, 0x5626: 0x00cc, 0x5627: 0x00cc, 0x5628: 0x00cc, 0x5629: 0x00cc, + 0x562a: 0x00cc, 0x562b: 0x00cc, 0x562c: 0x00cc, 0x562d: 0x00cc, 0x562e: 0x00cc, 0x562f: 0x00cc, + 0x5630: 0x00cc, 0x5631: 0x00cc, 0x5632: 0x00cc, 0x5633: 0x00cc, 0x5634: 0x00cc, + // Block 0x159, offset 0x5640 + 0x5640: 0x00cc, 0x5641: 0x00cc, 0x5642: 0x00cc, 0x5643: 0x00cc, 0x5644: 0x00cc, 0x5645: 0x00cc, + 0x5646: 0x00cc, 0x5647: 0x00cc, 0x5648: 0x00cc, 0x5649: 0x00cc, 0x564a: 0x00cc, 0x564b: 0x00cc, + 0x564c: 0x00cc, 0x564d: 0x00cc, 0x564e: 0x00cc, 0x564f: 0x00cc, 0x5650: 0x00cc, 0x5651: 0x00cc, + 0x5652: 0x00cc, 0x5653: 0x00cc, 0x5654: 0x00cc, 0x5655: 0x00cc, 0x5656: 0x00cc, 0x5657: 0x00cc, + 0x5658: 0x00cc, 0x5659: 0x00cc, 0x565a: 0x00cc, 0x565b: 0x00cc, 0x565c: 0x00cc, 0x565d: 0x00cc, + 0x5660: 0x00cc, 0x5661: 0x00cc, 0x5662: 0x00cc, 0x5663: 0x00cc, + 0x5664: 0x00cc, 0x5665: 0x00cc, 0x5666: 0x00cc, 0x5667: 0x00cc, 0x5668: 0x00cc, 0x5669: 0x00cc, + 0x566a: 0x00cc, 0x566b: 0x00cc, 0x566c: 0x00cc, 0x566d: 0x00cc, 0x566e: 0x00cc, 0x566f: 0x00cc, + 0x5670: 0x00cc, 0x5671: 0x00cc, 0x5672: 0x00cc, 0x5673: 0x00cc, 0x5674: 0x00cc, 0x5675: 0x00cc, + 0x5676: 0x00cc, 0x5677: 0x00cc, 0x5678: 0x00cc, 0x5679: 0x00cc, 0x567a: 0x00cc, 0x567b: 0x00cc, + 0x567c: 0x00cc, 0x567d: 0x00cc, 0x567e: 0x00cc, 0x567f: 0x00cc, + // Block 0x15a, offset 0x5680 + 0x5680: 0x00cc, 0x5681: 0x00cc, 0x5682: 0x00cc, 0x5683: 0x00cc, 0x5684: 0x00cc, 0x5685: 0x00cc, + 0x5686: 0x00cc, 0x5687: 0x00cc, 0x5688: 0x00cc, 0x5689: 0x00cc, 0x568a: 0x00cc, 0x568b: 0x00cc, + 0x568c: 0x00cc, 0x568d: 0x00cc, 0x568e: 0x00cc, 0x568f: 0x00cc, 0x5690: 0x00cc, 0x5691: 0x00cc, + 0x5692: 0x00cc, 0x5693: 0x00cc, 0x5694: 0x00cc, 0x5695: 0x00cc, 0x5696: 0x00cc, 0x5697: 0x00cc, + 0x5698: 0x00cc, 0x5699: 0x00cc, 0x569a: 0x00cc, 0x569b: 0x00cc, 0x569c: 0x00cc, 0x569d: 0x00cc, + 0x569e: 0x00cc, 0x569f: 0x00cc, 0x56a0: 0x00cc, 0x56a1: 0x00cc, + 0x56b0: 0x00cc, 0x56b1: 0x00cc, 0x56b2: 0x00cc, 0x56b3: 0x00cc, 0x56b4: 0x00cc, 0x56b5: 0x00cc, + 0x56b6: 0x00cc, 0x56b7: 0x00cc, 0x56b8: 0x00cc, 0x56b9: 0x00cc, 0x56ba: 0x00cc, 0x56bb: 0x00cc, + 0x56bc: 0x00cc, 0x56bd: 0x00cc, 0x56be: 0x00cc, 0x56bf: 0x00cc, + // Block 0x15b, offset 0x56c0 + 0x56c0: 0x00cc, 0x56c1: 0x00cc, 0x56c2: 0x00cc, 0x56c3: 0x00cc, 0x56c4: 0x00cc, 0x56c5: 0x00cc, + 0x56c6: 0x00cc, 0x56c7: 0x00cc, 0x56c8: 0x00cc, 0x56c9: 0x00cc, 0x56ca: 0x00cc, 0x56cb: 0x00cc, + 0x56cc: 0x00cc, 0x56cd: 0x00cc, 0x56ce: 0x00cc, 0x56cf: 0x00cc, 0x56d0: 0x00cc, 0x56d1: 0x00cc, + 0x56d2: 0x00cc, 0x56d3: 0x00cc, 0x56d4: 0x00cc, 0x56d5: 0x00cc, 0x56d6: 0x00cc, 0x56d7: 0x00cc, + 0x56d8: 0x00cc, 0x56d9: 0x00cc, 0x56da: 0x00cc, 0x56db: 0x00cc, 0x56dc: 0x00cc, 0x56dd: 0x00cc, + 0x56de: 0x00cc, 0x56df: 0x00cc, 0x56e0: 0x00cc, + // Block 0x15c, offset 0x5700 + 0x5700: 0x008c, 0x5701: 0x008c, 0x5702: 0x008c, 0x5703: 0x008c, 0x5704: 0x008c, 0x5705: 0x008c, + 0x5706: 0x008c, 0x5707: 0x008c, 0x5708: 0x008c, 0x5709: 0x008c, 0x570a: 0x008c, 0x570b: 0x008c, + 0x570c: 0x008c, 0x570d: 0x008c, 0x570e: 0x008c, 0x570f: 0x008c, 0x5710: 0x008c, 0x5711: 0x008c, + 0x5712: 0x008c, 0x5713: 0x008c, 0x5714: 0x008c, 0x5715: 0x008c, 0x5716: 0x008c, 0x5717: 0x008c, + 0x5718: 0x008c, 0x5719: 0x008c, 0x571a: 0x008c, 0x571b: 0x008c, 0x571c: 0x008c, 0x571d: 0x008c, + // Block 0x15d, offset 0x5740 + 0x5741: 0x0040, + 0x5760: 0x0040, 0x5761: 0x0040, 0x5762: 0x0040, 0x5763: 0x0040, + 0x5764: 0x0040, 0x5765: 0x0040, 0x5766: 0x0040, 0x5767: 0x0040, 0x5768: 0x0040, 0x5769: 0x0040, + 0x576a: 0x0040, 0x576b: 0x0040, 0x576c: 0x0040, 0x576d: 0x0040, 0x576e: 0x0040, 0x576f: 0x0040, + 0x5770: 0x0040, 0x5771: 0x0040, 0x5772: 0x0040, 0x5773: 0x0040, 0x5774: 0x0040, 0x5775: 0x0040, + 0x5776: 0x0040, 0x5777: 0x0040, 0x5778: 0x0040, 0x5779: 0x0040, 0x577a: 0x0040, 0x577b: 0x0040, + 0x577c: 0x0040, 0x577d: 0x0040, 0x577e: 0x0040, 0x577f: 0x0040, + // Block 0x15e, offset 0x5780 + 0x5780: 0x0040, 0x5781: 0x0040, 0x5782: 0x0040, 0x5783: 0x0040, 0x5784: 0x0040, 0x5785: 0x0040, + 0x5786: 0x0040, 0x5787: 0x0040, 0x5788: 0x0040, 0x5789: 0x0040, 0x578a: 0x0040, 0x578b: 0x0040, + 0x578c: 0x0040, 0x578d: 0x0040, 0x578e: 0x0040, 0x578f: 0x0040, 0x5790: 0x0040, 0x5791: 0x0040, + 0x5792: 0x0040, 0x5793: 0x0040, 0x5794: 0x0040, 0x5795: 0x0040, 0x5796: 0x0040, 0x5797: 0x0040, + 0x5798: 0x0040, 0x5799: 0x0040, 0x579a: 0x0040, 0x579b: 0x0040, 0x579c: 0x0040, 0x579d: 0x0040, + 0x579e: 0x0040, 0x579f: 0x0040, 0x57a0: 0x0040, 0x57a1: 0x0040, 0x57a2: 0x0040, 0x57a3: 0x0040, + 0x57a4: 0x0040, 0x57a5: 0x0040, 0x57a6: 0x0040, 0x57a7: 0x0040, 0x57a8: 0x0040, 0x57a9: 0x0040, + 0x57aa: 0x0040, 0x57ab: 0x0040, 0x57ac: 0x0040, 0x57ad: 0x0040, 0x57ae: 0x0040, 0x57af: 0x0040, + // Block 0x15f, offset 0x57c0 + 0x57c0: 0x0040, 0x57c1: 0x0040, 0x57c2: 0x0040, 0x57c3: 0x0040, 0x57c4: 0x0040, 0x57c5: 0x0040, + 0x57c6: 0x0040, 0x57c7: 0x0040, 0x57c8: 0x0040, 0x57c9: 0x0040, 0x57ca: 0x0040, 0x57cb: 0x0040, + 0x57cc: 0x0040, 0x57cd: 0x0040, 0x57ce: 0x0040, 0x57cf: 0x0040, 0x57d0: 0x0040, 0x57d1: 0x0040, + 0x57d2: 0x0040, 0x57d3: 0x0040, 0x57d4: 0x0040, 0x57d5: 0x0040, 0x57d6: 0x0040, 0x57d7: 0x0040, + 0x57d8: 0x0040, 0x57d9: 0x0040, 0x57da: 0x0040, 0x57db: 0x0040, 0x57dc: 0x0040, 0x57dd: 0x0040, + 0x57de: 0x0040, 0x57df: 0x0040, 0x57e0: 0x0040, 0x57e1: 0x0040, 0x57e2: 0x0040, 0x57e3: 0x0040, + 0x57e4: 0x0040, 0x57e5: 0x0040, 0x57e6: 0x0040, 0x57e7: 0x0040, 0x57e8: 0x0040, 0x57e9: 0x0040, + 0x57ea: 0x0040, 0x57eb: 0x0040, 0x57ec: 0x0040, 0x57ed: 0x0040, 0x57ee: 0x0040, 0x57ef: 0x0040, + 0x57f0: 0x0040, 0x57f1: 0x0040, 0x57f2: 0x0040, 0x57f3: 0x0040, 0x57f4: 0x0040, 0x57f5: 0x0040, + 0x57f6: 0x0040, 0x57f7: 0x0040, 0x57f8: 0x0040, 0x57f9: 0x0040, 0x57fa: 0x0040, 0x57fb: 0x0040, + 0x57fc: 0x0040, 0x57fd: 0x0040, +} + +// derivedPropertiesIndex: 37 blocks, 2368 entries, 4736 bytes +// Block 0 is the zero block. +var derivedPropertiesIndex = [2368]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc6: 0x05, 0xc7: 0x06, + 0xc8: 0x05, 0xc9: 0x05, 0xca: 0x07, 0xcb: 0x08, 0xcc: 0x09, 0xcd: 0x0a, 0xce: 0x0b, 0xcf: 0x0c, + 0xd0: 0x05, 0xd1: 0x05, 0xd2: 0x0d, 0xd3: 0x05, 0xd4: 0x0e, 0xd5: 0x0f, 0xd6: 0x10, 0xd7: 0x11, + 0xd8: 0x12, 0xd9: 0x13, 0xda: 0x14, 0xdb: 0x15, 0xdc: 0x16, 0xdd: 0x17, 0xde: 0x18, 0xdf: 0x19, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x0a, 0xec: 0x0a, 0xed: 0x0b, 0xee: 0x0c, 0xef: 0x0d, + 0xf0: 0x1e, 0xf3: 0x21, 0xf4: 0x22, + // Block 0x4, offset 0x100 + 0x120: 0x1a, 0x121: 0x1b, 0x122: 0x1c, 0x123: 0x1d, 0x124: 0x1e, 0x125: 0x1f, 0x126: 0x20, 0x127: 0x21, + 0x128: 0x22, 0x129: 0x23, 0x12a: 0x24, 0x12b: 0x25, 0x12c: 0x26, 0x12d: 0x27, 0x12e: 0x28, 0x12f: 0x29, + 0x130: 0x2a, 0x131: 0x2b, 0x132: 0x2c, 0x133: 0x2d, 0x134: 0x2e, 0x135: 0x2f, 0x136: 0x30, 0x137: 0x31, + 0x138: 0x32, 0x139: 0x33, 0x13a: 0x34, 0x13b: 0x35, 0x13c: 0x36, 0x13d: 0x37, 0x13e: 0x38, 0x13f: 0x39, + // Block 0x5, offset 0x140 + 0x140: 0x3a, 0x141: 0x3b, 0x142: 0x3c, 0x143: 0x3d, 0x144: 0x3e, 0x145: 0x3e, 0x146: 0x3e, 0x147: 0x3e, + 0x148: 0x05, 0x149: 0x3f, 0x14a: 0x40, 0x14b: 0x41, 0x14c: 0x42, 0x14d: 0x43, 0x14e: 0x44, 0x14f: 0x45, + 0x150: 0x46, 0x151: 0x05, 0x152: 0x05, 0x153: 0x05, 0x154: 0x05, 0x155: 0x05, 0x156: 0x05, 0x157: 0x05, + 0x158: 0x05, 0x159: 0x47, 0x15a: 0x48, 0x15b: 0x49, 0x15c: 0x4a, 0x15d: 0x4b, 0x15e: 0x4c, 0x15f: 0x4d, + 0x160: 0x4e, 0x161: 0x4f, 0x162: 0x50, 0x163: 0x51, 0x164: 0x52, 0x165: 0x53, 0x166: 0x54, 0x167: 0x55, + 0x168: 0x56, 0x169: 0x57, 0x16a: 0x58, 0x16c: 0x59, 0x16d: 0x5a, 0x16e: 0x5b, 0x16f: 0x5c, + 0x170: 0x5d, 0x171: 0x5e, 0x172: 0x5f, 0x173: 0x60, 0x174: 0x61, 0x175: 0x62, 0x176: 0x63, 0x177: 0x64, + 0x178: 0x05, 0x179: 0x05, 0x17a: 0x65, 0x17b: 0x05, 0x17c: 0x66, 0x17d: 0x67, 0x17e: 0x68, 0x17f: 0x69, + // Block 0x6, offset 0x180 + 0x180: 0x6a, 0x181: 0x6b, 0x182: 0x6c, 0x183: 0x6d, 0x184: 0x6e, 0x185: 0x6f, 0x186: 0x70, 0x187: 0x71, + 0x188: 0x71, 0x189: 0x71, 0x18a: 0x71, 0x18b: 0x71, 0x18c: 0x71, 0x18d: 0x71, 0x18e: 0x71, 0x18f: 0x71, + 0x190: 0x72, 0x191: 0x73, 0x192: 0x71, 0x193: 0x71, 0x194: 0x71, 0x195: 0x71, 0x196: 0x71, 0x197: 0x71, + 0x198: 0x71, 0x199: 0x71, 0x19a: 0x71, 0x19b: 0x71, 0x19c: 0x71, 0x19d: 0x71, 0x19e: 0x71, 0x19f: 0x71, + 0x1a0: 0x71, 0x1a1: 0x71, 0x1a2: 0x71, 0x1a3: 0x71, 0x1a4: 0x71, 0x1a5: 0x71, 0x1a6: 0x71, 0x1a7: 0x71, + 0x1a8: 0x71, 0x1a9: 0x71, 0x1aa: 0x71, 0x1ab: 0x71, 0x1ac: 0x71, 0x1ad: 0x74, 0x1ae: 0x75, 0x1af: 0x71, + 0x1b0: 0x76, 0x1b1: 0x77, 0x1b2: 0x05, 0x1b3: 0x78, 0x1b4: 0x79, 0x1b5: 0x7a, 0x1b6: 0x7b, 0x1b7: 0x7c, + 0x1b8: 0x7d, 0x1b9: 0x7e, 0x1ba: 0x7f, 0x1bb: 0x80, 0x1bc: 0x81, 0x1bd: 0x81, 0x1be: 0x81, 0x1bf: 0x82, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x83, 0x1c1: 0x84, 0x1c2: 0x85, 0x1c3: 0x86, 0x1c4: 0x87, 0x1c5: 0x88, 0x1c6: 0x89, 0x1c7: 0x8a, + 0x1c8: 0x8b, 0x1c9: 0x71, 0x1ca: 0x71, 0x1cb: 0x8c, 0x1cc: 0x81, 0x1cd: 0x8d, 0x1ce: 0x71, 0x1cf: 0x71, + 0x1d0: 0x8e, 0x1d1: 0x8e, 0x1d2: 0x8e, 0x1d3: 0x8e, 0x1d4: 0x8e, 0x1d5: 0x8e, 0x1d6: 0x8e, 0x1d7: 0x8e, + 0x1d8: 0x8e, 0x1d9: 0x8e, 0x1da: 0x8e, 0x1db: 0x8e, 0x1dc: 0x8e, 0x1dd: 0x8e, 0x1de: 0x8e, 0x1df: 0x8e, + 0x1e0: 0x8e, 0x1e1: 0x8e, 0x1e2: 0x8e, 0x1e3: 0x8e, 0x1e4: 0x8e, 0x1e5: 0x8e, 0x1e6: 0x8e, 0x1e7: 0x8e, + 0x1e8: 0x8e, 0x1e9: 0x8e, 0x1ea: 0x8e, 0x1eb: 0x8e, 0x1ec: 0x8e, 0x1ed: 0x8e, 0x1ee: 0x8e, 0x1ef: 0x8e, + 0x1f0: 0x8e, 0x1f1: 0x8e, 0x1f2: 0x8e, 0x1f3: 0x8e, 0x1f4: 0x8e, 0x1f5: 0x8e, 0x1f6: 0x8e, 0x1f7: 0x8e, + 0x1f8: 0x8e, 0x1f9: 0x8e, 0x1fa: 0x8e, 0x1fb: 0x8e, 0x1fc: 0x8e, 0x1fd: 0x8e, 0x1fe: 0x8e, 0x1ff: 0x8e, + // Block 0x8, offset 0x200 + 0x200: 0x8e, 0x201: 0x8e, 0x202: 0x8e, 0x203: 0x8e, 0x204: 0x8e, 0x205: 0x8e, 0x206: 0x8e, 0x207: 0x8e, + 0x208: 0x8e, 0x209: 0x8e, 0x20a: 0x8e, 0x20b: 0x8e, 0x20c: 0x8e, 0x20d: 0x8e, 0x20e: 0x8e, 0x20f: 0x8e, + 0x210: 0x8e, 0x211: 0x8e, 0x212: 0x8e, 0x213: 0x8e, 0x214: 0x8e, 0x215: 0x8e, 0x216: 0x8e, 0x217: 0x8e, + 0x218: 0x8e, 0x219: 0x8e, 0x21a: 0x8e, 0x21b: 0x8e, 0x21c: 0x8e, 0x21d: 0x8e, 0x21e: 0x8e, 0x21f: 0x8e, + 0x220: 0x8e, 0x221: 0x8e, 0x222: 0x8e, 0x223: 0x8e, 0x224: 0x8e, 0x225: 0x8e, 0x226: 0x8e, 0x227: 0x8e, + 0x228: 0x8e, 0x229: 0x8e, 0x22a: 0x8e, 0x22b: 0x8e, 0x22c: 0x8e, 0x22d: 0x8e, 0x22e: 0x8e, 0x22f: 0x8e, + 0x230: 0x8e, 0x231: 0x8e, 0x232: 0x8e, 0x233: 0x8e, 0x234: 0x8e, 0x235: 0x8e, 0x236: 0x8f, 0x237: 0x71, + 0x238: 0x8e, 0x239: 0x8e, 0x23a: 0x8e, 0x23b: 0x8e, 0x23c: 0x8e, 0x23d: 0x8e, 0x23e: 0x8e, 0x23f: 0x8e, + // Block 0x9, offset 0x240 + 0x240: 0x8e, 0x241: 0x8e, 0x242: 0x8e, 0x243: 0x8e, 0x244: 0x8e, 0x245: 0x8e, 0x246: 0x8e, 0x247: 0x8e, + 0x248: 0x8e, 0x249: 0x8e, 0x24a: 0x8e, 0x24b: 0x8e, 0x24c: 0x8e, 0x24d: 0x8e, 0x24e: 0x8e, 0x24f: 0x8e, + 0x250: 0x8e, 0x251: 0x8e, 0x252: 0x8e, 0x253: 0x8e, 0x254: 0x8e, 0x255: 0x8e, 0x256: 0x8e, 0x257: 0x8e, + 0x258: 0x8e, 0x259: 0x8e, 0x25a: 0x8e, 0x25b: 0x8e, 0x25c: 0x8e, 0x25d: 0x8e, 0x25e: 0x8e, 0x25f: 0x8e, + 0x260: 0x8e, 0x261: 0x8e, 0x262: 0x8e, 0x263: 0x8e, 0x264: 0x8e, 0x265: 0x8e, 0x266: 0x8e, 0x267: 0x8e, + 0x268: 0x8e, 0x269: 0x8e, 0x26a: 0x8e, 0x26b: 0x8e, 0x26c: 0x8e, 0x26d: 0x8e, 0x26e: 0x8e, 0x26f: 0x8e, + 0x270: 0x8e, 0x271: 0x8e, 0x272: 0x8e, 0x273: 0x8e, 0x274: 0x8e, 0x275: 0x8e, 0x276: 0x8e, 0x277: 0x8e, + 0x278: 0x8e, 0x279: 0x8e, 0x27a: 0x8e, 0x27b: 0x8e, 0x27c: 0x8e, 0x27d: 0x8e, 0x27e: 0x8e, 0x27f: 0x8e, + // Block 0xa, offset 0x280 + 0x280: 0x8e, 0x281: 0x8e, 0x282: 0x8e, 0x283: 0x8e, 0x284: 0x8e, 0x285: 0x8e, 0x286: 0x8e, 0x287: 0x8e, + 0x288: 0x8e, 0x289: 0x8e, 0x28a: 0x8e, 0x28b: 0x8e, 0x28c: 0x8e, 0x28d: 0x8e, 0x28e: 0x8e, 0x28f: 0x8e, + 0x290: 0x8e, 0x291: 0x8e, 0x292: 0x8e, 0x293: 0x8e, 0x294: 0x8e, 0x295: 0x8e, 0x296: 0x8e, 0x297: 0x8e, + 0x298: 0x8e, 0x299: 0x8e, 0x29a: 0x8e, 0x29b: 0x8e, 0x29c: 0x8e, 0x29d: 0x8e, 0x29e: 0x8e, 0x29f: 0x8e, + 0x2a0: 0x8e, 0x2a1: 0x8e, 0x2a2: 0x8e, 0x2a3: 0x8e, 0x2a4: 0x8e, 0x2a5: 0x8e, 0x2a6: 0x8e, 0x2a7: 0x8e, + 0x2a8: 0x8e, 0x2a9: 0x8e, 0x2aa: 0x8e, 0x2ab: 0x8e, 0x2ac: 0x8e, 0x2ad: 0x8e, 0x2ae: 0x8e, 0x2af: 0x8e, + 0x2b0: 0x8e, 0x2b1: 0x8e, 0x2b2: 0x8e, 0x2b3: 0x8e, 0x2b4: 0x8e, 0x2b5: 0x8e, 0x2b6: 0x8e, 0x2b7: 0x8e, + 0x2b8: 0x8e, 0x2b9: 0x8e, 0x2ba: 0x8e, 0x2bb: 0x8e, 0x2bc: 0x8e, 0x2bd: 0x8e, 0x2be: 0x8e, 0x2bf: 0x90, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x05, 0x2c1: 0x05, 0x2c2: 0x05, 0x2c3: 0x05, 0x2c4: 0x05, 0x2c5: 0x05, 0x2c6: 0x05, 0x2c7: 0x05, + 0x2c8: 0x05, 0x2c9: 0x05, 0x2ca: 0x05, 0x2cb: 0x05, 0x2cc: 0x05, 0x2cd: 0x05, 0x2ce: 0x05, 0x2cf: 0x05, + 0x2d0: 0x05, 0x2d1: 0x05, 0x2d2: 0x91, 0x2d3: 0x92, 0x2d4: 0x05, 0x2d5: 0x05, 0x2d6: 0x05, 0x2d7: 0x05, + 0x2d8: 0x93, 0x2d9: 0x94, 0x2da: 0x95, 0x2db: 0x96, 0x2dc: 0x97, 0x2dd: 0x98, 0x2de: 0x99, 0x2df: 0x9a, + 0x2e0: 0x9b, 0x2e1: 0x9c, 0x2e2: 0x05, 0x2e3: 0x9d, 0x2e4: 0x9e, 0x2e5: 0x9f, 0x2e6: 0xa0, 0x2e7: 0xa1, + 0x2e8: 0xa2, 0x2e9: 0xa3, 0x2ea: 0xa4, 0x2eb: 0xa5, 0x2ec: 0xa6, 0x2ed: 0xa7, 0x2ee: 0x05, 0x2ef: 0xa8, + 0x2f0: 0x05, 0x2f1: 0x05, 0x2f2: 0x05, 0x2f3: 0x05, 0x2f4: 0x05, 0x2f5: 0x05, 0x2f6: 0x05, 0x2f7: 0x05, + 0x2f8: 0x05, 0x2f9: 0x05, 0x2fa: 0x05, 0x2fb: 0x05, 0x2fc: 0x05, 0x2fd: 0x05, 0x2fe: 0x05, 0x2ff: 0x05, + // Block 0xc, offset 0x300 + 0x300: 0x05, 0x301: 0x05, 0x302: 0x05, 0x303: 0x05, 0x304: 0x05, 0x305: 0x05, 0x306: 0x05, 0x307: 0x05, + 0x308: 0x05, 0x309: 0x05, 0x30a: 0x05, 0x30b: 0x05, 0x30c: 0x05, 0x30d: 0x05, 0x30e: 0x05, 0x30f: 0x05, + 0x310: 0x05, 0x311: 0x05, 0x312: 0x05, 0x313: 0x05, 0x314: 0x05, 0x315: 0x05, 0x316: 0x05, 0x317: 0x05, + 0x318: 0x05, 0x319: 0x05, 0x31a: 0x05, 0x31b: 0x05, 0x31c: 0x05, 0x31d: 0x05, 0x31e: 0x05, 0x31f: 0x05, + 0x320: 0x05, 0x321: 0x05, 0x322: 0x05, 0x323: 0x05, 0x324: 0x05, 0x325: 0x05, 0x326: 0x05, 0x327: 0x05, + 0x328: 0x05, 0x329: 0x05, 0x32a: 0x05, 0x32b: 0x05, 0x32c: 0x05, 0x32d: 0x05, 0x32e: 0x05, 0x32f: 0x05, + 0x330: 0x05, 0x331: 0x05, 0x332: 0x05, 0x333: 0x05, 0x334: 0x05, 0x335: 0x05, 0x336: 0x05, 0x337: 0x05, + 0x338: 0x05, 0x339: 0x05, 0x33a: 0x05, 0x33b: 0x05, 0x33c: 0x05, 0x33d: 0x05, 0x33e: 0x05, 0x33f: 0x05, + // Block 0xd, offset 0x340 + 0x340: 0x05, 0x341: 0x05, 0x342: 0x05, 0x343: 0x05, 0x344: 0x05, 0x345: 0x05, 0x346: 0x05, 0x347: 0x05, + 0x348: 0x05, 0x349: 0x05, 0x34a: 0x05, 0x34b: 0x05, 0x34c: 0x05, 0x34d: 0x05, 0x34e: 0x05, 0x34f: 0x05, + 0x350: 0x05, 0x351: 0x05, 0x352: 0x05, 0x353: 0x05, 0x354: 0x05, 0x355: 0x05, 0x356: 0x05, 0x357: 0x05, + 0x358: 0x05, 0x359: 0x05, 0x35a: 0x05, 0x35b: 0x05, 0x35c: 0x05, 0x35d: 0x05, 0x35e: 0xa9, 0x35f: 0xaa, + // Block 0xe, offset 0x380 + 0x380: 0x3e, 0x381: 0x3e, 0x382: 0x3e, 0x383: 0x3e, 0x384: 0x3e, 0x385: 0x3e, 0x386: 0x3e, 0x387: 0x3e, + 0x388: 0x3e, 0x389: 0x3e, 0x38a: 0x3e, 0x38b: 0x3e, 0x38c: 0x3e, 0x38d: 0x3e, 0x38e: 0x3e, 0x38f: 0x3e, + 0x390: 0x3e, 0x391: 0x3e, 0x392: 0x3e, 0x393: 0x3e, 0x394: 0x3e, 0x395: 0x3e, 0x396: 0x3e, 0x397: 0x3e, + 0x398: 0x3e, 0x399: 0x3e, 0x39a: 0x3e, 0x39b: 0x3e, 0x39c: 0x3e, 0x39d: 0x3e, 0x39e: 0x3e, 0x39f: 0x3e, + 0x3a0: 0x3e, 0x3a1: 0x3e, 0x3a2: 0x3e, 0x3a3: 0x3e, 0x3a4: 0x3e, 0x3a5: 0x3e, 0x3a6: 0x3e, 0x3a7: 0x3e, + 0x3a8: 0x3e, 0x3a9: 0x3e, 0x3aa: 0x3e, 0x3ab: 0x3e, 0x3ac: 0x3e, 0x3ad: 0x3e, 0x3ae: 0x3e, 0x3af: 0x3e, + 0x3b0: 0x3e, 0x3b1: 0x3e, 0x3b2: 0x3e, 0x3b3: 0x3e, 0x3b4: 0x3e, 0x3b5: 0x3e, 0x3b6: 0x3e, 0x3b7: 0x3e, + 0x3b8: 0x3e, 0x3b9: 0x3e, 0x3ba: 0x3e, 0x3bb: 0x3e, 0x3bc: 0x3e, 0x3bd: 0x3e, 0x3be: 0x3e, 0x3bf: 0x3e, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x3e, 0x3c1: 0x3e, 0x3c2: 0x3e, 0x3c3: 0x3e, 0x3c4: 0x3e, 0x3c5: 0x3e, 0x3c6: 0x3e, 0x3c7: 0x3e, + 0x3c8: 0x3e, 0x3c9: 0x3e, 0x3ca: 0x3e, 0x3cb: 0x3e, 0x3cc: 0x3e, 0x3cd: 0x3e, 0x3ce: 0x3e, 0x3cf: 0x3e, + 0x3d0: 0x3e, 0x3d1: 0x3e, 0x3d2: 0x3e, 0x3d3: 0x3e, 0x3d4: 0x3e, 0x3d5: 0x3e, 0x3d6: 0x3e, 0x3d7: 0x3e, + 0x3d8: 0x3e, 0x3d9: 0x3e, 0x3da: 0x3e, 0x3db: 0x3e, 0x3dc: 0x3e, 0x3dd: 0x3e, 0x3de: 0x3e, 0x3df: 0x3e, + 0x3e0: 0x3e, 0x3e1: 0x3e, 0x3e2: 0x3e, 0x3e3: 0x3e, 0x3e4: 0x81, 0x3e5: 0x81, 0x3e6: 0x81, 0x3e7: 0x81, + 0x3e8: 0xab, 0x3e9: 0xac, 0x3ea: 0x81, 0x3eb: 0xad, 0x3ec: 0xae, 0x3ed: 0xaf, 0x3ee: 0x71, 0x3ef: 0xb0, + 0x3f0: 0x71, 0x3f1: 0x71, 0x3f2: 0x71, 0x3f3: 0x71, 0x3f4: 0x71, 0x3f5: 0xb1, 0x3f6: 0xb2, 0x3f7: 0xb3, + 0x3f8: 0xb4, 0x3f9: 0xb5, 0x3fa: 0x71, 0x3fb: 0xb6, 0x3fc: 0xb7, 0x3fd: 0xb8, 0x3fe: 0xb9, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0xbb, 0x401: 0xbc, 0x402: 0x05, 0x403: 0xbd, 0x404: 0xbe, 0x405: 0xbf, 0x406: 0xc0, 0x407: 0xc1, + 0x40a: 0xc2, 0x40b: 0xc3, 0x40c: 0xc4, 0x40d: 0xc5, 0x40e: 0xc6, 0x40f: 0xc7, + 0x410: 0x05, 0x411: 0x05, 0x412: 0xc8, 0x413: 0xc9, 0x414: 0xca, 0x415: 0xcb, + 0x418: 0x05, 0x419: 0x05, 0x41a: 0x05, 0x41b: 0x05, 0x41c: 0xcc, 0x41d: 0xcd, + 0x420: 0xce, 0x421: 0xcf, 0x422: 0xd0, 0x423: 0xd1, 0x424: 0xd2, 0x426: 0xd3, 0x427: 0xb2, + 0x428: 0xd4, 0x429: 0xd5, 0x42a: 0xd6, 0x42b: 0xd7, 0x42c: 0xd8, 0x42d: 0xd9, 0x42e: 0xda, + 0x430: 0x05, 0x431: 0xdb, 0x432: 0xdc, 0x433: 0xdd, 0x434: 0xde, + 0x439: 0xdf, 0x43c: 0xe0, 0x43d: 0xe1, 0x43f: 0xe2, + // Block 0x11, offset 0x440 + 0x440: 0xe3, 0x441: 0xe4, 0x442: 0xe5, 0x443: 0xe6, 0x444: 0xe7, 0x445: 0xe8, 0x446: 0xe9, 0x447: 0xea, + 0x448: 0xeb, 0x44a: 0xec, 0x44b: 0xed, 0x44c: 0xee, 0x44d: 0xef, + 0x450: 0xf0, 0x451: 0xf1, 0x452: 0xf2, 0x453: 0xf3, 0x456: 0xf4, 0x457: 0xf5, + 0x458: 0xf6, 0x459: 0xf7, 0x45a: 0xf8, 0x45b: 0xf9, 0x45c: 0xfa, + 0x460: 0xfb, 0x462: 0xfc, 0x463: 0xfd, 0x466: 0xfe, 0x467: 0xff, + 0x468: 0x100, 0x469: 0x101, 0x46a: 0x102, 0x46b: 0x103, + 0x470: 0x104, 0x471: 0x105, 0x472: 0x106, 0x474: 0x107, 0x475: 0x108, 0x476: 0x109, + 0x47b: 0x10a, 0x47f: 0x10b, + // Block 0x12, offset 0x480 + 0x480: 0x05, 0x481: 0x05, 0x482: 0x05, 0x483: 0x05, 0x484: 0x05, 0x485: 0x05, 0x486: 0x05, 0x487: 0x05, + 0x488: 0x05, 0x489: 0x05, 0x48a: 0x05, 0x48b: 0x05, 0x48c: 0x05, 0x48d: 0x05, 0x48e: 0x10c, + 0x490: 0x71, 0x491: 0x10d, 0x492: 0x05, 0x493: 0x05, 0x494: 0x05, 0x495: 0x10e, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x05, 0x4c1: 0x05, 0x4c2: 0x05, 0x4c3: 0x05, 0x4c4: 0x05, 0x4c5: 0x05, 0x4c6: 0x05, 0x4c7: 0x05, + 0x4c8: 0x05, 0x4c9: 0x05, 0x4ca: 0x05, 0x4cb: 0x05, 0x4cc: 0x05, 0x4cd: 0x05, 0x4ce: 0x05, 0x4cf: 0x05, + 0x4d0: 0x10f, + // Block 0x14, offset 0x500 + 0x510: 0x05, 0x511: 0x05, 0x512: 0x05, 0x513: 0x05, 0x514: 0x05, 0x515: 0x05, 0x516: 0x05, 0x517: 0x05, + 0x518: 0x05, 0x519: 0x110, + // Block 0x15, offset 0x540 + 0x560: 0x05, 0x561: 0x05, 0x562: 0x05, 0x563: 0x05, 0x564: 0x05, 0x565: 0x05, 0x566: 0x05, 0x567: 0x05, + 0x568: 0x103, 0x569: 0x111, 0x56b: 0x112, 0x56c: 0x113, 0x56d: 0x114, 0x56e: 0x115, + 0x579: 0x05, 0x57a: 0x116, 0x57c: 0x05, 0x57d: 0x117, 0x57e: 0x118, 0x57f: 0x119, + // Block 0x16, offset 0x580 + 0x580: 0x05, 0x581: 0x05, 0x582: 0x05, 0x583: 0x05, 0x584: 0x05, 0x585: 0x05, 0x586: 0x05, 0x587: 0x05, + 0x588: 0x05, 0x589: 0x05, 0x58a: 0x05, 0x58b: 0x05, 0x58c: 0x05, 0x58d: 0x05, 0x58e: 0x05, 0x58f: 0x05, + 0x590: 0x05, 0x591: 0x05, 0x592: 0x05, 0x593: 0x05, 0x594: 0x05, 0x595: 0x05, 0x596: 0x05, 0x597: 0x05, + 0x598: 0x05, 0x599: 0x05, 0x59a: 0x05, 0x59b: 0x05, 0x59c: 0x05, 0x59d: 0x05, 0x59e: 0x05, 0x59f: 0x11a, + 0x5a0: 0x05, 0x5a1: 0x05, 0x5a2: 0x05, 0x5a3: 0x05, 0x5a4: 0x05, 0x5a5: 0x05, 0x5a6: 0x05, 0x5a7: 0x05, + 0x5a8: 0x05, 0x5a9: 0x05, 0x5aa: 0x05, 0x5ab: 0xdc, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x8e, 0x5c1: 0x8e, 0x5c2: 0x8e, 0x5c3: 0x8e, 0x5c4: 0x11b, 0x5c5: 0x11c, 0x5c6: 0x05, 0x5c7: 0x05, + 0x5c8: 0x05, 0x5c9: 0x05, 0x5ca: 0x05, 0x5cb: 0x11d, + 0x5f0: 0x05, 0x5f1: 0x11e, 0x5f2: 0x11f, + // Block 0x18, offset 0x600 + 0x600: 0x71, 0x601: 0x71, 0x602: 0x71, 0x603: 0x120, 0x604: 0x121, 0x605: 0x122, 0x606: 0x123, 0x607: 0x124, + 0x608: 0xbf, 0x609: 0x125, 0x60b: 0x126, 0x60c: 0x71, 0x60d: 0x127, + 0x610: 0x71, 0x611: 0x128, 0x612: 0x129, 0x613: 0x12a, 0x614: 0x12b, 0x615: 0x12c, 0x616: 0x71, 0x617: 0x71, + 0x618: 0x71, 0x619: 0x71, 0x61a: 0x12d, 0x61b: 0x71, 0x61c: 0x71, 0x61d: 0x71, 0x61e: 0x71, 0x61f: 0x12e, + 0x620: 0x71, 0x621: 0x71, 0x622: 0x71, 0x623: 0x71, 0x624: 0x71, 0x625: 0x71, 0x626: 0x71, 0x627: 0x71, + 0x628: 0x12f, 0x629: 0x130, 0x62a: 0x131, + // Block 0x19, offset 0x640 + 0x640: 0x132, 0x644: 0x133, 0x645: 0x134, + 0x64b: 0x135, + 0x660: 0x05, 0x661: 0x05, 0x662: 0x05, 0x663: 0x136, 0x664: 0x137, 0x665: 0x138, + 0x671: 0x139, 0x672: 0x13a, 0x674: 0x13b, + 0x678: 0x13c, 0x679: 0x13d, 0x67a: 0x13e, 0x67b: 0x13f, + // Block 0x1a, offset 0x680 + 0x680: 0x140, 0x681: 0x71, 0x682: 0x141, 0x683: 0x142, 0x684: 0x143, 0x685: 0x144, 0x686: 0x145, 0x687: 0x146, + 0x688: 0x147, 0x689: 0x148, 0x68c: 0x71, 0x68d: 0x71, 0x68e: 0x71, 0x68f: 0x71, + 0x690: 0x71, 0x691: 0x71, 0x692: 0x71, 0x693: 0x71, 0x694: 0x71, 0x695: 0x71, 0x696: 0x71, 0x697: 0x71, + 0x698: 0x71, 0x699: 0x71, 0x69a: 0x71, 0x69b: 0x149, 0x69c: 0x71, 0x69d: 0x14a, 0x69e: 0x71, 0x69f: 0x14b, + 0x6a0: 0x14c, 0x6a1: 0x14d, 0x6a2: 0x14e, 0x6a4: 0x14f, 0x6a5: 0x150, 0x6a6: 0x151, 0x6a7: 0x152, + 0x6a8: 0x71, 0x6a9: 0x153, 0x6aa: 0x154, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x8e, 0x6c1: 0x8e, 0x6c2: 0x8e, 0x6c3: 0x8e, 0x6c4: 0x8e, 0x6c5: 0x8e, 0x6c6: 0x8e, 0x6c7: 0x8e, + 0x6c8: 0x8e, 0x6c9: 0x8e, 0x6ca: 0x8e, 0x6cb: 0x8e, 0x6cc: 0x8e, 0x6cd: 0x8e, 0x6ce: 0x8e, 0x6cf: 0x8e, + 0x6d0: 0x8e, 0x6d1: 0x8e, 0x6d2: 0x8e, 0x6d3: 0x8e, 0x6d4: 0x8e, 0x6d5: 0x8e, 0x6d6: 0x8e, 0x6d7: 0x8e, + 0x6d8: 0x8e, 0x6d9: 0x8e, 0x6da: 0x8e, 0x6db: 0x155, 0x6dc: 0x8e, 0x6dd: 0x8e, 0x6de: 0x8e, 0x6df: 0x8e, + 0x6e0: 0x8e, 0x6e1: 0x8e, 0x6e2: 0x8e, 0x6e3: 0x8e, 0x6e4: 0x8e, 0x6e5: 0x8e, 0x6e6: 0x8e, 0x6e7: 0x8e, + 0x6e8: 0x8e, 0x6e9: 0x8e, 0x6ea: 0x8e, 0x6eb: 0x8e, 0x6ec: 0x8e, 0x6ed: 0x8e, 0x6ee: 0x8e, 0x6ef: 0x8e, + 0x6f0: 0x8e, 0x6f1: 0x8e, 0x6f2: 0x8e, 0x6f3: 0x8e, 0x6f4: 0x8e, 0x6f5: 0x8e, 0x6f6: 0x8e, 0x6f7: 0x8e, + 0x6f8: 0x8e, 0x6f9: 0x8e, 0x6fa: 0x8e, 0x6fb: 0x8e, 0x6fc: 0x8e, 0x6fd: 0x8e, 0x6fe: 0x8e, 0x6ff: 0x8e, + // Block 0x1c, offset 0x700 + 0x700: 0x8e, 0x701: 0x8e, 0x702: 0x8e, 0x703: 0x8e, 0x704: 0x8e, 0x705: 0x8e, 0x706: 0x8e, 0x707: 0x8e, + 0x708: 0x8e, 0x709: 0x8e, 0x70a: 0x8e, 0x70b: 0x8e, 0x70c: 0x8e, 0x70d: 0x8e, 0x70e: 0x8e, 0x70f: 0x8e, + 0x710: 0x8e, 0x711: 0x8e, 0x712: 0x8e, 0x713: 0x8e, 0x714: 0x8e, 0x715: 0x8e, 0x716: 0x8e, 0x717: 0x8e, + 0x718: 0x8e, 0x719: 0x8e, 0x71a: 0x8e, 0x71b: 0x8e, 0x71c: 0x156, 0x71d: 0x8e, 0x71e: 0x8e, 0x71f: 0x8e, + 0x720: 0x157, 0x721: 0x8e, 0x722: 0x8e, 0x723: 0x8e, 0x724: 0x8e, 0x725: 0x8e, 0x726: 0x8e, 0x727: 0x8e, + 0x728: 0x8e, 0x729: 0x8e, 0x72a: 0x8e, 0x72b: 0x8e, 0x72c: 0x8e, 0x72d: 0x8e, 0x72e: 0x8e, 0x72f: 0x8e, + 0x730: 0x8e, 0x731: 0x8e, 0x732: 0x8e, 0x733: 0x8e, 0x734: 0x8e, 0x735: 0x8e, 0x736: 0x8e, 0x737: 0x8e, + 0x738: 0x8e, 0x739: 0x8e, 0x73a: 0x8e, 0x73b: 0x8e, 0x73c: 0x8e, 0x73d: 0x8e, 0x73e: 0x8e, 0x73f: 0x8e, + // Block 0x1d, offset 0x740 + 0x740: 0x8e, 0x741: 0x8e, 0x742: 0x8e, 0x743: 0x8e, 0x744: 0x8e, 0x745: 0x8e, 0x746: 0x8e, 0x747: 0x8e, + 0x748: 0x8e, 0x749: 0x8e, 0x74a: 0x8e, 0x74b: 0x8e, 0x74c: 0x8e, 0x74d: 0x8e, 0x74e: 0x8e, 0x74f: 0x8e, + 0x750: 0x8e, 0x751: 0x8e, 0x752: 0x8e, 0x753: 0x8e, 0x754: 0x8e, 0x755: 0x8e, 0x756: 0x8e, 0x757: 0x8e, + 0x758: 0x8e, 0x759: 0x8e, 0x75a: 0x8e, 0x75b: 0x8e, 0x75c: 0x8e, 0x75d: 0x8e, 0x75e: 0x8e, 0x75f: 0x8e, + 0x760: 0x8e, 0x761: 0x8e, 0x762: 0x8e, 0x763: 0x8e, 0x764: 0x8e, 0x765: 0x8e, 0x766: 0x8e, 0x767: 0x8e, + 0x768: 0x8e, 0x769: 0x8e, 0x76a: 0x8e, 0x76b: 0x8e, 0x76c: 0x8e, 0x76d: 0x8e, 0x76e: 0x8e, 0x76f: 0x8e, + 0x770: 0x8e, 0x771: 0x8e, 0x772: 0x8e, 0x773: 0x8e, 0x774: 0x8e, 0x775: 0x8e, 0x776: 0x8e, 0x777: 0x8e, + 0x778: 0x8e, 0x779: 0x8e, 0x77a: 0x158, 0x77b: 0x8e, 0x77c: 0x8e, 0x77d: 0x8e, 0x77e: 0x8e, 0x77f: 0x8e, + // Block 0x1e, offset 0x780 + 0x780: 0x8e, 0x781: 0x8e, 0x782: 0x8e, 0x783: 0x8e, 0x784: 0x8e, 0x785: 0x8e, 0x786: 0x8e, 0x787: 0x8e, + 0x788: 0x8e, 0x789: 0x8e, 0x78a: 0x8e, 0x78b: 0x8e, 0x78c: 0x8e, 0x78d: 0x8e, 0x78e: 0x8e, 0x78f: 0x8e, + 0x790: 0x8e, 0x791: 0x8e, 0x792: 0x8e, 0x793: 0x8e, 0x794: 0x8e, 0x795: 0x8e, 0x796: 0x8e, 0x797: 0x8e, + 0x798: 0x8e, 0x799: 0x8e, 0x79a: 0x8e, 0x79b: 0x8e, 0x79c: 0x8e, 0x79d: 0x8e, 0x79e: 0x8e, 0x79f: 0x8e, + 0x7a0: 0x8e, 0x7a1: 0x8e, 0x7a2: 0x8e, 0x7a3: 0x8e, 0x7a4: 0x8e, 0x7a5: 0x8e, 0x7a6: 0x8e, 0x7a7: 0x8e, + 0x7a8: 0x8e, 0x7a9: 0x8e, 0x7aa: 0x8e, 0x7ab: 0x8e, 0x7ac: 0x8e, 0x7ad: 0x8e, 0x7ae: 0x8e, 0x7af: 0x159, + // Block 0x1f, offset 0x7c0 + 0x7e0: 0x81, 0x7e1: 0x81, 0x7e2: 0x81, 0x7e3: 0x81, 0x7e4: 0x81, 0x7e5: 0x81, 0x7e6: 0x81, 0x7e7: 0x81, + 0x7e8: 0x15a, + // Block 0x20, offset 0x800 + 0x810: 0x0e, 0x811: 0x0f, 0x812: 0x10, 0x813: 0x11, 0x814: 0x12, 0x816: 0x13, 0x817: 0x0a, + 0x818: 0x14, 0x81b: 0x15, 0x81d: 0x16, 0x81e: 0x17, 0x81f: 0x18, + 0x820: 0x07, 0x821: 0x07, 0x822: 0x07, 0x823: 0x07, 0x824: 0x07, 0x825: 0x07, 0x826: 0x07, 0x827: 0x07, + 0x828: 0x07, 0x829: 0x07, 0x82a: 0x19, 0x82b: 0x1a, 0x82c: 0x1b, 0x82d: 0x07, 0x82e: 0x1c, 0x82f: 0x1d, + // Block 0x21, offset 0x840 + 0x840: 0x15b, 0x841: 0x3e, 0x844: 0x3e, 0x845: 0x3e, 0x846: 0x3e, 0x847: 0x15c, + // Block 0x22, offset 0x880 + 0x880: 0x3e, 0x881: 0x3e, 0x882: 0x3e, 0x883: 0x3e, 0x884: 0x3e, 0x885: 0x3e, 0x886: 0x3e, 0x887: 0x3e, + 0x888: 0x3e, 0x889: 0x3e, 0x88a: 0x3e, 0x88b: 0x3e, 0x88c: 0x3e, 0x88d: 0x3e, 0x88e: 0x3e, 0x88f: 0x3e, + 0x890: 0x3e, 0x891: 0x3e, 0x892: 0x3e, 0x893: 0x3e, 0x894: 0x3e, 0x895: 0x3e, 0x896: 0x3e, 0x897: 0x3e, + 0x898: 0x3e, 0x899: 0x3e, 0x89a: 0x3e, 0x89b: 0x3e, 0x89c: 0x3e, 0x89d: 0x3e, 0x89e: 0x3e, 0x89f: 0x3e, + 0x8a0: 0x3e, 0x8a1: 0x3e, 0x8a2: 0x3e, 0x8a3: 0x3e, 0x8a4: 0x3e, 0x8a5: 0x3e, 0x8a6: 0x3e, 0x8a7: 0x3e, + 0x8a8: 0x3e, 0x8a9: 0x3e, 0x8aa: 0x3e, 0x8ab: 0x3e, 0x8ac: 0x3e, 0x8ad: 0x3e, 0x8ae: 0x3e, 0x8af: 0x3e, + 0x8b0: 0x3e, 0x8b1: 0x3e, 0x8b2: 0x3e, 0x8b3: 0x3e, 0x8b4: 0x3e, 0x8b5: 0x3e, 0x8b6: 0x3e, 0x8b7: 0x3e, + 0x8b8: 0x3e, 0x8b9: 0x3e, 0x8ba: 0x3e, 0x8bb: 0x3e, 0x8bc: 0x3e, 0x8bd: 0x3e, 0x8be: 0x3e, 0x8bf: 0x15d, + // Block 0x23, offset 0x8c0 + 0x8e0: 0x1f, + 0x8f0: 0x0c, 0x8f1: 0x0c, 0x8f2: 0x0c, 0x8f3: 0x0c, 0x8f4: 0x0c, 0x8f5: 0x0c, 0x8f6: 0x0c, 0x8f7: 0x0c, + 0x8f8: 0x0c, 0x8f9: 0x0c, 0x8fa: 0x0c, 0x8fb: 0x0c, 0x8fc: 0x0c, 0x8fd: 0x0c, 0x8fe: 0x0c, 0x8ff: 0x20, + // Block 0x24, offset 0x900 + 0x900: 0x0c, 0x901: 0x0c, 0x902: 0x0c, 0x903: 0x0c, 0x904: 0x0c, 0x905: 0x0c, 0x906: 0x0c, 0x907: 0x0c, + 0x908: 0x0c, 0x909: 0x0c, 0x90a: 0x0c, 0x90b: 0x0c, 0x90c: 0x0c, 0x90d: 0x0c, 0x90e: 0x0c, 0x90f: 0x20, +} + +// Total table size 27264 bytes (26KiB); checksum: 811C9DC5 diff --git a/vendor/golang.org/x/text/secure/precis/tables13.0.0.go b/vendor/golang.org/x/text/secure/precis/tables13.0.0.go new file mode 100644 index 00000000000..aad68b35edb --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/tables13.0.0.go @@ -0,0 +1,4153 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +//go:build go1.16 +// +build go1.16 + +package precis + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "13.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// derivedPropertiesTrie. Total size: 27776 bytes (27.12 KiB). Checksum: c8bfc091c977a4c. +type derivedPropertiesTrie struct{} + +func newDerivedPropertiesTrie(i int) *derivedPropertiesTrie { + return &derivedPropertiesTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *derivedPropertiesTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(derivedPropertiesValues[n<<6+uint32(b)]) + } +} + +// derivedPropertiesValues: 358 blocks, 22912 entries, 22912 bytes +// The third block is the zero block. +var derivedPropertiesValues = [22912]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x0040, 0x01: 0x0040, 0x02: 0x0040, 0x03: 0x0040, 0x04: 0x0040, 0x05: 0x0040, + 0x06: 0x0040, 0x07: 0x0040, 0x08: 0x0040, 0x09: 0x0040, 0x0a: 0x0040, 0x0b: 0x0040, + 0x0c: 0x0040, 0x0d: 0x0040, 0x0e: 0x0040, 0x0f: 0x0040, 0x10: 0x0040, 0x11: 0x0040, + 0x12: 0x0040, 0x13: 0x0040, 0x14: 0x0040, 0x15: 0x0040, 0x16: 0x0040, 0x17: 0x0040, + 0x18: 0x0040, 0x19: 0x0040, 0x1a: 0x0040, 0x1b: 0x0040, 0x1c: 0x0040, 0x1d: 0x0040, + 0x1e: 0x0040, 0x1f: 0x0040, 0x20: 0x0080, 0x21: 0x00c0, 0x22: 0x00c0, 0x23: 0x00c0, + 0x24: 0x00c0, 0x25: 0x00c0, 0x26: 0x00c0, 0x27: 0x00c0, 0x28: 0x00c0, 0x29: 0x00c0, + 0x2a: 0x00c0, 0x2b: 0x00c0, 0x2c: 0x00c0, 0x2d: 0x00c0, 0x2e: 0x00c0, 0x2f: 0x00c0, + 0x30: 0x00c0, 0x31: 0x00c0, 0x32: 0x00c0, 0x33: 0x00c0, 0x34: 0x00c0, 0x35: 0x00c0, + 0x36: 0x00c0, 0x37: 0x00c0, 0x38: 0x00c0, 0x39: 0x00c0, 0x3a: 0x00c0, 0x3b: 0x00c0, + 0x3c: 0x00c0, 0x3d: 0x00c0, 0x3e: 0x00c0, 0x3f: 0x00c0, + // Block 0x1, offset 0x40 + 0x40: 0x00c0, 0x41: 0x00c0, 0x42: 0x00c0, 0x43: 0x00c0, 0x44: 0x00c0, 0x45: 0x00c0, + 0x46: 0x00c0, 0x47: 0x00c0, 0x48: 0x00c0, 0x49: 0x00c0, 0x4a: 0x00c0, 0x4b: 0x00c0, + 0x4c: 0x00c0, 0x4d: 0x00c0, 0x4e: 0x00c0, 0x4f: 0x00c0, 0x50: 0x00c0, 0x51: 0x00c0, + 0x52: 0x00c0, 0x53: 0x00c0, 0x54: 0x00c0, 0x55: 0x00c0, 0x56: 0x00c0, 0x57: 0x00c0, + 0x58: 0x00c0, 0x59: 0x00c0, 0x5a: 0x00c0, 0x5b: 0x00c0, 0x5c: 0x00c0, 0x5d: 0x00c0, + 0x5e: 0x00c0, 0x5f: 0x00c0, 0x60: 0x00c0, 0x61: 0x00c0, 0x62: 0x00c0, 0x63: 0x00c0, + 0x64: 0x00c0, 0x65: 0x00c0, 0x66: 0x00c0, 0x67: 0x00c0, 0x68: 0x00c0, 0x69: 0x00c0, + 0x6a: 0x00c0, 0x6b: 0x00c0, 0x6c: 0x00c7, 0x6d: 0x00c0, 0x6e: 0x00c0, 0x6f: 0x00c0, + 0x70: 0x00c0, 0x71: 0x00c0, 0x72: 0x00c0, 0x73: 0x00c0, 0x74: 0x00c0, 0x75: 0x00c0, + 0x76: 0x00c0, 0x77: 0x00c0, 0x78: 0x00c0, 0x79: 0x00c0, 0x7a: 0x00c0, 0x7b: 0x00c0, + 0x7c: 0x00c0, 0x7d: 0x00c0, 0x7e: 0x00c0, 0x7f: 0x0040, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x0080, 0xe1: 0x0080, 0xe2: 0x0080, 0xe3: 0x0080, + 0xe4: 0x0080, 0xe5: 0x0080, 0xe6: 0x0080, 0xe7: 0x0080, 0xe8: 0x0080, 0xe9: 0x0080, + 0xea: 0x0080, 0xeb: 0x0080, 0xec: 0x0080, 0xed: 0x0040, 0xee: 0x0080, 0xef: 0x0080, + 0xf0: 0x0080, 0xf1: 0x0080, 0xf2: 0x0080, 0xf3: 0x0080, 0xf4: 0x0080, 0xf5: 0x0080, + 0xf6: 0x0080, 0xf7: 0x004f, 0xf8: 0x0080, 0xf9: 0x0080, 0xfa: 0x0080, 0xfb: 0x0080, + 0xfc: 0x0080, 0xfd: 0x0080, 0xfe: 0x0080, 0xff: 0x0080, + // Block 0x4, offset 0x100 + 0x100: 0x00c0, 0x101: 0x00c0, 0x102: 0x00c0, 0x103: 0x00c0, 0x104: 0x00c0, 0x105: 0x00c0, + 0x106: 0x00c0, 0x107: 0x00c0, 0x108: 0x00c0, 0x109: 0x00c0, 0x10a: 0x00c0, 0x10b: 0x00c0, + 0x10c: 0x00c0, 0x10d: 0x00c0, 0x10e: 0x00c0, 0x10f: 0x00c0, 0x110: 0x00c0, 0x111: 0x00c0, + 0x112: 0x00c0, 0x113: 0x00c0, 0x114: 0x00c0, 0x115: 0x00c0, 0x116: 0x00c0, 0x117: 0x0080, + 0x118: 0x00c0, 0x119: 0x00c0, 0x11a: 0x00c0, 0x11b: 0x00c0, 0x11c: 0x00c0, 0x11d: 0x00c0, + 0x11e: 0x00c0, 0x11f: 0x00c0, 0x120: 0x00c0, 0x121: 0x00c0, 0x122: 0x00c0, 0x123: 0x00c0, + 0x124: 0x00c0, 0x125: 0x00c0, 0x126: 0x00c0, 0x127: 0x00c0, 0x128: 0x00c0, 0x129: 0x00c0, + 0x12a: 0x00c0, 0x12b: 0x00c0, 0x12c: 0x00c0, 0x12d: 0x00c0, 0x12e: 0x00c0, 0x12f: 0x00c0, + 0x130: 0x00c0, 0x131: 0x00c0, 0x132: 0x00c0, 0x133: 0x00c0, 0x134: 0x00c0, 0x135: 0x00c0, + 0x136: 0x00c0, 0x137: 0x0080, 0x138: 0x00c0, 0x139: 0x00c0, 0x13a: 0x00c0, 0x13b: 0x00c0, + 0x13c: 0x00c0, 0x13d: 0x00c0, 0x13e: 0x00c0, 0x13f: 0x00c0, + // Block 0x5, offset 0x140 + 0x140: 0x00c0, 0x141: 0x00c0, 0x142: 0x00c0, 0x143: 0x00c0, 0x144: 0x00c0, 0x145: 0x00c0, + 0x146: 0x00c0, 0x147: 0x00c0, 0x148: 0x00c0, 0x149: 0x00c0, 0x14a: 0x00c0, 0x14b: 0x00c0, + 0x14c: 0x00c0, 0x14d: 0x00c0, 0x14e: 0x00c0, 0x14f: 0x00c0, 0x150: 0x00c0, 0x151: 0x00c0, + 0x152: 0x00c0, 0x153: 0x00c0, 0x154: 0x00c0, 0x155: 0x00c0, 0x156: 0x00c0, 0x157: 0x00c0, + 0x158: 0x00c0, 0x159: 0x00c0, 0x15a: 0x00c0, 0x15b: 0x00c0, 0x15c: 0x00c0, 0x15d: 0x00c0, + 0x15e: 0x00c0, 0x15f: 0x00c0, 0x160: 0x00c0, 0x161: 0x00c0, 0x162: 0x00c0, 0x163: 0x00c0, + 0x164: 0x00c0, 0x165: 0x00c0, 0x166: 0x00c0, 0x167: 0x00c0, 0x168: 0x00c0, 0x169: 0x00c0, + 0x16a: 0x00c0, 0x16b: 0x00c0, 0x16c: 0x00c0, 0x16d: 0x00c0, 0x16e: 0x00c0, 0x16f: 0x00c0, + 0x170: 0x00c0, 0x171: 0x00c0, 0x172: 0x0080, 0x173: 0x0080, 0x174: 0x00c0, 0x175: 0x00c0, + 0x176: 0x00c0, 0x177: 0x00c0, 0x178: 0x00c0, 0x179: 0x00c0, 0x17a: 0x00c0, 0x17b: 0x00c0, + 0x17c: 0x00c0, 0x17d: 0x00c0, 0x17e: 0x00c0, 0x17f: 0x0080, + // Block 0x6, offset 0x180 + 0x180: 0x0080, 0x181: 0x00c0, 0x182: 0x00c0, 0x183: 0x00c0, 0x184: 0x00c0, 0x185: 0x00c0, + 0x186: 0x00c0, 0x187: 0x00c0, 0x188: 0x00c0, 0x189: 0x0080, 0x18a: 0x00c0, 0x18b: 0x00c0, + 0x18c: 0x00c0, 0x18d: 0x00c0, 0x18e: 0x00c0, 0x18f: 0x00c0, 0x190: 0x00c0, 0x191: 0x00c0, + 0x192: 0x00c0, 0x193: 0x00c0, 0x194: 0x00c0, 0x195: 0x00c0, 0x196: 0x00c0, 0x197: 0x00c0, + 0x198: 0x00c0, 0x199: 0x00c0, 0x19a: 0x00c0, 0x19b: 0x00c0, 0x19c: 0x00c0, 0x19d: 0x00c0, + 0x19e: 0x00c0, 0x19f: 0x00c0, 0x1a0: 0x00c0, 0x1a1: 0x00c0, 0x1a2: 0x00c0, 0x1a3: 0x00c0, + 0x1a4: 0x00c0, 0x1a5: 0x00c0, 0x1a6: 0x00c0, 0x1a7: 0x00c0, 0x1a8: 0x00c0, 0x1a9: 0x00c0, + 0x1aa: 0x00c0, 0x1ab: 0x00c0, 0x1ac: 0x00c0, 0x1ad: 0x00c0, 0x1ae: 0x00c0, 0x1af: 0x00c0, + 0x1b0: 0x00c0, 0x1b1: 0x00c0, 0x1b2: 0x00c0, 0x1b3: 0x00c0, 0x1b4: 0x00c0, 0x1b5: 0x00c0, + 0x1b6: 0x00c0, 0x1b7: 0x00c0, 0x1b8: 0x00c0, 0x1b9: 0x00c0, 0x1ba: 0x00c0, 0x1bb: 0x00c0, + 0x1bc: 0x00c0, 0x1bd: 0x00c0, 0x1be: 0x00c0, 0x1bf: 0x0080, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x00c0, 0x1c1: 0x00c0, 0x1c2: 0x00c0, 0x1c3: 0x00c0, 0x1c4: 0x00c0, 0x1c5: 0x00c0, + 0x1c6: 0x00c0, 0x1c7: 0x00c0, 0x1c8: 0x00c0, 0x1c9: 0x00c0, 0x1ca: 0x00c0, 0x1cb: 0x00c0, + 0x1cc: 0x00c0, 0x1cd: 0x00c0, 0x1ce: 0x00c0, 0x1cf: 0x00c0, 0x1d0: 0x00c0, 0x1d1: 0x00c0, + 0x1d2: 0x00c0, 0x1d3: 0x00c0, 0x1d4: 0x00c0, 0x1d5: 0x00c0, 0x1d6: 0x00c0, 0x1d7: 0x00c0, + 0x1d8: 0x00c0, 0x1d9: 0x00c0, 0x1da: 0x00c0, 0x1db: 0x00c0, 0x1dc: 0x00c0, 0x1dd: 0x00c0, + 0x1de: 0x00c0, 0x1df: 0x00c0, 0x1e0: 0x00c0, 0x1e1: 0x00c0, 0x1e2: 0x00c0, 0x1e3: 0x00c0, + 0x1e4: 0x00c0, 0x1e5: 0x00c0, 0x1e6: 0x00c0, 0x1e7: 0x00c0, 0x1e8: 0x00c0, 0x1e9: 0x00c0, + 0x1ea: 0x00c0, 0x1eb: 0x00c0, 0x1ec: 0x00c0, 0x1ed: 0x00c0, 0x1ee: 0x00c0, 0x1ef: 0x00c0, + 0x1f0: 0x00c0, 0x1f1: 0x00c0, 0x1f2: 0x00c0, 0x1f3: 0x00c0, 0x1f4: 0x00c0, 0x1f5: 0x00c0, + 0x1f6: 0x00c0, 0x1f7: 0x00c0, 0x1f8: 0x00c0, 0x1f9: 0x00c0, 0x1fa: 0x00c0, 0x1fb: 0x00c0, + 0x1fc: 0x00c0, 0x1fd: 0x00c0, 0x1fe: 0x00c0, 0x1ff: 0x00c0, + // Block 0x8, offset 0x200 + 0x200: 0x00c0, 0x201: 0x00c0, 0x202: 0x00c0, 0x203: 0x00c0, 0x204: 0x0080, 0x205: 0x0080, + 0x206: 0x0080, 0x207: 0x0080, 0x208: 0x0080, 0x209: 0x0080, 0x20a: 0x0080, 0x20b: 0x0080, + 0x20c: 0x0080, 0x20d: 0x00c0, 0x20e: 0x00c0, 0x20f: 0x00c0, 0x210: 0x00c0, 0x211: 0x00c0, + 0x212: 0x00c0, 0x213: 0x00c0, 0x214: 0x00c0, 0x215: 0x00c0, 0x216: 0x00c0, 0x217: 0x00c0, + 0x218: 0x00c0, 0x219: 0x00c0, 0x21a: 0x00c0, 0x21b: 0x00c0, 0x21c: 0x00c0, 0x21d: 0x00c0, + 0x21e: 0x00c0, 0x21f: 0x00c0, 0x220: 0x00c0, 0x221: 0x00c0, 0x222: 0x00c0, 0x223: 0x00c0, + 0x224: 0x00c0, 0x225: 0x00c0, 0x226: 0x00c0, 0x227: 0x00c0, 0x228: 0x00c0, 0x229: 0x00c0, + 0x22a: 0x00c0, 0x22b: 0x00c0, 0x22c: 0x00c0, 0x22d: 0x00c0, 0x22e: 0x00c0, 0x22f: 0x00c0, + 0x230: 0x00c0, 0x231: 0x0080, 0x232: 0x0080, 0x233: 0x0080, 0x234: 0x00c0, 0x235: 0x00c0, + 0x236: 0x00c0, 0x237: 0x00c0, 0x238: 0x00c0, 0x239: 0x00c0, 0x23a: 0x00c0, 0x23b: 0x00c0, + 0x23c: 0x00c0, 0x23d: 0x00c0, 0x23e: 0x00c0, 0x23f: 0x00c0, + // Block 0x9, offset 0x240 + 0x240: 0x00c0, 0x241: 0x00c0, 0x242: 0x00c0, 0x243: 0x00c0, 0x244: 0x00c0, 0x245: 0x00c0, + 0x246: 0x00c0, 0x247: 0x00c0, 0x248: 0x00c0, 0x249: 0x00c0, 0x24a: 0x00c0, 0x24b: 0x00c0, + 0x24c: 0x00c0, 0x24d: 0x00c0, 0x24e: 0x00c0, 0x24f: 0x00c0, 0x250: 0x00c0, 0x251: 0x00c0, + 0x252: 0x00c0, 0x253: 0x00c0, 0x254: 0x00c0, 0x255: 0x00c0, 0x256: 0x00c0, 0x257: 0x00c0, + 0x258: 0x00c0, 0x259: 0x00c0, 0x25a: 0x00c0, 0x25b: 0x00c0, 0x25c: 0x00c0, 0x25d: 0x00c0, + 0x25e: 0x00c0, 0x25f: 0x00c0, 0x260: 0x00c0, 0x261: 0x00c0, 0x262: 0x00c0, 0x263: 0x00c0, + 0x264: 0x00c0, 0x265: 0x00c0, 0x266: 0x00c0, 0x267: 0x00c0, 0x268: 0x00c0, 0x269: 0x00c0, + 0x26a: 0x00c0, 0x26b: 0x00c0, 0x26c: 0x00c0, 0x26d: 0x00c0, 0x26e: 0x00c0, 0x26f: 0x00c0, + 0x270: 0x0080, 0x271: 0x0080, 0x272: 0x0080, 0x273: 0x0080, 0x274: 0x0080, 0x275: 0x0080, + 0x276: 0x0080, 0x277: 0x0080, 0x278: 0x0080, 0x279: 0x00c0, 0x27a: 0x00c0, 0x27b: 0x00c0, + 0x27c: 0x00c0, 0x27d: 0x00c0, 0x27e: 0x00c0, 0x27f: 0x00c0, + // Block 0xa, offset 0x280 + 0x280: 0x00c0, 0x281: 0x00c0, 0x282: 0x0080, 0x283: 0x0080, 0x284: 0x0080, 0x285: 0x0080, + 0x286: 0x00c0, 0x287: 0x00c0, 0x288: 0x00c0, 0x289: 0x00c0, 0x28a: 0x00c0, 0x28b: 0x00c0, + 0x28c: 0x00c0, 0x28d: 0x00c0, 0x28e: 0x00c0, 0x28f: 0x00c0, 0x290: 0x00c0, 0x291: 0x00c0, + 0x292: 0x0080, 0x293: 0x0080, 0x294: 0x0080, 0x295: 0x0080, 0x296: 0x0080, 0x297: 0x0080, + 0x298: 0x0080, 0x299: 0x0080, 0x29a: 0x0080, 0x29b: 0x0080, 0x29c: 0x0080, 0x29d: 0x0080, + 0x29e: 0x0080, 0x29f: 0x0080, 0x2a0: 0x0080, 0x2a1: 0x0080, 0x2a2: 0x0080, 0x2a3: 0x0080, + 0x2a4: 0x0080, 0x2a5: 0x0080, 0x2a6: 0x0080, 0x2a7: 0x0080, 0x2a8: 0x0080, 0x2a9: 0x0080, + 0x2aa: 0x0080, 0x2ab: 0x0080, 0x2ac: 0x00c0, 0x2ad: 0x0080, 0x2ae: 0x00c0, 0x2af: 0x0080, + 0x2b0: 0x0080, 0x2b1: 0x0080, 0x2b2: 0x0080, 0x2b3: 0x0080, 0x2b4: 0x0080, 0x2b5: 0x0080, + 0x2b6: 0x0080, 0x2b7: 0x0080, 0x2b8: 0x0080, 0x2b9: 0x0080, 0x2ba: 0x0080, 0x2bb: 0x0080, + 0x2bc: 0x0080, 0x2bd: 0x0080, 0x2be: 0x0080, 0x2bf: 0x0080, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x00c3, 0x2c1: 0x00c3, 0x2c2: 0x00c3, 0x2c3: 0x00c3, 0x2c4: 0x00c3, 0x2c5: 0x00c3, + 0x2c6: 0x00c3, 0x2c7: 0x00c3, 0x2c8: 0x00c3, 0x2c9: 0x00c3, 0x2ca: 0x00c3, 0x2cb: 0x00c3, + 0x2cc: 0x00c3, 0x2cd: 0x00c3, 0x2ce: 0x00c3, 0x2cf: 0x00c3, 0x2d0: 0x00c3, 0x2d1: 0x00c3, + 0x2d2: 0x00c3, 0x2d3: 0x00c3, 0x2d4: 0x00c3, 0x2d5: 0x00c3, 0x2d6: 0x00c3, 0x2d7: 0x00c3, + 0x2d8: 0x00c3, 0x2d9: 0x00c3, 0x2da: 0x00c3, 0x2db: 0x00c3, 0x2dc: 0x00c3, 0x2dd: 0x00c3, + 0x2de: 0x00c3, 0x2df: 0x00c3, 0x2e0: 0x00c3, 0x2e1: 0x00c3, 0x2e2: 0x00c3, 0x2e3: 0x00c3, + 0x2e4: 0x00c3, 0x2e5: 0x00c3, 0x2e6: 0x00c3, 0x2e7: 0x00c3, 0x2e8: 0x00c3, 0x2e9: 0x00c3, + 0x2ea: 0x00c3, 0x2eb: 0x00c3, 0x2ec: 0x00c3, 0x2ed: 0x00c3, 0x2ee: 0x00c3, 0x2ef: 0x00c3, + 0x2f0: 0x00c3, 0x2f1: 0x00c3, 0x2f2: 0x00c3, 0x2f3: 0x00c3, 0x2f4: 0x00c3, 0x2f5: 0x00c3, + 0x2f6: 0x00c3, 0x2f7: 0x00c3, 0x2f8: 0x00c3, 0x2f9: 0x00c3, 0x2fa: 0x00c3, 0x2fb: 0x00c3, + 0x2fc: 0x00c3, 0x2fd: 0x00c3, 0x2fe: 0x00c3, 0x2ff: 0x00c3, + // Block 0xc, offset 0x300 + 0x300: 0x0083, 0x301: 0x0083, 0x302: 0x00c3, 0x303: 0x0083, 0x304: 0x0083, 0x305: 0x00c3, + 0x306: 0x00c3, 0x307: 0x00c3, 0x308: 0x00c3, 0x309: 0x00c3, 0x30a: 0x00c3, 0x30b: 0x00c3, + 0x30c: 0x00c3, 0x30d: 0x00c3, 0x30e: 0x00c3, 0x30f: 0x0040, 0x310: 0x00c3, 0x311: 0x00c3, + 0x312: 0x00c3, 0x313: 0x00c3, 0x314: 0x00c3, 0x315: 0x00c3, 0x316: 0x00c3, 0x317: 0x00c3, + 0x318: 0x00c3, 0x319: 0x00c3, 0x31a: 0x00c3, 0x31b: 0x00c3, 0x31c: 0x00c3, 0x31d: 0x00c3, + 0x31e: 0x00c3, 0x31f: 0x00c3, 0x320: 0x00c3, 0x321: 0x00c3, 0x322: 0x00c3, 0x323: 0x00c3, + 0x324: 0x00c3, 0x325: 0x00c3, 0x326: 0x00c3, 0x327: 0x00c3, 0x328: 0x00c3, 0x329: 0x00c3, + 0x32a: 0x00c3, 0x32b: 0x00c3, 0x32c: 0x00c3, 0x32d: 0x00c3, 0x32e: 0x00c3, 0x32f: 0x00c3, + 0x330: 0x00c8, 0x331: 0x00c8, 0x332: 0x00c8, 0x333: 0x00c8, 0x334: 0x0080, 0x335: 0x0050, + 0x336: 0x00c8, 0x337: 0x00c8, 0x33a: 0x0088, 0x33b: 0x00c8, + 0x33c: 0x00c8, 0x33d: 0x00c8, 0x33e: 0x0080, 0x33f: 0x00c8, + // Block 0xd, offset 0x340 + 0x344: 0x0088, 0x345: 0x0080, + 0x346: 0x00c8, 0x347: 0x0080, 0x348: 0x00c8, 0x349: 0x00c8, 0x34a: 0x00c8, + 0x34c: 0x00c8, 0x34e: 0x00c8, 0x34f: 0x00c8, 0x350: 0x00c8, 0x351: 0x00c8, + 0x352: 0x00c8, 0x353: 0x00c8, 0x354: 0x00c8, 0x355: 0x00c8, 0x356: 0x00c8, 0x357: 0x00c8, + 0x358: 0x00c8, 0x359: 0x00c8, 0x35a: 0x00c8, 0x35b: 0x00c8, 0x35c: 0x00c8, 0x35d: 0x00c8, + 0x35e: 0x00c8, 0x35f: 0x00c8, 0x360: 0x00c8, 0x361: 0x00c8, 0x363: 0x00c8, + 0x364: 0x00c8, 0x365: 0x00c8, 0x366: 0x00c8, 0x367: 0x00c8, 0x368: 0x00c8, 0x369: 0x00c8, + 0x36a: 0x00c8, 0x36b: 0x00c8, 0x36c: 0x00c8, 0x36d: 0x00c8, 0x36e: 0x00c8, 0x36f: 0x00c8, + 0x370: 0x00c8, 0x371: 0x00c8, 0x372: 0x00c8, 0x373: 0x00c8, 0x374: 0x00c8, 0x375: 0x00c8, + 0x376: 0x00c8, 0x377: 0x00c8, 0x378: 0x00c8, 0x379: 0x00c8, 0x37a: 0x00c8, 0x37b: 0x00c8, + 0x37c: 0x00c8, 0x37d: 0x00c8, 0x37e: 0x00c8, 0x37f: 0x00c8, + // Block 0xe, offset 0x380 + 0x380: 0x00c8, 0x381: 0x00c8, 0x382: 0x00c8, 0x383: 0x00c8, 0x384: 0x00c8, 0x385: 0x00c8, + 0x386: 0x00c8, 0x387: 0x00c8, 0x388: 0x00c8, 0x389: 0x00c8, 0x38a: 0x00c8, 0x38b: 0x00c8, + 0x38c: 0x00c8, 0x38d: 0x00c8, 0x38e: 0x00c8, 0x38f: 0x00c8, 0x390: 0x0088, 0x391: 0x0088, + 0x392: 0x0088, 0x393: 0x0088, 0x394: 0x0088, 0x395: 0x0088, 0x396: 0x0088, 0x397: 0x00c8, + 0x398: 0x00c8, 0x399: 0x00c8, 0x39a: 0x00c8, 0x39b: 0x00c8, 0x39c: 0x00c8, 0x39d: 0x00c8, + 0x39e: 0x00c8, 0x39f: 0x00c8, 0x3a0: 0x00c8, 0x3a1: 0x00c8, 0x3a2: 0x00c0, 0x3a3: 0x00c0, + 0x3a4: 0x00c0, 0x3a5: 0x00c0, 0x3a6: 0x00c0, 0x3a7: 0x00c0, 0x3a8: 0x00c0, 0x3a9: 0x00c0, + 0x3aa: 0x00c0, 0x3ab: 0x00c0, 0x3ac: 0x00c0, 0x3ad: 0x00c0, 0x3ae: 0x00c0, 0x3af: 0x00c0, + 0x3b0: 0x0088, 0x3b1: 0x0088, 0x3b2: 0x0088, 0x3b3: 0x00c8, 0x3b4: 0x0088, 0x3b5: 0x0088, + 0x3b6: 0x0088, 0x3b7: 0x00c8, 0x3b8: 0x00c8, 0x3b9: 0x0088, 0x3ba: 0x00c8, 0x3bb: 0x00c8, + 0x3bc: 0x00c8, 0x3bd: 0x00c8, 0x3be: 0x00c8, 0x3bf: 0x00c8, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x00c0, 0x3c1: 0x00c0, 0x3c2: 0x0080, 0x3c3: 0x00c3, 0x3c4: 0x00c3, 0x3c5: 0x00c3, + 0x3c6: 0x00c3, 0x3c7: 0x00c3, 0x3c8: 0x0083, 0x3c9: 0x0083, 0x3ca: 0x00c0, 0x3cb: 0x00c0, + 0x3cc: 0x00c0, 0x3cd: 0x00c0, 0x3ce: 0x00c0, 0x3cf: 0x00c0, 0x3d0: 0x00c0, 0x3d1: 0x00c0, + 0x3d2: 0x00c0, 0x3d3: 0x00c0, 0x3d4: 0x00c0, 0x3d5: 0x00c0, 0x3d6: 0x00c0, 0x3d7: 0x00c0, + 0x3d8: 0x00c0, 0x3d9: 0x00c0, 0x3da: 0x00c0, 0x3db: 0x00c0, 0x3dc: 0x00c0, 0x3dd: 0x00c0, + 0x3de: 0x00c0, 0x3df: 0x00c0, 0x3e0: 0x00c0, 0x3e1: 0x00c0, 0x3e2: 0x00c0, 0x3e3: 0x00c0, + 0x3e4: 0x00c0, 0x3e5: 0x00c0, 0x3e6: 0x00c0, 0x3e7: 0x00c0, 0x3e8: 0x00c0, 0x3e9: 0x00c0, + 0x3ea: 0x00c0, 0x3eb: 0x00c0, 0x3ec: 0x00c0, 0x3ed: 0x00c0, 0x3ee: 0x00c0, 0x3ef: 0x00c0, + 0x3f0: 0x00c0, 0x3f1: 0x00c0, 0x3f2: 0x00c0, 0x3f3: 0x00c0, 0x3f4: 0x00c0, 0x3f5: 0x00c0, + 0x3f6: 0x00c0, 0x3f7: 0x00c0, 0x3f8: 0x00c0, 0x3f9: 0x00c0, 0x3fa: 0x00c0, 0x3fb: 0x00c0, + 0x3fc: 0x00c0, 0x3fd: 0x00c0, 0x3fe: 0x00c0, 0x3ff: 0x00c0, + // Block 0x10, offset 0x400 + 0x400: 0x00c0, 0x401: 0x00c0, 0x402: 0x00c0, 0x403: 0x00c0, 0x404: 0x00c0, 0x405: 0x00c0, + 0x406: 0x00c0, 0x407: 0x00c0, 0x408: 0x00c0, 0x409: 0x00c0, 0x40a: 0x00c0, 0x40b: 0x00c0, + 0x40c: 0x00c0, 0x40d: 0x00c0, 0x40e: 0x00c0, 0x40f: 0x00c0, 0x410: 0x00c0, 0x411: 0x00c0, + 0x412: 0x00c0, 0x413: 0x00c0, 0x414: 0x00c0, 0x415: 0x00c0, 0x416: 0x00c0, 0x417: 0x00c0, + 0x418: 0x00c0, 0x419: 0x00c0, 0x41a: 0x00c0, 0x41b: 0x00c0, 0x41c: 0x00c0, 0x41d: 0x00c0, + 0x41e: 0x00c0, 0x41f: 0x00c0, 0x420: 0x00c0, 0x421: 0x00c0, 0x422: 0x00c0, 0x423: 0x00c0, + 0x424: 0x00c0, 0x425: 0x00c0, 0x426: 0x00c0, 0x427: 0x00c0, 0x428: 0x00c0, 0x429: 0x00c0, + 0x42a: 0x00c0, 0x42b: 0x00c0, 0x42c: 0x00c0, 0x42d: 0x00c0, 0x42e: 0x00c0, 0x42f: 0x00c0, + 0x431: 0x00c0, 0x432: 0x00c0, 0x433: 0x00c0, 0x434: 0x00c0, 0x435: 0x00c0, + 0x436: 0x00c0, 0x437: 0x00c0, 0x438: 0x00c0, 0x439: 0x00c0, 0x43a: 0x00c0, 0x43b: 0x00c0, + 0x43c: 0x00c0, 0x43d: 0x00c0, 0x43e: 0x00c0, 0x43f: 0x00c0, + // Block 0x11, offset 0x440 + 0x440: 0x00c0, 0x441: 0x00c0, 0x442: 0x00c0, 0x443: 0x00c0, 0x444: 0x00c0, 0x445: 0x00c0, + 0x446: 0x00c0, 0x447: 0x00c0, 0x448: 0x00c0, 0x449: 0x00c0, 0x44a: 0x00c0, 0x44b: 0x00c0, + 0x44c: 0x00c0, 0x44d: 0x00c0, 0x44e: 0x00c0, 0x44f: 0x00c0, 0x450: 0x00c0, 0x451: 0x00c0, + 0x452: 0x00c0, 0x453: 0x00c0, 0x454: 0x00c0, 0x455: 0x00c0, 0x456: 0x00c0, + 0x459: 0x00c0, 0x45a: 0x0080, 0x45b: 0x0080, 0x45c: 0x0080, 0x45d: 0x0080, + 0x45e: 0x0080, 0x45f: 0x0080, 0x460: 0x00c0, 0x461: 0x00c0, 0x462: 0x00c0, 0x463: 0x00c0, + 0x464: 0x00c0, 0x465: 0x00c0, 0x466: 0x00c0, 0x467: 0x00c0, 0x468: 0x00c0, 0x469: 0x00c0, + 0x46a: 0x00c0, 0x46b: 0x00c0, 0x46c: 0x00c0, 0x46d: 0x00c0, 0x46e: 0x00c0, 0x46f: 0x00c0, + 0x470: 0x00c0, 0x471: 0x00c0, 0x472: 0x00c0, 0x473: 0x00c0, 0x474: 0x00c0, 0x475: 0x00c0, + 0x476: 0x00c0, 0x477: 0x00c0, 0x478: 0x00c0, 0x479: 0x00c0, 0x47a: 0x00c0, 0x47b: 0x00c0, + 0x47c: 0x00c0, 0x47d: 0x00c0, 0x47e: 0x00c0, 0x47f: 0x00c0, + // Block 0x12, offset 0x480 + 0x480: 0x00c0, 0x481: 0x00c0, 0x482: 0x00c0, 0x483: 0x00c0, 0x484: 0x00c0, 0x485: 0x00c0, + 0x486: 0x00c0, 0x487: 0x0080, 0x488: 0x00c0, 0x489: 0x0080, 0x48a: 0x0080, + 0x48d: 0x0080, 0x48e: 0x0080, 0x48f: 0x0080, 0x491: 0x00cb, + 0x492: 0x00cb, 0x493: 0x00cb, 0x494: 0x00cb, 0x495: 0x00cb, 0x496: 0x00cb, 0x497: 0x00cb, + 0x498: 0x00cb, 0x499: 0x00cb, 0x49a: 0x00cb, 0x49b: 0x00cb, 0x49c: 0x00cb, 0x49d: 0x00cb, + 0x49e: 0x00cb, 0x49f: 0x00cb, 0x4a0: 0x00cb, 0x4a1: 0x00cb, 0x4a2: 0x00cb, 0x4a3: 0x00cb, + 0x4a4: 0x00cb, 0x4a5: 0x00cb, 0x4a6: 0x00cb, 0x4a7: 0x00cb, 0x4a8: 0x00cb, 0x4a9: 0x00cb, + 0x4aa: 0x00cb, 0x4ab: 0x00cb, 0x4ac: 0x00cb, 0x4ad: 0x00cb, 0x4ae: 0x00cb, 0x4af: 0x00cb, + 0x4b0: 0x00cb, 0x4b1: 0x00cb, 0x4b2: 0x00cb, 0x4b3: 0x00cb, 0x4b4: 0x00cb, 0x4b5: 0x00cb, + 0x4b6: 0x00cb, 0x4b7: 0x00cb, 0x4b8: 0x00cb, 0x4b9: 0x00cb, 0x4ba: 0x00cb, 0x4bb: 0x00cb, + 0x4bc: 0x00cb, 0x4bd: 0x00cb, 0x4be: 0x008a, 0x4bf: 0x00cb, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x008a, 0x4c1: 0x00cb, 0x4c2: 0x00cb, 0x4c3: 0x008a, 0x4c4: 0x00cb, 0x4c5: 0x00cb, + 0x4c6: 0x008a, 0x4c7: 0x00cb, + 0x4d0: 0x00ca, 0x4d1: 0x00ca, + 0x4d2: 0x00ca, 0x4d3: 0x00ca, 0x4d4: 0x00ca, 0x4d5: 0x00ca, 0x4d6: 0x00ca, 0x4d7: 0x00ca, + 0x4d8: 0x00ca, 0x4d9: 0x00ca, 0x4da: 0x00ca, 0x4db: 0x00ca, 0x4dc: 0x00ca, 0x4dd: 0x00ca, + 0x4de: 0x00ca, 0x4df: 0x00ca, 0x4e0: 0x00ca, 0x4e1: 0x00ca, 0x4e2: 0x00ca, 0x4e3: 0x00ca, + 0x4e4: 0x00ca, 0x4e5: 0x00ca, 0x4e6: 0x00ca, 0x4e7: 0x00ca, 0x4e8: 0x00ca, 0x4e9: 0x00ca, + 0x4ea: 0x00ca, 0x4ef: 0x00ca, + 0x4f0: 0x00ca, 0x4f1: 0x00ca, 0x4f2: 0x00ca, 0x4f3: 0x0051, 0x4f4: 0x0051, + // Block 0x14, offset 0x500 + 0x500: 0x0040, 0x501: 0x0040, 0x502: 0x0040, 0x503: 0x0040, 0x504: 0x0040, 0x505: 0x0040, + 0x506: 0x0080, 0x507: 0x0080, 0x508: 0x0080, 0x509: 0x0080, 0x50a: 0x0080, 0x50b: 0x0080, + 0x50c: 0x0080, 0x50d: 0x0080, 0x50e: 0x0080, 0x50f: 0x0080, 0x510: 0x00c3, 0x511: 0x00c3, + 0x512: 0x00c3, 0x513: 0x00c3, 0x514: 0x00c3, 0x515: 0x00c3, 0x516: 0x00c3, 0x517: 0x00c3, + 0x518: 0x00c3, 0x519: 0x00c3, 0x51a: 0x00c3, 0x51b: 0x0080, 0x51c: 0x0040, + 0x51e: 0x0080, 0x51f: 0x0080, 0x520: 0x00c2, 0x521: 0x00c0, 0x522: 0x00c4, 0x523: 0x00c4, + 0x524: 0x00c4, 0x525: 0x00c4, 0x526: 0x00c2, 0x527: 0x00c4, 0x528: 0x00c2, 0x529: 0x00c4, + 0x52a: 0x00c2, 0x52b: 0x00c2, 0x52c: 0x00c2, 0x52d: 0x00c2, 0x52e: 0x00c2, 0x52f: 0x00c4, + 0x530: 0x00c4, 0x531: 0x00c4, 0x532: 0x00c4, 0x533: 0x00c2, 0x534: 0x00c2, 0x535: 0x00c2, + 0x536: 0x00c2, 0x537: 0x00c2, 0x538: 0x00c2, 0x539: 0x00c2, 0x53a: 0x00c2, 0x53b: 0x00c2, + 0x53c: 0x00c2, 0x53d: 0x00c2, 0x53e: 0x00c2, 0x53f: 0x00c2, + // Block 0x15, offset 0x540 + 0x540: 0x0040, 0x541: 0x00c2, 0x542: 0x00c2, 0x543: 0x00c2, 0x544: 0x00c2, 0x545: 0x00c2, + 0x546: 0x00c2, 0x547: 0x00c2, 0x548: 0x00c4, 0x549: 0x00c2, 0x54a: 0x00c2, 0x54b: 0x00c3, + 0x54c: 0x00c3, 0x54d: 0x00c3, 0x54e: 0x00c3, 0x54f: 0x00c3, 0x550: 0x00c3, 0x551: 0x00c3, + 0x552: 0x00c3, 0x553: 0x00c3, 0x554: 0x00c3, 0x555: 0x00c3, 0x556: 0x00c3, 0x557: 0x00c3, + 0x558: 0x00c3, 0x559: 0x00c3, 0x55a: 0x00c3, 0x55b: 0x00c3, 0x55c: 0x00c3, 0x55d: 0x00c3, + 0x55e: 0x00c3, 0x55f: 0x00c3, 0x560: 0x0053, 0x561: 0x0053, 0x562: 0x0053, 0x563: 0x0053, + 0x564: 0x0053, 0x565: 0x0053, 0x566: 0x0053, 0x567: 0x0053, 0x568: 0x0053, 0x569: 0x0053, + 0x56a: 0x0080, 0x56b: 0x0080, 0x56c: 0x0080, 0x56d: 0x0080, 0x56e: 0x00c2, 0x56f: 0x00c2, + 0x570: 0x00c3, 0x571: 0x00c4, 0x572: 0x00c4, 0x573: 0x00c4, 0x574: 0x00c0, 0x575: 0x0084, + 0x576: 0x0084, 0x577: 0x0084, 0x578: 0x0082, 0x579: 0x00c2, 0x57a: 0x00c2, 0x57b: 0x00c2, + 0x57c: 0x00c2, 0x57d: 0x00c2, 0x57e: 0x00c2, 0x57f: 0x00c2, + // Block 0x16, offset 0x580 + 0x580: 0x00c2, 0x581: 0x00c2, 0x582: 0x00c2, 0x583: 0x00c2, 0x584: 0x00c2, 0x585: 0x00c2, + 0x586: 0x00c2, 0x587: 0x00c2, 0x588: 0x00c4, 0x589: 0x00c4, 0x58a: 0x00c4, 0x58b: 0x00c4, + 0x58c: 0x00c4, 0x58d: 0x00c4, 0x58e: 0x00c4, 0x58f: 0x00c4, 0x590: 0x00c4, 0x591: 0x00c4, + 0x592: 0x00c4, 0x593: 0x00c4, 0x594: 0x00c4, 0x595: 0x00c4, 0x596: 0x00c4, 0x597: 0x00c4, + 0x598: 0x00c4, 0x599: 0x00c4, 0x59a: 0x00c2, 0x59b: 0x00c2, 0x59c: 0x00c2, 0x59d: 0x00c2, + 0x59e: 0x00c2, 0x59f: 0x00c2, 0x5a0: 0x00c2, 0x5a1: 0x00c2, 0x5a2: 0x00c2, 0x5a3: 0x00c2, + 0x5a4: 0x00c2, 0x5a5: 0x00c2, 0x5a6: 0x00c2, 0x5a7: 0x00c2, 0x5a8: 0x00c2, 0x5a9: 0x00c2, + 0x5aa: 0x00c2, 0x5ab: 0x00c2, 0x5ac: 0x00c2, 0x5ad: 0x00c2, 0x5ae: 0x00c2, 0x5af: 0x00c2, + 0x5b0: 0x00c2, 0x5b1: 0x00c2, 0x5b2: 0x00c2, 0x5b3: 0x00c2, 0x5b4: 0x00c2, 0x5b5: 0x00c2, + 0x5b6: 0x00c2, 0x5b7: 0x00c2, 0x5b8: 0x00c2, 0x5b9: 0x00c2, 0x5ba: 0x00c2, 0x5bb: 0x00c2, + 0x5bc: 0x00c2, 0x5bd: 0x00c2, 0x5be: 0x00c2, 0x5bf: 0x00c2, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x00c4, 0x5c1: 0x00c2, 0x5c2: 0x00c2, 0x5c3: 0x00c4, 0x5c4: 0x00c4, 0x5c5: 0x00c4, + 0x5c6: 0x00c4, 0x5c7: 0x00c4, 0x5c8: 0x00c4, 0x5c9: 0x00c4, 0x5ca: 0x00c4, 0x5cb: 0x00c4, + 0x5cc: 0x00c2, 0x5cd: 0x00c4, 0x5ce: 0x00c2, 0x5cf: 0x00c4, 0x5d0: 0x00c2, 0x5d1: 0x00c2, + 0x5d2: 0x00c4, 0x5d3: 0x00c4, 0x5d4: 0x0080, 0x5d5: 0x00c4, 0x5d6: 0x00c3, 0x5d7: 0x00c3, + 0x5d8: 0x00c3, 0x5d9: 0x00c3, 0x5da: 0x00c3, 0x5db: 0x00c3, 0x5dc: 0x00c3, 0x5dd: 0x0040, + 0x5de: 0x0080, 0x5df: 0x00c3, 0x5e0: 0x00c3, 0x5e1: 0x00c3, 0x5e2: 0x00c3, 0x5e3: 0x00c3, + 0x5e4: 0x00c3, 0x5e5: 0x00c0, 0x5e6: 0x00c0, 0x5e7: 0x00c3, 0x5e8: 0x00c3, 0x5e9: 0x0080, + 0x5ea: 0x00c3, 0x5eb: 0x00c3, 0x5ec: 0x00c3, 0x5ed: 0x00c3, 0x5ee: 0x00c4, 0x5ef: 0x00c4, + 0x5f0: 0x0054, 0x5f1: 0x0054, 0x5f2: 0x0054, 0x5f3: 0x0054, 0x5f4: 0x0054, 0x5f5: 0x0054, + 0x5f6: 0x0054, 0x5f7: 0x0054, 0x5f8: 0x0054, 0x5f9: 0x0054, 0x5fa: 0x00c2, 0x5fb: 0x00c2, + 0x5fc: 0x00c2, 0x5fd: 0x00c0, 0x5fe: 0x00c0, 0x5ff: 0x00c2, + // Block 0x18, offset 0x600 + 0x600: 0x0080, 0x601: 0x0080, 0x602: 0x0080, 0x603: 0x0080, 0x604: 0x0080, 0x605: 0x0080, + 0x606: 0x0080, 0x607: 0x0080, 0x608: 0x0080, 0x609: 0x0080, 0x60a: 0x0080, 0x60b: 0x0080, + 0x60c: 0x0080, 0x60d: 0x0080, 0x60f: 0x0040, 0x610: 0x00c4, 0x611: 0x00c3, + 0x612: 0x00c2, 0x613: 0x00c2, 0x614: 0x00c2, 0x615: 0x00c4, 0x616: 0x00c4, 0x617: 0x00c4, + 0x618: 0x00c4, 0x619: 0x00c4, 0x61a: 0x00c2, 0x61b: 0x00c2, 0x61c: 0x00c2, 0x61d: 0x00c2, + 0x61e: 0x00c4, 0x61f: 0x00c2, 0x620: 0x00c2, 0x621: 0x00c2, 0x622: 0x00c2, 0x623: 0x00c2, + 0x624: 0x00c2, 0x625: 0x00c2, 0x626: 0x00c2, 0x627: 0x00c2, 0x628: 0x00c4, 0x629: 0x00c2, + 0x62a: 0x00c4, 0x62b: 0x00c2, 0x62c: 0x00c4, 0x62d: 0x00c2, 0x62e: 0x00c2, 0x62f: 0x00c4, + 0x630: 0x00c3, 0x631: 0x00c3, 0x632: 0x00c3, 0x633: 0x00c3, 0x634: 0x00c3, 0x635: 0x00c3, + 0x636: 0x00c3, 0x637: 0x00c3, 0x638: 0x00c3, 0x639: 0x00c3, 0x63a: 0x00c3, 0x63b: 0x00c3, + 0x63c: 0x00c3, 0x63d: 0x00c3, 0x63e: 0x00c3, 0x63f: 0x00c3, + // Block 0x19, offset 0x640 + 0x640: 0x00c3, 0x641: 0x00c3, 0x642: 0x00c3, 0x643: 0x00c3, 0x644: 0x00c3, 0x645: 0x00c3, + 0x646: 0x00c3, 0x647: 0x00c3, 0x648: 0x00c3, 0x649: 0x00c3, 0x64a: 0x00c3, + 0x64d: 0x00c4, 0x64e: 0x00c2, 0x64f: 0x00c2, 0x650: 0x00c2, 0x651: 0x00c2, + 0x652: 0x00c2, 0x653: 0x00c2, 0x654: 0x00c2, 0x655: 0x00c2, 0x656: 0x00c2, 0x657: 0x00c2, + 0x658: 0x00c2, 0x659: 0x00c4, 0x65a: 0x00c4, 0x65b: 0x00c4, 0x65c: 0x00c2, 0x65d: 0x00c2, + 0x65e: 0x00c2, 0x65f: 0x00c2, 0x660: 0x00c2, 0x661: 0x00c2, 0x662: 0x00c2, 0x663: 0x00c2, + 0x664: 0x00c2, 0x665: 0x00c2, 0x666: 0x00c2, 0x667: 0x00c2, 0x668: 0x00c2, 0x669: 0x00c2, + 0x66a: 0x00c2, 0x66b: 0x00c4, 0x66c: 0x00c4, 0x66d: 0x00c2, 0x66e: 0x00c2, 0x66f: 0x00c2, + 0x670: 0x00c2, 0x671: 0x00c4, 0x672: 0x00c2, 0x673: 0x00c4, 0x674: 0x00c4, 0x675: 0x00c2, + 0x676: 0x00c2, 0x677: 0x00c2, 0x678: 0x00c4, 0x679: 0x00c4, 0x67a: 0x00c2, 0x67b: 0x00c2, + 0x67c: 0x00c2, 0x67d: 0x00c2, 0x67e: 0x00c2, 0x67f: 0x00c2, + // Block 0x1a, offset 0x680 + 0x680: 0x00c0, 0x681: 0x00c0, 0x682: 0x00c0, 0x683: 0x00c0, 0x684: 0x00c0, 0x685: 0x00c0, + 0x686: 0x00c0, 0x687: 0x00c0, 0x688: 0x00c0, 0x689: 0x00c0, 0x68a: 0x00c0, 0x68b: 0x00c0, + 0x68c: 0x00c0, 0x68d: 0x00c0, 0x68e: 0x00c0, 0x68f: 0x00c0, 0x690: 0x00c0, 0x691: 0x00c0, + 0x692: 0x00c0, 0x693: 0x00c0, 0x694: 0x00c0, 0x695: 0x00c0, 0x696: 0x00c0, 0x697: 0x00c0, + 0x698: 0x00c0, 0x699: 0x00c0, 0x69a: 0x00c0, 0x69b: 0x00c0, 0x69c: 0x00c0, 0x69d: 0x00c0, + 0x69e: 0x00c0, 0x69f: 0x00c0, 0x6a0: 0x00c0, 0x6a1: 0x00c0, 0x6a2: 0x00c0, 0x6a3: 0x00c0, + 0x6a4: 0x00c0, 0x6a5: 0x00c0, 0x6a6: 0x00c3, 0x6a7: 0x00c3, 0x6a8: 0x00c3, 0x6a9: 0x00c3, + 0x6aa: 0x00c3, 0x6ab: 0x00c3, 0x6ac: 0x00c3, 0x6ad: 0x00c3, 0x6ae: 0x00c3, 0x6af: 0x00c3, + 0x6b0: 0x00c3, 0x6b1: 0x00c0, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x00c0, 0x6c1: 0x00c0, 0x6c2: 0x00c0, 0x6c3: 0x00c0, 0x6c4: 0x00c0, 0x6c5: 0x00c0, + 0x6c6: 0x00c0, 0x6c7: 0x00c0, 0x6c8: 0x00c0, 0x6c9: 0x00c0, 0x6ca: 0x00c2, 0x6cb: 0x00c2, + 0x6cc: 0x00c2, 0x6cd: 0x00c2, 0x6ce: 0x00c2, 0x6cf: 0x00c2, 0x6d0: 0x00c2, 0x6d1: 0x00c2, + 0x6d2: 0x00c2, 0x6d3: 0x00c2, 0x6d4: 0x00c2, 0x6d5: 0x00c2, 0x6d6: 0x00c2, 0x6d7: 0x00c2, + 0x6d8: 0x00c2, 0x6d9: 0x00c2, 0x6da: 0x00c2, 0x6db: 0x00c2, 0x6dc: 0x00c2, 0x6dd: 0x00c2, + 0x6de: 0x00c2, 0x6df: 0x00c2, 0x6e0: 0x00c2, 0x6e1: 0x00c2, 0x6e2: 0x00c2, 0x6e3: 0x00c2, + 0x6e4: 0x00c2, 0x6e5: 0x00c2, 0x6e6: 0x00c2, 0x6e7: 0x00c2, 0x6e8: 0x00c2, 0x6e9: 0x00c2, + 0x6ea: 0x00c2, 0x6eb: 0x00c3, 0x6ec: 0x00c3, 0x6ed: 0x00c3, 0x6ee: 0x00c3, 0x6ef: 0x00c3, + 0x6f0: 0x00c3, 0x6f1: 0x00c3, 0x6f2: 0x00c3, 0x6f3: 0x00c3, 0x6f4: 0x00c0, 0x6f5: 0x00c0, + 0x6f6: 0x0080, 0x6f7: 0x0080, 0x6f8: 0x0080, 0x6f9: 0x0080, 0x6fa: 0x0040, + 0x6fd: 0x00c3, 0x6fe: 0x0080, 0x6ff: 0x0080, + // Block 0x1c, offset 0x700 + 0x700: 0x00c0, 0x701: 0x00c0, 0x702: 0x00c0, 0x703: 0x00c0, 0x704: 0x00c0, 0x705: 0x00c0, + 0x706: 0x00c0, 0x707: 0x00c0, 0x708: 0x00c0, 0x709: 0x00c0, 0x70a: 0x00c0, 0x70b: 0x00c0, + 0x70c: 0x00c0, 0x70d: 0x00c0, 0x70e: 0x00c0, 0x70f: 0x00c0, 0x710: 0x00c0, 0x711: 0x00c0, + 0x712: 0x00c0, 0x713: 0x00c0, 0x714: 0x00c0, 0x715: 0x00c0, 0x716: 0x00c3, 0x717: 0x00c3, + 0x718: 0x00c3, 0x719: 0x00c3, 0x71a: 0x00c0, 0x71b: 0x00c3, 0x71c: 0x00c3, 0x71d: 0x00c3, + 0x71e: 0x00c3, 0x71f: 0x00c3, 0x720: 0x00c3, 0x721: 0x00c3, 0x722: 0x00c3, 0x723: 0x00c3, + 0x724: 0x00c0, 0x725: 0x00c3, 0x726: 0x00c3, 0x727: 0x00c3, 0x728: 0x00c0, 0x729: 0x00c3, + 0x72a: 0x00c3, 0x72b: 0x00c3, 0x72c: 0x00c3, 0x72d: 0x00c3, + 0x730: 0x0080, 0x731: 0x0080, 0x732: 0x0080, 0x733: 0x0080, 0x734: 0x0080, 0x735: 0x0080, + 0x736: 0x0080, 0x737: 0x0080, 0x738: 0x0080, 0x739: 0x0080, 0x73a: 0x0080, 0x73b: 0x0080, + 0x73c: 0x0080, 0x73d: 0x0080, 0x73e: 0x0080, + // Block 0x1d, offset 0x740 + 0x740: 0x00c4, 0x741: 0x00c2, 0x742: 0x00c2, 0x743: 0x00c2, 0x744: 0x00c2, 0x745: 0x00c2, + 0x746: 0x00c4, 0x747: 0x00c4, 0x748: 0x00c2, 0x749: 0x00c4, 0x74a: 0x00c2, 0x74b: 0x00c2, + 0x74c: 0x00c2, 0x74d: 0x00c2, 0x74e: 0x00c2, 0x74f: 0x00c2, 0x750: 0x00c2, 0x751: 0x00c2, + 0x752: 0x00c2, 0x753: 0x00c2, 0x754: 0x00c4, 0x755: 0x00c2, 0x756: 0x00c4, 0x757: 0x00c4, + 0x758: 0x00c4, 0x759: 0x00c3, 0x75a: 0x00c3, 0x75b: 0x00c3, + 0x75e: 0x0080, 0x760: 0x00c2, 0x761: 0x00c0, 0x762: 0x00c2, 0x763: 0x00c2, + 0x764: 0x00c2, 0x765: 0x00c2, 0x766: 0x00c0, 0x767: 0x00c4, 0x768: 0x00c2, 0x769: 0x00c4, + 0x76a: 0x00c4, + // Block 0x1e, offset 0x780 + 0x7a0: 0x00c2, 0x7a1: 0x00c2, 0x7a2: 0x00c2, 0x7a3: 0x00c2, + 0x7a4: 0x00c2, 0x7a5: 0x00c2, 0x7a6: 0x00c2, 0x7a7: 0x00c2, 0x7a8: 0x00c2, 0x7a9: 0x00c2, + 0x7aa: 0x00c4, 0x7ab: 0x00c4, 0x7ac: 0x00c4, 0x7ad: 0x00c0, 0x7ae: 0x00c4, 0x7af: 0x00c2, + 0x7b0: 0x00c2, 0x7b1: 0x00c4, 0x7b2: 0x00c4, 0x7b3: 0x00c2, 0x7b4: 0x00c2, + 0x7b6: 0x00c2, 0x7b7: 0x00c2, 0x7b8: 0x00c2, 0x7b9: 0x00c4, 0x7ba: 0x00c2, 0x7bb: 0x00c2, + 0x7bc: 0x00c2, 0x7bd: 0x00c2, 0x7be: 0x00c2, 0x7bf: 0x00c2, + // Block 0x1f, offset 0x7c0 + 0x7c0: 0x00c2, 0x7c1: 0x00c2, 0x7c2: 0x00c2, 0x7c3: 0x00c2, 0x7c4: 0x00c2, 0x7c5: 0x00c2, + 0x7c6: 0x00c2, 0x7c7: 0x00c2, + 0x7d3: 0x00c3, 0x7d4: 0x00c3, 0x7d5: 0x00c3, 0x7d6: 0x00c3, 0x7d7: 0x00c3, + 0x7d8: 0x00c3, 0x7d9: 0x00c3, 0x7da: 0x00c3, 0x7db: 0x00c3, 0x7dc: 0x00c3, 0x7dd: 0x00c3, + 0x7de: 0x00c3, 0x7df: 0x00c3, 0x7e0: 0x00c3, 0x7e1: 0x00c3, 0x7e2: 0x0040, 0x7e3: 0x00c3, + 0x7e4: 0x00c3, 0x7e5: 0x00c3, 0x7e6: 0x00c3, 0x7e7: 0x00c3, 0x7e8: 0x00c3, 0x7e9: 0x00c3, + 0x7ea: 0x00c3, 0x7eb: 0x00c3, 0x7ec: 0x00c3, 0x7ed: 0x00c3, 0x7ee: 0x00c3, 0x7ef: 0x00c3, + 0x7f0: 0x00c3, 0x7f1: 0x00c3, 0x7f2: 0x00c3, 0x7f3: 0x00c3, 0x7f4: 0x00c3, 0x7f5: 0x00c3, + 0x7f6: 0x00c3, 0x7f7: 0x00c3, 0x7f8: 0x00c3, 0x7f9: 0x00c3, 0x7fa: 0x00c3, 0x7fb: 0x00c3, + 0x7fc: 0x00c3, 0x7fd: 0x00c3, 0x7fe: 0x00c3, 0x7ff: 0x00c3, + // Block 0x20, offset 0x800 + 0x800: 0x00c3, 0x801: 0x00c3, 0x802: 0x00c3, 0x803: 0x00c0, 0x804: 0x00c0, 0x805: 0x00c0, + 0x806: 0x00c0, 0x807: 0x00c0, 0x808: 0x00c0, 0x809: 0x00c0, 0x80a: 0x00c0, 0x80b: 0x00c0, + 0x80c: 0x00c0, 0x80d: 0x00c0, 0x80e: 0x00c0, 0x80f: 0x00c0, 0x810: 0x00c0, 0x811: 0x00c0, + 0x812: 0x00c0, 0x813: 0x00c0, 0x814: 0x00c0, 0x815: 0x00c0, 0x816: 0x00c0, 0x817: 0x00c0, + 0x818: 0x00c0, 0x819: 0x00c0, 0x81a: 0x00c0, 0x81b: 0x00c0, 0x81c: 0x00c0, 0x81d: 0x00c0, + 0x81e: 0x00c0, 0x81f: 0x00c0, 0x820: 0x00c0, 0x821: 0x00c0, 0x822: 0x00c0, 0x823: 0x00c0, + 0x824: 0x00c0, 0x825: 0x00c0, 0x826: 0x00c0, 0x827: 0x00c0, 0x828: 0x00c0, 0x829: 0x00c0, + 0x82a: 0x00c0, 0x82b: 0x00c0, 0x82c: 0x00c0, 0x82d: 0x00c0, 0x82e: 0x00c0, 0x82f: 0x00c0, + 0x830: 0x00c0, 0x831: 0x00c0, 0x832: 0x00c0, 0x833: 0x00c0, 0x834: 0x00c0, 0x835: 0x00c0, + 0x836: 0x00c0, 0x837: 0x00c0, 0x838: 0x00c0, 0x839: 0x00c0, 0x83a: 0x00c3, 0x83b: 0x00c0, + 0x83c: 0x00c3, 0x83d: 0x00c0, 0x83e: 0x00c0, 0x83f: 0x00c0, + // Block 0x21, offset 0x840 + 0x840: 0x00c0, 0x841: 0x00c3, 0x842: 0x00c3, 0x843: 0x00c3, 0x844: 0x00c3, 0x845: 0x00c3, + 0x846: 0x00c3, 0x847: 0x00c3, 0x848: 0x00c3, 0x849: 0x00c0, 0x84a: 0x00c0, 0x84b: 0x00c0, + 0x84c: 0x00c0, 0x84d: 0x00c6, 0x84e: 0x00c0, 0x84f: 0x00c0, 0x850: 0x00c0, 0x851: 0x00c3, + 0x852: 0x00c3, 0x853: 0x00c3, 0x854: 0x00c3, 0x855: 0x00c3, 0x856: 0x00c3, 0x857: 0x00c3, + 0x858: 0x0080, 0x859: 0x0080, 0x85a: 0x0080, 0x85b: 0x0080, 0x85c: 0x0080, 0x85d: 0x0080, + 0x85e: 0x0080, 0x85f: 0x0080, 0x860: 0x00c0, 0x861: 0x00c0, 0x862: 0x00c3, 0x863: 0x00c3, + 0x864: 0x0080, 0x865: 0x0080, 0x866: 0x00c0, 0x867: 0x00c0, 0x868: 0x00c0, 0x869: 0x00c0, + 0x86a: 0x00c0, 0x86b: 0x00c0, 0x86c: 0x00c0, 0x86d: 0x00c0, 0x86e: 0x00c0, 0x86f: 0x00c0, + 0x870: 0x0080, 0x871: 0x00c0, 0x872: 0x00c0, 0x873: 0x00c0, 0x874: 0x00c0, 0x875: 0x00c0, + 0x876: 0x00c0, 0x877: 0x00c0, 0x878: 0x00c0, 0x879: 0x00c0, 0x87a: 0x00c0, 0x87b: 0x00c0, + 0x87c: 0x00c0, 0x87d: 0x00c0, 0x87e: 0x00c0, 0x87f: 0x00c0, + // Block 0x22, offset 0x880 + 0x880: 0x00c0, 0x881: 0x00c3, 0x882: 0x00c0, 0x883: 0x00c0, 0x885: 0x00c0, + 0x886: 0x00c0, 0x887: 0x00c0, 0x888: 0x00c0, 0x889: 0x00c0, 0x88a: 0x00c0, 0x88b: 0x00c0, + 0x88c: 0x00c0, 0x88f: 0x00c0, 0x890: 0x00c0, + 0x893: 0x00c0, 0x894: 0x00c0, 0x895: 0x00c0, 0x896: 0x00c0, 0x897: 0x00c0, + 0x898: 0x00c0, 0x899: 0x00c0, 0x89a: 0x00c0, 0x89b: 0x00c0, 0x89c: 0x00c0, 0x89d: 0x00c0, + 0x89e: 0x00c0, 0x89f: 0x00c0, 0x8a0: 0x00c0, 0x8a1: 0x00c0, 0x8a2: 0x00c0, 0x8a3: 0x00c0, + 0x8a4: 0x00c0, 0x8a5: 0x00c0, 0x8a6: 0x00c0, 0x8a7: 0x00c0, 0x8a8: 0x00c0, + 0x8aa: 0x00c0, 0x8ab: 0x00c0, 0x8ac: 0x00c0, 0x8ad: 0x00c0, 0x8ae: 0x00c0, 0x8af: 0x00c0, + 0x8b0: 0x00c0, 0x8b2: 0x00c0, + 0x8b6: 0x00c0, 0x8b7: 0x00c0, 0x8b8: 0x00c0, 0x8b9: 0x00c0, + 0x8bc: 0x00c3, 0x8bd: 0x00c0, 0x8be: 0x00c0, 0x8bf: 0x00c0, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x00c0, 0x8c1: 0x00c3, 0x8c2: 0x00c3, 0x8c3: 0x00c3, 0x8c4: 0x00c3, + 0x8c7: 0x00c0, 0x8c8: 0x00c0, 0x8cb: 0x00c0, + 0x8cc: 0x00c0, 0x8cd: 0x00c6, 0x8ce: 0x00c0, + 0x8d7: 0x00c0, + 0x8dc: 0x0080, 0x8dd: 0x0080, + 0x8df: 0x0080, 0x8e0: 0x00c0, 0x8e1: 0x00c0, 0x8e2: 0x00c3, 0x8e3: 0x00c3, + 0x8e6: 0x00c0, 0x8e7: 0x00c0, 0x8e8: 0x00c0, 0x8e9: 0x00c0, + 0x8ea: 0x00c0, 0x8eb: 0x00c0, 0x8ec: 0x00c0, 0x8ed: 0x00c0, 0x8ee: 0x00c0, 0x8ef: 0x00c0, + 0x8f0: 0x00c0, 0x8f1: 0x00c0, 0x8f2: 0x0080, 0x8f3: 0x0080, 0x8f4: 0x0080, 0x8f5: 0x0080, + 0x8f6: 0x0080, 0x8f7: 0x0080, 0x8f8: 0x0080, 0x8f9: 0x0080, 0x8fa: 0x0080, 0x8fb: 0x0080, + 0x8fc: 0x00c0, 0x8fd: 0x0080, 0x8fe: 0x00c3, + // Block 0x24, offset 0x900 + 0x901: 0x00c3, 0x902: 0x00c3, 0x903: 0x00c0, 0x905: 0x00c0, + 0x906: 0x00c0, 0x907: 0x00c0, 0x908: 0x00c0, 0x909: 0x00c0, 0x90a: 0x00c0, + 0x90f: 0x00c0, 0x910: 0x00c0, + 0x913: 0x00c0, 0x914: 0x00c0, 0x915: 0x00c0, 0x916: 0x00c0, 0x917: 0x00c0, + 0x918: 0x00c0, 0x919: 0x00c0, 0x91a: 0x00c0, 0x91b: 0x00c0, 0x91c: 0x00c0, 0x91d: 0x00c0, + 0x91e: 0x00c0, 0x91f: 0x00c0, 0x920: 0x00c0, 0x921: 0x00c0, 0x922: 0x00c0, 0x923: 0x00c0, + 0x924: 0x00c0, 0x925: 0x00c0, 0x926: 0x00c0, 0x927: 0x00c0, 0x928: 0x00c0, + 0x92a: 0x00c0, 0x92b: 0x00c0, 0x92c: 0x00c0, 0x92d: 0x00c0, 0x92e: 0x00c0, 0x92f: 0x00c0, + 0x930: 0x00c0, 0x932: 0x00c0, 0x933: 0x0080, 0x935: 0x00c0, + 0x936: 0x0080, 0x938: 0x00c0, 0x939: 0x00c0, + 0x93c: 0x00c3, 0x93e: 0x00c0, 0x93f: 0x00c0, + // Block 0x25, offset 0x940 + 0x940: 0x00c0, 0x941: 0x00c3, 0x942: 0x00c3, + 0x947: 0x00c3, 0x948: 0x00c3, 0x94b: 0x00c3, + 0x94c: 0x00c3, 0x94d: 0x00c6, 0x951: 0x00c3, + 0x959: 0x0080, 0x95a: 0x0080, 0x95b: 0x0080, 0x95c: 0x00c0, + 0x95e: 0x0080, + 0x966: 0x00c0, 0x967: 0x00c0, 0x968: 0x00c0, 0x969: 0x00c0, + 0x96a: 0x00c0, 0x96b: 0x00c0, 0x96c: 0x00c0, 0x96d: 0x00c0, 0x96e: 0x00c0, 0x96f: 0x00c0, + 0x970: 0x00c3, 0x971: 0x00c3, 0x972: 0x00c0, 0x973: 0x00c0, 0x974: 0x00c0, 0x975: 0x00c3, + 0x976: 0x0080, + // Block 0x26, offset 0x980 + 0x981: 0x00c3, 0x982: 0x00c3, 0x983: 0x00c0, 0x985: 0x00c0, + 0x986: 0x00c0, 0x987: 0x00c0, 0x988: 0x00c0, 0x989: 0x00c0, 0x98a: 0x00c0, 0x98b: 0x00c0, + 0x98c: 0x00c0, 0x98d: 0x00c0, 0x98f: 0x00c0, 0x990: 0x00c0, 0x991: 0x00c0, + 0x993: 0x00c0, 0x994: 0x00c0, 0x995: 0x00c0, 0x996: 0x00c0, 0x997: 0x00c0, + 0x998: 0x00c0, 0x999: 0x00c0, 0x99a: 0x00c0, 0x99b: 0x00c0, 0x99c: 0x00c0, 0x99d: 0x00c0, + 0x99e: 0x00c0, 0x99f: 0x00c0, 0x9a0: 0x00c0, 0x9a1: 0x00c0, 0x9a2: 0x00c0, 0x9a3: 0x00c0, + 0x9a4: 0x00c0, 0x9a5: 0x00c0, 0x9a6: 0x00c0, 0x9a7: 0x00c0, 0x9a8: 0x00c0, + 0x9aa: 0x00c0, 0x9ab: 0x00c0, 0x9ac: 0x00c0, 0x9ad: 0x00c0, 0x9ae: 0x00c0, 0x9af: 0x00c0, + 0x9b0: 0x00c0, 0x9b2: 0x00c0, 0x9b3: 0x00c0, 0x9b5: 0x00c0, + 0x9b6: 0x00c0, 0x9b7: 0x00c0, 0x9b8: 0x00c0, 0x9b9: 0x00c0, + 0x9bc: 0x00c3, 0x9bd: 0x00c0, 0x9be: 0x00c0, 0x9bf: 0x00c0, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x00c0, 0x9c1: 0x00c3, 0x9c2: 0x00c3, 0x9c3: 0x00c3, 0x9c4: 0x00c3, 0x9c5: 0x00c3, + 0x9c7: 0x00c3, 0x9c8: 0x00c3, 0x9c9: 0x00c0, 0x9cb: 0x00c0, + 0x9cc: 0x00c0, 0x9cd: 0x00c6, 0x9d0: 0x00c0, + 0x9e0: 0x00c0, 0x9e1: 0x00c0, 0x9e2: 0x00c3, 0x9e3: 0x00c3, + 0x9e6: 0x00c0, 0x9e7: 0x00c0, 0x9e8: 0x00c0, 0x9e9: 0x00c0, + 0x9ea: 0x00c0, 0x9eb: 0x00c0, 0x9ec: 0x00c0, 0x9ed: 0x00c0, 0x9ee: 0x00c0, 0x9ef: 0x00c0, + 0x9f0: 0x0080, 0x9f1: 0x0080, + 0x9f9: 0x00c0, 0x9fa: 0x00c3, 0x9fb: 0x00c3, + 0x9fc: 0x00c3, 0x9fd: 0x00c3, 0x9fe: 0x00c3, 0x9ff: 0x00c3, + // Block 0x28, offset 0xa00 + 0xa01: 0x00c3, 0xa02: 0x00c0, 0xa03: 0x00c0, 0xa05: 0x00c0, + 0xa06: 0x00c0, 0xa07: 0x00c0, 0xa08: 0x00c0, 0xa09: 0x00c0, 0xa0a: 0x00c0, 0xa0b: 0x00c0, + 0xa0c: 0x00c0, 0xa0f: 0x00c0, 0xa10: 0x00c0, + 0xa13: 0x00c0, 0xa14: 0x00c0, 0xa15: 0x00c0, 0xa16: 0x00c0, 0xa17: 0x00c0, + 0xa18: 0x00c0, 0xa19: 0x00c0, 0xa1a: 0x00c0, 0xa1b: 0x00c0, 0xa1c: 0x00c0, 0xa1d: 0x00c0, + 0xa1e: 0x00c0, 0xa1f: 0x00c0, 0xa20: 0x00c0, 0xa21: 0x00c0, 0xa22: 0x00c0, 0xa23: 0x00c0, + 0xa24: 0x00c0, 0xa25: 0x00c0, 0xa26: 0x00c0, 0xa27: 0x00c0, 0xa28: 0x00c0, + 0xa2a: 0x00c0, 0xa2b: 0x00c0, 0xa2c: 0x00c0, 0xa2d: 0x00c0, 0xa2e: 0x00c0, 0xa2f: 0x00c0, + 0xa30: 0x00c0, 0xa32: 0x00c0, 0xa33: 0x00c0, 0xa35: 0x00c0, + 0xa36: 0x00c0, 0xa37: 0x00c0, 0xa38: 0x00c0, 0xa39: 0x00c0, + 0xa3c: 0x00c3, 0xa3d: 0x00c0, 0xa3e: 0x00c0, 0xa3f: 0x00c3, + // Block 0x29, offset 0xa40 + 0xa40: 0x00c0, 0xa41: 0x00c3, 0xa42: 0x00c3, 0xa43: 0x00c3, 0xa44: 0x00c3, + 0xa47: 0x00c0, 0xa48: 0x00c0, 0xa4b: 0x00c0, + 0xa4c: 0x00c0, 0xa4d: 0x00c6, + 0xa55: 0x00c3, 0xa56: 0x00c3, 0xa57: 0x00c0, + 0xa5c: 0x0080, 0xa5d: 0x0080, + 0xa5f: 0x00c0, 0xa60: 0x00c0, 0xa61: 0x00c0, 0xa62: 0x00c3, 0xa63: 0x00c3, + 0xa66: 0x00c0, 0xa67: 0x00c0, 0xa68: 0x00c0, 0xa69: 0x00c0, + 0xa6a: 0x00c0, 0xa6b: 0x00c0, 0xa6c: 0x00c0, 0xa6d: 0x00c0, 0xa6e: 0x00c0, 0xa6f: 0x00c0, + 0xa70: 0x0080, 0xa71: 0x00c0, 0xa72: 0x0080, 0xa73: 0x0080, 0xa74: 0x0080, 0xa75: 0x0080, + 0xa76: 0x0080, 0xa77: 0x0080, + // Block 0x2a, offset 0xa80 + 0xa82: 0x00c3, 0xa83: 0x00c0, 0xa85: 0x00c0, + 0xa86: 0x00c0, 0xa87: 0x00c0, 0xa88: 0x00c0, 0xa89: 0x00c0, 0xa8a: 0x00c0, + 0xa8e: 0x00c0, 0xa8f: 0x00c0, 0xa90: 0x00c0, + 0xa92: 0x00c0, 0xa93: 0x00c0, 0xa94: 0x00c0, 0xa95: 0x00c0, + 0xa99: 0x00c0, 0xa9a: 0x00c0, 0xa9c: 0x00c0, + 0xa9e: 0x00c0, 0xa9f: 0x00c0, 0xaa3: 0x00c0, + 0xaa4: 0x00c0, 0xaa8: 0x00c0, 0xaa9: 0x00c0, + 0xaaa: 0x00c0, 0xaae: 0x00c0, 0xaaf: 0x00c0, + 0xab0: 0x00c0, 0xab1: 0x00c0, 0xab2: 0x00c0, 0xab3: 0x00c0, 0xab4: 0x00c0, 0xab5: 0x00c0, + 0xab6: 0x00c0, 0xab7: 0x00c0, 0xab8: 0x00c0, 0xab9: 0x00c0, + 0xabe: 0x00c0, 0xabf: 0x00c0, + // Block 0x2b, offset 0xac0 + 0xac0: 0x00c3, 0xac1: 0x00c0, 0xac2: 0x00c0, + 0xac6: 0x00c0, 0xac7: 0x00c0, 0xac8: 0x00c0, 0xaca: 0x00c0, 0xacb: 0x00c0, + 0xacc: 0x00c0, 0xacd: 0x00c6, 0xad0: 0x00c0, + 0xad7: 0x00c0, + 0xae6: 0x00c0, 0xae7: 0x00c0, 0xae8: 0x00c0, 0xae9: 0x00c0, + 0xaea: 0x00c0, 0xaeb: 0x00c0, 0xaec: 0x00c0, 0xaed: 0x00c0, 0xaee: 0x00c0, 0xaef: 0x00c0, + 0xaf0: 0x0080, 0xaf1: 0x0080, 0xaf2: 0x0080, 0xaf3: 0x0080, 0xaf4: 0x0080, 0xaf5: 0x0080, + 0xaf6: 0x0080, 0xaf7: 0x0080, 0xaf8: 0x0080, 0xaf9: 0x0080, 0xafa: 0x0080, + // Block 0x2c, offset 0xb00 + 0xb00: 0x00c3, 0xb01: 0x00c0, 0xb02: 0x00c0, 0xb03: 0x00c0, 0xb04: 0x00c3, 0xb05: 0x00c0, + 0xb06: 0x00c0, 0xb07: 0x00c0, 0xb08: 0x00c0, 0xb09: 0x00c0, 0xb0a: 0x00c0, 0xb0b: 0x00c0, + 0xb0c: 0x00c0, 0xb0e: 0x00c0, 0xb0f: 0x00c0, 0xb10: 0x00c0, + 0xb12: 0x00c0, 0xb13: 0x00c0, 0xb14: 0x00c0, 0xb15: 0x00c0, 0xb16: 0x00c0, 0xb17: 0x00c0, + 0xb18: 0x00c0, 0xb19: 0x00c0, 0xb1a: 0x00c0, 0xb1b: 0x00c0, 0xb1c: 0x00c0, 0xb1d: 0x00c0, + 0xb1e: 0x00c0, 0xb1f: 0x00c0, 0xb20: 0x00c0, 0xb21: 0x00c0, 0xb22: 0x00c0, 0xb23: 0x00c0, + 0xb24: 0x00c0, 0xb25: 0x00c0, 0xb26: 0x00c0, 0xb27: 0x00c0, 0xb28: 0x00c0, + 0xb2a: 0x00c0, 0xb2b: 0x00c0, 0xb2c: 0x00c0, 0xb2d: 0x00c0, 0xb2e: 0x00c0, 0xb2f: 0x00c0, + 0xb30: 0x00c0, 0xb31: 0x00c0, 0xb32: 0x00c0, 0xb33: 0x00c0, 0xb34: 0x00c0, 0xb35: 0x00c0, + 0xb36: 0x00c0, 0xb37: 0x00c0, 0xb38: 0x00c0, 0xb39: 0x00c0, + 0xb3d: 0x00c0, 0xb3e: 0x00c3, 0xb3f: 0x00c3, + // Block 0x2d, offset 0xb40 + 0xb40: 0x00c3, 0xb41: 0x00c0, 0xb42: 0x00c0, 0xb43: 0x00c0, 0xb44: 0x00c0, + 0xb46: 0x00c3, 0xb47: 0x00c3, 0xb48: 0x00c3, 0xb4a: 0x00c3, 0xb4b: 0x00c3, + 0xb4c: 0x00c3, 0xb4d: 0x00c6, + 0xb55: 0x00c3, 0xb56: 0x00c3, + 0xb58: 0x00c0, 0xb59: 0x00c0, 0xb5a: 0x00c0, + 0xb60: 0x00c0, 0xb61: 0x00c0, 0xb62: 0x00c3, 0xb63: 0x00c3, + 0xb66: 0x00c0, 0xb67: 0x00c0, 0xb68: 0x00c0, 0xb69: 0x00c0, + 0xb6a: 0x00c0, 0xb6b: 0x00c0, 0xb6c: 0x00c0, 0xb6d: 0x00c0, 0xb6e: 0x00c0, 0xb6f: 0x00c0, + 0xb77: 0x0080, 0xb78: 0x0080, 0xb79: 0x0080, 0xb7a: 0x0080, 0xb7b: 0x0080, + 0xb7c: 0x0080, 0xb7d: 0x0080, 0xb7e: 0x0080, 0xb7f: 0x0080, + // Block 0x2e, offset 0xb80 + 0xb80: 0x00c0, 0xb81: 0x00c3, 0xb82: 0x00c0, 0xb83: 0x00c0, 0xb84: 0x0080, 0xb85: 0x00c0, + 0xb86: 0x00c0, 0xb87: 0x00c0, 0xb88: 0x00c0, 0xb89: 0x00c0, 0xb8a: 0x00c0, 0xb8b: 0x00c0, + 0xb8c: 0x00c0, 0xb8e: 0x00c0, 0xb8f: 0x00c0, 0xb90: 0x00c0, + 0xb92: 0x00c0, 0xb93: 0x00c0, 0xb94: 0x00c0, 0xb95: 0x00c0, 0xb96: 0x00c0, 0xb97: 0x00c0, + 0xb98: 0x00c0, 0xb99: 0x00c0, 0xb9a: 0x00c0, 0xb9b: 0x00c0, 0xb9c: 0x00c0, 0xb9d: 0x00c0, + 0xb9e: 0x00c0, 0xb9f: 0x00c0, 0xba0: 0x00c0, 0xba1: 0x00c0, 0xba2: 0x00c0, 0xba3: 0x00c0, + 0xba4: 0x00c0, 0xba5: 0x00c0, 0xba6: 0x00c0, 0xba7: 0x00c0, 0xba8: 0x00c0, + 0xbaa: 0x00c0, 0xbab: 0x00c0, 0xbac: 0x00c0, 0xbad: 0x00c0, 0xbae: 0x00c0, 0xbaf: 0x00c0, + 0xbb0: 0x00c0, 0xbb1: 0x00c0, 0xbb2: 0x00c0, 0xbb3: 0x00c0, 0xbb5: 0x00c0, + 0xbb6: 0x00c0, 0xbb7: 0x00c0, 0xbb8: 0x00c0, 0xbb9: 0x00c0, + 0xbbc: 0x00c3, 0xbbd: 0x00c0, 0xbbe: 0x00c0, 0xbbf: 0x00c3, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x00c0, 0xbc1: 0x00c0, 0xbc2: 0x00c0, 0xbc3: 0x00c0, 0xbc4: 0x00c0, + 0xbc6: 0x00c3, 0xbc7: 0x00c0, 0xbc8: 0x00c0, 0xbca: 0x00c0, 0xbcb: 0x00c0, + 0xbcc: 0x00c3, 0xbcd: 0x00c6, + 0xbd5: 0x00c0, 0xbd6: 0x00c0, + 0xbde: 0x00c0, 0xbe0: 0x00c0, 0xbe1: 0x00c0, 0xbe2: 0x00c3, 0xbe3: 0x00c3, + 0xbe6: 0x00c0, 0xbe7: 0x00c0, 0xbe8: 0x00c0, 0xbe9: 0x00c0, + 0xbea: 0x00c0, 0xbeb: 0x00c0, 0xbec: 0x00c0, 0xbed: 0x00c0, 0xbee: 0x00c0, 0xbef: 0x00c0, + 0xbf1: 0x00c0, 0xbf2: 0x00c0, + // Block 0x30, offset 0xc00 + 0xc00: 0x00c3, 0xc01: 0x00c3, 0xc02: 0x00c0, 0xc03: 0x00c0, 0xc04: 0x00c0, 0xc05: 0x00c0, + 0xc06: 0x00c0, 0xc07: 0x00c0, 0xc08: 0x00c0, 0xc09: 0x00c0, 0xc0a: 0x00c0, 0xc0b: 0x00c0, + 0xc0c: 0x00c0, 0xc0e: 0x00c0, 0xc0f: 0x00c0, 0xc10: 0x00c0, + 0xc12: 0x00c0, 0xc13: 0x00c0, 0xc14: 0x00c0, 0xc15: 0x00c0, 0xc16: 0x00c0, 0xc17: 0x00c0, + 0xc18: 0x00c0, 0xc19: 0x00c0, 0xc1a: 0x00c0, 0xc1b: 0x00c0, 0xc1c: 0x00c0, 0xc1d: 0x00c0, + 0xc1e: 0x00c0, 0xc1f: 0x00c0, 0xc20: 0x00c0, 0xc21: 0x00c0, 0xc22: 0x00c0, 0xc23: 0x00c0, + 0xc24: 0x00c0, 0xc25: 0x00c0, 0xc26: 0x00c0, 0xc27: 0x00c0, 0xc28: 0x00c0, 0xc29: 0x00c0, + 0xc2a: 0x00c0, 0xc2b: 0x00c0, 0xc2c: 0x00c0, 0xc2d: 0x00c0, 0xc2e: 0x00c0, 0xc2f: 0x00c0, + 0xc30: 0x00c0, 0xc31: 0x00c0, 0xc32: 0x00c0, 0xc33: 0x00c0, 0xc34: 0x00c0, 0xc35: 0x00c0, + 0xc36: 0x00c0, 0xc37: 0x00c0, 0xc38: 0x00c0, 0xc39: 0x00c0, 0xc3a: 0x00c0, 0xc3b: 0x00c6, + 0xc3c: 0x00c6, 0xc3d: 0x00c0, 0xc3e: 0x00c0, 0xc3f: 0x00c0, + // Block 0x31, offset 0xc40 + 0xc40: 0x00c0, 0xc41: 0x00c3, 0xc42: 0x00c3, 0xc43: 0x00c3, 0xc44: 0x00c3, + 0xc46: 0x00c0, 0xc47: 0x00c0, 0xc48: 0x00c0, 0xc4a: 0x00c0, 0xc4b: 0x00c0, + 0xc4c: 0x00c0, 0xc4d: 0x00c6, 0xc4e: 0x00c0, 0xc4f: 0x0080, + 0xc54: 0x00c0, 0xc55: 0x00c0, 0xc56: 0x00c0, 0xc57: 0x00c0, + 0xc58: 0x0080, 0xc59: 0x0080, 0xc5a: 0x0080, 0xc5b: 0x0080, 0xc5c: 0x0080, 0xc5d: 0x0080, + 0xc5e: 0x0080, 0xc5f: 0x00c0, 0xc60: 0x00c0, 0xc61: 0x00c0, 0xc62: 0x00c3, 0xc63: 0x00c3, + 0xc66: 0x00c0, 0xc67: 0x00c0, 0xc68: 0x00c0, 0xc69: 0x00c0, + 0xc6a: 0x00c0, 0xc6b: 0x00c0, 0xc6c: 0x00c0, 0xc6d: 0x00c0, 0xc6e: 0x00c0, 0xc6f: 0x00c0, + 0xc70: 0x0080, 0xc71: 0x0080, 0xc72: 0x0080, 0xc73: 0x0080, 0xc74: 0x0080, 0xc75: 0x0080, + 0xc76: 0x0080, 0xc77: 0x0080, 0xc78: 0x0080, 0xc79: 0x0080, 0xc7a: 0x00c0, 0xc7b: 0x00c0, + 0xc7c: 0x00c0, 0xc7d: 0x00c0, 0xc7e: 0x00c0, 0xc7f: 0x00c0, + // Block 0x32, offset 0xc80 + 0xc81: 0x00c3, 0xc82: 0x00c0, 0xc83: 0x00c0, 0xc85: 0x00c0, + 0xc86: 0x00c0, 0xc87: 0x00c0, 0xc88: 0x00c0, 0xc89: 0x00c0, 0xc8a: 0x00c0, 0xc8b: 0x00c0, + 0xc8c: 0x00c0, 0xc8d: 0x00c0, 0xc8e: 0x00c0, 0xc8f: 0x00c0, 0xc90: 0x00c0, 0xc91: 0x00c0, + 0xc92: 0x00c0, 0xc93: 0x00c0, 0xc94: 0x00c0, 0xc95: 0x00c0, 0xc96: 0x00c0, + 0xc9a: 0x00c0, 0xc9b: 0x00c0, 0xc9c: 0x00c0, 0xc9d: 0x00c0, + 0xc9e: 0x00c0, 0xc9f: 0x00c0, 0xca0: 0x00c0, 0xca1: 0x00c0, 0xca2: 0x00c0, 0xca3: 0x00c0, + 0xca4: 0x00c0, 0xca5: 0x00c0, 0xca6: 0x00c0, 0xca7: 0x00c0, 0xca8: 0x00c0, 0xca9: 0x00c0, + 0xcaa: 0x00c0, 0xcab: 0x00c0, 0xcac: 0x00c0, 0xcad: 0x00c0, 0xcae: 0x00c0, 0xcaf: 0x00c0, + 0xcb0: 0x00c0, 0xcb1: 0x00c0, 0xcb3: 0x00c0, 0xcb4: 0x00c0, 0xcb5: 0x00c0, + 0xcb6: 0x00c0, 0xcb7: 0x00c0, 0xcb8: 0x00c0, 0xcb9: 0x00c0, 0xcba: 0x00c0, 0xcbb: 0x00c0, + 0xcbd: 0x00c0, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x00c0, 0xcc1: 0x00c0, 0xcc2: 0x00c0, 0xcc3: 0x00c0, 0xcc4: 0x00c0, 0xcc5: 0x00c0, + 0xcc6: 0x00c0, 0xcca: 0x00c6, + 0xccf: 0x00c0, 0xcd0: 0x00c0, 0xcd1: 0x00c0, + 0xcd2: 0x00c3, 0xcd3: 0x00c3, 0xcd4: 0x00c3, 0xcd6: 0x00c3, + 0xcd8: 0x00c0, 0xcd9: 0x00c0, 0xcda: 0x00c0, 0xcdb: 0x00c0, 0xcdc: 0x00c0, 0xcdd: 0x00c0, + 0xcde: 0x00c0, 0xcdf: 0x00c0, + 0xce6: 0x00c0, 0xce7: 0x00c0, 0xce8: 0x00c0, 0xce9: 0x00c0, + 0xcea: 0x00c0, 0xceb: 0x00c0, 0xcec: 0x00c0, 0xced: 0x00c0, 0xcee: 0x00c0, 0xcef: 0x00c0, + 0xcf2: 0x00c0, 0xcf3: 0x00c0, 0xcf4: 0x0080, + // Block 0x34, offset 0xd00 + 0xd01: 0x00c0, 0xd02: 0x00c0, 0xd03: 0x00c0, 0xd04: 0x00c0, 0xd05: 0x00c0, + 0xd06: 0x00c0, 0xd07: 0x00c0, 0xd08: 0x00c0, 0xd09: 0x00c0, 0xd0a: 0x00c0, 0xd0b: 0x00c0, + 0xd0c: 0x00c0, 0xd0d: 0x00c0, 0xd0e: 0x00c0, 0xd0f: 0x00c0, 0xd10: 0x00c0, 0xd11: 0x00c0, + 0xd12: 0x00c0, 0xd13: 0x00c0, 0xd14: 0x00c0, 0xd15: 0x00c0, 0xd16: 0x00c0, 0xd17: 0x00c0, + 0xd18: 0x00c0, 0xd19: 0x00c0, 0xd1a: 0x00c0, 0xd1b: 0x00c0, 0xd1c: 0x00c0, 0xd1d: 0x00c0, + 0xd1e: 0x00c0, 0xd1f: 0x00c0, 0xd20: 0x00c0, 0xd21: 0x00c0, 0xd22: 0x00c0, 0xd23: 0x00c0, + 0xd24: 0x00c0, 0xd25: 0x00c0, 0xd26: 0x00c0, 0xd27: 0x00c0, 0xd28: 0x00c0, 0xd29: 0x00c0, + 0xd2a: 0x00c0, 0xd2b: 0x00c0, 0xd2c: 0x00c0, 0xd2d: 0x00c0, 0xd2e: 0x00c0, 0xd2f: 0x00c0, + 0xd30: 0x00c0, 0xd31: 0x00c3, 0xd32: 0x00c0, 0xd33: 0x0080, 0xd34: 0x00c3, 0xd35: 0x00c3, + 0xd36: 0x00c3, 0xd37: 0x00c3, 0xd38: 0x00c3, 0xd39: 0x00c3, 0xd3a: 0x00c6, + 0xd3f: 0x0080, + // Block 0x35, offset 0xd40 + 0xd40: 0x00c0, 0xd41: 0x00c0, 0xd42: 0x00c0, 0xd43: 0x00c0, 0xd44: 0x00c0, 0xd45: 0x00c0, + 0xd46: 0x00c0, 0xd47: 0x00c3, 0xd48: 0x00c3, 0xd49: 0x00c3, 0xd4a: 0x00c3, 0xd4b: 0x00c3, + 0xd4c: 0x00c3, 0xd4d: 0x00c3, 0xd4e: 0x00c3, 0xd4f: 0x0080, 0xd50: 0x00c0, 0xd51: 0x00c0, + 0xd52: 0x00c0, 0xd53: 0x00c0, 0xd54: 0x00c0, 0xd55: 0x00c0, 0xd56: 0x00c0, 0xd57: 0x00c0, + 0xd58: 0x00c0, 0xd59: 0x00c0, 0xd5a: 0x0080, 0xd5b: 0x0080, + // Block 0x36, offset 0xd80 + 0xd81: 0x00c0, 0xd82: 0x00c0, 0xd84: 0x00c0, + 0xd86: 0x00c0, 0xd87: 0x00c0, 0xd88: 0x00c0, 0xd89: 0x00c0, 0xd8a: 0x00c0, + 0xd8c: 0x00c0, 0xd8d: 0x00c0, 0xd8e: 0x00c0, 0xd8f: 0x00c0, 0xd90: 0x00c0, 0xd91: 0x00c0, + 0xd92: 0x00c0, 0xd93: 0x00c0, 0xd94: 0x00c0, 0xd95: 0x00c0, 0xd96: 0x00c0, 0xd97: 0x00c0, + 0xd98: 0x00c0, 0xd99: 0x00c0, 0xd9a: 0x00c0, 0xd9b: 0x00c0, 0xd9c: 0x00c0, 0xd9d: 0x00c0, + 0xd9e: 0x00c0, 0xd9f: 0x00c0, 0xda0: 0x00c0, 0xda1: 0x00c0, 0xda2: 0x00c0, 0xda3: 0x00c0, + 0xda5: 0x00c0, 0xda7: 0x00c0, 0xda8: 0x00c0, 0xda9: 0x00c0, + 0xdaa: 0x00c0, 0xdab: 0x00c0, 0xdac: 0x00c0, 0xdad: 0x00c0, 0xdae: 0x00c0, 0xdaf: 0x00c0, + 0xdb0: 0x00c0, 0xdb1: 0x00c3, 0xdb2: 0x00c0, 0xdb3: 0x0080, 0xdb4: 0x00c3, 0xdb5: 0x00c3, + 0xdb6: 0x00c3, 0xdb7: 0x00c3, 0xdb8: 0x00c3, 0xdb9: 0x00c3, 0xdba: 0x00c6, 0xdbb: 0x00c3, + 0xdbc: 0x00c3, 0xdbd: 0x00c0, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x00c0, 0xdc1: 0x00c0, 0xdc2: 0x00c0, 0xdc3: 0x00c0, 0xdc4: 0x00c0, + 0xdc6: 0x00c0, 0xdc8: 0x00c3, 0xdc9: 0x00c3, 0xdca: 0x00c3, 0xdcb: 0x00c3, + 0xdcc: 0x00c3, 0xdcd: 0x00c3, 0xdd0: 0x00c0, 0xdd1: 0x00c0, + 0xdd2: 0x00c0, 0xdd3: 0x00c0, 0xdd4: 0x00c0, 0xdd5: 0x00c0, 0xdd6: 0x00c0, 0xdd7: 0x00c0, + 0xdd8: 0x00c0, 0xdd9: 0x00c0, 0xddc: 0x0080, 0xddd: 0x0080, + 0xdde: 0x00c0, 0xddf: 0x00c0, + // Block 0x38, offset 0xe00 + 0xe00: 0x00c0, 0xe01: 0x0080, 0xe02: 0x0080, 0xe03: 0x0080, 0xe04: 0x0080, 0xe05: 0x0080, + 0xe06: 0x0080, 0xe07: 0x0080, 0xe08: 0x0080, 0xe09: 0x0080, 0xe0a: 0x0080, 0xe0b: 0x00c0, + 0xe0c: 0x0080, 0xe0d: 0x0080, 0xe0e: 0x0080, 0xe0f: 0x0080, 0xe10: 0x0080, 0xe11: 0x0080, + 0xe12: 0x0080, 0xe13: 0x0080, 0xe14: 0x0080, 0xe15: 0x0080, 0xe16: 0x0080, 0xe17: 0x0080, + 0xe18: 0x00c3, 0xe19: 0x00c3, 0xe1a: 0x0080, 0xe1b: 0x0080, 0xe1c: 0x0080, 0xe1d: 0x0080, + 0xe1e: 0x0080, 0xe1f: 0x0080, 0xe20: 0x00c0, 0xe21: 0x00c0, 0xe22: 0x00c0, 0xe23: 0x00c0, + 0xe24: 0x00c0, 0xe25: 0x00c0, 0xe26: 0x00c0, 0xe27: 0x00c0, 0xe28: 0x00c0, 0xe29: 0x00c0, + 0xe2a: 0x0080, 0xe2b: 0x0080, 0xe2c: 0x0080, 0xe2d: 0x0080, 0xe2e: 0x0080, 0xe2f: 0x0080, + 0xe30: 0x0080, 0xe31: 0x0080, 0xe32: 0x0080, 0xe33: 0x0080, 0xe34: 0x0080, 0xe35: 0x00c3, + 0xe36: 0x0080, 0xe37: 0x00c3, 0xe38: 0x0080, 0xe39: 0x00c3, 0xe3a: 0x0080, 0xe3b: 0x0080, + 0xe3c: 0x0080, 0xe3d: 0x0080, 0xe3e: 0x00c0, 0xe3f: 0x00c0, + // Block 0x39, offset 0xe40 + 0xe40: 0x00c0, 0xe41: 0x00c0, 0xe42: 0x00c0, 0xe43: 0x0080, 0xe44: 0x00c0, 0xe45: 0x00c0, + 0xe46: 0x00c0, 0xe47: 0x00c0, 0xe49: 0x00c0, 0xe4a: 0x00c0, 0xe4b: 0x00c0, + 0xe4c: 0x00c0, 0xe4d: 0x0080, 0xe4e: 0x00c0, 0xe4f: 0x00c0, 0xe50: 0x00c0, 0xe51: 0x00c0, + 0xe52: 0x0080, 0xe53: 0x00c0, 0xe54: 0x00c0, 0xe55: 0x00c0, 0xe56: 0x00c0, 0xe57: 0x0080, + 0xe58: 0x00c0, 0xe59: 0x00c0, 0xe5a: 0x00c0, 0xe5b: 0x00c0, 0xe5c: 0x0080, 0xe5d: 0x00c0, + 0xe5e: 0x00c0, 0xe5f: 0x00c0, 0xe60: 0x00c0, 0xe61: 0x00c0, 0xe62: 0x00c0, 0xe63: 0x00c0, + 0xe64: 0x00c0, 0xe65: 0x00c0, 0xe66: 0x00c0, 0xe67: 0x00c0, 0xe68: 0x00c0, 0xe69: 0x0080, + 0xe6a: 0x00c0, 0xe6b: 0x00c0, 0xe6c: 0x00c0, + 0xe71: 0x00c3, 0xe72: 0x00c3, 0xe73: 0x0083, 0xe74: 0x00c3, 0xe75: 0x0083, + 0xe76: 0x0083, 0xe77: 0x0083, 0xe78: 0x0083, 0xe79: 0x0083, 0xe7a: 0x00c3, 0xe7b: 0x00c3, + 0xe7c: 0x00c3, 0xe7d: 0x00c3, 0xe7e: 0x00c3, 0xe7f: 0x00c0, + // Block 0x3a, offset 0xe80 + 0xe80: 0x00c3, 0xe81: 0x0083, 0xe82: 0x00c3, 0xe83: 0x00c3, 0xe84: 0x00c6, 0xe85: 0x0080, + 0xe86: 0x00c3, 0xe87: 0x00c3, 0xe88: 0x00c0, 0xe89: 0x00c0, 0xe8a: 0x00c0, 0xe8b: 0x00c0, + 0xe8c: 0x00c0, 0xe8d: 0x00c3, 0xe8e: 0x00c3, 0xe8f: 0x00c3, 0xe90: 0x00c3, 0xe91: 0x00c3, + 0xe92: 0x00c3, 0xe93: 0x0083, 0xe94: 0x00c3, 0xe95: 0x00c3, 0xe96: 0x00c3, 0xe97: 0x00c3, + 0xe99: 0x00c3, 0xe9a: 0x00c3, 0xe9b: 0x00c3, 0xe9c: 0x00c3, 0xe9d: 0x0083, + 0xe9e: 0x00c3, 0xe9f: 0x00c3, 0xea0: 0x00c3, 0xea1: 0x00c3, 0xea2: 0x0083, 0xea3: 0x00c3, + 0xea4: 0x00c3, 0xea5: 0x00c3, 0xea6: 0x00c3, 0xea7: 0x0083, 0xea8: 0x00c3, 0xea9: 0x00c3, + 0xeaa: 0x00c3, 0xeab: 0x00c3, 0xeac: 0x0083, 0xead: 0x00c3, 0xeae: 0x00c3, 0xeaf: 0x00c3, + 0xeb0: 0x00c3, 0xeb1: 0x00c3, 0xeb2: 0x00c3, 0xeb3: 0x00c3, 0xeb4: 0x00c3, 0xeb5: 0x00c3, + 0xeb6: 0x00c3, 0xeb7: 0x00c3, 0xeb8: 0x00c3, 0xeb9: 0x0083, 0xeba: 0x00c3, 0xebb: 0x00c3, + 0xebc: 0x00c3, 0xebe: 0x0080, 0xebf: 0x0080, + // Block 0x3b, offset 0xec0 + 0xec0: 0x0080, 0xec1: 0x0080, 0xec2: 0x0080, 0xec3: 0x0080, 0xec4: 0x0080, 0xec5: 0x0080, + 0xec6: 0x00c3, 0xec7: 0x0080, 0xec8: 0x0080, 0xec9: 0x0080, 0xeca: 0x0080, 0xecb: 0x0080, + 0xecc: 0x0080, 0xece: 0x0080, 0xecf: 0x0080, 0xed0: 0x0080, 0xed1: 0x0080, + 0xed2: 0x0080, 0xed3: 0x0080, 0xed4: 0x0080, 0xed5: 0x0080, 0xed6: 0x0080, 0xed7: 0x0080, + 0xed8: 0x0080, 0xed9: 0x0080, 0xeda: 0x0080, + // Block 0x3c, offset 0xf00 + 0xf00: 0x00c0, 0xf01: 0x00c0, 0xf02: 0x00c0, 0xf03: 0x00c0, 0xf04: 0x00c0, 0xf05: 0x00c0, + 0xf06: 0x00c0, 0xf07: 0x00c0, 0xf08: 0x00c0, 0xf09: 0x00c0, 0xf0a: 0x00c0, 0xf0b: 0x00c0, + 0xf0c: 0x00c0, 0xf0d: 0x00c0, 0xf0e: 0x00c0, 0xf0f: 0x00c0, 0xf10: 0x00c0, 0xf11: 0x00c0, + 0xf12: 0x00c0, 0xf13: 0x00c0, 0xf14: 0x00c0, 0xf15: 0x00c0, 0xf16: 0x00c0, 0xf17: 0x00c0, + 0xf18: 0x00c0, 0xf19: 0x00c0, 0xf1a: 0x00c0, 0xf1b: 0x00c0, 0xf1c: 0x00c0, 0xf1d: 0x00c0, + 0xf1e: 0x00c0, 0xf1f: 0x00c0, 0xf20: 0x00c0, 0xf21: 0x00c0, 0xf22: 0x00c0, 0xf23: 0x00c0, + 0xf24: 0x00c0, 0xf25: 0x00c0, 0xf26: 0x00c0, 0xf27: 0x00c0, 0xf28: 0x00c0, 0xf29: 0x00c0, + 0xf2a: 0x00c0, 0xf2b: 0x00c0, 0xf2c: 0x00c0, 0xf2d: 0x00c3, 0xf2e: 0x00c3, 0xf2f: 0x00c3, + 0xf30: 0x00c3, 0xf31: 0x00c0, 0xf32: 0x00c3, 0xf33: 0x00c3, 0xf34: 0x00c3, 0xf35: 0x00c3, + 0xf36: 0x00c3, 0xf37: 0x00c3, 0xf38: 0x00c0, 0xf39: 0x00c6, 0xf3a: 0x00c6, 0xf3b: 0x00c0, + 0xf3c: 0x00c0, 0xf3d: 0x00c3, 0xf3e: 0x00c3, 0xf3f: 0x00c0, + // Block 0x3d, offset 0xf40 + 0xf40: 0x00c0, 0xf41: 0x00c0, 0xf42: 0x00c0, 0xf43: 0x00c0, 0xf44: 0x00c0, 0xf45: 0x00c0, + 0xf46: 0x00c0, 0xf47: 0x00c0, 0xf48: 0x00c0, 0xf49: 0x00c0, 0xf4a: 0x0080, 0xf4b: 0x0080, + 0xf4c: 0x0080, 0xf4d: 0x0080, 0xf4e: 0x0080, 0xf4f: 0x0080, 0xf50: 0x00c0, 0xf51: 0x00c0, + 0xf52: 0x00c0, 0xf53: 0x00c0, 0xf54: 0x00c0, 0xf55: 0x00c0, 0xf56: 0x00c0, 0xf57: 0x00c0, + 0xf58: 0x00c3, 0xf59: 0x00c3, 0xf5a: 0x00c0, 0xf5b: 0x00c0, 0xf5c: 0x00c0, 0xf5d: 0x00c0, + 0xf5e: 0x00c3, 0xf5f: 0x00c3, 0xf60: 0x00c3, 0xf61: 0x00c0, 0xf62: 0x00c0, 0xf63: 0x00c0, + 0xf64: 0x00c0, 0xf65: 0x00c0, 0xf66: 0x00c0, 0xf67: 0x00c0, 0xf68: 0x00c0, 0xf69: 0x00c0, + 0xf6a: 0x00c0, 0xf6b: 0x00c0, 0xf6c: 0x00c0, 0xf6d: 0x00c0, 0xf6e: 0x00c0, 0xf6f: 0x00c0, + 0xf70: 0x00c0, 0xf71: 0x00c3, 0xf72: 0x00c3, 0xf73: 0x00c3, 0xf74: 0x00c3, 0xf75: 0x00c0, + 0xf76: 0x00c0, 0xf77: 0x00c0, 0xf78: 0x00c0, 0xf79: 0x00c0, 0xf7a: 0x00c0, 0xf7b: 0x00c0, + 0xf7c: 0x00c0, 0xf7d: 0x00c0, 0xf7e: 0x00c0, 0xf7f: 0x00c0, + // Block 0x3e, offset 0xf80 + 0xf80: 0x00c0, 0xf81: 0x00c0, 0xf82: 0x00c3, 0xf83: 0x00c0, 0xf84: 0x00c0, 0xf85: 0x00c3, + 0xf86: 0x00c3, 0xf87: 0x00c0, 0xf88: 0x00c0, 0xf89: 0x00c0, 0xf8a: 0x00c0, 0xf8b: 0x00c0, + 0xf8c: 0x00c0, 0xf8d: 0x00c3, 0xf8e: 0x00c0, 0xf8f: 0x00c0, 0xf90: 0x00c0, 0xf91: 0x00c0, + 0xf92: 0x00c0, 0xf93: 0x00c0, 0xf94: 0x00c0, 0xf95: 0x00c0, 0xf96: 0x00c0, 0xf97: 0x00c0, + 0xf98: 0x00c0, 0xf99: 0x00c0, 0xf9a: 0x00c0, 0xf9b: 0x00c0, 0xf9c: 0x00c0, 0xf9d: 0x00c3, + 0xf9e: 0x0080, 0xf9f: 0x0080, 0xfa0: 0x00c0, 0xfa1: 0x00c0, 0xfa2: 0x00c0, 0xfa3: 0x00c0, + 0xfa4: 0x00c0, 0xfa5: 0x00c0, 0xfa6: 0x00c0, 0xfa7: 0x00c0, 0xfa8: 0x00c0, 0xfa9: 0x00c0, + 0xfaa: 0x00c0, 0xfab: 0x00c0, 0xfac: 0x00c0, 0xfad: 0x00c0, 0xfae: 0x00c0, 0xfaf: 0x00c0, + 0xfb0: 0x00c0, 0xfb1: 0x00c0, 0xfb2: 0x00c0, 0xfb3: 0x00c0, 0xfb4: 0x00c0, 0xfb5: 0x00c0, + 0xfb6: 0x00c0, 0xfb7: 0x00c0, 0xfb8: 0x00c0, 0xfb9: 0x00c0, 0xfba: 0x00c0, 0xfbb: 0x00c0, + 0xfbc: 0x00c0, 0xfbd: 0x00c0, 0xfbe: 0x00c0, 0xfbf: 0x00c0, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x00c0, 0xfc1: 0x00c0, 0xfc2: 0x00c0, 0xfc3: 0x00c0, 0xfc4: 0x00c0, 0xfc5: 0x00c0, + 0xfc7: 0x00c0, + 0xfcd: 0x00c0, 0xfd0: 0x00c0, 0xfd1: 0x00c0, + 0xfd2: 0x00c0, 0xfd3: 0x00c0, 0xfd4: 0x00c0, 0xfd5: 0x00c0, 0xfd6: 0x00c0, 0xfd7: 0x00c0, + 0xfd8: 0x00c0, 0xfd9: 0x00c0, 0xfda: 0x00c0, 0xfdb: 0x00c0, 0xfdc: 0x00c0, 0xfdd: 0x00c0, + 0xfde: 0x00c0, 0xfdf: 0x00c0, 0xfe0: 0x00c0, 0xfe1: 0x00c0, 0xfe2: 0x00c0, 0xfe3: 0x00c0, + 0xfe4: 0x00c0, 0xfe5: 0x00c0, 0xfe6: 0x00c0, 0xfe7: 0x00c0, 0xfe8: 0x00c0, 0xfe9: 0x00c0, + 0xfea: 0x00c0, 0xfeb: 0x00c0, 0xfec: 0x00c0, 0xfed: 0x00c0, 0xfee: 0x00c0, 0xfef: 0x00c0, + 0xff0: 0x00c0, 0xff1: 0x00c0, 0xff2: 0x00c0, 0xff3: 0x00c0, 0xff4: 0x00c0, 0xff5: 0x00c0, + 0xff6: 0x00c0, 0xff7: 0x00c0, 0xff8: 0x00c0, 0xff9: 0x00c0, 0xffa: 0x00c0, 0xffb: 0x0080, + 0xffc: 0x0080, 0xffd: 0x00c0, 0xffe: 0x00c0, 0xfff: 0x00c0, + // Block 0x40, offset 0x1000 + 0x1000: 0x0040, 0x1001: 0x0040, 0x1002: 0x0040, 0x1003: 0x0040, 0x1004: 0x0040, 0x1005: 0x0040, + 0x1006: 0x0040, 0x1007: 0x0040, 0x1008: 0x0040, 0x1009: 0x0040, 0x100a: 0x0040, 0x100b: 0x0040, + 0x100c: 0x0040, 0x100d: 0x0040, 0x100e: 0x0040, 0x100f: 0x0040, 0x1010: 0x0040, 0x1011: 0x0040, + 0x1012: 0x0040, 0x1013: 0x0040, 0x1014: 0x0040, 0x1015: 0x0040, 0x1016: 0x0040, 0x1017: 0x0040, + 0x1018: 0x0040, 0x1019: 0x0040, 0x101a: 0x0040, 0x101b: 0x0040, 0x101c: 0x0040, 0x101d: 0x0040, + 0x101e: 0x0040, 0x101f: 0x0040, 0x1020: 0x0040, 0x1021: 0x0040, 0x1022: 0x0040, 0x1023: 0x0040, + 0x1024: 0x0040, 0x1025: 0x0040, 0x1026: 0x0040, 0x1027: 0x0040, 0x1028: 0x0040, 0x1029: 0x0040, + 0x102a: 0x0040, 0x102b: 0x0040, 0x102c: 0x0040, 0x102d: 0x0040, 0x102e: 0x0040, 0x102f: 0x0040, + 0x1030: 0x0040, 0x1031: 0x0040, 0x1032: 0x0040, 0x1033: 0x0040, 0x1034: 0x0040, 0x1035: 0x0040, + 0x1036: 0x0040, 0x1037: 0x0040, 0x1038: 0x0040, 0x1039: 0x0040, 0x103a: 0x0040, 0x103b: 0x0040, + 0x103c: 0x0040, 0x103d: 0x0040, 0x103e: 0x0040, 0x103f: 0x0040, + // Block 0x41, offset 0x1040 + 0x1040: 0x00c0, 0x1041: 0x00c0, 0x1042: 0x00c0, 0x1043: 0x00c0, 0x1044: 0x00c0, 0x1045: 0x00c0, + 0x1046: 0x00c0, 0x1047: 0x00c0, 0x1048: 0x00c0, 0x104a: 0x00c0, 0x104b: 0x00c0, + 0x104c: 0x00c0, 0x104d: 0x00c0, 0x1050: 0x00c0, 0x1051: 0x00c0, + 0x1052: 0x00c0, 0x1053: 0x00c0, 0x1054: 0x00c0, 0x1055: 0x00c0, 0x1056: 0x00c0, + 0x1058: 0x00c0, 0x105a: 0x00c0, 0x105b: 0x00c0, 0x105c: 0x00c0, 0x105d: 0x00c0, + 0x1060: 0x00c0, 0x1061: 0x00c0, 0x1062: 0x00c0, 0x1063: 0x00c0, + 0x1064: 0x00c0, 0x1065: 0x00c0, 0x1066: 0x00c0, 0x1067: 0x00c0, 0x1068: 0x00c0, 0x1069: 0x00c0, + 0x106a: 0x00c0, 0x106b: 0x00c0, 0x106c: 0x00c0, 0x106d: 0x00c0, 0x106e: 0x00c0, 0x106f: 0x00c0, + 0x1070: 0x00c0, 0x1071: 0x00c0, 0x1072: 0x00c0, 0x1073: 0x00c0, 0x1074: 0x00c0, 0x1075: 0x00c0, + 0x1076: 0x00c0, 0x1077: 0x00c0, 0x1078: 0x00c0, 0x1079: 0x00c0, 0x107a: 0x00c0, 0x107b: 0x00c0, + 0x107c: 0x00c0, 0x107d: 0x00c0, 0x107e: 0x00c0, 0x107f: 0x00c0, + // Block 0x42, offset 0x1080 + 0x1080: 0x00c0, 0x1081: 0x00c0, 0x1082: 0x00c0, 0x1083: 0x00c0, 0x1084: 0x00c0, 0x1085: 0x00c0, + 0x1086: 0x00c0, 0x1087: 0x00c0, 0x1088: 0x00c0, 0x108a: 0x00c0, 0x108b: 0x00c0, + 0x108c: 0x00c0, 0x108d: 0x00c0, 0x1090: 0x00c0, 0x1091: 0x00c0, + 0x1092: 0x00c0, 0x1093: 0x00c0, 0x1094: 0x00c0, 0x1095: 0x00c0, 0x1096: 0x00c0, 0x1097: 0x00c0, + 0x1098: 0x00c0, 0x1099: 0x00c0, 0x109a: 0x00c0, 0x109b: 0x00c0, 0x109c: 0x00c0, 0x109d: 0x00c0, + 0x109e: 0x00c0, 0x109f: 0x00c0, 0x10a0: 0x00c0, 0x10a1: 0x00c0, 0x10a2: 0x00c0, 0x10a3: 0x00c0, + 0x10a4: 0x00c0, 0x10a5: 0x00c0, 0x10a6: 0x00c0, 0x10a7: 0x00c0, 0x10a8: 0x00c0, 0x10a9: 0x00c0, + 0x10aa: 0x00c0, 0x10ab: 0x00c0, 0x10ac: 0x00c0, 0x10ad: 0x00c0, 0x10ae: 0x00c0, 0x10af: 0x00c0, + 0x10b0: 0x00c0, 0x10b2: 0x00c0, 0x10b3: 0x00c0, 0x10b4: 0x00c0, 0x10b5: 0x00c0, + 0x10b8: 0x00c0, 0x10b9: 0x00c0, 0x10ba: 0x00c0, 0x10bb: 0x00c0, + 0x10bc: 0x00c0, 0x10bd: 0x00c0, 0x10be: 0x00c0, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x00c0, 0x10c2: 0x00c0, 0x10c3: 0x00c0, 0x10c4: 0x00c0, 0x10c5: 0x00c0, + 0x10c8: 0x00c0, 0x10c9: 0x00c0, 0x10ca: 0x00c0, 0x10cb: 0x00c0, + 0x10cc: 0x00c0, 0x10cd: 0x00c0, 0x10ce: 0x00c0, 0x10cf: 0x00c0, 0x10d0: 0x00c0, 0x10d1: 0x00c0, + 0x10d2: 0x00c0, 0x10d3: 0x00c0, 0x10d4: 0x00c0, 0x10d5: 0x00c0, 0x10d6: 0x00c0, + 0x10d8: 0x00c0, 0x10d9: 0x00c0, 0x10da: 0x00c0, 0x10db: 0x00c0, 0x10dc: 0x00c0, 0x10dd: 0x00c0, + 0x10de: 0x00c0, 0x10df: 0x00c0, 0x10e0: 0x00c0, 0x10e1: 0x00c0, 0x10e2: 0x00c0, 0x10e3: 0x00c0, + 0x10e4: 0x00c0, 0x10e5: 0x00c0, 0x10e6: 0x00c0, 0x10e7: 0x00c0, 0x10e8: 0x00c0, 0x10e9: 0x00c0, + 0x10ea: 0x00c0, 0x10eb: 0x00c0, 0x10ec: 0x00c0, 0x10ed: 0x00c0, 0x10ee: 0x00c0, 0x10ef: 0x00c0, + 0x10f0: 0x00c0, 0x10f1: 0x00c0, 0x10f2: 0x00c0, 0x10f3: 0x00c0, 0x10f4: 0x00c0, 0x10f5: 0x00c0, + 0x10f6: 0x00c0, 0x10f7: 0x00c0, 0x10f8: 0x00c0, 0x10f9: 0x00c0, 0x10fa: 0x00c0, 0x10fb: 0x00c0, + 0x10fc: 0x00c0, 0x10fd: 0x00c0, 0x10fe: 0x00c0, 0x10ff: 0x00c0, + // Block 0x44, offset 0x1100 + 0x1100: 0x00c0, 0x1101: 0x00c0, 0x1102: 0x00c0, 0x1103: 0x00c0, 0x1104: 0x00c0, 0x1105: 0x00c0, + 0x1106: 0x00c0, 0x1107: 0x00c0, 0x1108: 0x00c0, 0x1109: 0x00c0, 0x110a: 0x00c0, 0x110b: 0x00c0, + 0x110c: 0x00c0, 0x110d: 0x00c0, 0x110e: 0x00c0, 0x110f: 0x00c0, 0x1110: 0x00c0, + 0x1112: 0x00c0, 0x1113: 0x00c0, 0x1114: 0x00c0, 0x1115: 0x00c0, + 0x1118: 0x00c0, 0x1119: 0x00c0, 0x111a: 0x00c0, 0x111b: 0x00c0, 0x111c: 0x00c0, 0x111d: 0x00c0, + 0x111e: 0x00c0, 0x111f: 0x00c0, 0x1120: 0x00c0, 0x1121: 0x00c0, 0x1122: 0x00c0, 0x1123: 0x00c0, + 0x1124: 0x00c0, 0x1125: 0x00c0, 0x1126: 0x00c0, 0x1127: 0x00c0, 0x1128: 0x00c0, 0x1129: 0x00c0, + 0x112a: 0x00c0, 0x112b: 0x00c0, 0x112c: 0x00c0, 0x112d: 0x00c0, 0x112e: 0x00c0, 0x112f: 0x00c0, + 0x1130: 0x00c0, 0x1131: 0x00c0, 0x1132: 0x00c0, 0x1133: 0x00c0, 0x1134: 0x00c0, 0x1135: 0x00c0, + 0x1136: 0x00c0, 0x1137: 0x00c0, 0x1138: 0x00c0, 0x1139: 0x00c0, 0x113a: 0x00c0, 0x113b: 0x00c0, + 0x113c: 0x00c0, 0x113d: 0x00c0, 0x113e: 0x00c0, 0x113f: 0x00c0, + // Block 0x45, offset 0x1140 + 0x1140: 0x00c0, 0x1141: 0x00c0, 0x1142: 0x00c0, 0x1143: 0x00c0, 0x1144: 0x00c0, 0x1145: 0x00c0, + 0x1146: 0x00c0, 0x1147: 0x00c0, 0x1148: 0x00c0, 0x1149: 0x00c0, 0x114a: 0x00c0, 0x114b: 0x00c0, + 0x114c: 0x00c0, 0x114d: 0x00c0, 0x114e: 0x00c0, 0x114f: 0x00c0, 0x1150: 0x00c0, 0x1151: 0x00c0, + 0x1152: 0x00c0, 0x1153: 0x00c0, 0x1154: 0x00c0, 0x1155: 0x00c0, 0x1156: 0x00c0, 0x1157: 0x00c0, + 0x1158: 0x00c0, 0x1159: 0x00c0, 0x115a: 0x00c0, 0x115d: 0x00c3, + 0x115e: 0x00c3, 0x115f: 0x00c3, 0x1160: 0x0080, 0x1161: 0x0080, 0x1162: 0x0080, 0x1163: 0x0080, + 0x1164: 0x0080, 0x1165: 0x0080, 0x1166: 0x0080, 0x1167: 0x0080, 0x1168: 0x0080, 0x1169: 0x0080, + 0x116a: 0x0080, 0x116b: 0x0080, 0x116c: 0x0080, 0x116d: 0x0080, 0x116e: 0x0080, 0x116f: 0x0080, + 0x1170: 0x0080, 0x1171: 0x0080, 0x1172: 0x0080, 0x1173: 0x0080, 0x1174: 0x0080, 0x1175: 0x0080, + 0x1176: 0x0080, 0x1177: 0x0080, 0x1178: 0x0080, 0x1179: 0x0080, 0x117a: 0x0080, 0x117b: 0x0080, + 0x117c: 0x0080, + // Block 0x46, offset 0x1180 + 0x1180: 0x00c0, 0x1181: 0x00c0, 0x1182: 0x00c0, 0x1183: 0x00c0, 0x1184: 0x00c0, 0x1185: 0x00c0, + 0x1186: 0x00c0, 0x1187: 0x00c0, 0x1188: 0x00c0, 0x1189: 0x00c0, 0x118a: 0x00c0, 0x118b: 0x00c0, + 0x118c: 0x00c0, 0x118d: 0x00c0, 0x118e: 0x00c0, 0x118f: 0x00c0, 0x1190: 0x0080, 0x1191: 0x0080, + 0x1192: 0x0080, 0x1193: 0x0080, 0x1194: 0x0080, 0x1195: 0x0080, 0x1196: 0x0080, 0x1197: 0x0080, + 0x1198: 0x0080, 0x1199: 0x0080, + 0x11a0: 0x00c0, 0x11a1: 0x00c0, 0x11a2: 0x00c0, 0x11a3: 0x00c0, + 0x11a4: 0x00c0, 0x11a5: 0x00c0, 0x11a6: 0x00c0, 0x11a7: 0x00c0, 0x11a8: 0x00c0, 0x11a9: 0x00c0, + 0x11aa: 0x00c0, 0x11ab: 0x00c0, 0x11ac: 0x00c0, 0x11ad: 0x00c0, 0x11ae: 0x00c0, 0x11af: 0x00c0, + 0x11b0: 0x00c0, 0x11b1: 0x00c0, 0x11b2: 0x00c0, 0x11b3: 0x00c0, 0x11b4: 0x00c0, 0x11b5: 0x00c0, + 0x11b6: 0x00c0, 0x11b7: 0x00c0, 0x11b8: 0x00c0, 0x11b9: 0x00c0, 0x11ba: 0x00c0, 0x11bb: 0x00c0, + 0x11bc: 0x00c0, 0x11bd: 0x00c0, 0x11be: 0x00c0, 0x11bf: 0x00c0, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x00c0, 0x11c1: 0x00c0, 0x11c2: 0x00c0, 0x11c3: 0x00c0, 0x11c4: 0x00c0, 0x11c5: 0x00c0, + 0x11c6: 0x00c0, 0x11c7: 0x00c0, 0x11c8: 0x00c0, 0x11c9: 0x00c0, 0x11ca: 0x00c0, 0x11cb: 0x00c0, + 0x11cc: 0x00c0, 0x11cd: 0x00c0, 0x11ce: 0x00c0, 0x11cf: 0x00c0, 0x11d0: 0x00c0, 0x11d1: 0x00c0, + 0x11d2: 0x00c0, 0x11d3: 0x00c0, 0x11d4: 0x00c0, 0x11d5: 0x00c0, 0x11d6: 0x00c0, 0x11d7: 0x00c0, + 0x11d8: 0x00c0, 0x11d9: 0x00c0, 0x11da: 0x00c0, 0x11db: 0x00c0, 0x11dc: 0x00c0, 0x11dd: 0x00c0, + 0x11de: 0x00c0, 0x11df: 0x00c0, 0x11e0: 0x00c0, 0x11e1: 0x00c0, 0x11e2: 0x00c0, 0x11e3: 0x00c0, + 0x11e4: 0x00c0, 0x11e5: 0x00c0, 0x11e6: 0x00c0, 0x11e7: 0x00c0, 0x11e8: 0x00c0, 0x11e9: 0x00c0, + 0x11ea: 0x00c0, 0x11eb: 0x00c0, 0x11ec: 0x00c0, 0x11ed: 0x00c0, 0x11ee: 0x00c0, 0x11ef: 0x00c0, + 0x11f0: 0x00c0, 0x11f1: 0x00c0, 0x11f2: 0x00c0, 0x11f3: 0x00c0, 0x11f4: 0x00c0, 0x11f5: 0x00c0, + 0x11f8: 0x00c0, 0x11f9: 0x00c0, 0x11fa: 0x00c0, 0x11fb: 0x00c0, + 0x11fc: 0x00c0, 0x11fd: 0x00c0, + // Block 0x48, offset 0x1200 + 0x1200: 0x0080, 0x1201: 0x00c0, 0x1202: 0x00c0, 0x1203: 0x00c0, 0x1204: 0x00c0, 0x1205: 0x00c0, + 0x1206: 0x00c0, 0x1207: 0x00c0, 0x1208: 0x00c0, 0x1209: 0x00c0, 0x120a: 0x00c0, 0x120b: 0x00c0, + 0x120c: 0x00c0, 0x120d: 0x00c0, 0x120e: 0x00c0, 0x120f: 0x00c0, 0x1210: 0x00c0, 0x1211: 0x00c0, + 0x1212: 0x00c0, 0x1213: 0x00c0, 0x1214: 0x00c0, 0x1215: 0x00c0, 0x1216: 0x00c0, 0x1217: 0x00c0, + 0x1218: 0x00c0, 0x1219: 0x00c0, 0x121a: 0x00c0, 0x121b: 0x00c0, 0x121c: 0x00c0, 0x121d: 0x00c0, + 0x121e: 0x00c0, 0x121f: 0x00c0, 0x1220: 0x00c0, 0x1221: 0x00c0, 0x1222: 0x00c0, 0x1223: 0x00c0, + 0x1224: 0x00c0, 0x1225: 0x00c0, 0x1226: 0x00c0, 0x1227: 0x00c0, 0x1228: 0x00c0, 0x1229: 0x00c0, + 0x122a: 0x00c0, 0x122b: 0x00c0, 0x122c: 0x00c0, 0x122d: 0x00c0, 0x122e: 0x00c0, 0x122f: 0x00c0, + 0x1230: 0x00c0, 0x1231: 0x00c0, 0x1232: 0x00c0, 0x1233: 0x00c0, 0x1234: 0x00c0, 0x1235: 0x00c0, + 0x1236: 0x00c0, 0x1237: 0x00c0, 0x1238: 0x00c0, 0x1239: 0x00c0, 0x123a: 0x00c0, 0x123b: 0x00c0, + 0x123c: 0x00c0, 0x123d: 0x00c0, 0x123e: 0x00c0, 0x123f: 0x00c0, + // Block 0x49, offset 0x1240 + 0x1240: 0x00c0, 0x1241: 0x00c0, 0x1242: 0x00c0, 0x1243: 0x00c0, 0x1244: 0x00c0, 0x1245: 0x00c0, + 0x1246: 0x00c0, 0x1247: 0x00c0, 0x1248: 0x00c0, 0x1249: 0x00c0, 0x124a: 0x00c0, 0x124b: 0x00c0, + 0x124c: 0x00c0, 0x124d: 0x00c0, 0x124e: 0x00c0, 0x124f: 0x00c0, 0x1250: 0x00c0, 0x1251: 0x00c0, + 0x1252: 0x00c0, 0x1253: 0x00c0, 0x1254: 0x00c0, 0x1255: 0x00c0, 0x1256: 0x00c0, 0x1257: 0x00c0, + 0x1258: 0x00c0, 0x1259: 0x00c0, 0x125a: 0x00c0, 0x125b: 0x00c0, 0x125c: 0x00c0, 0x125d: 0x00c0, + 0x125e: 0x00c0, 0x125f: 0x00c0, 0x1260: 0x00c0, 0x1261: 0x00c0, 0x1262: 0x00c0, 0x1263: 0x00c0, + 0x1264: 0x00c0, 0x1265: 0x00c0, 0x1266: 0x00c0, 0x1267: 0x00c0, 0x1268: 0x00c0, 0x1269: 0x00c0, + 0x126a: 0x00c0, 0x126b: 0x00c0, 0x126c: 0x00c0, 0x126d: 0x0080, 0x126e: 0x0080, 0x126f: 0x00c0, + 0x1270: 0x00c0, 0x1271: 0x00c0, 0x1272: 0x00c0, 0x1273: 0x00c0, 0x1274: 0x00c0, 0x1275: 0x00c0, + 0x1276: 0x00c0, 0x1277: 0x00c0, 0x1278: 0x00c0, 0x1279: 0x00c0, 0x127a: 0x00c0, 0x127b: 0x00c0, + 0x127c: 0x00c0, 0x127d: 0x00c0, 0x127e: 0x00c0, 0x127f: 0x00c0, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0080, 0x1281: 0x00c0, 0x1282: 0x00c0, 0x1283: 0x00c0, 0x1284: 0x00c0, 0x1285: 0x00c0, + 0x1286: 0x00c0, 0x1287: 0x00c0, 0x1288: 0x00c0, 0x1289: 0x00c0, 0x128a: 0x00c0, 0x128b: 0x00c0, + 0x128c: 0x00c0, 0x128d: 0x00c0, 0x128e: 0x00c0, 0x128f: 0x00c0, 0x1290: 0x00c0, 0x1291: 0x00c0, + 0x1292: 0x00c0, 0x1293: 0x00c0, 0x1294: 0x00c0, 0x1295: 0x00c0, 0x1296: 0x00c0, 0x1297: 0x00c0, + 0x1298: 0x00c0, 0x1299: 0x00c0, 0x129a: 0x00c0, 0x129b: 0x0080, 0x129c: 0x0080, + 0x12a0: 0x00c0, 0x12a1: 0x00c0, 0x12a2: 0x00c0, 0x12a3: 0x00c0, + 0x12a4: 0x00c0, 0x12a5: 0x00c0, 0x12a6: 0x00c0, 0x12a7: 0x00c0, 0x12a8: 0x00c0, 0x12a9: 0x00c0, + 0x12aa: 0x00c0, 0x12ab: 0x00c0, 0x12ac: 0x00c0, 0x12ad: 0x00c0, 0x12ae: 0x00c0, 0x12af: 0x00c0, + 0x12b0: 0x00c0, 0x12b1: 0x00c0, 0x12b2: 0x00c0, 0x12b3: 0x00c0, 0x12b4: 0x00c0, 0x12b5: 0x00c0, + 0x12b6: 0x00c0, 0x12b7: 0x00c0, 0x12b8: 0x00c0, 0x12b9: 0x00c0, 0x12ba: 0x00c0, 0x12bb: 0x00c0, + 0x12bc: 0x00c0, 0x12bd: 0x00c0, 0x12be: 0x00c0, 0x12bf: 0x00c0, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x00c0, 0x12c1: 0x00c0, 0x12c2: 0x00c0, 0x12c3: 0x00c0, 0x12c4: 0x00c0, 0x12c5: 0x00c0, + 0x12c6: 0x00c0, 0x12c7: 0x00c0, 0x12c8: 0x00c0, 0x12c9: 0x00c0, 0x12ca: 0x00c0, 0x12cb: 0x00c0, + 0x12cc: 0x00c0, 0x12cd: 0x00c0, 0x12ce: 0x00c0, 0x12cf: 0x00c0, 0x12d0: 0x00c0, 0x12d1: 0x00c0, + 0x12d2: 0x00c0, 0x12d3: 0x00c0, 0x12d4: 0x00c0, 0x12d5: 0x00c0, 0x12d6: 0x00c0, 0x12d7: 0x00c0, + 0x12d8: 0x00c0, 0x12d9: 0x00c0, 0x12da: 0x00c0, 0x12db: 0x00c0, 0x12dc: 0x00c0, 0x12dd: 0x00c0, + 0x12de: 0x00c0, 0x12df: 0x00c0, 0x12e0: 0x00c0, 0x12e1: 0x00c0, 0x12e2: 0x00c0, 0x12e3: 0x00c0, + 0x12e4: 0x00c0, 0x12e5: 0x00c0, 0x12e6: 0x00c0, 0x12e7: 0x00c0, 0x12e8: 0x00c0, 0x12e9: 0x00c0, + 0x12ea: 0x00c0, 0x12eb: 0x0080, 0x12ec: 0x0080, 0x12ed: 0x0080, 0x12ee: 0x0080, 0x12ef: 0x0080, + 0x12f0: 0x0080, 0x12f1: 0x00c0, 0x12f2: 0x00c0, 0x12f3: 0x00c0, 0x12f4: 0x00c0, 0x12f5: 0x00c0, + 0x12f6: 0x00c0, 0x12f7: 0x00c0, 0x12f8: 0x00c0, + // Block 0x4c, offset 0x1300 + 0x1300: 0x00c0, 0x1301: 0x00c0, 0x1302: 0x00c0, 0x1303: 0x00c0, 0x1304: 0x00c0, 0x1305: 0x00c0, + 0x1306: 0x00c0, 0x1307: 0x00c0, 0x1308: 0x00c0, 0x1309: 0x00c0, 0x130a: 0x00c0, 0x130b: 0x00c0, + 0x130c: 0x00c0, 0x130e: 0x00c0, 0x130f: 0x00c0, 0x1310: 0x00c0, 0x1311: 0x00c0, + 0x1312: 0x00c3, 0x1313: 0x00c3, 0x1314: 0x00c6, + 0x1320: 0x00c0, 0x1321: 0x00c0, 0x1322: 0x00c0, 0x1323: 0x00c0, + 0x1324: 0x00c0, 0x1325: 0x00c0, 0x1326: 0x00c0, 0x1327: 0x00c0, 0x1328: 0x00c0, 0x1329: 0x00c0, + 0x132a: 0x00c0, 0x132b: 0x00c0, 0x132c: 0x00c0, 0x132d: 0x00c0, 0x132e: 0x00c0, 0x132f: 0x00c0, + 0x1330: 0x00c0, 0x1331: 0x00c0, 0x1332: 0x00c3, 0x1333: 0x00c3, 0x1334: 0x00c6, 0x1335: 0x0080, + 0x1336: 0x0080, + // Block 0x4d, offset 0x1340 + 0x1340: 0x00c0, 0x1341: 0x00c0, 0x1342: 0x00c0, 0x1343: 0x00c0, 0x1344: 0x00c0, 0x1345: 0x00c0, + 0x1346: 0x00c0, 0x1347: 0x00c0, 0x1348: 0x00c0, 0x1349: 0x00c0, 0x134a: 0x00c0, 0x134b: 0x00c0, + 0x134c: 0x00c0, 0x134d: 0x00c0, 0x134e: 0x00c0, 0x134f: 0x00c0, 0x1350: 0x00c0, 0x1351: 0x00c0, + 0x1352: 0x00c3, 0x1353: 0x00c3, + 0x1360: 0x00c0, 0x1361: 0x00c0, 0x1362: 0x00c0, 0x1363: 0x00c0, + 0x1364: 0x00c0, 0x1365: 0x00c0, 0x1366: 0x00c0, 0x1367: 0x00c0, 0x1368: 0x00c0, 0x1369: 0x00c0, + 0x136a: 0x00c0, 0x136b: 0x00c0, 0x136c: 0x00c0, 0x136e: 0x00c0, 0x136f: 0x00c0, + 0x1370: 0x00c0, 0x1372: 0x00c3, 0x1373: 0x00c3, + // Block 0x4e, offset 0x1380 + 0x1380: 0x00c0, 0x1381: 0x00c0, 0x1382: 0x00c0, 0x1383: 0x00c0, 0x1384: 0x00c0, 0x1385: 0x00c0, + 0x1386: 0x00c0, 0x1387: 0x00c0, 0x1388: 0x00c0, 0x1389: 0x00c0, 0x138a: 0x00c0, 0x138b: 0x00c0, + 0x138c: 0x00c0, 0x138d: 0x00c0, 0x138e: 0x00c0, 0x138f: 0x00c0, 0x1390: 0x00c0, 0x1391: 0x00c0, + 0x1392: 0x00c0, 0x1393: 0x00c0, 0x1394: 0x00c0, 0x1395: 0x00c0, 0x1396: 0x00c0, 0x1397: 0x00c0, + 0x1398: 0x00c0, 0x1399: 0x00c0, 0x139a: 0x00c0, 0x139b: 0x00c0, 0x139c: 0x00c0, 0x139d: 0x00c0, + 0x139e: 0x00c0, 0x139f: 0x00c0, 0x13a0: 0x00c0, 0x13a1: 0x00c0, 0x13a2: 0x00c0, 0x13a3: 0x00c0, + 0x13a4: 0x00c0, 0x13a5: 0x00c0, 0x13a6: 0x00c0, 0x13a7: 0x00c0, 0x13a8: 0x00c0, 0x13a9: 0x00c0, + 0x13aa: 0x00c0, 0x13ab: 0x00c0, 0x13ac: 0x00c0, 0x13ad: 0x00c0, 0x13ae: 0x00c0, 0x13af: 0x00c0, + 0x13b0: 0x00c0, 0x13b1: 0x00c0, 0x13b2: 0x00c0, 0x13b3: 0x00c0, 0x13b4: 0x0040, 0x13b5: 0x0040, + 0x13b6: 0x00c0, 0x13b7: 0x00c3, 0x13b8: 0x00c3, 0x13b9: 0x00c3, 0x13ba: 0x00c3, 0x13bb: 0x00c3, + 0x13bc: 0x00c3, 0x13bd: 0x00c3, 0x13be: 0x00c0, 0x13bf: 0x00c0, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x00c0, 0x13c1: 0x00c0, 0x13c2: 0x00c0, 0x13c3: 0x00c0, 0x13c4: 0x00c0, 0x13c5: 0x00c0, + 0x13c6: 0x00c3, 0x13c7: 0x00c0, 0x13c8: 0x00c0, 0x13c9: 0x00c3, 0x13ca: 0x00c3, 0x13cb: 0x00c3, + 0x13cc: 0x00c3, 0x13cd: 0x00c3, 0x13ce: 0x00c3, 0x13cf: 0x00c3, 0x13d0: 0x00c3, 0x13d1: 0x00c3, + 0x13d2: 0x00c6, 0x13d3: 0x00c3, 0x13d4: 0x0080, 0x13d5: 0x0080, 0x13d6: 0x0080, 0x13d7: 0x00c0, + 0x13d8: 0x0080, 0x13d9: 0x0080, 0x13da: 0x0080, 0x13db: 0x0080, 0x13dc: 0x00c0, 0x13dd: 0x00c3, + 0x13e0: 0x00c0, 0x13e1: 0x00c0, 0x13e2: 0x00c0, 0x13e3: 0x00c0, + 0x13e4: 0x00c0, 0x13e5: 0x00c0, 0x13e6: 0x00c0, 0x13e7: 0x00c0, 0x13e8: 0x00c0, 0x13e9: 0x00c0, + 0x13f0: 0x0080, 0x13f1: 0x0080, 0x13f2: 0x0080, 0x13f3: 0x0080, 0x13f4: 0x0080, 0x13f5: 0x0080, + 0x13f6: 0x0080, 0x13f7: 0x0080, 0x13f8: 0x0080, 0x13f9: 0x0080, + // Block 0x50, offset 0x1400 + 0x1400: 0x0080, 0x1401: 0x0080, 0x1402: 0x0080, 0x1403: 0x0080, 0x1404: 0x0080, 0x1405: 0x0080, + 0x1406: 0x0080, 0x1407: 0x0082, 0x1408: 0x0080, 0x1409: 0x0080, 0x140a: 0x0080, 0x140b: 0x0040, + 0x140c: 0x0040, 0x140d: 0x0040, 0x140e: 0x0040, 0x1410: 0x00c0, 0x1411: 0x00c0, + 0x1412: 0x00c0, 0x1413: 0x00c0, 0x1414: 0x00c0, 0x1415: 0x00c0, 0x1416: 0x00c0, 0x1417: 0x00c0, + 0x1418: 0x00c0, 0x1419: 0x00c0, + 0x1420: 0x00c2, 0x1421: 0x00c2, 0x1422: 0x00c2, 0x1423: 0x00c2, + 0x1424: 0x00c2, 0x1425: 0x00c2, 0x1426: 0x00c2, 0x1427: 0x00c2, 0x1428: 0x00c2, 0x1429: 0x00c2, + 0x142a: 0x00c2, 0x142b: 0x00c2, 0x142c: 0x00c2, 0x142d: 0x00c2, 0x142e: 0x00c2, 0x142f: 0x00c2, + 0x1430: 0x00c2, 0x1431: 0x00c2, 0x1432: 0x00c2, 0x1433: 0x00c2, 0x1434: 0x00c2, 0x1435: 0x00c2, + 0x1436: 0x00c2, 0x1437: 0x00c2, 0x1438: 0x00c2, 0x1439: 0x00c2, 0x143a: 0x00c2, 0x143b: 0x00c2, + 0x143c: 0x00c2, 0x143d: 0x00c2, 0x143e: 0x00c2, 0x143f: 0x00c2, + // Block 0x51, offset 0x1440 + 0x1440: 0x00c2, 0x1441: 0x00c2, 0x1442: 0x00c2, 0x1443: 0x00c2, 0x1444: 0x00c2, 0x1445: 0x00c2, + 0x1446: 0x00c2, 0x1447: 0x00c2, 0x1448: 0x00c2, 0x1449: 0x00c2, 0x144a: 0x00c2, 0x144b: 0x00c2, + 0x144c: 0x00c2, 0x144d: 0x00c2, 0x144e: 0x00c2, 0x144f: 0x00c2, 0x1450: 0x00c2, 0x1451: 0x00c2, + 0x1452: 0x00c2, 0x1453: 0x00c2, 0x1454: 0x00c2, 0x1455: 0x00c2, 0x1456: 0x00c2, 0x1457: 0x00c2, + 0x1458: 0x00c2, 0x1459: 0x00c2, 0x145a: 0x00c2, 0x145b: 0x00c2, 0x145c: 0x00c2, 0x145d: 0x00c2, + 0x145e: 0x00c2, 0x145f: 0x00c2, 0x1460: 0x00c2, 0x1461: 0x00c2, 0x1462: 0x00c2, 0x1463: 0x00c2, + 0x1464: 0x00c2, 0x1465: 0x00c2, 0x1466: 0x00c2, 0x1467: 0x00c2, 0x1468: 0x00c2, 0x1469: 0x00c2, + 0x146a: 0x00c2, 0x146b: 0x00c2, 0x146c: 0x00c2, 0x146d: 0x00c2, 0x146e: 0x00c2, 0x146f: 0x00c2, + 0x1470: 0x00c2, 0x1471: 0x00c2, 0x1472: 0x00c2, 0x1473: 0x00c2, 0x1474: 0x00c2, 0x1475: 0x00c2, + 0x1476: 0x00c2, 0x1477: 0x00c2, 0x1478: 0x00c2, + // Block 0x52, offset 0x1480 + 0x1480: 0x00c0, 0x1481: 0x00c0, 0x1482: 0x00c0, 0x1483: 0x00c0, 0x1484: 0x00c0, 0x1485: 0x00c3, + 0x1486: 0x00c3, 0x1487: 0x00c2, 0x1488: 0x00c2, 0x1489: 0x00c2, 0x148a: 0x00c2, 0x148b: 0x00c2, + 0x148c: 0x00c2, 0x148d: 0x00c2, 0x148e: 0x00c2, 0x148f: 0x00c2, 0x1490: 0x00c2, 0x1491: 0x00c2, + 0x1492: 0x00c2, 0x1493: 0x00c2, 0x1494: 0x00c2, 0x1495: 0x00c2, 0x1496: 0x00c2, 0x1497: 0x00c2, + 0x1498: 0x00c2, 0x1499: 0x00c2, 0x149a: 0x00c2, 0x149b: 0x00c2, 0x149c: 0x00c2, 0x149d: 0x00c2, + 0x149e: 0x00c2, 0x149f: 0x00c2, 0x14a0: 0x00c2, 0x14a1: 0x00c2, 0x14a2: 0x00c2, 0x14a3: 0x00c2, + 0x14a4: 0x00c2, 0x14a5: 0x00c2, 0x14a6: 0x00c2, 0x14a7: 0x00c2, 0x14a8: 0x00c2, 0x14a9: 0x00c3, + 0x14aa: 0x00c2, + 0x14b0: 0x00c0, 0x14b1: 0x00c0, 0x14b2: 0x00c0, 0x14b3: 0x00c0, 0x14b4: 0x00c0, 0x14b5: 0x00c0, + 0x14b6: 0x00c0, 0x14b7: 0x00c0, 0x14b8: 0x00c0, 0x14b9: 0x00c0, 0x14ba: 0x00c0, 0x14bb: 0x00c0, + 0x14bc: 0x00c0, 0x14bd: 0x00c0, 0x14be: 0x00c0, 0x14bf: 0x00c0, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x00c0, 0x14c1: 0x00c0, 0x14c2: 0x00c0, 0x14c3: 0x00c0, 0x14c4: 0x00c0, 0x14c5: 0x00c0, + 0x14c6: 0x00c0, 0x14c7: 0x00c0, 0x14c8: 0x00c0, 0x14c9: 0x00c0, 0x14ca: 0x00c0, 0x14cb: 0x00c0, + 0x14cc: 0x00c0, 0x14cd: 0x00c0, 0x14ce: 0x00c0, 0x14cf: 0x00c0, 0x14d0: 0x00c0, 0x14d1: 0x00c0, + 0x14d2: 0x00c0, 0x14d3: 0x00c0, 0x14d4: 0x00c0, 0x14d5: 0x00c0, 0x14d6: 0x00c0, 0x14d7: 0x00c0, + 0x14d8: 0x00c0, 0x14d9: 0x00c0, 0x14da: 0x00c0, 0x14db: 0x00c0, 0x14dc: 0x00c0, 0x14dd: 0x00c0, + 0x14de: 0x00c0, 0x14df: 0x00c0, 0x14e0: 0x00c0, 0x14e1: 0x00c0, 0x14e2: 0x00c0, 0x14e3: 0x00c0, + 0x14e4: 0x00c0, 0x14e5: 0x00c0, 0x14e6: 0x00c0, 0x14e7: 0x00c0, 0x14e8: 0x00c0, 0x14e9: 0x00c0, + 0x14ea: 0x00c0, 0x14eb: 0x00c0, 0x14ec: 0x00c0, 0x14ed: 0x00c0, 0x14ee: 0x00c0, 0x14ef: 0x00c0, + 0x14f0: 0x00c0, 0x14f1: 0x00c0, 0x14f2: 0x00c0, 0x14f3: 0x00c0, 0x14f4: 0x00c0, 0x14f5: 0x00c0, + // Block 0x54, offset 0x1500 + 0x1500: 0x00c0, 0x1501: 0x00c0, 0x1502: 0x00c0, 0x1503: 0x00c0, 0x1504: 0x00c0, 0x1505: 0x00c0, + 0x1506: 0x00c0, 0x1507: 0x00c0, 0x1508: 0x00c0, 0x1509: 0x00c0, 0x150a: 0x00c0, 0x150b: 0x00c0, + 0x150c: 0x00c0, 0x150d: 0x00c0, 0x150e: 0x00c0, 0x150f: 0x00c0, 0x1510: 0x00c0, 0x1511: 0x00c0, + 0x1512: 0x00c0, 0x1513: 0x00c0, 0x1514: 0x00c0, 0x1515: 0x00c0, 0x1516: 0x00c0, 0x1517: 0x00c0, + 0x1518: 0x00c0, 0x1519: 0x00c0, 0x151a: 0x00c0, 0x151b: 0x00c0, 0x151c: 0x00c0, 0x151d: 0x00c0, + 0x151e: 0x00c0, 0x1520: 0x00c3, 0x1521: 0x00c3, 0x1522: 0x00c3, 0x1523: 0x00c0, + 0x1524: 0x00c0, 0x1525: 0x00c0, 0x1526: 0x00c0, 0x1527: 0x00c3, 0x1528: 0x00c3, 0x1529: 0x00c0, + 0x152a: 0x00c0, 0x152b: 0x00c0, + 0x1530: 0x00c0, 0x1531: 0x00c0, 0x1532: 0x00c3, 0x1533: 0x00c0, 0x1534: 0x00c0, 0x1535: 0x00c0, + 0x1536: 0x00c0, 0x1537: 0x00c0, 0x1538: 0x00c0, 0x1539: 0x00c3, 0x153a: 0x00c3, 0x153b: 0x00c3, + // Block 0x55, offset 0x1540 + 0x1540: 0x0080, 0x1544: 0x0080, 0x1545: 0x0080, + 0x1546: 0x00c0, 0x1547: 0x00c0, 0x1548: 0x00c0, 0x1549: 0x00c0, 0x154a: 0x00c0, 0x154b: 0x00c0, + 0x154c: 0x00c0, 0x154d: 0x00c0, 0x154e: 0x00c0, 0x154f: 0x00c0, 0x1550: 0x00c0, 0x1551: 0x00c0, + 0x1552: 0x00c0, 0x1553: 0x00c0, 0x1554: 0x00c0, 0x1555: 0x00c0, 0x1556: 0x00c0, 0x1557: 0x00c0, + 0x1558: 0x00c0, 0x1559: 0x00c0, 0x155a: 0x00c0, 0x155b: 0x00c0, 0x155c: 0x00c0, 0x155d: 0x00c0, + 0x155e: 0x00c0, 0x155f: 0x00c0, 0x1560: 0x00c0, 0x1561: 0x00c0, 0x1562: 0x00c0, 0x1563: 0x00c0, + 0x1564: 0x00c0, 0x1565: 0x00c0, 0x1566: 0x00c0, 0x1567: 0x00c0, 0x1568: 0x00c0, 0x1569: 0x00c0, + 0x156a: 0x00c0, 0x156b: 0x00c0, 0x156c: 0x00c0, 0x156d: 0x00c0, + 0x1570: 0x00c0, 0x1571: 0x00c0, 0x1572: 0x00c0, 0x1573: 0x00c0, 0x1574: 0x00c0, + // Block 0x56, offset 0x1580 + 0x1580: 0x00c0, 0x1581: 0x00c0, 0x1582: 0x00c0, 0x1583: 0x00c0, 0x1584: 0x00c0, 0x1585: 0x00c0, + 0x1586: 0x00c0, 0x1587: 0x00c0, 0x1588: 0x00c0, 0x1589: 0x00c0, 0x158a: 0x00c0, 0x158b: 0x00c0, + 0x158c: 0x00c0, 0x158d: 0x00c0, 0x158e: 0x00c0, 0x158f: 0x00c0, 0x1590: 0x00c0, 0x1591: 0x00c0, + 0x1592: 0x00c0, 0x1593: 0x00c0, 0x1594: 0x00c0, 0x1595: 0x00c0, 0x1596: 0x00c0, 0x1597: 0x00c0, + 0x1598: 0x00c0, 0x1599: 0x00c0, 0x159a: 0x00c0, 0x159b: 0x00c0, 0x159c: 0x00c0, 0x159d: 0x00c0, + 0x159e: 0x00c0, 0x159f: 0x00c0, 0x15a0: 0x00c0, 0x15a1: 0x00c0, 0x15a2: 0x00c0, 0x15a3: 0x00c0, + 0x15a4: 0x00c0, 0x15a5: 0x00c0, 0x15a6: 0x00c0, 0x15a7: 0x00c0, 0x15a8: 0x00c0, 0x15a9: 0x00c0, + 0x15aa: 0x00c0, 0x15ab: 0x00c0, + 0x15b0: 0x00c0, 0x15b1: 0x00c0, 0x15b2: 0x00c0, 0x15b3: 0x00c0, 0x15b4: 0x00c0, 0x15b5: 0x00c0, + 0x15b6: 0x00c0, 0x15b7: 0x00c0, 0x15b8: 0x00c0, 0x15b9: 0x00c0, 0x15ba: 0x00c0, 0x15bb: 0x00c0, + 0x15bc: 0x00c0, 0x15bd: 0x00c0, 0x15be: 0x00c0, 0x15bf: 0x00c0, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x00c0, 0x15c1: 0x00c0, 0x15c2: 0x00c0, 0x15c3: 0x00c0, 0x15c4: 0x00c0, 0x15c5: 0x00c0, + 0x15c6: 0x00c0, 0x15c7: 0x00c0, 0x15c8: 0x00c0, 0x15c9: 0x00c0, + 0x15d0: 0x00c0, 0x15d1: 0x00c0, + 0x15d2: 0x00c0, 0x15d3: 0x00c0, 0x15d4: 0x00c0, 0x15d5: 0x00c0, 0x15d6: 0x00c0, 0x15d7: 0x00c0, + 0x15d8: 0x00c0, 0x15d9: 0x00c0, 0x15da: 0x0080, + 0x15de: 0x0080, 0x15df: 0x0080, 0x15e0: 0x0080, 0x15e1: 0x0080, 0x15e2: 0x0080, 0x15e3: 0x0080, + 0x15e4: 0x0080, 0x15e5: 0x0080, 0x15e6: 0x0080, 0x15e7: 0x0080, 0x15e8: 0x0080, 0x15e9: 0x0080, + 0x15ea: 0x0080, 0x15eb: 0x0080, 0x15ec: 0x0080, 0x15ed: 0x0080, 0x15ee: 0x0080, 0x15ef: 0x0080, + 0x15f0: 0x0080, 0x15f1: 0x0080, 0x15f2: 0x0080, 0x15f3: 0x0080, 0x15f4: 0x0080, 0x15f5: 0x0080, + 0x15f6: 0x0080, 0x15f7: 0x0080, 0x15f8: 0x0080, 0x15f9: 0x0080, 0x15fa: 0x0080, 0x15fb: 0x0080, + 0x15fc: 0x0080, 0x15fd: 0x0080, 0x15fe: 0x0080, 0x15ff: 0x0080, + // Block 0x58, offset 0x1600 + 0x1600: 0x00c0, 0x1601: 0x00c0, 0x1602: 0x00c0, 0x1603: 0x00c0, 0x1604: 0x00c0, 0x1605: 0x00c0, + 0x1606: 0x00c0, 0x1607: 0x00c0, 0x1608: 0x00c0, 0x1609: 0x00c0, 0x160a: 0x00c0, 0x160b: 0x00c0, + 0x160c: 0x00c0, 0x160d: 0x00c0, 0x160e: 0x00c0, 0x160f: 0x00c0, 0x1610: 0x00c0, 0x1611: 0x00c0, + 0x1612: 0x00c0, 0x1613: 0x00c0, 0x1614: 0x00c0, 0x1615: 0x00c0, 0x1616: 0x00c0, 0x1617: 0x00c3, + 0x1618: 0x00c3, 0x1619: 0x00c0, 0x161a: 0x00c0, 0x161b: 0x00c3, + 0x161e: 0x0080, 0x161f: 0x0080, 0x1620: 0x00c0, 0x1621: 0x00c0, 0x1622: 0x00c0, 0x1623: 0x00c0, + 0x1624: 0x00c0, 0x1625: 0x00c0, 0x1626: 0x00c0, 0x1627: 0x00c0, 0x1628: 0x00c0, 0x1629: 0x00c0, + 0x162a: 0x00c0, 0x162b: 0x00c0, 0x162c: 0x00c0, 0x162d: 0x00c0, 0x162e: 0x00c0, 0x162f: 0x00c0, + 0x1630: 0x00c0, 0x1631: 0x00c0, 0x1632: 0x00c0, 0x1633: 0x00c0, 0x1634: 0x00c0, 0x1635: 0x00c0, + 0x1636: 0x00c0, 0x1637: 0x00c0, 0x1638: 0x00c0, 0x1639: 0x00c0, 0x163a: 0x00c0, 0x163b: 0x00c0, + 0x163c: 0x00c0, 0x163d: 0x00c0, 0x163e: 0x00c0, 0x163f: 0x00c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x00c0, 0x1641: 0x00c0, 0x1642: 0x00c0, 0x1643: 0x00c0, 0x1644: 0x00c0, 0x1645: 0x00c0, + 0x1646: 0x00c0, 0x1647: 0x00c0, 0x1648: 0x00c0, 0x1649: 0x00c0, 0x164a: 0x00c0, 0x164b: 0x00c0, + 0x164c: 0x00c0, 0x164d: 0x00c0, 0x164e: 0x00c0, 0x164f: 0x00c0, 0x1650: 0x00c0, 0x1651: 0x00c0, + 0x1652: 0x00c0, 0x1653: 0x00c0, 0x1654: 0x00c0, 0x1655: 0x00c0, 0x1656: 0x00c3, 0x1657: 0x00c0, + 0x1658: 0x00c3, 0x1659: 0x00c3, 0x165a: 0x00c3, 0x165b: 0x00c3, 0x165c: 0x00c3, 0x165d: 0x00c3, + 0x165e: 0x00c3, 0x1660: 0x00c6, 0x1661: 0x00c0, 0x1662: 0x00c3, 0x1663: 0x00c0, + 0x1664: 0x00c0, 0x1665: 0x00c3, 0x1666: 0x00c3, 0x1667: 0x00c3, 0x1668: 0x00c3, 0x1669: 0x00c3, + 0x166a: 0x00c3, 0x166b: 0x00c3, 0x166c: 0x00c3, 0x166d: 0x00c0, 0x166e: 0x00c0, 0x166f: 0x00c0, + 0x1670: 0x00c0, 0x1671: 0x00c0, 0x1672: 0x00c0, 0x1673: 0x00c3, 0x1674: 0x00c3, 0x1675: 0x00c3, + 0x1676: 0x00c3, 0x1677: 0x00c3, 0x1678: 0x00c3, 0x1679: 0x00c3, 0x167a: 0x00c3, 0x167b: 0x00c3, + 0x167c: 0x00c3, 0x167f: 0x00c3, + // Block 0x5a, offset 0x1680 + 0x1680: 0x00c0, 0x1681: 0x00c0, 0x1682: 0x00c0, 0x1683: 0x00c0, 0x1684: 0x00c0, 0x1685: 0x00c0, + 0x1686: 0x00c0, 0x1687: 0x00c0, 0x1688: 0x00c0, 0x1689: 0x00c0, + 0x1690: 0x00c0, 0x1691: 0x00c0, + 0x1692: 0x00c0, 0x1693: 0x00c0, 0x1694: 0x00c0, 0x1695: 0x00c0, 0x1696: 0x00c0, 0x1697: 0x00c0, + 0x1698: 0x00c0, 0x1699: 0x00c0, + 0x16a0: 0x0080, 0x16a1: 0x0080, 0x16a2: 0x0080, 0x16a3: 0x0080, + 0x16a4: 0x0080, 0x16a5: 0x0080, 0x16a6: 0x0080, 0x16a7: 0x00c0, 0x16a8: 0x0080, 0x16a9: 0x0080, + 0x16aa: 0x0080, 0x16ab: 0x0080, 0x16ac: 0x0080, 0x16ad: 0x0080, + 0x16b0: 0x00c3, 0x16b1: 0x00c3, 0x16b2: 0x00c3, 0x16b3: 0x00c3, 0x16b4: 0x00c3, 0x16b5: 0x00c3, + 0x16b6: 0x00c3, 0x16b7: 0x00c3, 0x16b8: 0x00c3, 0x16b9: 0x00c3, 0x16ba: 0x00c3, 0x16bb: 0x00c3, + 0x16bc: 0x00c3, 0x16bd: 0x00c3, 0x16be: 0x0083, 0x16bf: 0x00c3, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x00c3, + // Block 0x5c, offset 0x1700 + 0x1700: 0x00c3, 0x1701: 0x00c3, 0x1702: 0x00c3, 0x1703: 0x00c3, 0x1704: 0x00c0, 0x1705: 0x00c0, + 0x1706: 0x00c0, 0x1707: 0x00c0, 0x1708: 0x00c0, 0x1709: 0x00c0, 0x170a: 0x00c0, 0x170b: 0x00c0, + 0x170c: 0x00c0, 0x170d: 0x00c0, 0x170e: 0x00c0, 0x170f: 0x00c0, 0x1710: 0x00c0, 0x1711: 0x00c0, + 0x1712: 0x00c0, 0x1713: 0x00c0, 0x1714: 0x00c0, 0x1715: 0x00c0, 0x1716: 0x00c0, 0x1717: 0x00c0, + 0x1718: 0x00c0, 0x1719: 0x00c0, 0x171a: 0x00c0, 0x171b: 0x00c0, 0x171c: 0x00c0, 0x171d: 0x00c0, + 0x171e: 0x00c0, 0x171f: 0x00c0, 0x1720: 0x00c0, 0x1721: 0x00c0, 0x1722: 0x00c0, 0x1723: 0x00c0, + 0x1724: 0x00c0, 0x1725: 0x00c0, 0x1726: 0x00c0, 0x1727: 0x00c0, 0x1728: 0x00c0, 0x1729: 0x00c0, + 0x172a: 0x00c0, 0x172b: 0x00c0, 0x172c: 0x00c0, 0x172d: 0x00c0, 0x172e: 0x00c0, 0x172f: 0x00c0, + 0x1730: 0x00c0, 0x1731: 0x00c0, 0x1732: 0x00c0, 0x1733: 0x00c0, 0x1734: 0x00c3, 0x1735: 0x00c0, + 0x1736: 0x00c3, 0x1737: 0x00c3, 0x1738: 0x00c3, 0x1739: 0x00c3, 0x173a: 0x00c3, 0x173b: 0x00c0, + 0x173c: 0x00c3, 0x173d: 0x00c0, 0x173e: 0x00c0, 0x173f: 0x00c0, + // Block 0x5d, offset 0x1740 + 0x1740: 0x00c0, 0x1741: 0x00c0, 0x1742: 0x00c3, 0x1743: 0x00c0, 0x1744: 0x00c5, 0x1745: 0x00c0, + 0x1746: 0x00c0, 0x1747: 0x00c0, 0x1748: 0x00c0, 0x1749: 0x00c0, 0x174a: 0x00c0, 0x174b: 0x00c0, + 0x1750: 0x00c0, 0x1751: 0x00c0, + 0x1752: 0x00c0, 0x1753: 0x00c0, 0x1754: 0x00c0, 0x1755: 0x00c0, 0x1756: 0x00c0, 0x1757: 0x00c0, + 0x1758: 0x00c0, 0x1759: 0x00c0, 0x175a: 0x0080, 0x175b: 0x0080, 0x175c: 0x0080, 0x175d: 0x0080, + 0x175e: 0x0080, 0x175f: 0x0080, 0x1760: 0x0080, 0x1761: 0x0080, 0x1762: 0x0080, 0x1763: 0x0080, + 0x1764: 0x0080, 0x1765: 0x0080, 0x1766: 0x0080, 0x1767: 0x0080, 0x1768: 0x0080, 0x1769: 0x0080, + 0x176a: 0x0080, 0x176b: 0x00c3, 0x176c: 0x00c3, 0x176d: 0x00c3, 0x176e: 0x00c3, 0x176f: 0x00c3, + 0x1770: 0x00c3, 0x1771: 0x00c3, 0x1772: 0x00c3, 0x1773: 0x00c3, 0x1774: 0x0080, 0x1775: 0x0080, + 0x1776: 0x0080, 0x1777: 0x0080, 0x1778: 0x0080, 0x1779: 0x0080, 0x177a: 0x0080, 0x177b: 0x0080, + 0x177c: 0x0080, + // Block 0x5e, offset 0x1780 + 0x1780: 0x00c3, 0x1781: 0x00c3, 0x1782: 0x00c0, 0x1783: 0x00c0, 0x1784: 0x00c0, 0x1785: 0x00c0, + 0x1786: 0x00c0, 0x1787: 0x00c0, 0x1788: 0x00c0, 0x1789: 0x00c0, 0x178a: 0x00c0, 0x178b: 0x00c0, + 0x178c: 0x00c0, 0x178d: 0x00c0, 0x178e: 0x00c0, 0x178f: 0x00c0, 0x1790: 0x00c0, 0x1791: 0x00c0, + 0x1792: 0x00c0, 0x1793: 0x00c0, 0x1794: 0x00c0, 0x1795: 0x00c0, 0x1796: 0x00c0, 0x1797: 0x00c0, + 0x1798: 0x00c0, 0x1799: 0x00c0, 0x179a: 0x00c0, 0x179b: 0x00c0, 0x179c: 0x00c0, 0x179d: 0x00c0, + 0x179e: 0x00c0, 0x179f: 0x00c0, 0x17a0: 0x00c0, 0x17a1: 0x00c0, 0x17a2: 0x00c3, 0x17a3: 0x00c3, + 0x17a4: 0x00c3, 0x17a5: 0x00c3, 0x17a6: 0x00c0, 0x17a7: 0x00c0, 0x17a8: 0x00c3, 0x17a9: 0x00c3, + 0x17aa: 0x00c5, 0x17ab: 0x00c6, 0x17ac: 0x00c3, 0x17ad: 0x00c3, 0x17ae: 0x00c0, 0x17af: 0x00c0, + 0x17b0: 0x00c0, 0x17b1: 0x00c0, 0x17b2: 0x00c0, 0x17b3: 0x00c0, 0x17b4: 0x00c0, 0x17b5: 0x00c0, + 0x17b6: 0x00c0, 0x17b7: 0x00c0, 0x17b8: 0x00c0, 0x17b9: 0x00c0, 0x17ba: 0x00c0, 0x17bb: 0x00c0, + 0x17bc: 0x00c0, 0x17bd: 0x00c0, 0x17be: 0x00c0, 0x17bf: 0x00c0, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x00c0, 0x17c1: 0x00c0, 0x17c2: 0x00c0, 0x17c3: 0x00c0, 0x17c4: 0x00c0, 0x17c5: 0x00c0, + 0x17c6: 0x00c0, 0x17c7: 0x00c0, 0x17c8: 0x00c0, 0x17c9: 0x00c0, 0x17ca: 0x00c0, 0x17cb: 0x00c0, + 0x17cc: 0x00c0, 0x17cd: 0x00c0, 0x17ce: 0x00c0, 0x17cf: 0x00c0, 0x17d0: 0x00c0, 0x17d1: 0x00c0, + 0x17d2: 0x00c0, 0x17d3: 0x00c0, 0x17d4: 0x00c0, 0x17d5: 0x00c0, 0x17d6: 0x00c0, 0x17d7: 0x00c0, + 0x17d8: 0x00c0, 0x17d9: 0x00c0, 0x17da: 0x00c0, 0x17db: 0x00c0, 0x17dc: 0x00c0, 0x17dd: 0x00c0, + 0x17de: 0x00c0, 0x17df: 0x00c0, 0x17e0: 0x00c0, 0x17e1: 0x00c0, 0x17e2: 0x00c0, 0x17e3: 0x00c0, + 0x17e4: 0x00c0, 0x17e5: 0x00c0, 0x17e6: 0x00c3, 0x17e7: 0x00c0, 0x17e8: 0x00c3, 0x17e9: 0x00c3, + 0x17ea: 0x00c0, 0x17eb: 0x00c0, 0x17ec: 0x00c0, 0x17ed: 0x00c3, 0x17ee: 0x00c0, 0x17ef: 0x00c3, + 0x17f0: 0x00c3, 0x17f1: 0x00c3, 0x17f2: 0x00c5, 0x17f3: 0x00c5, + 0x17fc: 0x0080, 0x17fd: 0x0080, 0x17fe: 0x0080, 0x17ff: 0x0080, + // Block 0x60, offset 0x1800 + 0x1800: 0x00c0, 0x1801: 0x00c0, 0x1802: 0x00c0, 0x1803: 0x00c0, 0x1804: 0x00c0, 0x1805: 0x00c0, + 0x1806: 0x00c0, 0x1807: 0x00c0, 0x1808: 0x00c0, 0x1809: 0x00c0, 0x180a: 0x00c0, 0x180b: 0x00c0, + 0x180c: 0x00c0, 0x180d: 0x00c0, 0x180e: 0x00c0, 0x180f: 0x00c0, 0x1810: 0x00c0, 0x1811: 0x00c0, + 0x1812: 0x00c0, 0x1813: 0x00c0, 0x1814: 0x00c0, 0x1815: 0x00c0, 0x1816: 0x00c0, 0x1817: 0x00c0, + 0x1818: 0x00c0, 0x1819: 0x00c0, 0x181a: 0x00c0, 0x181b: 0x00c0, 0x181c: 0x00c0, 0x181d: 0x00c0, + 0x181e: 0x00c0, 0x181f: 0x00c0, 0x1820: 0x00c0, 0x1821: 0x00c0, 0x1822: 0x00c0, 0x1823: 0x00c0, + 0x1824: 0x00c0, 0x1825: 0x00c0, 0x1826: 0x00c0, 0x1827: 0x00c0, 0x1828: 0x00c0, 0x1829: 0x00c0, + 0x182a: 0x00c0, 0x182b: 0x00c0, 0x182c: 0x00c3, 0x182d: 0x00c3, 0x182e: 0x00c3, 0x182f: 0x00c3, + 0x1830: 0x00c3, 0x1831: 0x00c3, 0x1832: 0x00c3, 0x1833: 0x00c3, 0x1834: 0x00c0, 0x1835: 0x00c0, + 0x1836: 0x00c3, 0x1837: 0x00c3, 0x183b: 0x0080, + 0x183c: 0x0080, 0x183d: 0x0080, 0x183e: 0x0080, 0x183f: 0x0080, + // Block 0x61, offset 0x1840 + 0x1840: 0x00c0, 0x1841: 0x00c0, 0x1842: 0x00c0, 0x1843: 0x00c0, 0x1844: 0x00c0, 0x1845: 0x00c0, + 0x1846: 0x00c0, 0x1847: 0x00c0, 0x1848: 0x00c0, 0x1849: 0x00c0, + 0x184d: 0x00c0, 0x184e: 0x00c0, 0x184f: 0x00c0, 0x1850: 0x00c0, 0x1851: 0x00c0, + 0x1852: 0x00c0, 0x1853: 0x00c0, 0x1854: 0x00c0, 0x1855: 0x00c0, 0x1856: 0x00c0, 0x1857: 0x00c0, + 0x1858: 0x00c0, 0x1859: 0x00c0, 0x185a: 0x00c0, 0x185b: 0x00c0, 0x185c: 0x00c0, 0x185d: 0x00c0, + 0x185e: 0x00c0, 0x185f: 0x00c0, 0x1860: 0x00c0, 0x1861: 0x00c0, 0x1862: 0x00c0, 0x1863: 0x00c0, + 0x1864: 0x00c0, 0x1865: 0x00c0, 0x1866: 0x00c0, 0x1867: 0x00c0, 0x1868: 0x00c0, 0x1869: 0x00c0, + 0x186a: 0x00c0, 0x186b: 0x00c0, 0x186c: 0x00c0, 0x186d: 0x00c0, 0x186e: 0x00c0, 0x186f: 0x00c0, + 0x1870: 0x00c0, 0x1871: 0x00c0, 0x1872: 0x00c0, 0x1873: 0x00c0, 0x1874: 0x00c0, 0x1875: 0x00c0, + 0x1876: 0x00c0, 0x1877: 0x00c0, 0x1878: 0x00c0, 0x1879: 0x00c0, 0x187a: 0x00c0, 0x187b: 0x00c0, + 0x187c: 0x00c0, 0x187d: 0x00c0, 0x187e: 0x0080, 0x187f: 0x0080, + // Block 0x62, offset 0x1880 + 0x1880: 0x00c0, 0x1881: 0x00c0, 0x1882: 0x00c0, 0x1883: 0x00c0, 0x1884: 0x00c0, 0x1885: 0x00c0, + 0x1886: 0x00c0, 0x1887: 0x00c0, 0x1888: 0x00c0, + 0x1890: 0x00c0, 0x1891: 0x00c0, + 0x1892: 0x00c0, 0x1893: 0x00c0, 0x1894: 0x00c0, 0x1895: 0x00c0, 0x1896: 0x00c0, 0x1897: 0x00c0, + 0x1898: 0x00c0, 0x1899: 0x00c0, 0x189a: 0x00c0, 0x189b: 0x00c0, 0x189c: 0x00c0, 0x189d: 0x00c0, + 0x189e: 0x00c0, 0x189f: 0x00c0, 0x18a0: 0x00c0, 0x18a1: 0x00c0, 0x18a2: 0x00c0, 0x18a3: 0x00c0, + 0x18a4: 0x00c0, 0x18a5: 0x00c0, 0x18a6: 0x00c0, 0x18a7: 0x00c0, 0x18a8: 0x00c0, 0x18a9: 0x00c0, + 0x18aa: 0x00c0, 0x18ab: 0x00c0, 0x18ac: 0x00c0, 0x18ad: 0x00c0, 0x18ae: 0x00c0, 0x18af: 0x00c0, + 0x18b0: 0x00c0, 0x18b1: 0x00c0, 0x18b2: 0x00c0, 0x18b3: 0x00c0, 0x18b4: 0x00c0, 0x18b5: 0x00c0, + 0x18b6: 0x00c0, 0x18b7: 0x00c0, 0x18b8: 0x00c0, 0x18b9: 0x00c0, 0x18ba: 0x00c0, + 0x18bd: 0x00c0, 0x18be: 0x00c0, 0x18bf: 0x00c0, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x0080, 0x18c1: 0x0080, 0x18c2: 0x0080, 0x18c3: 0x0080, 0x18c4: 0x0080, 0x18c5: 0x0080, + 0x18c6: 0x0080, 0x18c7: 0x0080, + 0x18d0: 0x00c3, 0x18d1: 0x00c3, + 0x18d2: 0x00c3, 0x18d3: 0x0080, 0x18d4: 0x00c3, 0x18d5: 0x00c3, 0x18d6: 0x00c3, 0x18d7: 0x00c3, + 0x18d8: 0x00c3, 0x18d9: 0x00c3, 0x18da: 0x00c3, 0x18db: 0x00c3, 0x18dc: 0x00c3, 0x18dd: 0x00c3, + 0x18de: 0x00c3, 0x18df: 0x00c3, 0x18e0: 0x00c3, 0x18e1: 0x00c0, 0x18e2: 0x00c3, 0x18e3: 0x00c3, + 0x18e4: 0x00c3, 0x18e5: 0x00c3, 0x18e6: 0x00c3, 0x18e7: 0x00c3, 0x18e8: 0x00c3, 0x18e9: 0x00c0, + 0x18ea: 0x00c0, 0x18eb: 0x00c0, 0x18ec: 0x00c0, 0x18ed: 0x00c3, 0x18ee: 0x00c0, 0x18ef: 0x00c0, + 0x18f0: 0x00c0, 0x18f1: 0x00c0, 0x18f2: 0x00c0, 0x18f3: 0x00c0, 0x18f4: 0x00c3, 0x18f5: 0x00c0, + 0x18f6: 0x00c0, 0x18f7: 0x00c0, 0x18f8: 0x00c3, 0x18f9: 0x00c3, 0x18fa: 0x00c0, + // Block 0x64, offset 0x1900 + 0x1900: 0x00c0, 0x1901: 0x00c0, 0x1902: 0x00c0, 0x1903: 0x00c0, 0x1904: 0x00c0, 0x1905: 0x00c0, + 0x1906: 0x00c0, 0x1907: 0x00c0, 0x1908: 0x00c0, 0x1909: 0x00c0, 0x190a: 0x00c0, 0x190b: 0x00c0, + 0x190c: 0x00c0, 0x190d: 0x00c0, 0x190e: 0x00c0, 0x190f: 0x00c0, 0x1910: 0x00c0, 0x1911: 0x00c0, + 0x1912: 0x00c0, 0x1913: 0x00c0, 0x1914: 0x00c0, 0x1915: 0x00c0, 0x1916: 0x00c0, 0x1917: 0x00c0, + 0x1918: 0x00c0, 0x1919: 0x00c0, 0x191a: 0x00c0, 0x191b: 0x00c0, 0x191c: 0x00c0, 0x191d: 0x00c0, + 0x191e: 0x00c0, 0x191f: 0x00c0, 0x1920: 0x00c0, 0x1921: 0x00c0, 0x1922: 0x00c0, 0x1923: 0x00c0, + 0x1924: 0x00c0, 0x1925: 0x00c0, 0x1926: 0x00c8, 0x1927: 0x00c8, 0x1928: 0x00c8, 0x1929: 0x00c8, + 0x192a: 0x00c8, 0x192b: 0x00c0, 0x192c: 0x0080, 0x192d: 0x0080, 0x192e: 0x0080, 0x192f: 0x00c0, + 0x1930: 0x0080, 0x1931: 0x0080, 0x1932: 0x0080, 0x1933: 0x0080, 0x1934: 0x0080, 0x1935: 0x0080, + 0x1936: 0x0080, 0x1937: 0x0080, 0x1938: 0x0080, 0x1939: 0x0080, 0x193a: 0x0080, 0x193b: 0x00c0, + 0x193c: 0x0080, 0x193d: 0x0080, 0x193e: 0x0080, 0x193f: 0x0080, + // Block 0x65, offset 0x1940 + 0x1940: 0x0080, 0x1941: 0x0080, 0x1942: 0x0080, 0x1943: 0x0080, 0x1944: 0x0080, 0x1945: 0x0080, + 0x1946: 0x0080, 0x1947: 0x0080, 0x1948: 0x0080, 0x1949: 0x0080, 0x194a: 0x0080, 0x194b: 0x0080, + 0x194c: 0x0080, 0x194d: 0x0080, 0x194e: 0x00c0, 0x194f: 0x0080, 0x1950: 0x0080, 0x1951: 0x0080, + 0x1952: 0x0080, 0x1953: 0x0080, 0x1954: 0x0080, 0x1955: 0x0080, 0x1956: 0x0080, 0x1957: 0x0080, + 0x1958: 0x0080, 0x1959: 0x0080, 0x195a: 0x0080, 0x195b: 0x0080, 0x195c: 0x0080, 0x195d: 0x0088, + 0x195e: 0x0088, 0x195f: 0x0088, 0x1960: 0x0088, 0x1961: 0x0088, 0x1962: 0x0080, 0x1963: 0x0080, + 0x1964: 0x0080, 0x1965: 0x0080, 0x1966: 0x0088, 0x1967: 0x0088, 0x1968: 0x0088, 0x1969: 0x0088, + 0x196a: 0x0088, 0x196b: 0x00c0, 0x196c: 0x00c0, 0x196d: 0x00c0, 0x196e: 0x00c0, 0x196f: 0x00c0, + 0x1970: 0x00c0, 0x1971: 0x00c0, 0x1972: 0x00c0, 0x1973: 0x00c0, 0x1974: 0x00c0, 0x1975: 0x00c0, + 0x1976: 0x00c0, 0x1977: 0x00c0, 0x1978: 0x0080, 0x1979: 0x00c0, 0x197a: 0x00c0, 0x197b: 0x00c0, + 0x197c: 0x00c0, 0x197d: 0x00c0, 0x197e: 0x00c0, 0x197f: 0x00c0, + // Block 0x66, offset 0x1980 + 0x1980: 0x00c0, 0x1981: 0x00c0, 0x1982: 0x00c0, 0x1983: 0x00c0, 0x1984: 0x00c0, 0x1985: 0x00c0, + 0x1986: 0x00c0, 0x1987: 0x00c0, 0x1988: 0x00c0, 0x1989: 0x00c0, 0x198a: 0x00c0, 0x198b: 0x00c0, + 0x198c: 0x00c0, 0x198d: 0x00c0, 0x198e: 0x00c0, 0x198f: 0x00c0, 0x1990: 0x00c0, 0x1991: 0x00c0, + 0x1992: 0x00c0, 0x1993: 0x00c0, 0x1994: 0x00c0, 0x1995: 0x00c0, 0x1996: 0x00c0, 0x1997: 0x00c0, + 0x1998: 0x00c0, 0x1999: 0x00c0, 0x199a: 0x00c0, 0x199b: 0x0080, 0x199c: 0x0080, 0x199d: 0x0080, + 0x199e: 0x0080, 0x199f: 0x0080, 0x19a0: 0x0080, 0x19a1: 0x0080, 0x19a2: 0x0080, 0x19a3: 0x0080, + 0x19a4: 0x0080, 0x19a5: 0x0080, 0x19a6: 0x0080, 0x19a7: 0x0080, 0x19a8: 0x0080, 0x19a9: 0x0080, + 0x19aa: 0x0080, 0x19ab: 0x0080, 0x19ac: 0x0080, 0x19ad: 0x0080, 0x19ae: 0x0080, 0x19af: 0x0080, + 0x19b0: 0x0080, 0x19b1: 0x0080, 0x19b2: 0x0080, 0x19b3: 0x0080, 0x19b4: 0x0080, 0x19b5: 0x0080, + 0x19b6: 0x0080, 0x19b7: 0x0080, 0x19b8: 0x0080, 0x19b9: 0x0080, 0x19ba: 0x0080, 0x19bb: 0x0080, + 0x19bc: 0x0080, 0x19bd: 0x0080, 0x19be: 0x0080, 0x19bf: 0x0088, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x00c3, 0x19c1: 0x00c3, 0x19c2: 0x00c3, 0x19c3: 0x00c3, 0x19c4: 0x00c3, 0x19c5: 0x00c3, + 0x19c6: 0x00c3, 0x19c7: 0x00c3, 0x19c8: 0x00c3, 0x19c9: 0x00c3, 0x19ca: 0x00c3, 0x19cb: 0x00c3, + 0x19cc: 0x00c3, 0x19cd: 0x00c3, 0x19ce: 0x00c3, 0x19cf: 0x00c3, 0x19d0: 0x00c3, 0x19d1: 0x00c3, + 0x19d2: 0x00c3, 0x19d3: 0x00c3, 0x19d4: 0x00c3, 0x19d5: 0x00c3, 0x19d6: 0x00c3, 0x19d7: 0x00c3, + 0x19d8: 0x00c3, 0x19d9: 0x00c3, 0x19da: 0x00c3, 0x19db: 0x00c3, 0x19dc: 0x00c3, 0x19dd: 0x00c3, + 0x19de: 0x00c3, 0x19df: 0x00c3, 0x19e0: 0x00c3, 0x19e1: 0x00c3, 0x19e2: 0x00c3, 0x19e3: 0x00c3, + 0x19e4: 0x00c3, 0x19e5: 0x00c3, 0x19e6: 0x00c3, 0x19e7: 0x00c3, 0x19e8: 0x00c3, 0x19e9: 0x00c3, + 0x19ea: 0x00c3, 0x19eb: 0x00c3, 0x19ec: 0x00c3, 0x19ed: 0x00c3, 0x19ee: 0x00c3, 0x19ef: 0x00c3, + 0x19f0: 0x00c3, 0x19f1: 0x00c3, 0x19f2: 0x00c3, 0x19f3: 0x00c3, 0x19f4: 0x00c3, 0x19f5: 0x00c3, + 0x19f6: 0x00c3, 0x19f7: 0x00c3, 0x19f8: 0x00c3, 0x19f9: 0x00c3, 0x19fb: 0x00c3, + 0x19fc: 0x00c3, 0x19fd: 0x00c3, 0x19fe: 0x00c3, 0x19ff: 0x00c3, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x00c0, 0x1a01: 0x00c0, 0x1a02: 0x00c0, 0x1a03: 0x00c0, 0x1a04: 0x00c0, 0x1a05: 0x00c0, + 0x1a06: 0x00c0, 0x1a07: 0x00c0, 0x1a08: 0x00c0, 0x1a09: 0x00c0, 0x1a0a: 0x00c0, 0x1a0b: 0x00c0, + 0x1a0c: 0x00c0, 0x1a0d: 0x00c0, 0x1a0e: 0x00c0, 0x1a0f: 0x00c0, 0x1a10: 0x00c0, 0x1a11: 0x00c0, + 0x1a12: 0x00c0, 0x1a13: 0x00c0, 0x1a14: 0x00c0, 0x1a15: 0x00c0, 0x1a16: 0x00c0, 0x1a17: 0x00c0, + 0x1a18: 0x00c0, 0x1a19: 0x00c0, 0x1a1a: 0x0080, 0x1a1b: 0x0080, 0x1a1c: 0x00c0, 0x1a1d: 0x00c0, + 0x1a1e: 0x00c0, 0x1a1f: 0x00c0, 0x1a20: 0x00c0, 0x1a21: 0x00c0, 0x1a22: 0x00c0, 0x1a23: 0x00c0, + 0x1a24: 0x00c0, 0x1a25: 0x00c0, 0x1a26: 0x00c0, 0x1a27: 0x00c0, 0x1a28: 0x00c0, 0x1a29: 0x00c0, + 0x1a2a: 0x00c0, 0x1a2b: 0x00c0, 0x1a2c: 0x00c0, 0x1a2d: 0x00c0, 0x1a2e: 0x00c0, 0x1a2f: 0x00c0, + 0x1a30: 0x00c0, 0x1a31: 0x00c0, 0x1a32: 0x00c0, 0x1a33: 0x00c0, 0x1a34: 0x00c0, 0x1a35: 0x00c0, + 0x1a36: 0x00c0, 0x1a37: 0x00c0, 0x1a38: 0x00c0, 0x1a39: 0x00c0, 0x1a3a: 0x00c0, 0x1a3b: 0x00c0, + 0x1a3c: 0x00c0, 0x1a3d: 0x00c0, 0x1a3e: 0x00c0, 0x1a3f: 0x00c0, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x00c8, 0x1a41: 0x00c8, 0x1a42: 0x00c8, 0x1a43: 0x00c8, 0x1a44: 0x00c8, 0x1a45: 0x00c8, + 0x1a46: 0x00c8, 0x1a47: 0x00c8, 0x1a48: 0x00c8, 0x1a49: 0x00c8, 0x1a4a: 0x00c8, 0x1a4b: 0x00c8, + 0x1a4c: 0x00c8, 0x1a4d: 0x00c8, 0x1a4e: 0x00c8, 0x1a4f: 0x00c8, 0x1a50: 0x00c8, 0x1a51: 0x00c8, + 0x1a52: 0x00c8, 0x1a53: 0x00c8, 0x1a54: 0x00c8, 0x1a55: 0x00c8, + 0x1a58: 0x00c8, 0x1a59: 0x00c8, 0x1a5a: 0x00c8, 0x1a5b: 0x00c8, 0x1a5c: 0x00c8, 0x1a5d: 0x00c8, + 0x1a60: 0x00c8, 0x1a61: 0x00c8, 0x1a62: 0x00c8, 0x1a63: 0x00c8, + 0x1a64: 0x00c8, 0x1a65: 0x00c8, 0x1a66: 0x00c8, 0x1a67: 0x00c8, 0x1a68: 0x00c8, 0x1a69: 0x00c8, + 0x1a6a: 0x00c8, 0x1a6b: 0x00c8, 0x1a6c: 0x00c8, 0x1a6d: 0x00c8, 0x1a6e: 0x00c8, 0x1a6f: 0x00c8, + 0x1a70: 0x00c8, 0x1a71: 0x00c8, 0x1a72: 0x00c8, 0x1a73: 0x00c8, 0x1a74: 0x00c8, 0x1a75: 0x00c8, + 0x1a76: 0x00c8, 0x1a77: 0x00c8, 0x1a78: 0x00c8, 0x1a79: 0x00c8, 0x1a7a: 0x00c8, 0x1a7b: 0x00c8, + 0x1a7c: 0x00c8, 0x1a7d: 0x00c8, 0x1a7e: 0x00c8, 0x1a7f: 0x00c8, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x00c8, 0x1a81: 0x00c8, 0x1a82: 0x00c8, 0x1a83: 0x00c8, 0x1a84: 0x00c8, 0x1a85: 0x00c8, + 0x1a88: 0x00c8, 0x1a89: 0x00c8, 0x1a8a: 0x00c8, 0x1a8b: 0x00c8, + 0x1a8c: 0x00c8, 0x1a8d: 0x00c8, 0x1a90: 0x00c8, 0x1a91: 0x00c8, + 0x1a92: 0x00c8, 0x1a93: 0x00c8, 0x1a94: 0x00c8, 0x1a95: 0x00c8, 0x1a96: 0x00c8, 0x1a97: 0x00c8, + 0x1a99: 0x00c8, 0x1a9b: 0x00c8, 0x1a9d: 0x00c8, + 0x1a9f: 0x00c8, 0x1aa0: 0x00c8, 0x1aa1: 0x00c8, 0x1aa2: 0x00c8, 0x1aa3: 0x00c8, + 0x1aa4: 0x00c8, 0x1aa5: 0x00c8, 0x1aa6: 0x00c8, 0x1aa7: 0x00c8, 0x1aa8: 0x00c8, 0x1aa9: 0x00c8, + 0x1aaa: 0x00c8, 0x1aab: 0x00c8, 0x1aac: 0x00c8, 0x1aad: 0x00c8, 0x1aae: 0x00c8, 0x1aaf: 0x00c8, + 0x1ab0: 0x00c8, 0x1ab1: 0x0088, 0x1ab2: 0x00c8, 0x1ab3: 0x0088, 0x1ab4: 0x00c8, 0x1ab5: 0x0088, + 0x1ab6: 0x00c8, 0x1ab7: 0x0088, 0x1ab8: 0x00c8, 0x1ab9: 0x0088, 0x1aba: 0x00c8, 0x1abb: 0x0088, + 0x1abc: 0x00c8, 0x1abd: 0x0088, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x00c8, 0x1ac1: 0x00c8, 0x1ac2: 0x00c8, 0x1ac3: 0x00c8, 0x1ac4: 0x00c8, 0x1ac5: 0x00c8, + 0x1ac6: 0x00c8, 0x1ac7: 0x00c8, 0x1ac8: 0x0088, 0x1ac9: 0x0088, 0x1aca: 0x0088, 0x1acb: 0x0088, + 0x1acc: 0x0088, 0x1acd: 0x0088, 0x1ace: 0x0088, 0x1acf: 0x0088, 0x1ad0: 0x00c8, 0x1ad1: 0x00c8, + 0x1ad2: 0x00c8, 0x1ad3: 0x00c8, 0x1ad4: 0x00c8, 0x1ad5: 0x00c8, 0x1ad6: 0x00c8, 0x1ad7: 0x00c8, + 0x1ad8: 0x0088, 0x1ad9: 0x0088, 0x1ada: 0x0088, 0x1adb: 0x0088, 0x1adc: 0x0088, 0x1add: 0x0088, + 0x1ade: 0x0088, 0x1adf: 0x0088, 0x1ae0: 0x00c8, 0x1ae1: 0x00c8, 0x1ae2: 0x00c8, 0x1ae3: 0x00c8, + 0x1ae4: 0x00c8, 0x1ae5: 0x00c8, 0x1ae6: 0x00c8, 0x1ae7: 0x00c8, 0x1ae8: 0x0088, 0x1ae9: 0x0088, + 0x1aea: 0x0088, 0x1aeb: 0x0088, 0x1aec: 0x0088, 0x1aed: 0x0088, 0x1aee: 0x0088, 0x1aef: 0x0088, + 0x1af0: 0x00c8, 0x1af1: 0x00c8, 0x1af2: 0x00c8, 0x1af3: 0x00c8, 0x1af4: 0x00c8, + 0x1af6: 0x00c8, 0x1af7: 0x00c8, 0x1af8: 0x00c8, 0x1af9: 0x00c8, 0x1afa: 0x00c8, 0x1afb: 0x0088, + 0x1afc: 0x0088, 0x1afd: 0x0088, 0x1afe: 0x0088, 0x1aff: 0x0088, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x0088, 0x1b01: 0x0088, 0x1b02: 0x00c8, 0x1b03: 0x00c8, 0x1b04: 0x00c8, + 0x1b06: 0x00c8, 0x1b07: 0x00c8, 0x1b08: 0x00c8, 0x1b09: 0x0088, 0x1b0a: 0x00c8, 0x1b0b: 0x0088, + 0x1b0c: 0x0088, 0x1b0d: 0x0088, 0x1b0e: 0x0088, 0x1b0f: 0x0088, 0x1b10: 0x00c8, 0x1b11: 0x00c8, + 0x1b12: 0x00c8, 0x1b13: 0x0088, 0x1b16: 0x00c8, 0x1b17: 0x00c8, + 0x1b18: 0x00c8, 0x1b19: 0x00c8, 0x1b1a: 0x00c8, 0x1b1b: 0x0088, 0x1b1d: 0x0088, + 0x1b1e: 0x0088, 0x1b1f: 0x0088, 0x1b20: 0x00c8, 0x1b21: 0x00c8, 0x1b22: 0x00c8, 0x1b23: 0x0088, + 0x1b24: 0x00c8, 0x1b25: 0x00c8, 0x1b26: 0x00c8, 0x1b27: 0x00c8, 0x1b28: 0x00c8, 0x1b29: 0x00c8, + 0x1b2a: 0x00c8, 0x1b2b: 0x0088, 0x1b2c: 0x00c8, 0x1b2d: 0x0088, 0x1b2e: 0x0088, 0x1b2f: 0x0088, + 0x1b32: 0x00c8, 0x1b33: 0x00c8, 0x1b34: 0x00c8, + 0x1b36: 0x00c8, 0x1b37: 0x00c8, 0x1b38: 0x00c8, 0x1b39: 0x0088, 0x1b3a: 0x00c8, 0x1b3b: 0x0088, + 0x1b3c: 0x0088, 0x1b3d: 0x0088, 0x1b3e: 0x0088, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x0080, 0x1b41: 0x0080, 0x1b42: 0x0080, 0x1b43: 0x0080, 0x1b44: 0x0080, 0x1b45: 0x0080, + 0x1b46: 0x0080, 0x1b47: 0x0080, 0x1b48: 0x0080, 0x1b49: 0x0080, 0x1b4a: 0x0080, 0x1b4b: 0x0040, + 0x1b4c: 0x004d, 0x1b4d: 0x004e, 0x1b4e: 0x0040, 0x1b4f: 0x0040, 0x1b50: 0x0080, 0x1b51: 0x0080, + 0x1b52: 0x0080, 0x1b53: 0x0080, 0x1b54: 0x0080, 0x1b55: 0x0080, 0x1b56: 0x0080, 0x1b57: 0x0080, + 0x1b58: 0x0080, 0x1b59: 0x0080, 0x1b5a: 0x0080, 0x1b5b: 0x0080, 0x1b5c: 0x0080, 0x1b5d: 0x0080, + 0x1b5e: 0x0080, 0x1b5f: 0x0080, 0x1b60: 0x0080, 0x1b61: 0x0080, 0x1b62: 0x0080, 0x1b63: 0x0080, + 0x1b64: 0x0080, 0x1b65: 0x0080, 0x1b66: 0x0080, 0x1b67: 0x0080, 0x1b68: 0x0040, 0x1b69: 0x0040, + 0x1b6a: 0x0040, 0x1b6b: 0x0040, 0x1b6c: 0x0040, 0x1b6d: 0x0040, 0x1b6e: 0x0040, 0x1b6f: 0x0080, + 0x1b70: 0x0080, 0x1b71: 0x0080, 0x1b72: 0x0080, 0x1b73: 0x0080, 0x1b74: 0x0080, 0x1b75: 0x0080, + 0x1b76: 0x0080, 0x1b77: 0x0080, 0x1b78: 0x0080, 0x1b79: 0x0080, 0x1b7a: 0x0080, 0x1b7b: 0x0080, + 0x1b7c: 0x0080, 0x1b7d: 0x0080, 0x1b7e: 0x0080, 0x1b7f: 0x0080, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x0080, 0x1b81: 0x0080, 0x1b82: 0x0080, 0x1b83: 0x0080, 0x1b84: 0x0080, 0x1b85: 0x0080, + 0x1b86: 0x0080, 0x1b87: 0x0080, 0x1b88: 0x0080, 0x1b89: 0x0080, 0x1b8a: 0x0080, 0x1b8b: 0x0080, + 0x1b8c: 0x0080, 0x1b8d: 0x0080, 0x1b8e: 0x0080, 0x1b8f: 0x0080, 0x1b90: 0x0080, 0x1b91: 0x0080, + 0x1b92: 0x0080, 0x1b93: 0x0080, 0x1b94: 0x0080, 0x1b95: 0x0080, 0x1b96: 0x0080, 0x1b97: 0x0080, + 0x1b98: 0x0080, 0x1b99: 0x0080, 0x1b9a: 0x0080, 0x1b9b: 0x0080, 0x1b9c: 0x0080, 0x1b9d: 0x0080, + 0x1b9e: 0x0080, 0x1b9f: 0x0080, 0x1ba0: 0x0040, 0x1ba1: 0x0040, 0x1ba2: 0x0040, 0x1ba3: 0x0040, + 0x1ba4: 0x0040, 0x1ba6: 0x0040, 0x1ba7: 0x0040, 0x1ba8: 0x0040, 0x1ba9: 0x0040, + 0x1baa: 0x0040, 0x1bab: 0x0040, 0x1bac: 0x0040, 0x1bad: 0x0040, 0x1bae: 0x0040, 0x1baf: 0x0040, + 0x1bb0: 0x0080, 0x1bb1: 0x0080, 0x1bb4: 0x0080, 0x1bb5: 0x0080, + 0x1bb6: 0x0080, 0x1bb7: 0x0080, 0x1bb8: 0x0080, 0x1bb9: 0x0080, 0x1bba: 0x0080, 0x1bbb: 0x0080, + 0x1bbc: 0x0080, 0x1bbd: 0x0080, 0x1bbe: 0x0080, 0x1bbf: 0x0080, + // Block 0x6f, offset 0x1bc0 + 0x1bc0: 0x0080, 0x1bc1: 0x0080, 0x1bc2: 0x0080, 0x1bc3: 0x0080, 0x1bc4: 0x0080, 0x1bc5: 0x0080, + 0x1bc6: 0x0080, 0x1bc7: 0x0080, 0x1bc8: 0x0080, 0x1bc9: 0x0080, 0x1bca: 0x0080, 0x1bcb: 0x0080, + 0x1bcc: 0x0080, 0x1bcd: 0x0080, 0x1bce: 0x0080, 0x1bd0: 0x0080, 0x1bd1: 0x0080, + 0x1bd2: 0x0080, 0x1bd3: 0x0080, 0x1bd4: 0x0080, 0x1bd5: 0x0080, 0x1bd6: 0x0080, 0x1bd7: 0x0080, + 0x1bd8: 0x0080, 0x1bd9: 0x0080, 0x1bda: 0x0080, 0x1bdb: 0x0080, 0x1bdc: 0x0080, + 0x1be0: 0x0080, 0x1be1: 0x0080, 0x1be2: 0x0080, 0x1be3: 0x0080, + 0x1be4: 0x0080, 0x1be5: 0x0080, 0x1be6: 0x0080, 0x1be7: 0x0080, 0x1be8: 0x0080, 0x1be9: 0x0080, + 0x1bea: 0x0080, 0x1beb: 0x0080, 0x1bec: 0x0080, 0x1bed: 0x0080, 0x1bee: 0x0080, 0x1bef: 0x0080, + 0x1bf0: 0x0080, 0x1bf1: 0x0080, 0x1bf2: 0x0080, 0x1bf3: 0x0080, 0x1bf4: 0x0080, 0x1bf5: 0x0080, + 0x1bf6: 0x0080, 0x1bf7: 0x0080, 0x1bf8: 0x0080, 0x1bf9: 0x0080, 0x1bfa: 0x0080, 0x1bfb: 0x0080, + 0x1bfc: 0x0080, 0x1bfd: 0x0080, 0x1bfe: 0x0080, 0x1bff: 0x0080, + // Block 0x70, offset 0x1c00 + 0x1c10: 0x00c3, 0x1c11: 0x00c3, + 0x1c12: 0x00c3, 0x1c13: 0x00c3, 0x1c14: 0x00c3, 0x1c15: 0x00c3, 0x1c16: 0x00c3, 0x1c17: 0x00c3, + 0x1c18: 0x00c3, 0x1c19: 0x00c3, 0x1c1a: 0x00c3, 0x1c1b: 0x00c3, 0x1c1c: 0x00c3, 0x1c1d: 0x0083, + 0x1c1e: 0x0083, 0x1c1f: 0x0083, 0x1c20: 0x0083, 0x1c21: 0x00c3, 0x1c22: 0x0083, 0x1c23: 0x0083, + 0x1c24: 0x0083, 0x1c25: 0x00c3, 0x1c26: 0x00c3, 0x1c27: 0x00c3, 0x1c28: 0x00c3, 0x1c29: 0x00c3, + 0x1c2a: 0x00c3, 0x1c2b: 0x00c3, 0x1c2c: 0x00c3, 0x1c2d: 0x00c3, 0x1c2e: 0x00c3, 0x1c2f: 0x00c3, + 0x1c30: 0x00c3, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x0080, 0x1c41: 0x0080, 0x1c42: 0x0080, 0x1c43: 0x0080, 0x1c44: 0x0080, 0x1c45: 0x0080, + 0x1c46: 0x0080, 0x1c47: 0x0080, 0x1c48: 0x0080, 0x1c49: 0x0080, 0x1c4a: 0x0080, 0x1c4b: 0x0080, + 0x1c4c: 0x0080, 0x1c4d: 0x0080, 0x1c4e: 0x0080, 0x1c4f: 0x0080, 0x1c50: 0x0080, 0x1c51: 0x0080, + 0x1c52: 0x0080, 0x1c53: 0x0080, 0x1c54: 0x0080, 0x1c55: 0x0080, 0x1c56: 0x0080, 0x1c57: 0x0080, + 0x1c58: 0x0080, 0x1c59: 0x0080, 0x1c5a: 0x0080, 0x1c5b: 0x0080, 0x1c5c: 0x0080, 0x1c5d: 0x0080, + 0x1c5e: 0x0080, 0x1c5f: 0x0080, 0x1c60: 0x0080, 0x1c61: 0x0080, 0x1c62: 0x0080, 0x1c63: 0x0080, + 0x1c64: 0x0080, 0x1c65: 0x0080, 0x1c66: 0x0088, 0x1c67: 0x0080, 0x1c68: 0x0080, 0x1c69: 0x0080, + 0x1c6a: 0x0080, 0x1c6b: 0x0080, 0x1c6c: 0x0080, 0x1c6d: 0x0080, 0x1c6e: 0x0080, 0x1c6f: 0x0080, + 0x1c70: 0x0080, 0x1c71: 0x0080, 0x1c72: 0x00c0, 0x1c73: 0x0080, 0x1c74: 0x0080, 0x1c75: 0x0080, + 0x1c76: 0x0080, 0x1c77: 0x0080, 0x1c78: 0x0080, 0x1c79: 0x0080, 0x1c7a: 0x0080, 0x1c7b: 0x0080, + 0x1c7c: 0x0080, 0x1c7d: 0x0080, 0x1c7e: 0x0080, 0x1c7f: 0x0080, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x0080, 0x1c81: 0x0080, 0x1c82: 0x0080, 0x1c83: 0x0080, 0x1c84: 0x0080, 0x1c85: 0x0080, + 0x1c86: 0x0080, 0x1c87: 0x0080, 0x1c88: 0x0080, 0x1c89: 0x0080, 0x1c8a: 0x0080, 0x1c8b: 0x0080, + 0x1c8c: 0x0080, 0x1c8d: 0x0080, 0x1c8e: 0x00c0, 0x1c8f: 0x0080, 0x1c90: 0x0080, 0x1c91: 0x0080, + 0x1c92: 0x0080, 0x1c93: 0x0080, 0x1c94: 0x0080, 0x1c95: 0x0080, 0x1c96: 0x0080, 0x1c97: 0x0080, + 0x1c98: 0x0080, 0x1c99: 0x0080, 0x1c9a: 0x0080, 0x1c9b: 0x0080, 0x1c9c: 0x0080, 0x1c9d: 0x0080, + 0x1c9e: 0x0080, 0x1c9f: 0x0080, 0x1ca0: 0x0080, 0x1ca1: 0x0080, 0x1ca2: 0x0080, 0x1ca3: 0x0080, + 0x1ca4: 0x0080, 0x1ca5: 0x0080, 0x1ca6: 0x0080, 0x1ca7: 0x0080, 0x1ca8: 0x0080, 0x1ca9: 0x0080, + 0x1caa: 0x0080, 0x1cab: 0x0080, 0x1cac: 0x0080, 0x1cad: 0x0080, 0x1cae: 0x0080, 0x1caf: 0x0080, + 0x1cb0: 0x0080, 0x1cb1: 0x0080, 0x1cb2: 0x0080, 0x1cb3: 0x0080, 0x1cb4: 0x0080, 0x1cb5: 0x0080, + 0x1cb6: 0x0080, 0x1cb7: 0x0080, 0x1cb8: 0x0080, 0x1cb9: 0x0080, 0x1cba: 0x0080, 0x1cbb: 0x0080, + 0x1cbc: 0x0080, 0x1cbd: 0x0080, 0x1cbe: 0x0080, 0x1cbf: 0x0080, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0080, 0x1cc1: 0x0080, 0x1cc2: 0x0080, 0x1cc3: 0x00c0, 0x1cc4: 0x00c0, 0x1cc5: 0x0080, + 0x1cc6: 0x0080, 0x1cc7: 0x0080, 0x1cc8: 0x0080, 0x1cc9: 0x0080, 0x1cca: 0x0080, 0x1ccb: 0x0080, + 0x1cd0: 0x0080, 0x1cd1: 0x0080, + 0x1cd2: 0x0080, 0x1cd3: 0x0080, 0x1cd4: 0x0080, 0x1cd5: 0x0080, 0x1cd6: 0x0080, 0x1cd7: 0x0080, + 0x1cd8: 0x0080, 0x1cd9: 0x0080, 0x1cda: 0x0080, 0x1cdb: 0x0080, 0x1cdc: 0x0080, 0x1cdd: 0x0080, + 0x1cde: 0x0080, 0x1cdf: 0x0080, 0x1ce0: 0x0080, 0x1ce1: 0x0080, 0x1ce2: 0x0080, 0x1ce3: 0x0080, + 0x1ce4: 0x0080, 0x1ce5: 0x0080, 0x1ce6: 0x0080, 0x1ce7: 0x0080, 0x1ce8: 0x0080, 0x1ce9: 0x0080, + 0x1cea: 0x0080, 0x1ceb: 0x0080, 0x1cec: 0x0080, 0x1ced: 0x0080, 0x1cee: 0x0080, 0x1cef: 0x0080, + 0x1cf0: 0x0080, 0x1cf1: 0x0080, 0x1cf2: 0x0080, 0x1cf3: 0x0080, 0x1cf4: 0x0080, 0x1cf5: 0x0080, + 0x1cf6: 0x0080, 0x1cf7: 0x0080, 0x1cf8: 0x0080, 0x1cf9: 0x0080, 0x1cfa: 0x0080, 0x1cfb: 0x0080, + 0x1cfc: 0x0080, 0x1cfd: 0x0080, 0x1cfe: 0x0080, 0x1cff: 0x0080, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0080, 0x1d01: 0x0080, 0x1d02: 0x0080, 0x1d03: 0x0080, 0x1d04: 0x0080, 0x1d05: 0x0080, + 0x1d06: 0x0080, 0x1d07: 0x0080, 0x1d08: 0x0080, 0x1d09: 0x0080, 0x1d0a: 0x0080, 0x1d0b: 0x0080, + 0x1d0c: 0x0080, 0x1d0d: 0x0080, 0x1d0e: 0x0080, 0x1d0f: 0x0080, 0x1d10: 0x0080, 0x1d11: 0x0080, + 0x1d12: 0x0080, 0x1d13: 0x0080, 0x1d14: 0x0080, 0x1d15: 0x0080, 0x1d16: 0x0080, 0x1d17: 0x0080, + 0x1d18: 0x0080, 0x1d19: 0x0080, 0x1d1a: 0x0080, 0x1d1b: 0x0080, 0x1d1c: 0x0080, 0x1d1d: 0x0080, + 0x1d1e: 0x0080, 0x1d1f: 0x0080, 0x1d20: 0x0080, 0x1d21: 0x0080, 0x1d22: 0x0080, 0x1d23: 0x0080, + 0x1d24: 0x0080, 0x1d25: 0x0080, 0x1d26: 0x0080, 0x1d27: 0x0080, 0x1d28: 0x0080, 0x1d29: 0x0080, + 0x1d2a: 0x0080, 0x1d2b: 0x0080, 0x1d2c: 0x0080, 0x1d2d: 0x0080, 0x1d2e: 0x0080, 0x1d2f: 0x0080, + 0x1d30: 0x0080, 0x1d31: 0x0080, 0x1d32: 0x0080, 0x1d33: 0x0080, 0x1d34: 0x0080, 0x1d35: 0x0080, + 0x1d36: 0x0080, 0x1d37: 0x0080, 0x1d38: 0x0080, 0x1d39: 0x0080, 0x1d3a: 0x0080, 0x1d3b: 0x0080, + 0x1d3c: 0x0080, 0x1d3d: 0x0080, 0x1d3e: 0x0080, 0x1d3f: 0x0080, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0080, 0x1d41: 0x0080, 0x1d42: 0x0080, 0x1d43: 0x0080, 0x1d44: 0x0080, 0x1d45: 0x0080, + 0x1d46: 0x0080, 0x1d47: 0x0080, 0x1d48: 0x0080, 0x1d49: 0x0080, 0x1d4a: 0x0080, 0x1d4b: 0x0080, + 0x1d4c: 0x0080, 0x1d4d: 0x0080, 0x1d4e: 0x0080, 0x1d4f: 0x0080, 0x1d50: 0x0080, 0x1d51: 0x0080, + 0x1d52: 0x0080, 0x1d53: 0x0080, 0x1d54: 0x0080, 0x1d55: 0x0080, 0x1d56: 0x0080, 0x1d57: 0x0080, + 0x1d58: 0x0080, 0x1d59: 0x0080, 0x1d5a: 0x0080, 0x1d5b: 0x0080, 0x1d5c: 0x0080, 0x1d5d: 0x0080, + 0x1d5e: 0x0080, 0x1d5f: 0x0080, 0x1d60: 0x0080, 0x1d61: 0x0080, 0x1d62: 0x0080, 0x1d63: 0x0080, + 0x1d64: 0x0080, 0x1d65: 0x0080, 0x1d66: 0x0080, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x0080, 0x1d81: 0x0080, 0x1d82: 0x0080, 0x1d83: 0x0080, 0x1d84: 0x0080, 0x1d85: 0x0080, + 0x1d86: 0x0080, 0x1d87: 0x0080, 0x1d88: 0x0080, 0x1d89: 0x0080, 0x1d8a: 0x0080, + 0x1da0: 0x0080, 0x1da1: 0x0080, 0x1da2: 0x0080, 0x1da3: 0x0080, + 0x1da4: 0x0080, 0x1da5: 0x0080, 0x1da6: 0x0080, 0x1da7: 0x0080, 0x1da8: 0x0080, 0x1da9: 0x0080, + 0x1daa: 0x0080, 0x1dab: 0x0080, 0x1dac: 0x0080, 0x1dad: 0x0080, 0x1dae: 0x0080, 0x1daf: 0x0080, + 0x1db0: 0x0080, 0x1db1: 0x0080, 0x1db2: 0x0080, 0x1db3: 0x0080, 0x1db4: 0x0080, 0x1db5: 0x0080, + 0x1db6: 0x0080, 0x1db7: 0x0080, 0x1db8: 0x0080, 0x1db9: 0x0080, 0x1dba: 0x0080, 0x1dbb: 0x0080, + 0x1dbc: 0x0080, 0x1dbd: 0x0080, 0x1dbe: 0x0080, 0x1dbf: 0x0080, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x0080, 0x1dc1: 0x0080, 0x1dc2: 0x0080, 0x1dc3: 0x0080, 0x1dc4: 0x0080, 0x1dc5: 0x0080, + 0x1dc6: 0x0080, 0x1dc7: 0x0080, 0x1dc8: 0x0080, 0x1dc9: 0x0080, 0x1dca: 0x0080, 0x1dcb: 0x0080, + 0x1dcc: 0x0080, 0x1dcd: 0x0080, 0x1dce: 0x0080, 0x1dcf: 0x0080, 0x1dd0: 0x0080, 0x1dd1: 0x0080, + 0x1dd2: 0x0080, 0x1dd3: 0x0080, 0x1dd4: 0x0080, 0x1dd5: 0x0080, 0x1dd6: 0x0080, 0x1dd7: 0x0080, + 0x1dd8: 0x0080, 0x1dd9: 0x0080, 0x1dda: 0x0080, 0x1ddb: 0x0080, 0x1ddc: 0x0080, 0x1ddd: 0x0080, + 0x1dde: 0x0080, 0x1ddf: 0x0080, 0x1de0: 0x0080, 0x1de1: 0x0080, 0x1de2: 0x0080, 0x1de3: 0x0080, + 0x1de4: 0x0080, 0x1de5: 0x0080, 0x1de6: 0x0080, 0x1de7: 0x0080, 0x1de8: 0x0080, 0x1de9: 0x0080, + 0x1dea: 0x0080, 0x1deb: 0x0080, 0x1dec: 0x0080, 0x1ded: 0x0080, 0x1dee: 0x0080, 0x1def: 0x0080, + 0x1df0: 0x0080, 0x1df1: 0x0080, 0x1df2: 0x0080, 0x1df3: 0x0080, + 0x1df6: 0x0080, 0x1df7: 0x0080, 0x1df8: 0x0080, 0x1df9: 0x0080, 0x1dfa: 0x0080, 0x1dfb: 0x0080, + 0x1dfc: 0x0080, 0x1dfd: 0x0080, 0x1dfe: 0x0080, 0x1dff: 0x0080, + // Block 0x78, offset 0x1e00 + 0x1e00: 0x0080, 0x1e01: 0x0080, 0x1e02: 0x0080, 0x1e03: 0x0080, 0x1e04: 0x0080, 0x1e05: 0x0080, + 0x1e06: 0x0080, 0x1e07: 0x0080, 0x1e08: 0x0080, 0x1e09: 0x0080, 0x1e0a: 0x0080, 0x1e0b: 0x0080, + 0x1e0c: 0x0080, 0x1e0d: 0x0080, 0x1e0e: 0x0080, 0x1e0f: 0x0080, 0x1e10: 0x0080, 0x1e11: 0x0080, + 0x1e12: 0x0080, 0x1e13: 0x0080, 0x1e14: 0x0080, 0x1e15: 0x0080, 0x1e17: 0x0080, + 0x1e18: 0x0080, 0x1e19: 0x0080, 0x1e1a: 0x0080, 0x1e1b: 0x0080, 0x1e1c: 0x0080, 0x1e1d: 0x0080, + 0x1e1e: 0x0080, 0x1e1f: 0x0080, 0x1e20: 0x0080, 0x1e21: 0x0080, 0x1e22: 0x0080, 0x1e23: 0x0080, + 0x1e24: 0x0080, 0x1e25: 0x0080, 0x1e26: 0x0080, 0x1e27: 0x0080, 0x1e28: 0x0080, 0x1e29: 0x0080, + 0x1e2a: 0x0080, 0x1e2b: 0x0080, 0x1e2c: 0x0080, 0x1e2d: 0x0080, 0x1e2e: 0x0080, 0x1e2f: 0x0080, + 0x1e30: 0x0080, 0x1e31: 0x0080, 0x1e32: 0x0080, 0x1e33: 0x0080, 0x1e34: 0x0080, 0x1e35: 0x0080, + 0x1e36: 0x0080, 0x1e37: 0x0080, 0x1e38: 0x0080, 0x1e39: 0x0080, 0x1e3a: 0x0080, 0x1e3b: 0x0080, + 0x1e3c: 0x0080, 0x1e3d: 0x0080, 0x1e3e: 0x0080, 0x1e3f: 0x0080, + // Block 0x79, offset 0x1e40 + 0x1e40: 0x00c0, 0x1e41: 0x00c0, 0x1e42: 0x00c0, 0x1e43: 0x00c0, 0x1e44: 0x00c0, 0x1e45: 0x00c0, + 0x1e46: 0x00c0, 0x1e47: 0x00c0, 0x1e48: 0x00c0, 0x1e49: 0x00c0, 0x1e4a: 0x00c0, 0x1e4b: 0x00c0, + 0x1e4c: 0x00c0, 0x1e4d: 0x00c0, 0x1e4e: 0x00c0, 0x1e4f: 0x00c0, 0x1e50: 0x00c0, 0x1e51: 0x00c0, + 0x1e52: 0x00c0, 0x1e53: 0x00c0, 0x1e54: 0x00c0, 0x1e55: 0x00c0, 0x1e56: 0x00c0, 0x1e57: 0x00c0, + 0x1e58: 0x00c0, 0x1e59: 0x00c0, 0x1e5a: 0x00c0, 0x1e5b: 0x00c0, 0x1e5c: 0x00c0, 0x1e5d: 0x00c0, + 0x1e5e: 0x00c0, 0x1e5f: 0x00c0, 0x1e60: 0x00c0, 0x1e61: 0x00c0, 0x1e62: 0x00c0, 0x1e63: 0x00c0, + 0x1e64: 0x00c0, 0x1e65: 0x00c0, 0x1e66: 0x00c0, 0x1e67: 0x00c0, 0x1e68: 0x00c0, 0x1e69: 0x00c0, + 0x1e6a: 0x00c0, 0x1e6b: 0x00c0, 0x1e6c: 0x00c0, 0x1e6d: 0x00c0, 0x1e6e: 0x00c0, + 0x1e70: 0x00c0, 0x1e71: 0x00c0, 0x1e72: 0x00c0, 0x1e73: 0x00c0, 0x1e74: 0x00c0, 0x1e75: 0x00c0, + 0x1e76: 0x00c0, 0x1e77: 0x00c0, 0x1e78: 0x00c0, 0x1e79: 0x00c0, 0x1e7a: 0x00c0, 0x1e7b: 0x00c0, + 0x1e7c: 0x00c0, 0x1e7d: 0x00c0, 0x1e7e: 0x00c0, 0x1e7f: 0x00c0, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x00c0, 0x1e81: 0x00c0, 0x1e82: 0x00c0, 0x1e83: 0x00c0, 0x1e84: 0x00c0, 0x1e85: 0x00c0, + 0x1e86: 0x00c0, 0x1e87: 0x00c0, 0x1e88: 0x00c0, 0x1e89: 0x00c0, 0x1e8a: 0x00c0, 0x1e8b: 0x00c0, + 0x1e8c: 0x00c0, 0x1e8d: 0x00c0, 0x1e8e: 0x00c0, 0x1e8f: 0x00c0, 0x1e90: 0x00c0, 0x1e91: 0x00c0, + 0x1e92: 0x00c0, 0x1e93: 0x00c0, 0x1e94: 0x00c0, 0x1e95: 0x00c0, 0x1e96: 0x00c0, 0x1e97: 0x00c0, + 0x1e98: 0x00c0, 0x1e99: 0x00c0, 0x1e9a: 0x00c0, 0x1e9b: 0x00c0, 0x1e9c: 0x00c0, 0x1e9d: 0x00c0, + 0x1e9e: 0x00c0, 0x1ea0: 0x00c0, 0x1ea1: 0x00c0, 0x1ea2: 0x00c0, 0x1ea3: 0x00c0, + 0x1ea4: 0x00c0, 0x1ea5: 0x00c0, 0x1ea6: 0x00c0, 0x1ea7: 0x00c0, 0x1ea8: 0x00c0, 0x1ea9: 0x00c0, + 0x1eaa: 0x00c0, 0x1eab: 0x00c0, 0x1eac: 0x00c0, 0x1ead: 0x00c0, 0x1eae: 0x00c0, 0x1eaf: 0x00c0, + 0x1eb0: 0x00c0, 0x1eb1: 0x00c0, 0x1eb2: 0x00c0, 0x1eb3: 0x00c0, 0x1eb4: 0x00c0, 0x1eb5: 0x00c0, + 0x1eb6: 0x00c0, 0x1eb7: 0x00c0, 0x1eb8: 0x00c0, 0x1eb9: 0x00c0, 0x1eba: 0x00c0, 0x1ebb: 0x00c0, + 0x1ebc: 0x0080, 0x1ebd: 0x0080, 0x1ebe: 0x00c0, 0x1ebf: 0x00c0, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x00c0, 0x1ec1: 0x00c0, 0x1ec2: 0x00c0, 0x1ec3: 0x00c0, 0x1ec4: 0x00c0, 0x1ec5: 0x00c0, + 0x1ec6: 0x00c0, 0x1ec7: 0x00c0, 0x1ec8: 0x00c0, 0x1ec9: 0x00c0, 0x1eca: 0x00c0, 0x1ecb: 0x00c0, + 0x1ecc: 0x00c0, 0x1ecd: 0x00c0, 0x1ece: 0x00c0, 0x1ecf: 0x00c0, 0x1ed0: 0x00c0, 0x1ed1: 0x00c0, + 0x1ed2: 0x00c0, 0x1ed3: 0x00c0, 0x1ed4: 0x00c0, 0x1ed5: 0x00c0, 0x1ed6: 0x00c0, 0x1ed7: 0x00c0, + 0x1ed8: 0x00c0, 0x1ed9: 0x00c0, 0x1eda: 0x00c0, 0x1edb: 0x00c0, 0x1edc: 0x00c0, 0x1edd: 0x00c0, + 0x1ede: 0x00c0, 0x1edf: 0x00c0, 0x1ee0: 0x00c0, 0x1ee1: 0x00c0, 0x1ee2: 0x00c0, 0x1ee3: 0x00c0, + 0x1ee4: 0x00c0, 0x1ee5: 0x0080, 0x1ee6: 0x0080, 0x1ee7: 0x0080, 0x1ee8: 0x0080, 0x1ee9: 0x0080, + 0x1eea: 0x0080, 0x1eeb: 0x00c0, 0x1eec: 0x00c0, 0x1eed: 0x00c0, 0x1eee: 0x00c0, 0x1eef: 0x00c3, + 0x1ef0: 0x00c3, 0x1ef1: 0x00c3, 0x1ef2: 0x00c0, 0x1ef3: 0x00c0, + 0x1ef9: 0x0080, 0x1efa: 0x0080, 0x1efb: 0x0080, + 0x1efc: 0x0080, 0x1efd: 0x0080, 0x1efe: 0x0080, 0x1eff: 0x0080, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0x00c0, 0x1f01: 0x00c0, 0x1f02: 0x00c0, 0x1f03: 0x00c0, 0x1f04: 0x00c0, 0x1f05: 0x00c0, + 0x1f06: 0x00c0, 0x1f07: 0x00c0, 0x1f08: 0x00c0, 0x1f09: 0x00c0, 0x1f0a: 0x00c0, 0x1f0b: 0x00c0, + 0x1f0c: 0x00c0, 0x1f0d: 0x00c0, 0x1f0e: 0x00c0, 0x1f0f: 0x00c0, 0x1f10: 0x00c0, 0x1f11: 0x00c0, + 0x1f12: 0x00c0, 0x1f13: 0x00c0, 0x1f14: 0x00c0, 0x1f15: 0x00c0, 0x1f16: 0x00c0, 0x1f17: 0x00c0, + 0x1f18: 0x00c0, 0x1f19: 0x00c0, 0x1f1a: 0x00c0, 0x1f1b: 0x00c0, 0x1f1c: 0x00c0, 0x1f1d: 0x00c0, + 0x1f1e: 0x00c0, 0x1f1f: 0x00c0, 0x1f20: 0x00c0, 0x1f21: 0x00c0, 0x1f22: 0x00c0, 0x1f23: 0x00c0, + 0x1f24: 0x00c0, 0x1f25: 0x00c0, 0x1f27: 0x00c0, + 0x1f2d: 0x00c0, + 0x1f30: 0x00c0, 0x1f31: 0x00c0, 0x1f32: 0x00c0, 0x1f33: 0x00c0, 0x1f34: 0x00c0, 0x1f35: 0x00c0, + 0x1f36: 0x00c0, 0x1f37: 0x00c0, 0x1f38: 0x00c0, 0x1f39: 0x00c0, 0x1f3a: 0x00c0, 0x1f3b: 0x00c0, + 0x1f3c: 0x00c0, 0x1f3d: 0x00c0, 0x1f3e: 0x00c0, 0x1f3f: 0x00c0, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0x00c0, 0x1f41: 0x00c0, 0x1f42: 0x00c0, 0x1f43: 0x00c0, 0x1f44: 0x00c0, 0x1f45: 0x00c0, + 0x1f46: 0x00c0, 0x1f47: 0x00c0, 0x1f48: 0x00c0, 0x1f49: 0x00c0, 0x1f4a: 0x00c0, 0x1f4b: 0x00c0, + 0x1f4c: 0x00c0, 0x1f4d: 0x00c0, 0x1f4e: 0x00c0, 0x1f4f: 0x00c0, 0x1f50: 0x00c0, 0x1f51: 0x00c0, + 0x1f52: 0x00c0, 0x1f53: 0x00c0, 0x1f54: 0x00c0, 0x1f55: 0x00c0, 0x1f56: 0x00c0, 0x1f57: 0x00c0, + 0x1f58: 0x00c0, 0x1f59: 0x00c0, 0x1f5a: 0x00c0, 0x1f5b: 0x00c0, 0x1f5c: 0x00c0, 0x1f5d: 0x00c0, + 0x1f5e: 0x00c0, 0x1f5f: 0x00c0, 0x1f60: 0x00c0, 0x1f61: 0x00c0, 0x1f62: 0x00c0, 0x1f63: 0x00c0, + 0x1f64: 0x00c0, 0x1f65: 0x00c0, 0x1f66: 0x00c0, 0x1f67: 0x00c0, + 0x1f6f: 0x0080, + 0x1f70: 0x0080, + 0x1f7f: 0x00c6, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0x00c0, 0x1f81: 0x00c0, 0x1f82: 0x00c0, 0x1f83: 0x00c0, 0x1f84: 0x00c0, 0x1f85: 0x00c0, + 0x1f86: 0x00c0, 0x1f87: 0x00c0, 0x1f88: 0x00c0, 0x1f89: 0x00c0, 0x1f8a: 0x00c0, 0x1f8b: 0x00c0, + 0x1f8c: 0x00c0, 0x1f8d: 0x00c0, 0x1f8e: 0x00c0, 0x1f8f: 0x00c0, 0x1f90: 0x00c0, 0x1f91: 0x00c0, + 0x1f92: 0x00c0, 0x1f93: 0x00c0, 0x1f94: 0x00c0, 0x1f95: 0x00c0, 0x1f96: 0x00c0, + 0x1fa0: 0x00c0, 0x1fa1: 0x00c0, 0x1fa2: 0x00c0, 0x1fa3: 0x00c0, + 0x1fa4: 0x00c0, 0x1fa5: 0x00c0, 0x1fa6: 0x00c0, 0x1fa8: 0x00c0, 0x1fa9: 0x00c0, + 0x1faa: 0x00c0, 0x1fab: 0x00c0, 0x1fac: 0x00c0, 0x1fad: 0x00c0, 0x1fae: 0x00c0, + 0x1fb0: 0x00c0, 0x1fb1: 0x00c0, 0x1fb2: 0x00c0, 0x1fb3: 0x00c0, 0x1fb4: 0x00c0, 0x1fb5: 0x00c0, + 0x1fb6: 0x00c0, 0x1fb8: 0x00c0, 0x1fb9: 0x00c0, 0x1fba: 0x00c0, 0x1fbb: 0x00c0, + 0x1fbc: 0x00c0, 0x1fbd: 0x00c0, 0x1fbe: 0x00c0, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x00c0, 0x1fc1: 0x00c0, 0x1fc2: 0x00c0, 0x1fc3: 0x00c0, 0x1fc4: 0x00c0, 0x1fc5: 0x00c0, + 0x1fc6: 0x00c0, 0x1fc8: 0x00c0, 0x1fc9: 0x00c0, 0x1fca: 0x00c0, 0x1fcb: 0x00c0, + 0x1fcc: 0x00c0, 0x1fcd: 0x00c0, 0x1fce: 0x00c0, 0x1fd0: 0x00c0, 0x1fd1: 0x00c0, + 0x1fd2: 0x00c0, 0x1fd3: 0x00c0, 0x1fd4: 0x00c0, 0x1fd5: 0x00c0, 0x1fd6: 0x00c0, + 0x1fd8: 0x00c0, 0x1fd9: 0x00c0, 0x1fda: 0x00c0, 0x1fdb: 0x00c0, 0x1fdc: 0x00c0, 0x1fdd: 0x00c0, + 0x1fde: 0x00c0, 0x1fe0: 0x00c3, 0x1fe1: 0x00c3, 0x1fe2: 0x00c3, 0x1fe3: 0x00c3, + 0x1fe4: 0x00c3, 0x1fe5: 0x00c3, 0x1fe6: 0x00c3, 0x1fe7: 0x00c3, 0x1fe8: 0x00c3, 0x1fe9: 0x00c3, + 0x1fea: 0x00c3, 0x1feb: 0x00c3, 0x1fec: 0x00c3, 0x1fed: 0x00c3, 0x1fee: 0x00c3, 0x1fef: 0x00c3, + 0x1ff0: 0x00c3, 0x1ff1: 0x00c3, 0x1ff2: 0x00c3, 0x1ff3: 0x00c3, 0x1ff4: 0x00c3, 0x1ff5: 0x00c3, + 0x1ff6: 0x00c3, 0x1ff7: 0x00c3, 0x1ff8: 0x00c3, 0x1ff9: 0x00c3, 0x1ffa: 0x00c3, 0x1ffb: 0x00c3, + 0x1ffc: 0x00c3, 0x1ffd: 0x00c3, 0x1ffe: 0x00c3, 0x1fff: 0x00c3, + // Block 0x80, offset 0x2000 + 0x2000: 0x0080, 0x2001: 0x0080, 0x2002: 0x0080, 0x2003: 0x0080, 0x2004: 0x0080, 0x2005: 0x0080, + 0x2006: 0x0080, 0x2007: 0x0080, 0x2008: 0x0080, 0x2009: 0x0080, 0x200a: 0x0080, 0x200b: 0x0080, + 0x200c: 0x0080, 0x200d: 0x0080, 0x200e: 0x0080, 0x200f: 0x0080, 0x2010: 0x0080, 0x2011: 0x0080, + 0x2012: 0x0080, 0x2013: 0x0080, 0x2014: 0x0080, 0x2015: 0x0080, 0x2016: 0x0080, 0x2017: 0x0080, + 0x2018: 0x0080, 0x2019: 0x0080, 0x201a: 0x0080, 0x201b: 0x0080, 0x201c: 0x0080, 0x201d: 0x0080, + 0x201e: 0x0080, 0x201f: 0x0080, 0x2020: 0x0080, 0x2021: 0x0080, 0x2022: 0x0080, 0x2023: 0x0080, + 0x2024: 0x0080, 0x2025: 0x0080, 0x2026: 0x0080, 0x2027: 0x0080, 0x2028: 0x0080, 0x2029: 0x0080, + 0x202a: 0x0080, 0x202b: 0x0080, 0x202c: 0x0080, 0x202d: 0x0080, 0x202e: 0x0080, 0x202f: 0x00c0, + 0x2030: 0x0080, 0x2031: 0x0080, 0x2032: 0x0080, 0x2033: 0x0080, 0x2034: 0x0080, 0x2035: 0x0080, + 0x2036: 0x0080, 0x2037: 0x0080, 0x2038: 0x0080, 0x2039: 0x0080, 0x203a: 0x0080, 0x203b: 0x0080, + 0x203c: 0x0080, 0x203d: 0x0080, 0x203e: 0x0080, 0x203f: 0x0080, + // Block 0x81, offset 0x2040 + 0x2040: 0x0080, 0x2041: 0x0080, 0x2042: 0x0080, 0x2043: 0x0080, 0x2044: 0x0080, 0x2045: 0x0080, + 0x2046: 0x0080, 0x2047: 0x0080, 0x2048: 0x0080, 0x2049: 0x0080, 0x204a: 0x0080, 0x204b: 0x0080, + 0x204c: 0x0080, 0x204d: 0x0080, 0x204e: 0x0080, 0x204f: 0x0080, 0x2050: 0x0080, 0x2051: 0x0080, + 0x2052: 0x0080, + // Block 0x82, offset 0x2080 + 0x2080: 0x008c, 0x2081: 0x008c, 0x2082: 0x008c, 0x2083: 0x008c, 0x2084: 0x008c, 0x2085: 0x008c, + 0x2086: 0x008c, 0x2087: 0x008c, 0x2088: 0x008c, 0x2089: 0x008c, 0x208a: 0x008c, 0x208b: 0x008c, + 0x208c: 0x008c, 0x208d: 0x008c, 0x208e: 0x008c, 0x208f: 0x008c, 0x2090: 0x008c, 0x2091: 0x008c, + 0x2092: 0x008c, 0x2093: 0x008c, 0x2094: 0x008c, 0x2095: 0x008c, 0x2096: 0x008c, 0x2097: 0x008c, + 0x2098: 0x008c, 0x2099: 0x008c, 0x209b: 0x008c, 0x209c: 0x008c, 0x209d: 0x008c, + 0x209e: 0x008c, 0x209f: 0x008c, 0x20a0: 0x008c, 0x20a1: 0x008c, 0x20a2: 0x008c, 0x20a3: 0x008c, + 0x20a4: 0x008c, 0x20a5: 0x008c, 0x20a6: 0x008c, 0x20a7: 0x008c, 0x20a8: 0x008c, 0x20a9: 0x008c, + 0x20aa: 0x008c, 0x20ab: 0x008c, 0x20ac: 0x008c, 0x20ad: 0x008c, 0x20ae: 0x008c, 0x20af: 0x008c, + 0x20b0: 0x008c, 0x20b1: 0x008c, 0x20b2: 0x008c, 0x20b3: 0x008c, 0x20b4: 0x008c, 0x20b5: 0x008c, + 0x20b6: 0x008c, 0x20b7: 0x008c, 0x20b8: 0x008c, 0x20b9: 0x008c, 0x20ba: 0x008c, 0x20bb: 0x008c, + 0x20bc: 0x008c, 0x20bd: 0x008c, 0x20be: 0x008c, 0x20bf: 0x008c, + // Block 0x83, offset 0x20c0 + 0x20c0: 0x008c, 0x20c1: 0x008c, 0x20c2: 0x008c, 0x20c3: 0x008c, 0x20c4: 0x008c, 0x20c5: 0x008c, + 0x20c6: 0x008c, 0x20c7: 0x008c, 0x20c8: 0x008c, 0x20c9: 0x008c, 0x20ca: 0x008c, 0x20cb: 0x008c, + 0x20cc: 0x008c, 0x20cd: 0x008c, 0x20ce: 0x008c, 0x20cf: 0x008c, 0x20d0: 0x008c, 0x20d1: 0x008c, + 0x20d2: 0x008c, 0x20d3: 0x008c, 0x20d4: 0x008c, 0x20d5: 0x008c, 0x20d6: 0x008c, 0x20d7: 0x008c, + 0x20d8: 0x008c, 0x20d9: 0x008c, 0x20da: 0x008c, 0x20db: 0x008c, 0x20dc: 0x008c, 0x20dd: 0x008c, + 0x20de: 0x008c, 0x20df: 0x008c, 0x20e0: 0x008c, 0x20e1: 0x008c, 0x20e2: 0x008c, 0x20e3: 0x008c, + 0x20e4: 0x008c, 0x20e5: 0x008c, 0x20e6: 0x008c, 0x20e7: 0x008c, 0x20e8: 0x008c, 0x20e9: 0x008c, + 0x20ea: 0x008c, 0x20eb: 0x008c, 0x20ec: 0x008c, 0x20ed: 0x008c, 0x20ee: 0x008c, 0x20ef: 0x008c, + 0x20f0: 0x008c, 0x20f1: 0x008c, 0x20f2: 0x008c, 0x20f3: 0x008c, + // Block 0x84, offset 0x2100 + 0x2100: 0x008c, 0x2101: 0x008c, 0x2102: 0x008c, 0x2103: 0x008c, 0x2104: 0x008c, 0x2105: 0x008c, + 0x2106: 0x008c, 0x2107: 0x008c, 0x2108: 0x008c, 0x2109: 0x008c, 0x210a: 0x008c, 0x210b: 0x008c, + 0x210c: 0x008c, 0x210d: 0x008c, 0x210e: 0x008c, 0x210f: 0x008c, 0x2110: 0x008c, 0x2111: 0x008c, + 0x2112: 0x008c, 0x2113: 0x008c, 0x2114: 0x008c, 0x2115: 0x008c, 0x2116: 0x008c, 0x2117: 0x008c, + 0x2118: 0x008c, 0x2119: 0x008c, 0x211a: 0x008c, 0x211b: 0x008c, 0x211c: 0x008c, 0x211d: 0x008c, + 0x211e: 0x008c, 0x211f: 0x008c, 0x2120: 0x008c, 0x2121: 0x008c, 0x2122: 0x008c, 0x2123: 0x008c, + 0x2124: 0x008c, 0x2125: 0x008c, 0x2126: 0x008c, 0x2127: 0x008c, 0x2128: 0x008c, 0x2129: 0x008c, + 0x212a: 0x008c, 0x212b: 0x008c, 0x212c: 0x008c, 0x212d: 0x008c, 0x212e: 0x008c, 0x212f: 0x008c, + 0x2130: 0x008c, 0x2131: 0x008c, 0x2132: 0x008c, 0x2133: 0x008c, 0x2134: 0x008c, 0x2135: 0x008c, + 0x2136: 0x008c, 0x2137: 0x008c, 0x2138: 0x008c, 0x2139: 0x008c, 0x213a: 0x008c, 0x213b: 0x008c, + 0x213c: 0x008c, 0x213d: 0x008c, 0x213e: 0x008c, 0x213f: 0x008c, + // Block 0x85, offset 0x2140 + 0x2140: 0x008c, 0x2141: 0x008c, 0x2142: 0x008c, 0x2143: 0x008c, 0x2144: 0x008c, 0x2145: 0x008c, + 0x2146: 0x008c, 0x2147: 0x008c, 0x2148: 0x008c, 0x2149: 0x008c, 0x214a: 0x008c, 0x214b: 0x008c, + 0x214c: 0x008c, 0x214d: 0x008c, 0x214e: 0x008c, 0x214f: 0x008c, 0x2150: 0x008c, 0x2151: 0x008c, + 0x2152: 0x008c, 0x2153: 0x008c, 0x2154: 0x008c, 0x2155: 0x008c, + 0x2170: 0x0080, 0x2171: 0x0080, 0x2172: 0x0080, 0x2173: 0x0080, 0x2174: 0x0080, 0x2175: 0x0080, + 0x2176: 0x0080, 0x2177: 0x0080, 0x2178: 0x0080, 0x2179: 0x0080, 0x217a: 0x0080, 0x217b: 0x0080, + // Block 0x86, offset 0x2180 + 0x2180: 0x0080, 0x2181: 0x0080, 0x2182: 0x0080, 0x2183: 0x0080, 0x2184: 0x0080, 0x2185: 0x00cc, + 0x2186: 0x00c0, 0x2187: 0x00cc, 0x2188: 0x0080, 0x2189: 0x0080, 0x218a: 0x0080, 0x218b: 0x0080, + 0x218c: 0x0080, 0x218d: 0x0080, 0x218e: 0x0080, 0x218f: 0x0080, 0x2190: 0x0080, 0x2191: 0x0080, + 0x2192: 0x0080, 0x2193: 0x0080, 0x2194: 0x0080, 0x2195: 0x0080, 0x2196: 0x0080, 0x2197: 0x0080, + 0x2198: 0x0080, 0x2199: 0x0080, 0x219a: 0x0080, 0x219b: 0x0080, 0x219c: 0x0080, 0x219d: 0x0080, + 0x219e: 0x0080, 0x219f: 0x0080, 0x21a0: 0x0080, 0x21a1: 0x008c, 0x21a2: 0x008c, 0x21a3: 0x008c, + 0x21a4: 0x008c, 0x21a5: 0x008c, 0x21a6: 0x008c, 0x21a7: 0x008c, 0x21a8: 0x008c, 0x21a9: 0x008c, + 0x21aa: 0x00c3, 0x21ab: 0x00c3, 0x21ac: 0x00c3, 0x21ad: 0x00c3, 0x21ae: 0x0040, 0x21af: 0x0040, + 0x21b0: 0x0080, 0x21b1: 0x0040, 0x21b2: 0x0040, 0x21b3: 0x0040, 0x21b4: 0x0040, 0x21b5: 0x0040, + 0x21b6: 0x0080, 0x21b7: 0x0080, 0x21b8: 0x008c, 0x21b9: 0x008c, 0x21ba: 0x008c, 0x21bb: 0x0040, + 0x21bc: 0x00c0, 0x21bd: 0x0080, 0x21be: 0x0080, 0x21bf: 0x0080, + // Block 0x87, offset 0x21c0 + 0x21c1: 0x00cc, 0x21c2: 0x00cc, 0x21c3: 0x00cc, 0x21c4: 0x00cc, 0x21c5: 0x00cc, + 0x21c6: 0x00cc, 0x21c7: 0x00cc, 0x21c8: 0x00cc, 0x21c9: 0x00cc, 0x21ca: 0x00cc, 0x21cb: 0x00cc, + 0x21cc: 0x00cc, 0x21cd: 0x00cc, 0x21ce: 0x00cc, 0x21cf: 0x00cc, 0x21d0: 0x00cc, 0x21d1: 0x00cc, + 0x21d2: 0x00cc, 0x21d3: 0x00cc, 0x21d4: 0x00cc, 0x21d5: 0x00cc, 0x21d6: 0x00cc, 0x21d7: 0x00cc, + 0x21d8: 0x00cc, 0x21d9: 0x00cc, 0x21da: 0x00cc, 0x21db: 0x00cc, 0x21dc: 0x00cc, 0x21dd: 0x00cc, + 0x21de: 0x00cc, 0x21df: 0x00cc, 0x21e0: 0x00cc, 0x21e1: 0x00cc, 0x21e2: 0x00cc, 0x21e3: 0x00cc, + 0x21e4: 0x00cc, 0x21e5: 0x00cc, 0x21e6: 0x00cc, 0x21e7: 0x00cc, 0x21e8: 0x00cc, 0x21e9: 0x00cc, + 0x21ea: 0x00cc, 0x21eb: 0x00cc, 0x21ec: 0x00cc, 0x21ed: 0x00cc, 0x21ee: 0x00cc, 0x21ef: 0x00cc, + 0x21f0: 0x00cc, 0x21f1: 0x00cc, 0x21f2: 0x00cc, 0x21f3: 0x00cc, 0x21f4: 0x00cc, 0x21f5: 0x00cc, + 0x21f6: 0x00cc, 0x21f7: 0x00cc, 0x21f8: 0x00cc, 0x21f9: 0x00cc, 0x21fa: 0x00cc, 0x21fb: 0x00cc, + 0x21fc: 0x00cc, 0x21fd: 0x00cc, 0x21fe: 0x00cc, 0x21ff: 0x00cc, + // Block 0x88, offset 0x2200 + 0x2200: 0x00cc, 0x2201: 0x00cc, 0x2202: 0x00cc, 0x2203: 0x00cc, 0x2204: 0x00cc, 0x2205: 0x00cc, + 0x2206: 0x00cc, 0x2207: 0x00cc, 0x2208: 0x00cc, 0x2209: 0x00cc, 0x220a: 0x00cc, 0x220b: 0x00cc, + 0x220c: 0x00cc, 0x220d: 0x00cc, 0x220e: 0x00cc, 0x220f: 0x00cc, 0x2210: 0x00cc, 0x2211: 0x00cc, + 0x2212: 0x00cc, 0x2213: 0x00cc, 0x2214: 0x00cc, 0x2215: 0x00cc, 0x2216: 0x00cc, + 0x2219: 0x00c3, 0x221a: 0x00c3, 0x221b: 0x0080, 0x221c: 0x0080, 0x221d: 0x00cc, + 0x221e: 0x00cc, 0x221f: 0x008c, 0x2220: 0x0080, 0x2221: 0x00cc, 0x2222: 0x00cc, 0x2223: 0x00cc, + 0x2224: 0x00cc, 0x2225: 0x00cc, 0x2226: 0x00cc, 0x2227: 0x00cc, 0x2228: 0x00cc, 0x2229: 0x00cc, + 0x222a: 0x00cc, 0x222b: 0x00cc, 0x222c: 0x00cc, 0x222d: 0x00cc, 0x222e: 0x00cc, 0x222f: 0x00cc, + 0x2230: 0x00cc, 0x2231: 0x00cc, 0x2232: 0x00cc, 0x2233: 0x00cc, 0x2234: 0x00cc, 0x2235: 0x00cc, + 0x2236: 0x00cc, 0x2237: 0x00cc, 0x2238: 0x00cc, 0x2239: 0x00cc, 0x223a: 0x00cc, 0x223b: 0x00cc, + 0x223c: 0x00cc, 0x223d: 0x00cc, 0x223e: 0x00cc, 0x223f: 0x00cc, + // Block 0x89, offset 0x2240 + 0x2240: 0x00cc, 0x2241: 0x00cc, 0x2242: 0x00cc, 0x2243: 0x00cc, 0x2244: 0x00cc, 0x2245: 0x00cc, + 0x2246: 0x00cc, 0x2247: 0x00cc, 0x2248: 0x00cc, 0x2249: 0x00cc, 0x224a: 0x00cc, 0x224b: 0x00cc, + 0x224c: 0x00cc, 0x224d: 0x00cc, 0x224e: 0x00cc, 0x224f: 0x00cc, 0x2250: 0x00cc, 0x2251: 0x00cc, + 0x2252: 0x00cc, 0x2253: 0x00cc, 0x2254: 0x00cc, 0x2255: 0x00cc, 0x2256: 0x00cc, 0x2257: 0x00cc, + 0x2258: 0x00cc, 0x2259: 0x00cc, 0x225a: 0x00cc, 0x225b: 0x00cc, 0x225c: 0x00cc, 0x225d: 0x00cc, + 0x225e: 0x00cc, 0x225f: 0x00cc, 0x2260: 0x00cc, 0x2261: 0x00cc, 0x2262: 0x00cc, 0x2263: 0x00cc, + 0x2264: 0x00cc, 0x2265: 0x00cc, 0x2266: 0x00cc, 0x2267: 0x00cc, 0x2268: 0x00cc, 0x2269: 0x00cc, + 0x226a: 0x00cc, 0x226b: 0x00cc, 0x226c: 0x00cc, 0x226d: 0x00cc, 0x226e: 0x00cc, 0x226f: 0x00cc, + 0x2270: 0x00cc, 0x2271: 0x00cc, 0x2272: 0x00cc, 0x2273: 0x00cc, 0x2274: 0x00cc, 0x2275: 0x00cc, + 0x2276: 0x00cc, 0x2277: 0x00cc, 0x2278: 0x00cc, 0x2279: 0x00cc, 0x227a: 0x00cc, 0x227b: 0x00d2, + 0x227c: 0x00c0, 0x227d: 0x00cc, 0x227e: 0x00cc, 0x227f: 0x008c, + // Block 0x8a, offset 0x2280 + 0x2285: 0x00c0, + 0x2286: 0x00c0, 0x2287: 0x00c0, 0x2288: 0x00c0, 0x2289: 0x00c0, 0x228a: 0x00c0, 0x228b: 0x00c0, + 0x228c: 0x00c0, 0x228d: 0x00c0, 0x228e: 0x00c0, 0x228f: 0x00c0, 0x2290: 0x00c0, 0x2291: 0x00c0, + 0x2292: 0x00c0, 0x2293: 0x00c0, 0x2294: 0x00c0, 0x2295: 0x00c0, 0x2296: 0x00c0, 0x2297: 0x00c0, + 0x2298: 0x00c0, 0x2299: 0x00c0, 0x229a: 0x00c0, 0x229b: 0x00c0, 0x229c: 0x00c0, 0x229d: 0x00c0, + 0x229e: 0x00c0, 0x229f: 0x00c0, 0x22a0: 0x00c0, 0x22a1: 0x00c0, 0x22a2: 0x00c0, 0x22a3: 0x00c0, + 0x22a4: 0x00c0, 0x22a5: 0x00c0, 0x22a6: 0x00c0, 0x22a7: 0x00c0, 0x22a8: 0x00c0, 0x22a9: 0x00c0, + 0x22aa: 0x00c0, 0x22ab: 0x00c0, 0x22ac: 0x00c0, 0x22ad: 0x00c0, 0x22ae: 0x00c0, 0x22af: 0x00c0, + 0x22b1: 0x0080, 0x22b2: 0x0080, 0x22b3: 0x0080, 0x22b4: 0x0080, 0x22b5: 0x0080, + 0x22b6: 0x0080, 0x22b7: 0x0080, 0x22b8: 0x0080, 0x22b9: 0x0080, 0x22ba: 0x0080, 0x22bb: 0x0080, + 0x22bc: 0x0080, 0x22bd: 0x0080, 0x22be: 0x0080, 0x22bf: 0x0080, + // Block 0x8b, offset 0x22c0 + 0x22c0: 0x0080, 0x22c1: 0x0080, 0x22c2: 0x0080, 0x22c3: 0x0080, 0x22c4: 0x0080, 0x22c5: 0x0080, + 0x22c6: 0x0080, 0x22c7: 0x0080, 0x22c8: 0x0080, 0x22c9: 0x0080, 0x22ca: 0x0080, 0x22cb: 0x0080, + 0x22cc: 0x0080, 0x22cd: 0x0080, 0x22ce: 0x0080, 0x22cf: 0x0080, 0x22d0: 0x0080, 0x22d1: 0x0080, + 0x22d2: 0x0080, 0x22d3: 0x0080, 0x22d4: 0x0080, 0x22d5: 0x0080, 0x22d6: 0x0080, 0x22d7: 0x0080, + 0x22d8: 0x0080, 0x22d9: 0x0080, 0x22da: 0x0080, 0x22db: 0x0080, 0x22dc: 0x0080, 0x22dd: 0x0080, + 0x22de: 0x0080, 0x22df: 0x0080, 0x22e0: 0x0080, 0x22e1: 0x0080, 0x22e2: 0x0080, 0x22e3: 0x0080, + 0x22e4: 0x0040, 0x22e5: 0x0080, 0x22e6: 0x0080, 0x22e7: 0x0080, 0x22e8: 0x0080, 0x22e9: 0x0080, + 0x22ea: 0x0080, 0x22eb: 0x0080, 0x22ec: 0x0080, 0x22ed: 0x0080, 0x22ee: 0x0080, 0x22ef: 0x0080, + 0x22f0: 0x0080, 0x22f1: 0x0080, 0x22f2: 0x0080, 0x22f3: 0x0080, 0x22f4: 0x0080, 0x22f5: 0x0080, + 0x22f6: 0x0080, 0x22f7: 0x0080, 0x22f8: 0x0080, 0x22f9: 0x0080, 0x22fa: 0x0080, 0x22fb: 0x0080, + 0x22fc: 0x0080, 0x22fd: 0x0080, 0x22fe: 0x0080, 0x22ff: 0x0080, + // Block 0x8c, offset 0x2300 + 0x2300: 0x0080, 0x2301: 0x0080, 0x2302: 0x0080, 0x2303: 0x0080, 0x2304: 0x0080, 0x2305: 0x0080, + 0x2306: 0x0080, 0x2307: 0x0080, 0x2308: 0x0080, 0x2309: 0x0080, 0x230a: 0x0080, 0x230b: 0x0080, + 0x230c: 0x0080, 0x230d: 0x0080, 0x230e: 0x0080, 0x2310: 0x0080, 0x2311: 0x0080, + 0x2312: 0x0080, 0x2313: 0x0080, 0x2314: 0x0080, 0x2315: 0x0080, 0x2316: 0x0080, 0x2317: 0x0080, + 0x2318: 0x0080, 0x2319: 0x0080, 0x231a: 0x0080, 0x231b: 0x0080, 0x231c: 0x0080, 0x231d: 0x0080, + 0x231e: 0x0080, 0x231f: 0x0080, 0x2320: 0x00c0, 0x2321: 0x00c0, 0x2322: 0x00c0, 0x2323: 0x00c0, + 0x2324: 0x00c0, 0x2325: 0x00c0, 0x2326: 0x00c0, 0x2327: 0x00c0, 0x2328: 0x00c0, 0x2329: 0x00c0, + 0x232a: 0x00c0, 0x232b: 0x00c0, 0x232c: 0x00c0, 0x232d: 0x00c0, 0x232e: 0x00c0, 0x232f: 0x00c0, + 0x2330: 0x00c0, 0x2331: 0x00c0, 0x2332: 0x00c0, 0x2333: 0x00c0, 0x2334: 0x00c0, 0x2335: 0x00c0, + 0x2336: 0x00c0, 0x2337: 0x00c0, 0x2338: 0x00c0, 0x2339: 0x00c0, 0x233a: 0x00c0, 0x233b: 0x00c0, + 0x233c: 0x00c0, 0x233d: 0x00c0, 0x233e: 0x00c0, 0x233f: 0x00c0, + // Block 0x8d, offset 0x2340 + 0x2340: 0x0080, 0x2341: 0x0080, 0x2342: 0x0080, 0x2343: 0x0080, 0x2344: 0x0080, 0x2345: 0x0080, + 0x2346: 0x0080, 0x2347: 0x0080, 0x2348: 0x0080, 0x2349: 0x0080, 0x234a: 0x0080, 0x234b: 0x0080, + 0x234c: 0x0080, 0x234d: 0x0080, 0x234e: 0x0080, 0x234f: 0x0080, 0x2350: 0x0080, 0x2351: 0x0080, + 0x2352: 0x0080, 0x2353: 0x0080, 0x2354: 0x0080, 0x2355: 0x0080, 0x2356: 0x0080, 0x2357: 0x0080, + 0x2358: 0x0080, 0x2359: 0x0080, 0x235a: 0x0080, 0x235b: 0x0080, 0x235c: 0x0080, 0x235d: 0x0080, + 0x235e: 0x0080, 0x235f: 0x0080, 0x2360: 0x0080, 0x2361: 0x0080, 0x2362: 0x0080, 0x2363: 0x0080, + 0x2370: 0x00cc, 0x2371: 0x00cc, 0x2372: 0x00cc, 0x2373: 0x00cc, 0x2374: 0x00cc, 0x2375: 0x00cc, + 0x2376: 0x00cc, 0x2377: 0x00cc, 0x2378: 0x00cc, 0x2379: 0x00cc, 0x237a: 0x00cc, 0x237b: 0x00cc, + 0x237c: 0x00cc, 0x237d: 0x00cc, 0x237e: 0x00cc, 0x237f: 0x00cc, + // Block 0x8e, offset 0x2380 + 0x2380: 0x0080, 0x2381: 0x0080, 0x2382: 0x0080, 0x2383: 0x0080, 0x2384: 0x0080, 0x2385: 0x0080, + 0x2386: 0x0080, 0x2387: 0x0080, 0x2388: 0x0080, 0x2389: 0x0080, 0x238a: 0x0080, 0x238b: 0x0080, + 0x238c: 0x0080, 0x238d: 0x0080, 0x238e: 0x0080, 0x238f: 0x0080, 0x2390: 0x0080, 0x2391: 0x0080, + 0x2392: 0x0080, 0x2393: 0x0080, 0x2394: 0x0080, 0x2395: 0x0080, 0x2396: 0x0080, 0x2397: 0x0080, + 0x2398: 0x0080, 0x2399: 0x0080, 0x239a: 0x0080, 0x239b: 0x0080, 0x239c: 0x0080, 0x239d: 0x0080, + 0x239e: 0x0080, 0x23a0: 0x0080, 0x23a1: 0x0080, 0x23a2: 0x0080, 0x23a3: 0x0080, + 0x23a4: 0x0080, 0x23a5: 0x0080, 0x23a6: 0x0080, 0x23a7: 0x0080, 0x23a8: 0x0080, 0x23a9: 0x0080, + 0x23aa: 0x0080, 0x23ab: 0x0080, 0x23ac: 0x0080, 0x23ad: 0x0080, 0x23ae: 0x0080, 0x23af: 0x0080, + 0x23b0: 0x0080, 0x23b1: 0x0080, 0x23b2: 0x0080, 0x23b3: 0x0080, 0x23b4: 0x0080, 0x23b5: 0x0080, + 0x23b6: 0x0080, 0x23b7: 0x0080, 0x23b8: 0x0080, 0x23b9: 0x0080, 0x23ba: 0x0080, 0x23bb: 0x0080, + 0x23bc: 0x0080, 0x23bd: 0x0080, 0x23be: 0x0080, 0x23bf: 0x0080, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x0080, 0x23c1: 0x0080, 0x23c2: 0x0080, 0x23c3: 0x0080, 0x23c4: 0x0080, 0x23c5: 0x0080, + 0x23c6: 0x0080, 0x23c7: 0x0080, 0x23c8: 0x0080, 0x23c9: 0x0080, 0x23ca: 0x0080, 0x23cb: 0x0080, + 0x23cc: 0x0080, 0x23cd: 0x0080, 0x23ce: 0x0080, 0x23cf: 0x0080, 0x23d0: 0x008c, 0x23d1: 0x008c, + 0x23d2: 0x008c, 0x23d3: 0x008c, 0x23d4: 0x008c, 0x23d5: 0x008c, 0x23d6: 0x008c, 0x23d7: 0x008c, + 0x23d8: 0x008c, 0x23d9: 0x008c, 0x23da: 0x008c, 0x23db: 0x008c, 0x23dc: 0x008c, 0x23dd: 0x008c, + 0x23de: 0x008c, 0x23df: 0x008c, 0x23e0: 0x008c, 0x23e1: 0x008c, 0x23e2: 0x008c, 0x23e3: 0x008c, + 0x23e4: 0x008c, 0x23e5: 0x008c, 0x23e6: 0x008c, 0x23e7: 0x008c, 0x23e8: 0x008c, 0x23e9: 0x008c, + 0x23ea: 0x008c, 0x23eb: 0x008c, 0x23ec: 0x008c, 0x23ed: 0x008c, 0x23ee: 0x008c, 0x23ef: 0x008c, + 0x23f0: 0x008c, 0x23f1: 0x008c, 0x23f2: 0x008c, 0x23f3: 0x008c, 0x23f4: 0x008c, 0x23f5: 0x008c, + 0x23f6: 0x008c, 0x23f7: 0x008c, 0x23f8: 0x008c, 0x23f9: 0x008c, 0x23fa: 0x008c, 0x23fb: 0x008c, + 0x23fc: 0x008c, 0x23fd: 0x008c, 0x23fe: 0x008c, 0x23ff: 0x0080, + // Block 0x90, offset 0x2400 + 0x2400: 0x008c, 0x2401: 0x008c, 0x2402: 0x008c, 0x2403: 0x008c, 0x2404: 0x008c, 0x2405: 0x008c, + 0x2406: 0x008c, 0x2407: 0x008c, 0x2408: 0x008c, 0x2409: 0x008c, 0x240a: 0x008c, 0x240b: 0x008c, + 0x240c: 0x008c, 0x240d: 0x008c, 0x240e: 0x008c, 0x240f: 0x008c, 0x2410: 0x008c, 0x2411: 0x008c, + 0x2412: 0x008c, 0x2413: 0x008c, 0x2414: 0x008c, 0x2415: 0x008c, 0x2416: 0x008c, 0x2417: 0x008c, + 0x2418: 0x0080, 0x2419: 0x0080, 0x241a: 0x0080, 0x241b: 0x0080, 0x241c: 0x0080, 0x241d: 0x0080, + 0x241e: 0x0080, 0x241f: 0x0080, 0x2420: 0x0080, 0x2421: 0x0080, 0x2422: 0x0080, 0x2423: 0x0080, + 0x2424: 0x0080, 0x2425: 0x0080, 0x2426: 0x0080, 0x2427: 0x0080, 0x2428: 0x0080, 0x2429: 0x0080, + 0x242a: 0x0080, 0x242b: 0x0080, 0x242c: 0x0080, 0x242d: 0x0080, 0x242e: 0x0080, 0x242f: 0x0080, + 0x2430: 0x0080, 0x2431: 0x0080, 0x2432: 0x0080, 0x2433: 0x0080, 0x2434: 0x0080, 0x2435: 0x0080, + 0x2436: 0x0080, 0x2437: 0x0080, 0x2438: 0x0080, 0x2439: 0x0080, 0x243a: 0x0080, 0x243b: 0x0080, + 0x243c: 0x0080, 0x243d: 0x0080, 0x243e: 0x0080, 0x243f: 0x0080, + // Block 0x91, offset 0x2440 + 0x2440: 0x00cc, 0x2441: 0x00cc, 0x2442: 0x00cc, 0x2443: 0x00cc, 0x2444: 0x00cc, 0x2445: 0x00cc, + 0x2446: 0x00cc, 0x2447: 0x00cc, 0x2448: 0x00cc, 0x2449: 0x00cc, 0x244a: 0x00cc, 0x244b: 0x00cc, + 0x244c: 0x00cc, 0x244d: 0x00cc, 0x244e: 0x00cc, 0x244f: 0x00cc, 0x2450: 0x00cc, 0x2451: 0x00cc, + 0x2452: 0x00cc, 0x2453: 0x00cc, 0x2454: 0x00cc, 0x2455: 0x00cc, 0x2456: 0x00cc, 0x2457: 0x00cc, + 0x2458: 0x00cc, 0x2459: 0x00cc, 0x245a: 0x00cc, 0x245b: 0x00cc, 0x245c: 0x00cc, 0x245d: 0x00cc, + 0x245e: 0x00cc, 0x245f: 0x00cc, 0x2460: 0x00cc, 0x2461: 0x00cc, 0x2462: 0x00cc, 0x2463: 0x00cc, + 0x2464: 0x00cc, 0x2465: 0x00cc, 0x2466: 0x00cc, 0x2467: 0x00cc, 0x2468: 0x00cc, 0x2469: 0x00cc, + 0x246a: 0x00cc, 0x246b: 0x00cc, 0x246c: 0x00cc, 0x246d: 0x00cc, 0x246e: 0x00cc, 0x246f: 0x00cc, + 0x2470: 0x00cc, 0x2471: 0x00cc, 0x2472: 0x00cc, 0x2473: 0x00cc, 0x2474: 0x00cc, 0x2475: 0x00cc, + 0x2476: 0x00cc, 0x2477: 0x00cc, 0x2478: 0x00cc, 0x2479: 0x00cc, 0x247a: 0x00cc, 0x247b: 0x00cc, + 0x247c: 0x00cc, 0x247d: 0x00cc, 0x247e: 0x00cc, 0x247f: 0x00cc, + // Block 0x92, offset 0x2480 + 0x2480: 0x00cc, 0x2481: 0x00cc, 0x2482: 0x00cc, 0x2483: 0x00cc, 0x2484: 0x00cc, 0x2485: 0x00cc, + 0x2486: 0x00cc, 0x2487: 0x00cc, 0x2488: 0x00cc, 0x2489: 0x00cc, 0x248a: 0x00cc, 0x248b: 0x00cc, + 0x248c: 0x00cc, 0x248d: 0x00cc, 0x248e: 0x00cc, 0x248f: 0x00cc, 0x2490: 0x00cc, 0x2491: 0x00cc, + 0x2492: 0x00cc, 0x2493: 0x00cc, 0x2494: 0x00cc, 0x2495: 0x00cc, 0x2496: 0x00cc, 0x2497: 0x00cc, + 0x2498: 0x00cc, 0x2499: 0x00cc, 0x249a: 0x00cc, 0x249b: 0x00cc, 0x249c: 0x00cc, 0x249d: 0x00cc, + 0x249e: 0x00cc, 0x249f: 0x00cc, 0x24a0: 0x00cc, 0x24a1: 0x00cc, 0x24a2: 0x00cc, 0x24a3: 0x00cc, + 0x24a4: 0x00cc, 0x24a5: 0x00cc, 0x24a6: 0x00cc, 0x24a7: 0x00cc, 0x24a8: 0x00cc, 0x24a9: 0x00cc, + 0x24aa: 0x00cc, 0x24ab: 0x00cc, 0x24ac: 0x00cc, 0x24ad: 0x00cc, 0x24ae: 0x00cc, 0x24af: 0x00cc, + 0x24b0: 0x00cc, 0x24b1: 0x00cc, 0x24b2: 0x00cc, 0x24b3: 0x00cc, 0x24b4: 0x00cc, 0x24b5: 0x00cc, + 0x24b6: 0x00cc, 0x24b7: 0x00cc, 0x24b8: 0x00cc, 0x24b9: 0x00cc, 0x24ba: 0x00cc, 0x24bb: 0x00cc, + 0x24bc: 0x00cc, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x00c0, 0x24c1: 0x00c0, 0x24c2: 0x00c0, 0x24c3: 0x00c0, 0x24c4: 0x00c0, 0x24c5: 0x00c0, + 0x24c6: 0x00c0, 0x24c7: 0x00c0, 0x24c8: 0x00c0, 0x24c9: 0x00c0, 0x24ca: 0x00c0, 0x24cb: 0x00c0, + 0x24cc: 0x00c0, 0x24d0: 0x0080, 0x24d1: 0x0080, + 0x24d2: 0x0080, 0x24d3: 0x0080, 0x24d4: 0x0080, 0x24d5: 0x0080, 0x24d6: 0x0080, 0x24d7: 0x0080, + 0x24d8: 0x0080, 0x24d9: 0x0080, 0x24da: 0x0080, 0x24db: 0x0080, 0x24dc: 0x0080, 0x24dd: 0x0080, + 0x24de: 0x0080, 0x24df: 0x0080, 0x24e0: 0x0080, 0x24e1: 0x0080, 0x24e2: 0x0080, 0x24e3: 0x0080, + 0x24e4: 0x0080, 0x24e5: 0x0080, 0x24e6: 0x0080, 0x24e7: 0x0080, 0x24e8: 0x0080, 0x24e9: 0x0080, + 0x24ea: 0x0080, 0x24eb: 0x0080, 0x24ec: 0x0080, 0x24ed: 0x0080, 0x24ee: 0x0080, 0x24ef: 0x0080, + 0x24f0: 0x0080, 0x24f1: 0x0080, 0x24f2: 0x0080, 0x24f3: 0x0080, 0x24f4: 0x0080, 0x24f5: 0x0080, + 0x24f6: 0x0080, 0x24f7: 0x0080, 0x24f8: 0x0080, 0x24f9: 0x0080, 0x24fa: 0x0080, 0x24fb: 0x0080, + 0x24fc: 0x0080, 0x24fd: 0x0080, 0x24fe: 0x0080, 0x24ff: 0x0080, + // Block 0x94, offset 0x2500 + 0x2500: 0x0080, 0x2501: 0x0080, 0x2502: 0x0080, 0x2503: 0x0080, 0x2504: 0x0080, 0x2505: 0x0080, + 0x2506: 0x0080, + 0x2510: 0x00c0, 0x2511: 0x00c0, + 0x2512: 0x00c0, 0x2513: 0x00c0, 0x2514: 0x00c0, 0x2515: 0x00c0, 0x2516: 0x00c0, 0x2517: 0x00c0, + 0x2518: 0x00c0, 0x2519: 0x00c0, 0x251a: 0x00c0, 0x251b: 0x00c0, 0x251c: 0x00c0, 0x251d: 0x00c0, + 0x251e: 0x00c0, 0x251f: 0x00c0, 0x2520: 0x00c0, 0x2521: 0x00c0, 0x2522: 0x00c0, 0x2523: 0x00c0, + 0x2524: 0x00c0, 0x2525: 0x00c0, 0x2526: 0x00c0, 0x2527: 0x00c0, 0x2528: 0x00c0, 0x2529: 0x00c0, + 0x252a: 0x00c0, 0x252b: 0x00c0, 0x252c: 0x00c0, 0x252d: 0x00c0, 0x252e: 0x00c0, 0x252f: 0x00c0, + 0x2530: 0x00c0, 0x2531: 0x00c0, 0x2532: 0x00c0, 0x2533: 0x00c0, 0x2534: 0x00c0, 0x2535: 0x00c0, + 0x2536: 0x00c0, 0x2537: 0x00c0, 0x2538: 0x00c0, 0x2539: 0x00c0, 0x253a: 0x00c0, 0x253b: 0x00c0, + 0x253c: 0x00c0, 0x253d: 0x00c0, 0x253e: 0x0080, 0x253f: 0x0080, + // Block 0x95, offset 0x2540 + 0x2540: 0x00c0, 0x2541: 0x00c0, 0x2542: 0x00c0, 0x2543: 0x00c0, 0x2544: 0x00c0, 0x2545: 0x00c0, + 0x2546: 0x00c0, 0x2547: 0x00c0, 0x2548: 0x00c0, 0x2549: 0x00c0, 0x254a: 0x00c0, 0x254b: 0x00c0, + 0x254c: 0x00c0, 0x254d: 0x0080, 0x254e: 0x0080, 0x254f: 0x0080, 0x2550: 0x00c0, 0x2551: 0x00c0, + 0x2552: 0x00c0, 0x2553: 0x00c0, 0x2554: 0x00c0, 0x2555: 0x00c0, 0x2556: 0x00c0, 0x2557: 0x00c0, + 0x2558: 0x00c0, 0x2559: 0x00c0, 0x255a: 0x00c0, 0x255b: 0x00c0, 0x255c: 0x00c0, 0x255d: 0x00c0, + 0x255e: 0x00c0, 0x255f: 0x00c0, 0x2560: 0x00c0, 0x2561: 0x00c0, 0x2562: 0x00c0, 0x2563: 0x00c0, + 0x2564: 0x00c0, 0x2565: 0x00c0, 0x2566: 0x00c0, 0x2567: 0x00c0, 0x2568: 0x00c0, 0x2569: 0x00c0, + 0x256a: 0x00c0, 0x256b: 0x00c0, + // Block 0x96, offset 0x2580 + 0x2580: 0x00c0, 0x2581: 0x00c0, 0x2582: 0x00c0, 0x2583: 0x00c0, 0x2584: 0x00c0, 0x2585: 0x00c0, + 0x2586: 0x00c0, 0x2587: 0x00c0, 0x2588: 0x00c0, 0x2589: 0x00c0, 0x258a: 0x00c0, 0x258b: 0x00c0, + 0x258c: 0x00c0, 0x258d: 0x00c0, 0x258e: 0x00c0, 0x258f: 0x00c0, 0x2590: 0x00c0, 0x2591: 0x00c0, + 0x2592: 0x00c0, 0x2593: 0x00c0, 0x2594: 0x00c0, 0x2595: 0x00c0, 0x2596: 0x00c0, 0x2597: 0x00c0, + 0x2598: 0x00c0, 0x2599: 0x00c0, 0x259a: 0x00c0, 0x259b: 0x00c0, 0x259c: 0x00c0, 0x259d: 0x00c0, + 0x259e: 0x00c0, 0x259f: 0x00c0, 0x25a0: 0x00c0, 0x25a1: 0x00c0, 0x25a2: 0x00c0, 0x25a3: 0x00c0, + 0x25a4: 0x00c0, 0x25a5: 0x00c0, 0x25a6: 0x00c0, 0x25a7: 0x00c0, 0x25a8: 0x00c0, 0x25a9: 0x00c0, + 0x25aa: 0x00c0, 0x25ab: 0x00c0, 0x25ac: 0x00c0, 0x25ad: 0x00c0, 0x25ae: 0x00c0, 0x25af: 0x00c3, + 0x25b0: 0x0083, 0x25b1: 0x0083, 0x25b2: 0x0083, 0x25b3: 0x0080, 0x25b4: 0x00c3, 0x25b5: 0x00c3, + 0x25b6: 0x00c3, 0x25b7: 0x00c3, 0x25b8: 0x00c3, 0x25b9: 0x00c3, 0x25ba: 0x00c3, 0x25bb: 0x00c3, + 0x25bc: 0x00c3, 0x25bd: 0x00c3, 0x25be: 0x0080, 0x25bf: 0x00c0, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x00c0, 0x25c1: 0x00c0, 0x25c2: 0x00c0, 0x25c3: 0x00c0, 0x25c4: 0x00c0, 0x25c5: 0x00c0, + 0x25c6: 0x00c0, 0x25c7: 0x00c0, 0x25c8: 0x00c0, 0x25c9: 0x00c0, 0x25ca: 0x00c0, 0x25cb: 0x00c0, + 0x25cc: 0x00c0, 0x25cd: 0x00c0, 0x25ce: 0x00c0, 0x25cf: 0x00c0, 0x25d0: 0x00c0, 0x25d1: 0x00c0, + 0x25d2: 0x00c0, 0x25d3: 0x00c0, 0x25d4: 0x00c0, 0x25d5: 0x00c0, 0x25d6: 0x00c0, 0x25d7: 0x00c0, + 0x25d8: 0x00c0, 0x25d9: 0x00c0, 0x25da: 0x00c0, 0x25db: 0x00c0, 0x25dc: 0x0080, 0x25dd: 0x0080, + 0x25de: 0x00c3, 0x25df: 0x00c3, 0x25e0: 0x00c0, 0x25e1: 0x00c0, 0x25e2: 0x00c0, 0x25e3: 0x00c0, + 0x25e4: 0x00c0, 0x25e5: 0x00c0, 0x25e6: 0x00c0, 0x25e7: 0x00c0, 0x25e8: 0x00c0, 0x25e9: 0x00c0, + 0x25ea: 0x00c0, 0x25eb: 0x00c0, 0x25ec: 0x00c0, 0x25ed: 0x00c0, 0x25ee: 0x00c0, 0x25ef: 0x00c0, + 0x25f0: 0x00c0, 0x25f1: 0x00c0, 0x25f2: 0x00c0, 0x25f3: 0x00c0, 0x25f4: 0x00c0, 0x25f5: 0x00c0, + 0x25f6: 0x00c0, 0x25f7: 0x00c0, 0x25f8: 0x00c0, 0x25f9: 0x00c0, 0x25fa: 0x00c0, 0x25fb: 0x00c0, + 0x25fc: 0x00c0, 0x25fd: 0x00c0, 0x25fe: 0x00c0, 0x25ff: 0x00c0, + // Block 0x98, offset 0x2600 + 0x2600: 0x00c0, 0x2601: 0x00c0, 0x2602: 0x00c0, 0x2603: 0x00c0, 0x2604: 0x00c0, 0x2605: 0x00c0, + 0x2606: 0x00c0, 0x2607: 0x00c0, 0x2608: 0x00c0, 0x2609: 0x00c0, 0x260a: 0x00c0, 0x260b: 0x00c0, + 0x260c: 0x00c0, 0x260d: 0x00c0, 0x260e: 0x00c0, 0x260f: 0x00c0, 0x2610: 0x00c0, 0x2611: 0x00c0, + 0x2612: 0x00c0, 0x2613: 0x00c0, 0x2614: 0x00c0, 0x2615: 0x00c0, 0x2616: 0x00c0, 0x2617: 0x00c0, + 0x2618: 0x00c0, 0x2619: 0x00c0, 0x261a: 0x00c0, 0x261b: 0x00c0, 0x261c: 0x00c0, 0x261d: 0x00c0, + 0x261e: 0x00c0, 0x261f: 0x00c0, 0x2620: 0x00c0, 0x2621: 0x00c0, 0x2622: 0x00c0, 0x2623: 0x00c0, + 0x2624: 0x00c0, 0x2625: 0x00c0, 0x2626: 0x0080, 0x2627: 0x0080, 0x2628: 0x0080, 0x2629: 0x0080, + 0x262a: 0x0080, 0x262b: 0x0080, 0x262c: 0x0080, 0x262d: 0x0080, 0x262e: 0x0080, 0x262f: 0x0080, + 0x2630: 0x00c3, 0x2631: 0x00c3, 0x2632: 0x0080, 0x2633: 0x0080, 0x2634: 0x0080, 0x2635: 0x0080, + 0x2636: 0x0080, 0x2637: 0x0080, + // Block 0x99, offset 0x2640 + 0x2640: 0x0080, 0x2641: 0x0080, 0x2642: 0x0080, 0x2643: 0x0080, 0x2644: 0x0080, 0x2645: 0x0080, + 0x2646: 0x0080, 0x2647: 0x0080, 0x2648: 0x0080, 0x2649: 0x0080, 0x264a: 0x0080, 0x264b: 0x0080, + 0x264c: 0x0080, 0x264d: 0x0080, 0x264e: 0x0080, 0x264f: 0x0080, 0x2650: 0x0080, 0x2651: 0x0080, + 0x2652: 0x0080, 0x2653: 0x0080, 0x2654: 0x0080, 0x2655: 0x0080, 0x2656: 0x0080, 0x2657: 0x00c0, + 0x2658: 0x00c0, 0x2659: 0x00c0, 0x265a: 0x00c0, 0x265b: 0x00c0, 0x265c: 0x00c0, 0x265d: 0x00c0, + 0x265e: 0x00c0, 0x265f: 0x00c0, 0x2660: 0x0080, 0x2661: 0x0080, 0x2662: 0x00c0, 0x2663: 0x00c0, + 0x2664: 0x00c0, 0x2665: 0x00c0, 0x2666: 0x00c0, 0x2667: 0x00c0, 0x2668: 0x00c0, 0x2669: 0x00c0, + 0x266a: 0x00c0, 0x266b: 0x00c0, 0x266c: 0x00c0, 0x266d: 0x00c0, 0x266e: 0x00c0, 0x266f: 0x00c0, + 0x2670: 0x00c0, 0x2671: 0x00c0, 0x2672: 0x00c0, 0x2673: 0x00c0, 0x2674: 0x00c0, 0x2675: 0x00c0, + 0x2676: 0x00c0, 0x2677: 0x00c0, 0x2678: 0x00c0, 0x2679: 0x00c0, 0x267a: 0x00c0, 0x267b: 0x00c0, + 0x267c: 0x00c0, 0x267d: 0x00c0, 0x267e: 0x00c0, 0x267f: 0x00c0, + // Block 0x9a, offset 0x2680 + 0x2680: 0x00c0, 0x2681: 0x00c0, 0x2682: 0x00c0, 0x2683: 0x00c0, 0x2684: 0x00c0, 0x2685: 0x00c0, + 0x2686: 0x00c0, 0x2687: 0x00c0, 0x2688: 0x00c0, 0x2689: 0x00c0, 0x268a: 0x00c0, 0x268b: 0x00c0, + 0x268c: 0x00c0, 0x268d: 0x00c0, 0x268e: 0x00c0, 0x268f: 0x00c0, 0x2690: 0x00c0, 0x2691: 0x00c0, + 0x2692: 0x00c0, 0x2693: 0x00c0, 0x2694: 0x00c0, 0x2695: 0x00c0, 0x2696: 0x00c0, 0x2697: 0x00c0, + 0x2698: 0x00c0, 0x2699: 0x00c0, 0x269a: 0x00c0, 0x269b: 0x00c0, 0x269c: 0x00c0, 0x269d: 0x00c0, + 0x269e: 0x00c0, 0x269f: 0x00c0, 0x26a0: 0x00c0, 0x26a1: 0x00c0, 0x26a2: 0x00c0, 0x26a3: 0x00c0, + 0x26a4: 0x00c0, 0x26a5: 0x00c0, 0x26a6: 0x00c0, 0x26a7: 0x00c0, 0x26a8: 0x00c0, 0x26a9: 0x00c0, + 0x26aa: 0x00c0, 0x26ab: 0x00c0, 0x26ac: 0x00c0, 0x26ad: 0x00c0, 0x26ae: 0x00c0, 0x26af: 0x00c0, + 0x26b0: 0x0080, 0x26b1: 0x00c0, 0x26b2: 0x00c0, 0x26b3: 0x00c0, 0x26b4: 0x00c0, 0x26b5: 0x00c0, + 0x26b6: 0x00c0, 0x26b7: 0x00c0, 0x26b8: 0x00c0, 0x26b9: 0x00c0, 0x26ba: 0x00c0, 0x26bb: 0x00c0, + 0x26bc: 0x00c0, 0x26bd: 0x00c0, 0x26be: 0x00c0, 0x26bf: 0x00c0, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x00c0, 0x26c1: 0x00c0, 0x26c2: 0x00c0, 0x26c3: 0x00c0, 0x26c4: 0x00c0, 0x26c5: 0x00c0, + 0x26c6: 0x00c0, 0x26c7: 0x00c0, 0x26c8: 0x00c0, 0x26c9: 0x0080, 0x26ca: 0x0080, 0x26cb: 0x00c0, + 0x26cc: 0x00c0, 0x26cd: 0x00c0, 0x26ce: 0x00c0, 0x26cf: 0x00c0, 0x26d0: 0x00c0, 0x26d1: 0x00c0, + 0x26d2: 0x00c0, 0x26d3: 0x00c0, 0x26d4: 0x00c0, 0x26d5: 0x00c0, 0x26d6: 0x00c0, 0x26d7: 0x00c0, + 0x26d8: 0x00c0, 0x26d9: 0x00c0, 0x26da: 0x00c0, 0x26db: 0x00c0, 0x26dc: 0x00c0, 0x26dd: 0x00c0, + 0x26de: 0x00c0, 0x26df: 0x00c0, 0x26e0: 0x00c0, 0x26e1: 0x00c0, 0x26e2: 0x00c0, 0x26e3: 0x00c0, + 0x26e4: 0x00c0, 0x26e5: 0x00c0, 0x26e6: 0x00c0, 0x26e7: 0x00c0, 0x26e8: 0x00c0, 0x26e9: 0x00c0, + 0x26ea: 0x00c0, 0x26eb: 0x00c0, 0x26ec: 0x00c0, 0x26ed: 0x00c0, 0x26ee: 0x00c0, 0x26ef: 0x00c0, + 0x26f0: 0x00c0, 0x26f1: 0x00c0, 0x26f2: 0x00c0, 0x26f3: 0x00c0, 0x26f4: 0x00c0, 0x26f5: 0x00c0, + 0x26f6: 0x00c0, 0x26f7: 0x00c0, 0x26f8: 0x00c0, 0x26f9: 0x00c0, 0x26fa: 0x00c0, 0x26fb: 0x00c0, + 0x26fc: 0x00c0, 0x26fd: 0x00c0, 0x26fe: 0x00c0, 0x26ff: 0x00c0, + // Block 0x9c, offset 0x2700 + 0x2702: 0x00c0, 0x2703: 0x00c0, 0x2704: 0x00c0, 0x2705: 0x00c0, + 0x2706: 0x00c0, 0x2707: 0x00c0, 0x2708: 0x00c0, 0x2709: 0x00c0, 0x270a: 0x00c0, + 0x2735: 0x00c0, + 0x2736: 0x00c0, 0x2737: 0x00c0, 0x2738: 0x0080, 0x2739: 0x0080, 0x273a: 0x00c0, 0x273b: 0x00c0, + 0x273c: 0x00c0, 0x273d: 0x00c0, 0x273e: 0x00c0, 0x273f: 0x00c0, + // Block 0x9d, offset 0x2740 + 0x2740: 0x00c0, 0x2741: 0x00c0, 0x2742: 0x00c3, 0x2743: 0x00c0, 0x2744: 0x00c0, 0x2745: 0x00c0, + 0x2746: 0x00c6, 0x2747: 0x00c0, 0x2748: 0x00c0, 0x2749: 0x00c0, 0x274a: 0x00c0, 0x274b: 0x00c3, + 0x274c: 0x00c0, 0x274d: 0x00c0, 0x274e: 0x00c0, 0x274f: 0x00c0, 0x2750: 0x00c0, 0x2751: 0x00c0, + 0x2752: 0x00c0, 0x2753: 0x00c0, 0x2754: 0x00c0, 0x2755: 0x00c0, 0x2756: 0x00c0, 0x2757: 0x00c0, + 0x2758: 0x00c0, 0x2759: 0x00c0, 0x275a: 0x00c0, 0x275b: 0x00c0, 0x275c: 0x00c0, 0x275d: 0x00c0, + 0x275e: 0x00c0, 0x275f: 0x00c0, 0x2760: 0x00c0, 0x2761: 0x00c0, 0x2762: 0x00c0, 0x2763: 0x00c0, + 0x2764: 0x00c0, 0x2765: 0x00c3, 0x2766: 0x00c3, 0x2767: 0x00c0, 0x2768: 0x0080, 0x2769: 0x0080, + 0x276a: 0x0080, 0x276b: 0x0080, 0x276c: 0x00c6, + 0x2770: 0x0080, 0x2771: 0x0080, 0x2772: 0x0080, 0x2773: 0x0080, 0x2774: 0x0080, 0x2775: 0x0080, + 0x2776: 0x0080, 0x2777: 0x0080, 0x2778: 0x0080, 0x2779: 0x0080, + // Block 0x9e, offset 0x2780 + 0x2780: 0x00c2, 0x2781: 0x00c2, 0x2782: 0x00c2, 0x2783: 0x00c2, 0x2784: 0x00c2, 0x2785: 0x00c2, + 0x2786: 0x00c2, 0x2787: 0x00c2, 0x2788: 0x00c2, 0x2789: 0x00c2, 0x278a: 0x00c2, 0x278b: 0x00c2, + 0x278c: 0x00c2, 0x278d: 0x00c2, 0x278e: 0x00c2, 0x278f: 0x00c2, 0x2790: 0x00c2, 0x2791: 0x00c2, + 0x2792: 0x00c2, 0x2793: 0x00c2, 0x2794: 0x00c2, 0x2795: 0x00c2, 0x2796: 0x00c2, 0x2797: 0x00c2, + 0x2798: 0x00c2, 0x2799: 0x00c2, 0x279a: 0x00c2, 0x279b: 0x00c2, 0x279c: 0x00c2, 0x279d: 0x00c2, + 0x279e: 0x00c2, 0x279f: 0x00c2, 0x27a0: 0x00c2, 0x27a1: 0x00c2, 0x27a2: 0x00c2, 0x27a3: 0x00c2, + 0x27a4: 0x00c2, 0x27a5: 0x00c2, 0x27a6: 0x00c2, 0x27a7: 0x00c2, 0x27a8: 0x00c2, 0x27a9: 0x00c2, + 0x27aa: 0x00c2, 0x27ab: 0x00c2, 0x27ac: 0x00c2, 0x27ad: 0x00c2, 0x27ae: 0x00c2, 0x27af: 0x00c2, + 0x27b0: 0x00c2, 0x27b1: 0x00c2, 0x27b2: 0x00c1, 0x27b3: 0x00c0, 0x27b4: 0x0080, 0x27b5: 0x0080, + 0x27b6: 0x0080, 0x27b7: 0x0080, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x00c0, 0x27c1: 0x00c0, 0x27c2: 0x00c0, 0x27c3: 0x00c0, 0x27c4: 0x00c6, 0x27c5: 0x00c3, + 0x27ce: 0x0080, 0x27cf: 0x0080, 0x27d0: 0x00c0, 0x27d1: 0x00c0, + 0x27d2: 0x00c0, 0x27d3: 0x00c0, 0x27d4: 0x00c0, 0x27d5: 0x00c0, 0x27d6: 0x00c0, 0x27d7: 0x00c0, + 0x27d8: 0x00c0, 0x27d9: 0x00c0, + 0x27e0: 0x00c3, 0x27e1: 0x00c3, 0x27e2: 0x00c3, 0x27e3: 0x00c3, + 0x27e4: 0x00c3, 0x27e5: 0x00c3, 0x27e6: 0x00c3, 0x27e7: 0x00c3, 0x27e8: 0x00c3, 0x27e9: 0x00c3, + 0x27ea: 0x00c3, 0x27eb: 0x00c3, 0x27ec: 0x00c3, 0x27ed: 0x00c3, 0x27ee: 0x00c3, 0x27ef: 0x00c3, + 0x27f0: 0x00c3, 0x27f1: 0x00c3, 0x27f2: 0x00c0, 0x27f3: 0x00c0, 0x27f4: 0x00c0, 0x27f5: 0x00c0, + 0x27f6: 0x00c0, 0x27f7: 0x00c0, 0x27f8: 0x0080, 0x27f9: 0x0080, 0x27fa: 0x0080, 0x27fb: 0x00c0, + 0x27fc: 0x0080, 0x27fd: 0x00c0, 0x27fe: 0x00c0, 0x27ff: 0x00c3, + // Block 0xa0, offset 0x2800 + 0x2800: 0x00c0, 0x2801: 0x00c0, 0x2802: 0x00c0, 0x2803: 0x00c0, 0x2804: 0x00c0, 0x2805: 0x00c0, + 0x2806: 0x00c0, 0x2807: 0x00c0, 0x2808: 0x00c0, 0x2809: 0x00c0, 0x280a: 0x00c0, 0x280b: 0x00c0, + 0x280c: 0x00c0, 0x280d: 0x00c0, 0x280e: 0x00c0, 0x280f: 0x00c0, 0x2810: 0x00c0, 0x2811: 0x00c0, + 0x2812: 0x00c0, 0x2813: 0x00c0, 0x2814: 0x00c0, 0x2815: 0x00c0, 0x2816: 0x00c0, 0x2817: 0x00c0, + 0x2818: 0x00c0, 0x2819: 0x00c0, 0x281a: 0x00c0, 0x281b: 0x00c0, 0x281c: 0x00c0, 0x281d: 0x00c0, + 0x281e: 0x00c0, 0x281f: 0x00c0, 0x2820: 0x00c0, 0x2821: 0x00c0, 0x2822: 0x00c0, 0x2823: 0x00c0, + 0x2824: 0x00c0, 0x2825: 0x00c0, 0x2826: 0x00c3, 0x2827: 0x00c3, 0x2828: 0x00c3, 0x2829: 0x00c3, + 0x282a: 0x00c3, 0x282b: 0x00c3, 0x282c: 0x00c3, 0x282d: 0x00c3, 0x282e: 0x0080, 0x282f: 0x0080, + 0x2830: 0x00c0, 0x2831: 0x00c0, 0x2832: 0x00c0, 0x2833: 0x00c0, 0x2834: 0x00c0, 0x2835: 0x00c0, + 0x2836: 0x00c0, 0x2837: 0x00c0, 0x2838: 0x00c0, 0x2839: 0x00c0, 0x283a: 0x00c0, 0x283b: 0x00c0, + 0x283c: 0x00c0, 0x283d: 0x00c0, 0x283e: 0x00c0, 0x283f: 0x00c0, + // Block 0xa1, offset 0x2840 + 0x2840: 0x00c0, 0x2841: 0x00c0, 0x2842: 0x00c0, 0x2843: 0x00c0, 0x2844: 0x00c0, 0x2845: 0x00c0, + 0x2846: 0x00c0, 0x2847: 0x00c3, 0x2848: 0x00c3, 0x2849: 0x00c3, 0x284a: 0x00c3, 0x284b: 0x00c3, + 0x284c: 0x00c3, 0x284d: 0x00c3, 0x284e: 0x00c3, 0x284f: 0x00c3, 0x2850: 0x00c3, 0x2851: 0x00c3, + 0x2852: 0x00c0, 0x2853: 0x00c5, + 0x285f: 0x0080, 0x2860: 0x0040, 0x2861: 0x0040, 0x2862: 0x0040, 0x2863: 0x0040, + 0x2864: 0x0040, 0x2865: 0x0040, 0x2866: 0x0040, 0x2867: 0x0040, 0x2868: 0x0040, 0x2869: 0x0040, + 0x286a: 0x0040, 0x286b: 0x0040, 0x286c: 0x0040, 0x286d: 0x0040, 0x286e: 0x0040, 0x286f: 0x0040, + 0x2870: 0x0040, 0x2871: 0x0040, 0x2872: 0x0040, 0x2873: 0x0040, 0x2874: 0x0040, 0x2875: 0x0040, + 0x2876: 0x0040, 0x2877: 0x0040, 0x2878: 0x0040, 0x2879: 0x0040, 0x287a: 0x0040, 0x287b: 0x0040, + 0x287c: 0x0040, + // Block 0xa2, offset 0x2880 + 0x2880: 0x00c3, 0x2881: 0x00c3, 0x2882: 0x00c3, 0x2883: 0x00c0, 0x2884: 0x00c0, 0x2885: 0x00c0, + 0x2886: 0x00c0, 0x2887: 0x00c0, 0x2888: 0x00c0, 0x2889: 0x00c0, 0x288a: 0x00c0, 0x288b: 0x00c0, + 0x288c: 0x00c0, 0x288d: 0x00c0, 0x288e: 0x00c0, 0x288f: 0x00c0, 0x2890: 0x00c0, 0x2891: 0x00c0, + 0x2892: 0x00c0, 0x2893: 0x00c0, 0x2894: 0x00c0, 0x2895: 0x00c0, 0x2896: 0x00c0, 0x2897: 0x00c0, + 0x2898: 0x00c0, 0x2899: 0x00c0, 0x289a: 0x00c0, 0x289b: 0x00c0, 0x289c: 0x00c0, 0x289d: 0x00c0, + 0x289e: 0x00c0, 0x289f: 0x00c0, 0x28a0: 0x00c0, 0x28a1: 0x00c0, 0x28a2: 0x00c0, 0x28a3: 0x00c0, + 0x28a4: 0x00c0, 0x28a5: 0x00c0, 0x28a6: 0x00c0, 0x28a7: 0x00c0, 0x28a8: 0x00c0, 0x28a9: 0x00c0, + 0x28aa: 0x00c0, 0x28ab: 0x00c0, 0x28ac: 0x00c0, 0x28ad: 0x00c0, 0x28ae: 0x00c0, 0x28af: 0x00c0, + 0x28b0: 0x00c0, 0x28b1: 0x00c0, 0x28b2: 0x00c0, 0x28b3: 0x00c3, 0x28b4: 0x00c0, 0x28b5: 0x00c0, + 0x28b6: 0x00c3, 0x28b7: 0x00c3, 0x28b8: 0x00c3, 0x28b9: 0x00c3, 0x28ba: 0x00c0, 0x28bb: 0x00c0, + 0x28bc: 0x00c3, 0x28bd: 0x00c3, 0x28be: 0x00c0, 0x28bf: 0x00c0, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x00c5, 0x28c1: 0x0080, 0x28c2: 0x0080, 0x28c3: 0x0080, 0x28c4: 0x0080, 0x28c5: 0x0080, + 0x28c6: 0x0080, 0x28c7: 0x0080, 0x28c8: 0x0080, 0x28c9: 0x0080, 0x28ca: 0x0080, 0x28cb: 0x0080, + 0x28cc: 0x0080, 0x28cd: 0x0080, 0x28cf: 0x00c0, 0x28d0: 0x00c0, 0x28d1: 0x00c0, + 0x28d2: 0x00c0, 0x28d3: 0x00c0, 0x28d4: 0x00c0, 0x28d5: 0x00c0, 0x28d6: 0x00c0, 0x28d7: 0x00c0, + 0x28d8: 0x00c0, 0x28d9: 0x00c0, + 0x28de: 0x0080, 0x28df: 0x0080, 0x28e0: 0x00c0, 0x28e1: 0x00c0, 0x28e2: 0x00c0, 0x28e3: 0x00c0, + 0x28e4: 0x00c0, 0x28e5: 0x00c3, 0x28e6: 0x00c0, 0x28e7: 0x00c0, 0x28e8: 0x00c0, 0x28e9: 0x00c0, + 0x28ea: 0x00c0, 0x28eb: 0x00c0, 0x28ec: 0x00c0, 0x28ed: 0x00c0, 0x28ee: 0x00c0, 0x28ef: 0x00c0, + 0x28f0: 0x00c0, 0x28f1: 0x00c0, 0x28f2: 0x00c0, 0x28f3: 0x00c0, 0x28f4: 0x00c0, 0x28f5: 0x00c0, + 0x28f6: 0x00c0, 0x28f7: 0x00c0, 0x28f8: 0x00c0, 0x28f9: 0x00c0, 0x28fa: 0x00c0, 0x28fb: 0x00c0, + 0x28fc: 0x00c0, 0x28fd: 0x00c0, 0x28fe: 0x00c0, + // Block 0xa4, offset 0x2900 + 0x2900: 0x00c0, 0x2901: 0x00c0, 0x2902: 0x00c0, 0x2903: 0x00c0, 0x2904: 0x00c0, 0x2905: 0x00c0, + 0x2906: 0x00c0, 0x2907: 0x00c0, 0x2908: 0x00c0, 0x2909: 0x00c0, 0x290a: 0x00c0, 0x290b: 0x00c0, + 0x290c: 0x00c0, 0x290d: 0x00c0, 0x290e: 0x00c0, 0x290f: 0x00c0, 0x2910: 0x00c0, 0x2911: 0x00c0, + 0x2912: 0x00c0, 0x2913: 0x00c0, 0x2914: 0x00c0, 0x2915: 0x00c0, 0x2916: 0x00c0, 0x2917: 0x00c0, + 0x2918: 0x00c0, 0x2919: 0x00c0, 0x291a: 0x00c0, 0x291b: 0x00c0, 0x291c: 0x00c0, 0x291d: 0x00c0, + 0x291e: 0x00c0, 0x291f: 0x00c0, 0x2920: 0x00c0, 0x2921: 0x00c0, 0x2922: 0x00c0, 0x2923: 0x00c0, + 0x2924: 0x00c0, 0x2925: 0x00c0, 0x2926: 0x00c0, 0x2927: 0x00c0, 0x2928: 0x00c0, 0x2929: 0x00c3, + 0x292a: 0x00c3, 0x292b: 0x00c3, 0x292c: 0x00c3, 0x292d: 0x00c3, 0x292e: 0x00c3, 0x292f: 0x00c0, + 0x2930: 0x00c0, 0x2931: 0x00c3, 0x2932: 0x00c3, 0x2933: 0x00c0, 0x2934: 0x00c0, 0x2935: 0x00c3, + 0x2936: 0x00c3, + // Block 0xa5, offset 0x2940 + 0x2940: 0x00c0, 0x2941: 0x00c0, 0x2942: 0x00c0, 0x2943: 0x00c3, 0x2944: 0x00c0, 0x2945: 0x00c0, + 0x2946: 0x00c0, 0x2947: 0x00c0, 0x2948: 0x00c0, 0x2949: 0x00c0, 0x294a: 0x00c0, 0x294b: 0x00c0, + 0x294c: 0x00c3, 0x294d: 0x00c0, 0x2950: 0x00c0, 0x2951: 0x00c0, + 0x2952: 0x00c0, 0x2953: 0x00c0, 0x2954: 0x00c0, 0x2955: 0x00c0, 0x2956: 0x00c0, 0x2957: 0x00c0, + 0x2958: 0x00c0, 0x2959: 0x00c0, 0x295c: 0x0080, 0x295d: 0x0080, + 0x295e: 0x0080, 0x295f: 0x0080, 0x2960: 0x00c0, 0x2961: 0x00c0, 0x2962: 0x00c0, 0x2963: 0x00c0, + 0x2964: 0x00c0, 0x2965: 0x00c0, 0x2966: 0x00c0, 0x2967: 0x00c0, 0x2968: 0x00c0, 0x2969: 0x00c0, + 0x296a: 0x00c0, 0x296b: 0x00c0, 0x296c: 0x00c0, 0x296d: 0x00c0, 0x296e: 0x00c0, 0x296f: 0x00c0, + 0x2970: 0x00c0, 0x2971: 0x00c0, 0x2972: 0x00c0, 0x2973: 0x00c0, 0x2974: 0x00c0, 0x2975: 0x00c0, + 0x2976: 0x00c0, 0x2977: 0x0080, 0x2978: 0x0080, 0x2979: 0x0080, 0x297a: 0x00c0, 0x297b: 0x00c0, + 0x297c: 0x00c3, 0x297d: 0x00c0, 0x297e: 0x00c0, 0x297f: 0x00c0, + // Block 0xa6, offset 0x2980 + 0x2980: 0x00c0, 0x2981: 0x00c0, 0x2982: 0x00c0, 0x2983: 0x00c0, 0x2984: 0x00c0, 0x2985: 0x00c0, + 0x2986: 0x00c0, 0x2987: 0x00c0, 0x2988: 0x00c0, 0x2989: 0x00c0, 0x298a: 0x00c0, 0x298b: 0x00c0, + 0x298c: 0x00c0, 0x298d: 0x00c0, 0x298e: 0x00c0, 0x298f: 0x00c0, 0x2990: 0x00c0, 0x2991: 0x00c0, + 0x2992: 0x00c0, 0x2993: 0x00c0, 0x2994: 0x00c0, 0x2995: 0x00c0, 0x2996: 0x00c0, 0x2997: 0x00c0, + 0x2998: 0x00c0, 0x2999: 0x00c0, 0x299a: 0x00c0, 0x299b: 0x00c0, 0x299c: 0x00c0, 0x299d: 0x00c0, + 0x299e: 0x00c0, 0x299f: 0x00c0, 0x29a0: 0x00c0, 0x29a1: 0x00c0, 0x29a2: 0x00c0, 0x29a3: 0x00c0, + 0x29a4: 0x00c0, 0x29a5: 0x00c0, 0x29a6: 0x00c0, 0x29a7: 0x00c0, 0x29a8: 0x00c0, 0x29a9: 0x00c0, + 0x29aa: 0x00c0, 0x29ab: 0x00c0, 0x29ac: 0x00c0, 0x29ad: 0x00c0, 0x29ae: 0x00c0, 0x29af: 0x00c0, + 0x29b0: 0x00c3, 0x29b1: 0x00c0, 0x29b2: 0x00c3, 0x29b3: 0x00c3, 0x29b4: 0x00c3, 0x29b5: 0x00c0, + 0x29b6: 0x00c0, 0x29b7: 0x00c3, 0x29b8: 0x00c3, 0x29b9: 0x00c0, 0x29ba: 0x00c0, 0x29bb: 0x00c0, + 0x29bc: 0x00c0, 0x29bd: 0x00c0, 0x29be: 0x00c3, 0x29bf: 0x00c3, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x00c0, 0x29c1: 0x00c3, 0x29c2: 0x00c0, + 0x29db: 0x00c0, 0x29dc: 0x00c0, 0x29dd: 0x00c0, + 0x29de: 0x0080, 0x29df: 0x0080, 0x29e0: 0x00c0, 0x29e1: 0x00c0, 0x29e2: 0x00c0, 0x29e3: 0x00c0, + 0x29e4: 0x00c0, 0x29e5: 0x00c0, 0x29e6: 0x00c0, 0x29e7: 0x00c0, 0x29e8: 0x00c0, 0x29e9: 0x00c0, + 0x29ea: 0x00c0, 0x29eb: 0x00c0, 0x29ec: 0x00c3, 0x29ed: 0x00c3, 0x29ee: 0x00c0, 0x29ef: 0x00c0, + 0x29f0: 0x0080, 0x29f1: 0x0080, 0x29f2: 0x00c0, 0x29f3: 0x00c0, 0x29f4: 0x00c0, 0x29f5: 0x00c0, + 0x29f6: 0x00c6, + // Block 0xa8, offset 0x2a00 + 0x2a01: 0x00c0, 0x2a02: 0x00c0, 0x2a03: 0x00c0, 0x2a04: 0x00c0, 0x2a05: 0x00c0, + 0x2a06: 0x00c0, 0x2a09: 0x00c0, 0x2a0a: 0x00c0, 0x2a0b: 0x00c0, + 0x2a0c: 0x00c0, 0x2a0d: 0x00c0, 0x2a0e: 0x00c0, 0x2a11: 0x00c0, + 0x2a12: 0x00c0, 0x2a13: 0x00c0, 0x2a14: 0x00c0, 0x2a15: 0x00c0, 0x2a16: 0x00c0, + 0x2a20: 0x00c0, 0x2a21: 0x00c0, 0x2a22: 0x00c0, 0x2a23: 0x00c0, + 0x2a24: 0x00c0, 0x2a25: 0x00c0, 0x2a26: 0x00c0, 0x2a28: 0x00c0, 0x2a29: 0x00c0, + 0x2a2a: 0x00c0, 0x2a2b: 0x00c0, 0x2a2c: 0x00c0, 0x2a2d: 0x00c0, 0x2a2e: 0x00c0, + 0x2a30: 0x00c0, 0x2a31: 0x00c0, 0x2a32: 0x00c0, 0x2a33: 0x00c0, 0x2a34: 0x00c0, 0x2a35: 0x00c0, + 0x2a36: 0x00c0, 0x2a37: 0x00c0, 0x2a38: 0x00c0, 0x2a39: 0x00c0, 0x2a3a: 0x00c0, 0x2a3b: 0x00c0, + 0x2a3c: 0x00c0, 0x2a3d: 0x00c0, 0x2a3e: 0x00c0, 0x2a3f: 0x00c0, + // Block 0xa9, offset 0x2a40 + 0x2a40: 0x00c0, 0x2a41: 0x00c0, 0x2a42: 0x00c0, 0x2a43: 0x00c0, 0x2a44: 0x00c0, 0x2a45: 0x00c0, + 0x2a46: 0x00c0, 0x2a47: 0x00c0, 0x2a48: 0x00c0, 0x2a49: 0x00c0, 0x2a4a: 0x00c0, 0x2a4b: 0x00c0, + 0x2a4c: 0x00c0, 0x2a4d: 0x00c0, 0x2a4e: 0x00c0, 0x2a4f: 0x00c0, 0x2a50: 0x00c0, 0x2a51: 0x00c0, + 0x2a52: 0x00c0, 0x2a53: 0x00c0, 0x2a54: 0x00c0, 0x2a55: 0x00c0, 0x2a56: 0x00c0, 0x2a57: 0x00c0, + 0x2a58: 0x00c0, 0x2a59: 0x00c0, 0x2a5a: 0x00c0, 0x2a5b: 0x0080, 0x2a5c: 0x0080, 0x2a5d: 0x0080, + 0x2a5e: 0x0080, 0x2a5f: 0x0080, 0x2a60: 0x00c0, 0x2a61: 0x00c0, 0x2a62: 0x00c0, 0x2a63: 0x00c0, + 0x2a64: 0x00c0, 0x2a65: 0x00c8, 0x2a66: 0x00c0, 0x2a67: 0x00c0, 0x2a68: 0x00c0, 0x2a69: 0x0080, + 0x2a6a: 0x0080, 0x2a6b: 0x0080, + 0x2a70: 0x00c0, 0x2a71: 0x00c0, 0x2a72: 0x00c0, 0x2a73: 0x00c0, 0x2a74: 0x00c0, 0x2a75: 0x00c0, + 0x2a76: 0x00c0, 0x2a77: 0x00c0, 0x2a78: 0x00c0, 0x2a79: 0x00c0, 0x2a7a: 0x00c0, 0x2a7b: 0x00c0, + 0x2a7c: 0x00c0, 0x2a7d: 0x00c0, 0x2a7e: 0x00c0, 0x2a7f: 0x00c0, + // Block 0xaa, offset 0x2a80 + 0x2a80: 0x00c0, 0x2a81: 0x00c0, 0x2a82: 0x00c0, 0x2a83: 0x00c0, 0x2a84: 0x00c0, 0x2a85: 0x00c0, + 0x2a86: 0x00c0, 0x2a87: 0x00c0, 0x2a88: 0x00c0, 0x2a89: 0x00c0, 0x2a8a: 0x00c0, 0x2a8b: 0x00c0, + 0x2a8c: 0x00c0, 0x2a8d: 0x00c0, 0x2a8e: 0x00c0, 0x2a8f: 0x00c0, 0x2a90: 0x00c0, 0x2a91: 0x00c0, + 0x2a92: 0x00c0, 0x2a93: 0x00c0, 0x2a94: 0x00c0, 0x2a95: 0x00c0, 0x2a96: 0x00c0, 0x2a97: 0x00c0, + 0x2a98: 0x00c0, 0x2a99: 0x00c0, 0x2a9a: 0x00c0, 0x2a9b: 0x00c0, 0x2a9c: 0x00c0, 0x2a9d: 0x00c0, + 0x2a9e: 0x00c0, 0x2a9f: 0x00c0, 0x2aa0: 0x00c0, 0x2aa1: 0x00c0, 0x2aa2: 0x00c0, 0x2aa3: 0x00c0, + 0x2aa4: 0x00c0, 0x2aa5: 0x00c3, 0x2aa6: 0x00c0, 0x2aa7: 0x00c0, 0x2aa8: 0x00c3, 0x2aa9: 0x00c0, + 0x2aaa: 0x00c0, 0x2aab: 0x0080, 0x2aac: 0x00c0, 0x2aad: 0x00c6, + 0x2ab0: 0x00c0, 0x2ab1: 0x00c0, 0x2ab2: 0x00c0, 0x2ab3: 0x00c0, 0x2ab4: 0x00c0, 0x2ab5: 0x00c0, + 0x2ab6: 0x00c0, 0x2ab7: 0x00c0, 0x2ab8: 0x00c0, 0x2ab9: 0x00c0, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x00c0, 0x2ac1: 0x00c0, 0x2ac2: 0x00c0, 0x2ac3: 0x00c0, 0x2ac4: 0x00c0, 0x2ac5: 0x00c0, + 0x2ac6: 0x00c0, 0x2ac7: 0x00c0, 0x2ac8: 0x00c0, 0x2ac9: 0x00c0, 0x2aca: 0x00c0, 0x2acb: 0x00c0, + 0x2acc: 0x00c0, 0x2acd: 0x00c0, 0x2ace: 0x00c0, 0x2acf: 0x00c0, 0x2ad0: 0x00c0, 0x2ad1: 0x00c0, + 0x2ad2: 0x00c0, 0x2ad3: 0x00c0, 0x2ad4: 0x00c0, 0x2ad5: 0x00c0, 0x2ad6: 0x00c0, 0x2ad7: 0x00c0, + 0x2ad8: 0x00c0, 0x2ad9: 0x00c0, 0x2ada: 0x00c0, 0x2adb: 0x00c0, 0x2adc: 0x00c0, 0x2add: 0x00c0, + 0x2ade: 0x00c0, 0x2adf: 0x00c0, 0x2ae0: 0x00c0, 0x2ae1: 0x00c0, 0x2ae2: 0x00c0, 0x2ae3: 0x00c0, + 0x2af0: 0x0040, 0x2af1: 0x0040, 0x2af2: 0x0040, 0x2af3: 0x0040, 0x2af4: 0x0040, 0x2af5: 0x0040, + 0x2af6: 0x0040, 0x2af7: 0x0040, 0x2af8: 0x0040, 0x2af9: 0x0040, 0x2afa: 0x0040, 0x2afb: 0x0040, + 0x2afc: 0x0040, 0x2afd: 0x0040, 0x2afe: 0x0040, 0x2aff: 0x0040, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x0040, 0x2b01: 0x0040, 0x2b02: 0x0040, 0x2b03: 0x0040, 0x2b04: 0x0040, 0x2b05: 0x0040, + 0x2b06: 0x0040, 0x2b0b: 0x0040, + 0x2b0c: 0x0040, 0x2b0d: 0x0040, 0x2b0e: 0x0040, 0x2b0f: 0x0040, 0x2b10: 0x0040, 0x2b11: 0x0040, + 0x2b12: 0x0040, 0x2b13: 0x0040, 0x2b14: 0x0040, 0x2b15: 0x0040, 0x2b16: 0x0040, 0x2b17: 0x0040, + 0x2b18: 0x0040, 0x2b19: 0x0040, 0x2b1a: 0x0040, 0x2b1b: 0x0040, 0x2b1c: 0x0040, 0x2b1d: 0x0040, + 0x2b1e: 0x0040, 0x2b1f: 0x0040, 0x2b20: 0x0040, 0x2b21: 0x0040, 0x2b22: 0x0040, 0x2b23: 0x0040, + 0x2b24: 0x0040, 0x2b25: 0x0040, 0x2b26: 0x0040, 0x2b27: 0x0040, 0x2b28: 0x0040, 0x2b29: 0x0040, + 0x2b2a: 0x0040, 0x2b2b: 0x0040, 0x2b2c: 0x0040, 0x2b2d: 0x0040, 0x2b2e: 0x0040, 0x2b2f: 0x0040, + 0x2b30: 0x0040, 0x2b31: 0x0040, 0x2b32: 0x0040, 0x2b33: 0x0040, 0x2b34: 0x0040, 0x2b35: 0x0040, + 0x2b36: 0x0040, 0x2b37: 0x0040, 0x2b38: 0x0040, 0x2b39: 0x0040, 0x2b3a: 0x0040, 0x2b3b: 0x0040, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x008c, 0x2b41: 0x008c, 0x2b42: 0x008c, 0x2b43: 0x008c, 0x2b44: 0x008c, 0x2b45: 0x008c, + 0x2b46: 0x008c, 0x2b47: 0x008c, 0x2b48: 0x008c, 0x2b49: 0x008c, 0x2b4a: 0x008c, 0x2b4b: 0x008c, + 0x2b4c: 0x008c, 0x2b4d: 0x008c, 0x2b4e: 0x00cc, 0x2b4f: 0x00cc, 0x2b50: 0x008c, 0x2b51: 0x00cc, + 0x2b52: 0x008c, 0x2b53: 0x00cc, 0x2b54: 0x00cc, 0x2b55: 0x008c, 0x2b56: 0x008c, 0x2b57: 0x008c, + 0x2b58: 0x008c, 0x2b59: 0x008c, 0x2b5a: 0x008c, 0x2b5b: 0x008c, 0x2b5c: 0x008c, 0x2b5d: 0x008c, + 0x2b5e: 0x008c, 0x2b5f: 0x00cc, 0x2b60: 0x008c, 0x2b61: 0x00cc, 0x2b62: 0x008c, 0x2b63: 0x00cc, + 0x2b64: 0x00cc, 0x2b65: 0x008c, 0x2b66: 0x008c, 0x2b67: 0x00cc, 0x2b68: 0x00cc, 0x2b69: 0x00cc, + 0x2b6a: 0x008c, 0x2b6b: 0x008c, 0x2b6c: 0x008c, 0x2b6d: 0x008c, 0x2b6e: 0x008c, 0x2b6f: 0x008c, + 0x2b70: 0x008c, 0x2b71: 0x008c, 0x2b72: 0x008c, 0x2b73: 0x008c, 0x2b74: 0x008c, 0x2b75: 0x008c, + 0x2b76: 0x008c, 0x2b77: 0x008c, 0x2b78: 0x008c, 0x2b79: 0x008c, 0x2b7a: 0x008c, 0x2b7b: 0x008c, + 0x2b7c: 0x008c, 0x2b7d: 0x008c, 0x2b7e: 0x008c, 0x2b7f: 0x008c, + // Block 0xae, offset 0x2b80 + 0x2b80: 0x008c, 0x2b81: 0x008c, 0x2b82: 0x008c, 0x2b83: 0x008c, 0x2b84: 0x008c, 0x2b85: 0x008c, + 0x2b86: 0x008c, 0x2b87: 0x008c, 0x2b88: 0x008c, 0x2b89: 0x008c, 0x2b8a: 0x008c, 0x2b8b: 0x008c, + 0x2b8c: 0x008c, 0x2b8d: 0x008c, 0x2b8e: 0x008c, 0x2b8f: 0x008c, 0x2b90: 0x008c, 0x2b91: 0x008c, + 0x2b92: 0x008c, 0x2b93: 0x008c, 0x2b94: 0x008c, 0x2b95: 0x008c, 0x2b96: 0x008c, 0x2b97: 0x008c, + 0x2b98: 0x008c, 0x2b99: 0x008c, 0x2b9a: 0x008c, 0x2b9b: 0x008c, 0x2b9c: 0x008c, 0x2b9d: 0x008c, + 0x2b9e: 0x008c, 0x2b9f: 0x008c, 0x2ba0: 0x008c, 0x2ba1: 0x008c, 0x2ba2: 0x008c, 0x2ba3: 0x008c, + 0x2ba4: 0x008c, 0x2ba5: 0x008c, 0x2ba6: 0x008c, 0x2ba7: 0x008c, 0x2ba8: 0x008c, 0x2ba9: 0x008c, + 0x2baa: 0x008c, 0x2bab: 0x008c, 0x2bac: 0x008c, 0x2bad: 0x008c, + 0x2bb0: 0x008c, 0x2bb1: 0x008c, 0x2bb2: 0x008c, 0x2bb3: 0x008c, 0x2bb4: 0x008c, 0x2bb5: 0x008c, + 0x2bb6: 0x008c, 0x2bb7: 0x008c, 0x2bb8: 0x008c, 0x2bb9: 0x008c, 0x2bba: 0x008c, 0x2bbb: 0x008c, + 0x2bbc: 0x008c, 0x2bbd: 0x008c, 0x2bbe: 0x008c, 0x2bbf: 0x008c, + // Block 0xaf, offset 0x2bc0 + 0x2bc0: 0x008c, 0x2bc1: 0x008c, 0x2bc2: 0x008c, 0x2bc3: 0x008c, 0x2bc4: 0x008c, 0x2bc5: 0x008c, + 0x2bc6: 0x008c, 0x2bc7: 0x008c, 0x2bc8: 0x008c, 0x2bc9: 0x008c, 0x2bca: 0x008c, 0x2bcb: 0x008c, + 0x2bcc: 0x008c, 0x2bcd: 0x008c, 0x2bce: 0x008c, 0x2bcf: 0x008c, 0x2bd0: 0x008c, 0x2bd1: 0x008c, + 0x2bd2: 0x008c, 0x2bd3: 0x008c, 0x2bd4: 0x008c, 0x2bd5: 0x008c, 0x2bd6: 0x008c, 0x2bd7: 0x008c, + 0x2bd8: 0x008c, 0x2bd9: 0x008c, + // Block 0xb0, offset 0x2c00 + 0x2c00: 0x0080, 0x2c01: 0x0080, 0x2c02: 0x0080, 0x2c03: 0x0080, 0x2c04: 0x0080, 0x2c05: 0x0080, + 0x2c06: 0x0080, + 0x2c13: 0x0080, 0x2c14: 0x0080, 0x2c15: 0x0080, 0x2c16: 0x0080, 0x2c17: 0x0080, + 0x2c1d: 0x008a, + 0x2c1e: 0x00cb, 0x2c1f: 0x008a, 0x2c20: 0x008a, 0x2c21: 0x008a, 0x2c22: 0x008a, 0x2c23: 0x008a, + 0x2c24: 0x008a, 0x2c25: 0x008a, 0x2c26: 0x008a, 0x2c27: 0x008a, 0x2c28: 0x008a, 0x2c29: 0x008a, + 0x2c2a: 0x008a, 0x2c2b: 0x008a, 0x2c2c: 0x008a, 0x2c2d: 0x008a, 0x2c2e: 0x008a, 0x2c2f: 0x008a, + 0x2c30: 0x008a, 0x2c31: 0x008a, 0x2c32: 0x008a, 0x2c33: 0x008a, 0x2c34: 0x008a, 0x2c35: 0x008a, + 0x2c36: 0x008a, 0x2c38: 0x008a, 0x2c39: 0x008a, 0x2c3a: 0x008a, 0x2c3b: 0x008a, + 0x2c3c: 0x008a, 0x2c3e: 0x008a, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x008a, 0x2c41: 0x008a, 0x2c43: 0x008a, 0x2c44: 0x008a, + 0x2c46: 0x008a, 0x2c47: 0x008a, 0x2c48: 0x008a, 0x2c49: 0x008a, 0x2c4a: 0x008a, 0x2c4b: 0x008a, + 0x2c4c: 0x008a, 0x2c4d: 0x008a, 0x2c4e: 0x008a, 0x2c4f: 0x008a, 0x2c50: 0x0080, 0x2c51: 0x0080, + 0x2c52: 0x0080, 0x2c53: 0x0080, 0x2c54: 0x0080, 0x2c55: 0x0080, 0x2c56: 0x0080, 0x2c57: 0x0080, + 0x2c58: 0x0080, 0x2c59: 0x0080, 0x2c5a: 0x0080, 0x2c5b: 0x0080, 0x2c5c: 0x0080, 0x2c5d: 0x0080, + 0x2c5e: 0x0080, 0x2c5f: 0x0080, 0x2c60: 0x0080, 0x2c61: 0x0080, 0x2c62: 0x0080, 0x2c63: 0x0080, + 0x2c64: 0x0080, 0x2c65: 0x0080, 0x2c66: 0x0080, 0x2c67: 0x0080, 0x2c68: 0x0080, 0x2c69: 0x0080, + 0x2c6a: 0x0080, 0x2c6b: 0x0080, 0x2c6c: 0x0080, 0x2c6d: 0x0080, 0x2c6e: 0x0080, 0x2c6f: 0x0080, + 0x2c70: 0x0080, 0x2c71: 0x0080, 0x2c72: 0x0080, 0x2c73: 0x0080, 0x2c74: 0x0080, 0x2c75: 0x0080, + 0x2c76: 0x0080, 0x2c77: 0x0080, 0x2c78: 0x0080, 0x2c79: 0x0080, 0x2c7a: 0x0080, 0x2c7b: 0x0080, + 0x2c7c: 0x0080, 0x2c7d: 0x0080, 0x2c7e: 0x0080, 0x2c7f: 0x0080, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0x0080, 0x2c81: 0x0080, + 0x2c93: 0x0080, 0x2c94: 0x0080, 0x2c95: 0x0080, 0x2c96: 0x0080, 0x2c97: 0x0080, + 0x2c98: 0x0080, 0x2c99: 0x0080, 0x2c9a: 0x0080, 0x2c9b: 0x0080, 0x2c9c: 0x0080, 0x2c9d: 0x0080, + 0x2c9e: 0x0080, 0x2c9f: 0x0080, 0x2ca0: 0x0080, 0x2ca1: 0x0080, 0x2ca2: 0x0080, 0x2ca3: 0x0080, + 0x2ca4: 0x0080, 0x2ca5: 0x0080, 0x2ca6: 0x0080, 0x2ca7: 0x0080, 0x2ca8: 0x0080, 0x2ca9: 0x0080, + 0x2caa: 0x0080, 0x2cab: 0x0080, 0x2cac: 0x0080, 0x2cad: 0x0080, 0x2cae: 0x0080, 0x2caf: 0x0080, + 0x2cb0: 0x0080, 0x2cb1: 0x0080, 0x2cb2: 0x0080, 0x2cb3: 0x0080, 0x2cb4: 0x0080, 0x2cb5: 0x0080, + 0x2cb6: 0x0080, 0x2cb7: 0x0080, 0x2cb8: 0x0080, 0x2cb9: 0x0080, 0x2cba: 0x0080, 0x2cbb: 0x0080, + 0x2cbc: 0x0080, 0x2cbd: 0x0080, 0x2cbe: 0x0080, 0x2cbf: 0x0080, + // Block 0xb3, offset 0x2cc0 + 0x2cd0: 0x0080, 0x2cd1: 0x0080, + 0x2cd2: 0x0080, 0x2cd3: 0x0080, 0x2cd4: 0x0080, 0x2cd5: 0x0080, 0x2cd6: 0x0080, 0x2cd7: 0x0080, + 0x2cd8: 0x0080, 0x2cd9: 0x0080, 0x2cda: 0x0080, 0x2cdb: 0x0080, 0x2cdc: 0x0080, 0x2cdd: 0x0080, + 0x2cde: 0x0080, 0x2cdf: 0x0080, 0x2ce0: 0x0080, 0x2ce1: 0x0080, 0x2ce2: 0x0080, 0x2ce3: 0x0080, + 0x2ce4: 0x0080, 0x2ce5: 0x0080, 0x2ce6: 0x0080, 0x2ce7: 0x0080, 0x2ce8: 0x0080, 0x2ce9: 0x0080, + 0x2cea: 0x0080, 0x2ceb: 0x0080, 0x2cec: 0x0080, 0x2ced: 0x0080, 0x2cee: 0x0080, 0x2cef: 0x0080, + 0x2cf0: 0x0080, 0x2cf1: 0x0080, 0x2cf2: 0x0080, 0x2cf3: 0x0080, 0x2cf4: 0x0080, 0x2cf5: 0x0080, + 0x2cf6: 0x0080, 0x2cf7: 0x0080, 0x2cf8: 0x0080, 0x2cf9: 0x0080, 0x2cfa: 0x0080, 0x2cfb: 0x0080, + 0x2cfc: 0x0080, 0x2cfd: 0x0080, 0x2cfe: 0x0080, 0x2cff: 0x0080, + // Block 0xb4, offset 0x2d00 + 0x2d00: 0x0080, 0x2d01: 0x0080, 0x2d02: 0x0080, 0x2d03: 0x0080, 0x2d04: 0x0080, 0x2d05: 0x0080, + 0x2d06: 0x0080, 0x2d07: 0x0080, 0x2d08: 0x0080, 0x2d09: 0x0080, 0x2d0a: 0x0080, 0x2d0b: 0x0080, + 0x2d0c: 0x0080, 0x2d0d: 0x0080, 0x2d0e: 0x0080, 0x2d0f: 0x0080, + 0x2d12: 0x0080, 0x2d13: 0x0080, 0x2d14: 0x0080, 0x2d15: 0x0080, 0x2d16: 0x0080, 0x2d17: 0x0080, + 0x2d18: 0x0080, 0x2d19: 0x0080, 0x2d1a: 0x0080, 0x2d1b: 0x0080, 0x2d1c: 0x0080, 0x2d1d: 0x0080, + 0x2d1e: 0x0080, 0x2d1f: 0x0080, 0x2d20: 0x0080, 0x2d21: 0x0080, 0x2d22: 0x0080, 0x2d23: 0x0080, + 0x2d24: 0x0080, 0x2d25: 0x0080, 0x2d26: 0x0080, 0x2d27: 0x0080, 0x2d28: 0x0080, 0x2d29: 0x0080, + 0x2d2a: 0x0080, 0x2d2b: 0x0080, 0x2d2c: 0x0080, 0x2d2d: 0x0080, 0x2d2e: 0x0080, 0x2d2f: 0x0080, + 0x2d30: 0x0080, 0x2d31: 0x0080, 0x2d32: 0x0080, 0x2d33: 0x0080, 0x2d34: 0x0080, 0x2d35: 0x0080, + 0x2d36: 0x0080, 0x2d37: 0x0080, 0x2d38: 0x0080, 0x2d39: 0x0080, 0x2d3a: 0x0080, 0x2d3b: 0x0080, + 0x2d3c: 0x0080, 0x2d3d: 0x0080, 0x2d3e: 0x0080, 0x2d3f: 0x0080, + // Block 0xb5, offset 0x2d40 + 0x2d40: 0x0080, 0x2d41: 0x0080, 0x2d42: 0x0080, 0x2d43: 0x0080, 0x2d44: 0x0080, 0x2d45: 0x0080, + 0x2d46: 0x0080, 0x2d47: 0x0080, + 0x2d70: 0x0080, 0x2d71: 0x0080, 0x2d72: 0x0080, 0x2d73: 0x0080, 0x2d74: 0x0080, 0x2d75: 0x0080, + 0x2d76: 0x0080, 0x2d77: 0x0080, 0x2d78: 0x0080, 0x2d79: 0x0080, 0x2d7a: 0x0080, 0x2d7b: 0x0080, + 0x2d7c: 0x0080, 0x2d7d: 0x0080, + // Block 0xb6, offset 0x2d80 + 0x2d80: 0x0040, 0x2d81: 0x0040, 0x2d82: 0x0040, 0x2d83: 0x0040, 0x2d84: 0x0040, 0x2d85: 0x0040, + 0x2d86: 0x0040, 0x2d87: 0x0040, 0x2d88: 0x0040, 0x2d89: 0x0040, 0x2d8a: 0x0040, 0x2d8b: 0x0040, + 0x2d8c: 0x0040, 0x2d8d: 0x0040, 0x2d8e: 0x0040, 0x2d8f: 0x0040, 0x2d90: 0x0080, 0x2d91: 0x0080, + 0x2d92: 0x0080, 0x2d93: 0x0080, 0x2d94: 0x0080, 0x2d95: 0x0080, 0x2d96: 0x0080, 0x2d97: 0x0080, + 0x2d98: 0x0080, 0x2d99: 0x0080, + 0x2da0: 0x00c3, 0x2da1: 0x00c3, 0x2da2: 0x00c3, 0x2da3: 0x00c3, + 0x2da4: 0x00c3, 0x2da5: 0x00c3, 0x2da6: 0x00c3, 0x2da7: 0x00c3, 0x2da8: 0x00c3, 0x2da9: 0x00c3, + 0x2daa: 0x00c3, 0x2dab: 0x00c3, 0x2dac: 0x00c3, 0x2dad: 0x00c3, 0x2dae: 0x00c3, 0x2daf: 0x00c3, + 0x2db0: 0x0080, 0x2db1: 0x0080, 0x2db2: 0x0080, 0x2db3: 0x0080, 0x2db4: 0x0080, 0x2db5: 0x0080, + 0x2db6: 0x0080, 0x2db7: 0x0080, 0x2db8: 0x0080, 0x2db9: 0x0080, 0x2dba: 0x0080, 0x2dbb: 0x0080, + 0x2dbc: 0x0080, 0x2dbd: 0x0080, 0x2dbe: 0x0080, 0x2dbf: 0x0080, + // Block 0xb7, offset 0x2dc0 + 0x2dc0: 0x0080, 0x2dc1: 0x0080, 0x2dc2: 0x0080, 0x2dc3: 0x0080, 0x2dc4: 0x0080, 0x2dc5: 0x0080, + 0x2dc6: 0x0080, 0x2dc7: 0x0080, 0x2dc8: 0x0080, 0x2dc9: 0x0080, 0x2dca: 0x0080, 0x2dcb: 0x0080, + 0x2dcc: 0x0080, 0x2dcd: 0x0080, 0x2dce: 0x0080, 0x2dcf: 0x0080, 0x2dd0: 0x0080, 0x2dd1: 0x0080, + 0x2dd2: 0x0080, 0x2dd4: 0x0080, 0x2dd5: 0x0080, 0x2dd6: 0x0080, 0x2dd7: 0x0080, + 0x2dd8: 0x0080, 0x2dd9: 0x0080, 0x2dda: 0x0080, 0x2ddb: 0x0080, 0x2ddc: 0x0080, 0x2ddd: 0x0080, + 0x2dde: 0x0080, 0x2ddf: 0x0080, 0x2de0: 0x0080, 0x2de1: 0x0080, 0x2de2: 0x0080, 0x2de3: 0x0080, + 0x2de4: 0x0080, 0x2de5: 0x0080, 0x2de6: 0x0080, 0x2de8: 0x0080, 0x2de9: 0x0080, + 0x2dea: 0x0080, 0x2deb: 0x0080, + 0x2df0: 0x0080, 0x2df1: 0x0080, 0x2df2: 0x0080, 0x2df3: 0x00c0, 0x2df4: 0x0080, + 0x2df6: 0x0080, 0x2df7: 0x0080, 0x2df8: 0x0080, 0x2df9: 0x0080, 0x2dfa: 0x0080, 0x2dfb: 0x0080, + 0x2dfc: 0x0080, 0x2dfd: 0x0080, 0x2dfe: 0x0080, 0x2dff: 0x0080, + // Block 0xb8, offset 0x2e00 + 0x2e00: 0x0080, 0x2e01: 0x0080, 0x2e02: 0x0080, 0x2e03: 0x0080, 0x2e04: 0x0080, 0x2e05: 0x0080, + 0x2e06: 0x0080, 0x2e07: 0x0080, 0x2e08: 0x0080, 0x2e09: 0x0080, 0x2e0a: 0x0080, 0x2e0b: 0x0080, + 0x2e0c: 0x0080, 0x2e0d: 0x0080, 0x2e0e: 0x0080, 0x2e0f: 0x0080, 0x2e10: 0x0080, 0x2e11: 0x0080, + 0x2e12: 0x0080, 0x2e13: 0x0080, 0x2e14: 0x0080, 0x2e15: 0x0080, 0x2e16: 0x0080, 0x2e17: 0x0080, + 0x2e18: 0x0080, 0x2e19: 0x0080, 0x2e1a: 0x0080, 0x2e1b: 0x0080, 0x2e1c: 0x0080, 0x2e1d: 0x0080, + 0x2e1e: 0x0080, 0x2e1f: 0x0080, 0x2e20: 0x0080, 0x2e21: 0x0080, 0x2e22: 0x0080, 0x2e23: 0x0080, + 0x2e24: 0x0080, 0x2e25: 0x0080, 0x2e26: 0x0080, 0x2e27: 0x0080, 0x2e28: 0x0080, 0x2e29: 0x0080, + 0x2e2a: 0x0080, 0x2e2b: 0x0080, 0x2e2c: 0x0080, 0x2e2d: 0x0080, 0x2e2e: 0x0080, 0x2e2f: 0x0080, + 0x2e30: 0x0080, 0x2e31: 0x0080, 0x2e32: 0x0080, 0x2e33: 0x0080, 0x2e34: 0x0080, 0x2e35: 0x0080, + 0x2e36: 0x0080, 0x2e37: 0x0080, 0x2e38: 0x0080, 0x2e39: 0x0080, 0x2e3a: 0x0080, 0x2e3b: 0x0080, + 0x2e3c: 0x0080, 0x2e3f: 0x0040, + // Block 0xb9, offset 0x2e40 + 0x2e41: 0x0080, 0x2e42: 0x0080, 0x2e43: 0x0080, 0x2e44: 0x0080, 0x2e45: 0x0080, + 0x2e46: 0x0080, 0x2e47: 0x0080, 0x2e48: 0x0080, 0x2e49: 0x0080, 0x2e4a: 0x0080, 0x2e4b: 0x0080, + 0x2e4c: 0x0080, 0x2e4d: 0x0080, 0x2e4e: 0x0080, 0x2e4f: 0x0080, 0x2e50: 0x0080, 0x2e51: 0x0080, + 0x2e52: 0x0080, 0x2e53: 0x0080, 0x2e54: 0x0080, 0x2e55: 0x0080, 0x2e56: 0x0080, 0x2e57: 0x0080, + 0x2e58: 0x0080, 0x2e59: 0x0080, 0x2e5a: 0x0080, 0x2e5b: 0x0080, 0x2e5c: 0x0080, 0x2e5d: 0x0080, + 0x2e5e: 0x0080, 0x2e5f: 0x0080, 0x2e60: 0x0080, 0x2e61: 0x0080, 0x2e62: 0x0080, 0x2e63: 0x0080, + 0x2e64: 0x0080, 0x2e65: 0x0080, 0x2e66: 0x0080, 0x2e67: 0x0080, 0x2e68: 0x0080, 0x2e69: 0x0080, + 0x2e6a: 0x0080, 0x2e6b: 0x0080, 0x2e6c: 0x0080, 0x2e6d: 0x0080, 0x2e6e: 0x0080, 0x2e6f: 0x0080, + 0x2e70: 0x0080, 0x2e71: 0x0080, 0x2e72: 0x0080, 0x2e73: 0x0080, 0x2e74: 0x0080, 0x2e75: 0x0080, + 0x2e76: 0x0080, 0x2e77: 0x0080, 0x2e78: 0x0080, 0x2e79: 0x0080, 0x2e7a: 0x0080, 0x2e7b: 0x0080, + 0x2e7c: 0x0080, 0x2e7d: 0x0080, 0x2e7e: 0x0080, 0x2e7f: 0x0080, + // Block 0xba, offset 0x2e80 + 0x2e80: 0x0080, 0x2e81: 0x0080, 0x2e82: 0x0080, 0x2e83: 0x0080, 0x2e84: 0x0080, 0x2e85: 0x0080, + 0x2e86: 0x0080, 0x2e87: 0x0080, 0x2e88: 0x0080, 0x2e89: 0x0080, 0x2e8a: 0x0080, 0x2e8b: 0x0080, + 0x2e8c: 0x0080, 0x2e8d: 0x0080, 0x2e8e: 0x0080, 0x2e8f: 0x0080, 0x2e90: 0x0080, 0x2e91: 0x0080, + 0x2e92: 0x0080, 0x2e93: 0x0080, 0x2e94: 0x0080, 0x2e95: 0x0080, 0x2e96: 0x0080, 0x2e97: 0x0080, + 0x2e98: 0x0080, 0x2e99: 0x0080, 0x2e9a: 0x0080, 0x2e9b: 0x0080, 0x2e9c: 0x0080, 0x2e9d: 0x0080, + 0x2e9e: 0x0080, 0x2e9f: 0x0080, 0x2ea0: 0x0080, 0x2ea1: 0x0080, 0x2ea2: 0x0080, 0x2ea3: 0x0080, + 0x2ea4: 0x0080, 0x2ea5: 0x0080, 0x2ea6: 0x008c, 0x2ea7: 0x008c, 0x2ea8: 0x008c, 0x2ea9: 0x008c, + 0x2eaa: 0x008c, 0x2eab: 0x008c, 0x2eac: 0x008c, 0x2ead: 0x008c, 0x2eae: 0x008c, 0x2eaf: 0x008c, + 0x2eb0: 0x0080, 0x2eb1: 0x008c, 0x2eb2: 0x008c, 0x2eb3: 0x008c, 0x2eb4: 0x008c, 0x2eb5: 0x008c, + 0x2eb6: 0x008c, 0x2eb7: 0x008c, 0x2eb8: 0x008c, 0x2eb9: 0x008c, 0x2eba: 0x008c, 0x2ebb: 0x008c, + 0x2ebc: 0x008c, 0x2ebd: 0x008c, 0x2ebe: 0x008c, 0x2ebf: 0x008c, + // Block 0xbb, offset 0x2ec0 + 0x2ec0: 0x008c, 0x2ec1: 0x008c, 0x2ec2: 0x008c, 0x2ec3: 0x008c, 0x2ec4: 0x008c, 0x2ec5: 0x008c, + 0x2ec6: 0x008c, 0x2ec7: 0x008c, 0x2ec8: 0x008c, 0x2ec9: 0x008c, 0x2eca: 0x008c, 0x2ecb: 0x008c, + 0x2ecc: 0x008c, 0x2ecd: 0x008c, 0x2ece: 0x008c, 0x2ecf: 0x008c, 0x2ed0: 0x008c, 0x2ed1: 0x008c, + 0x2ed2: 0x008c, 0x2ed3: 0x008c, 0x2ed4: 0x008c, 0x2ed5: 0x008c, 0x2ed6: 0x008c, 0x2ed7: 0x008c, + 0x2ed8: 0x008c, 0x2ed9: 0x008c, 0x2eda: 0x008c, 0x2edb: 0x008c, 0x2edc: 0x008c, 0x2edd: 0x008c, + 0x2ede: 0x0080, 0x2edf: 0x0080, 0x2ee0: 0x0040, 0x2ee1: 0x0080, 0x2ee2: 0x0080, 0x2ee3: 0x0080, + 0x2ee4: 0x0080, 0x2ee5: 0x0080, 0x2ee6: 0x0080, 0x2ee7: 0x0080, 0x2ee8: 0x0080, 0x2ee9: 0x0080, + 0x2eea: 0x0080, 0x2eeb: 0x0080, 0x2eec: 0x0080, 0x2eed: 0x0080, 0x2eee: 0x0080, 0x2eef: 0x0080, + 0x2ef0: 0x0080, 0x2ef1: 0x0080, 0x2ef2: 0x0080, 0x2ef3: 0x0080, 0x2ef4: 0x0080, 0x2ef5: 0x0080, + 0x2ef6: 0x0080, 0x2ef7: 0x0080, 0x2ef8: 0x0080, 0x2ef9: 0x0080, 0x2efa: 0x0080, 0x2efb: 0x0080, + 0x2efc: 0x0080, 0x2efd: 0x0080, 0x2efe: 0x0080, + // Block 0xbc, offset 0x2f00 + 0x2f02: 0x0080, 0x2f03: 0x0080, 0x2f04: 0x0080, 0x2f05: 0x0080, + 0x2f06: 0x0080, 0x2f07: 0x0080, 0x2f0a: 0x0080, 0x2f0b: 0x0080, + 0x2f0c: 0x0080, 0x2f0d: 0x0080, 0x2f0e: 0x0080, 0x2f0f: 0x0080, + 0x2f12: 0x0080, 0x2f13: 0x0080, 0x2f14: 0x0080, 0x2f15: 0x0080, 0x2f16: 0x0080, 0x2f17: 0x0080, + 0x2f1a: 0x0080, 0x2f1b: 0x0080, 0x2f1c: 0x0080, + 0x2f20: 0x0080, 0x2f21: 0x0080, 0x2f22: 0x0080, 0x2f23: 0x0080, + 0x2f24: 0x0080, 0x2f25: 0x0080, 0x2f26: 0x0080, 0x2f28: 0x0080, 0x2f29: 0x0080, + 0x2f2a: 0x0080, 0x2f2b: 0x0080, 0x2f2c: 0x0080, 0x2f2d: 0x0080, 0x2f2e: 0x0080, + 0x2f39: 0x0040, 0x2f3a: 0x0040, 0x2f3b: 0x0040, + 0x2f3c: 0x0080, 0x2f3d: 0x0080, + // Block 0xbd, offset 0x2f40 + 0x2f40: 0x00c0, 0x2f41: 0x00c0, 0x2f42: 0x00c0, 0x2f43: 0x00c0, 0x2f44: 0x00c0, 0x2f45: 0x00c0, + 0x2f46: 0x00c0, 0x2f47: 0x00c0, 0x2f48: 0x00c0, 0x2f49: 0x00c0, 0x2f4a: 0x00c0, 0x2f4b: 0x00c0, + 0x2f4d: 0x00c0, 0x2f4e: 0x00c0, 0x2f4f: 0x00c0, 0x2f50: 0x00c0, 0x2f51: 0x00c0, + 0x2f52: 0x00c0, 0x2f53: 0x00c0, 0x2f54: 0x00c0, 0x2f55: 0x00c0, 0x2f56: 0x00c0, 0x2f57: 0x00c0, + 0x2f58: 0x00c0, 0x2f59: 0x00c0, 0x2f5a: 0x00c0, 0x2f5b: 0x00c0, 0x2f5c: 0x00c0, 0x2f5d: 0x00c0, + 0x2f5e: 0x00c0, 0x2f5f: 0x00c0, 0x2f60: 0x00c0, 0x2f61: 0x00c0, 0x2f62: 0x00c0, 0x2f63: 0x00c0, + 0x2f64: 0x00c0, 0x2f65: 0x00c0, 0x2f66: 0x00c0, 0x2f68: 0x00c0, 0x2f69: 0x00c0, + 0x2f6a: 0x00c0, 0x2f6b: 0x00c0, 0x2f6c: 0x00c0, 0x2f6d: 0x00c0, 0x2f6e: 0x00c0, 0x2f6f: 0x00c0, + 0x2f70: 0x00c0, 0x2f71: 0x00c0, 0x2f72: 0x00c0, 0x2f73: 0x00c0, 0x2f74: 0x00c0, 0x2f75: 0x00c0, + 0x2f76: 0x00c0, 0x2f77: 0x00c0, 0x2f78: 0x00c0, 0x2f79: 0x00c0, 0x2f7a: 0x00c0, + 0x2f7c: 0x00c0, 0x2f7d: 0x00c0, 0x2f7f: 0x00c0, + // Block 0xbe, offset 0x2f80 + 0x2f80: 0x00c0, 0x2f81: 0x00c0, 0x2f82: 0x00c0, 0x2f83: 0x00c0, 0x2f84: 0x00c0, 0x2f85: 0x00c0, + 0x2f86: 0x00c0, 0x2f87: 0x00c0, 0x2f88: 0x00c0, 0x2f89: 0x00c0, 0x2f8a: 0x00c0, 0x2f8b: 0x00c0, + 0x2f8c: 0x00c0, 0x2f8d: 0x00c0, 0x2f90: 0x00c0, 0x2f91: 0x00c0, + 0x2f92: 0x00c0, 0x2f93: 0x00c0, 0x2f94: 0x00c0, 0x2f95: 0x00c0, 0x2f96: 0x00c0, 0x2f97: 0x00c0, + 0x2f98: 0x00c0, 0x2f99: 0x00c0, 0x2f9a: 0x00c0, 0x2f9b: 0x00c0, 0x2f9c: 0x00c0, 0x2f9d: 0x00c0, + // Block 0xbf, offset 0x2fc0 + 0x2fc0: 0x00c0, 0x2fc1: 0x00c0, 0x2fc2: 0x00c0, 0x2fc3: 0x00c0, 0x2fc4: 0x00c0, 0x2fc5: 0x00c0, + 0x2fc6: 0x00c0, 0x2fc7: 0x00c0, 0x2fc8: 0x00c0, 0x2fc9: 0x00c0, 0x2fca: 0x00c0, 0x2fcb: 0x00c0, + 0x2fcc: 0x00c0, 0x2fcd: 0x00c0, 0x2fce: 0x00c0, 0x2fcf: 0x00c0, 0x2fd0: 0x00c0, 0x2fd1: 0x00c0, + 0x2fd2: 0x00c0, 0x2fd3: 0x00c0, 0x2fd4: 0x00c0, 0x2fd5: 0x00c0, 0x2fd6: 0x00c0, 0x2fd7: 0x00c0, + 0x2fd8: 0x00c0, 0x2fd9: 0x00c0, 0x2fda: 0x00c0, 0x2fdb: 0x00c0, 0x2fdc: 0x00c0, 0x2fdd: 0x00c0, + 0x2fde: 0x00c0, 0x2fdf: 0x00c0, 0x2fe0: 0x00c0, 0x2fe1: 0x00c0, 0x2fe2: 0x00c0, 0x2fe3: 0x00c0, + 0x2fe4: 0x00c0, 0x2fe5: 0x00c0, 0x2fe6: 0x00c0, 0x2fe7: 0x00c0, 0x2fe8: 0x00c0, 0x2fe9: 0x00c0, + 0x2fea: 0x00c0, 0x2feb: 0x00c0, 0x2fec: 0x00c0, 0x2fed: 0x00c0, 0x2fee: 0x00c0, 0x2fef: 0x00c0, + 0x2ff0: 0x00c0, 0x2ff1: 0x00c0, 0x2ff2: 0x00c0, 0x2ff3: 0x00c0, 0x2ff4: 0x00c0, 0x2ff5: 0x00c0, + 0x2ff6: 0x00c0, 0x2ff7: 0x00c0, 0x2ff8: 0x00c0, 0x2ff9: 0x00c0, 0x2ffa: 0x00c0, + // Block 0xc0, offset 0x3000 + 0x3000: 0x0080, 0x3001: 0x0080, 0x3002: 0x0080, + 0x3007: 0x0080, 0x3008: 0x0080, 0x3009: 0x0080, 0x300a: 0x0080, 0x300b: 0x0080, + 0x300c: 0x0080, 0x300d: 0x0080, 0x300e: 0x0080, 0x300f: 0x0080, 0x3010: 0x0080, 0x3011: 0x0080, + 0x3012: 0x0080, 0x3013: 0x0080, 0x3014: 0x0080, 0x3015: 0x0080, 0x3016: 0x0080, 0x3017: 0x0080, + 0x3018: 0x0080, 0x3019: 0x0080, 0x301a: 0x0080, 0x301b: 0x0080, 0x301c: 0x0080, 0x301d: 0x0080, + 0x301e: 0x0080, 0x301f: 0x0080, 0x3020: 0x0080, 0x3021: 0x0080, 0x3022: 0x0080, 0x3023: 0x0080, + 0x3024: 0x0080, 0x3025: 0x0080, 0x3026: 0x0080, 0x3027: 0x0080, 0x3028: 0x0080, 0x3029: 0x0080, + 0x302a: 0x0080, 0x302b: 0x0080, 0x302c: 0x0080, 0x302d: 0x0080, 0x302e: 0x0080, 0x302f: 0x0080, + 0x3030: 0x0080, 0x3031: 0x0080, 0x3032: 0x0080, 0x3033: 0x0080, + 0x3037: 0x0080, 0x3038: 0x0080, 0x3039: 0x0080, 0x303a: 0x0080, 0x303b: 0x0080, + 0x303c: 0x0080, 0x303d: 0x0080, 0x303e: 0x0080, 0x303f: 0x0080, + // Block 0xc1, offset 0x3040 + 0x3040: 0x0088, 0x3041: 0x0088, 0x3042: 0x0088, 0x3043: 0x0088, 0x3044: 0x0088, 0x3045: 0x0088, + 0x3046: 0x0088, 0x3047: 0x0088, 0x3048: 0x0088, 0x3049: 0x0088, 0x304a: 0x0088, 0x304b: 0x0088, + 0x304c: 0x0088, 0x304d: 0x0088, 0x304e: 0x0088, 0x304f: 0x0088, 0x3050: 0x0088, 0x3051: 0x0088, + 0x3052: 0x0088, 0x3053: 0x0088, 0x3054: 0x0088, 0x3055: 0x0088, 0x3056: 0x0088, 0x3057: 0x0088, + 0x3058: 0x0088, 0x3059: 0x0088, 0x305a: 0x0088, 0x305b: 0x0088, 0x305c: 0x0088, 0x305d: 0x0088, + 0x305e: 0x0088, 0x305f: 0x0088, 0x3060: 0x0088, 0x3061: 0x0088, 0x3062: 0x0088, 0x3063: 0x0088, + 0x3064: 0x0088, 0x3065: 0x0088, 0x3066: 0x0088, 0x3067: 0x0088, 0x3068: 0x0088, 0x3069: 0x0088, + 0x306a: 0x0088, 0x306b: 0x0088, 0x306c: 0x0088, 0x306d: 0x0088, 0x306e: 0x0088, 0x306f: 0x0088, + 0x3070: 0x0088, 0x3071: 0x0088, 0x3072: 0x0088, 0x3073: 0x0088, 0x3074: 0x0088, 0x3075: 0x0088, + 0x3076: 0x0088, 0x3077: 0x0088, 0x3078: 0x0088, 0x3079: 0x0088, 0x307a: 0x0088, 0x307b: 0x0088, + 0x307c: 0x0088, 0x307d: 0x0088, 0x307e: 0x0088, 0x307f: 0x0088, + // Block 0xc2, offset 0x3080 + 0x3080: 0x0088, 0x3081: 0x0088, 0x3082: 0x0088, 0x3083: 0x0088, 0x3084: 0x0088, 0x3085: 0x0088, + 0x3086: 0x0088, 0x3087: 0x0088, 0x3088: 0x0088, 0x3089: 0x0088, 0x308a: 0x0088, 0x308b: 0x0088, + 0x308c: 0x0088, 0x308d: 0x0088, 0x308e: 0x0088, 0x3090: 0x0080, 0x3091: 0x0080, + 0x3092: 0x0080, 0x3093: 0x0080, 0x3094: 0x0080, 0x3095: 0x0080, 0x3096: 0x0080, 0x3097: 0x0080, + 0x3098: 0x0080, 0x3099: 0x0080, 0x309a: 0x0080, 0x309b: 0x0080, 0x309c: 0x0080, + 0x30a0: 0x0088, + // Block 0xc3, offset 0x30c0 + 0x30d0: 0x0080, 0x30d1: 0x0080, + 0x30d2: 0x0080, 0x30d3: 0x0080, 0x30d4: 0x0080, 0x30d5: 0x0080, 0x30d6: 0x0080, 0x30d7: 0x0080, + 0x30d8: 0x0080, 0x30d9: 0x0080, 0x30da: 0x0080, 0x30db: 0x0080, 0x30dc: 0x0080, 0x30dd: 0x0080, + 0x30de: 0x0080, 0x30df: 0x0080, 0x30e0: 0x0080, 0x30e1: 0x0080, 0x30e2: 0x0080, 0x30e3: 0x0080, + 0x30e4: 0x0080, 0x30e5: 0x0080, 0x30e6: 0x0080, 0x30e7: 0x0080, 0x30e8: 0x0080, 0x30e9: 0x0080, + 0x30ea: 0x0080, 0x30eb: 0x0080, 0x30ec: 0x0080, 0x30ed: 0x0080, 0x30ee: 0x0080, 0x30ef: 0x0080, + 0x30f0: 0x0080, 0x30f1: 0x0080, 0x30f2: 0x0080, 0x30f3: 0x0080, 0x30f4: 0x0080, 0x30f5: 0x0080, + 0x30f6: 0x0080, 0x30f7: 0x0080, 0x30f8: 0x0080, 0x30f9: 0x0080, 0x30fa: 0x0080, 0x30fb: 0x0080, + 0x30fc: 0x0080, 0x30fd: 0x00c3, + // Block 0xc4, offset 0x3100 + 0x3100: 0x00c0, 0x3101: 0x00c0, 0x3102: 0x00c0, 0x3103: 0x00c0, 0x3104: 0x00c0, 0x3105: 0x00c0, + 0x3106: 0x00c0, 0x3107: 0x00c0, 0x3108: 0x00c0, 0x3109: 0x00c0, 0x310a: 0x00c0, 0x310b: 0x00c0, + 0x310c: 0x00c0, 0x310d: 0x00c0, 0x310e: 0x00c0, 0x310f: 0x00c0, 0x3110: 0x00c0, 0x3111: 0x00c0, + 0x3112: 0x00c0, 0x3113: 0x00c0, 0x3114: 0x00c0, 0x3115: 0x00c0, 0x3116: 0x00c0, 0x3117: 0x00c0, + 0x3118: 0x00c0, 0x3119: 0x00c0, 0x311a: 0x00c0, 0x311b: 0x00c0, 0x311c: 0x00c0, + 0x3120: 0x00c0, 0x3121: 0x00c0, 0x3122: 0x00c0, 0x3123: 0x00c0, + 0x3124: 0x00c0, 0x3125: 0x00c0, 0x3126: 0x00c0, 0x3127: 0x00c0, 0x3128: 0x00c0, 0x3129: 0x00c0, + 0x312a: 0x00c0, 0x312b: 0x00c0, 0x312c: 0x00c0, 0x312d: 0x00c0, 0x312e: 0x00c0, 0x312f: 0x00c0, + 0x3130: 0x00c0, 0x3131: 0x00c0, 0x3132: 0x00c0, 0x3133: 0x00c0, 0x3134: 0x00c0, 0x3135: 0x00c0, + 0x3136: 0x00c0, 0x3137: 0x00c0, 0x3138: 0x00c0, 0x3139: 0x00c0, 0x313a: 0x00c0, 0x313b: 0x00c0, + 0x313c: 0x00c0, 0x313d: 0x00c0, 0x313e: 0x00c0, 0x313f: 0x00c0, + // Block 0xc5, offset 0x3140 + 0x3140: 0x00c0, 0x3141: 0x00c0, 0x3142: 0x00c0, 0x3143: 0x00c0, 0x3144: 0x00c0, 0x3145: 0x00c0, + 0x3146: 0x00c0, 0x3147: 0x00c0, 0x3148: 0x00c0, 0x3149: 0x00c0, 0x314a: 0x00c0, 0x314b: 0x00c0, + 0x314c: 0x00c0, 0x314d: 0x00c0, 0x314e: 0x00c0, 0x314f: 0x00c0, 0x3150: 0x00c0, + 0x3160: 0x00c3, 0x3161: 0x0080, 0x3162: 0x0080, 0x3163: 0x0080, + 0x3164: 0x0080, 0x3165: 0x0080, 0x3166: 0x0080, 0x3167: 0x0080, 0x3168: 0x0080, 0x3169: 0x0080, + 0x316a: 0x0080, 0x316b: 0x0080, 0x316c: 0x0080, 0x316d: 0x0080, 0x316e: 0x0080, 0x316f: 0x0080, + 0x3170: 0x0080, 0x3171: 0x0080, 0x3172: 0x0080, 0x3173: 0x0080, 0x3174: 0x0080, 0x3175: 0x0080, + 0x3176: 0x0080, 0x3177: 0x0080, 0x3178: 0x0080, 0x3179: 0x0080, 0x317a: 0x0080, 0x317b: 0x0080, + // Block 0xc6, offset 0x3180 + 0x3180: 0x00c0, 0x3181: 0x00c0, 0x3182: 0x00c0, 0x3183: 0x00c0, 0x3184: 0x00c0, 0x3185: 0x00c0, + 0x3186: 0x00c0, 0x3187: 0x00c0, 0x3188: 0x00c0, 0x3189: 0x00c0, 0x318a: 0x00c0, 0x318b: 0x00c0, + 0x318c: 0x00c0, 0x318d: 0x00c0, 0x318e: 0x00c0, 0x318f: 0x00c0, 0x3190: 0x00c0, 0x3191: 0x00c0, + 0x3192: 0x00c0, 0x3193: 0x00c0, 0x3194: 0x00c0, 0x3195: 0x00c0, 0x3196: 0x00c0, 0x3197: 0x00c0, + 0x3198: 0x00c0, 0x3199: 0x00c0, 0x319a: 0x00c0, 0x319b: 0x00c0, 0x319c: 0x00c0, 0x319d: 0x00c0, + 0x319e: 0x00c0, 0x319f: 0x00c0, 0x31a0: 0x0080, 0x31a1: 0x0080, 0x31a2: 0x0080, 0x31a3: 0x0080, + 0x31ad: 0x00c0, 0x31ae: 0x00c0, 0x31af: 0x00c0, + 0x31b0: 0x00c0, 0x31b1: 0x00c0, 0x31b2: 0x00c0, 0x31b3: 0x00c0, 0x31b4: 0x00c0, 0x31b5: 0x00c0, + 0x31b6: 0x00c0, 0x31b7: 0x00c0, 0x31b8: 0x00c0, 0x31b9: 0x00c0, 0x31ba: 0x00c0, 0x31bb: 0x00c0, + 0x31bc: 0x00c0, 0x31bd: 0x00c0, 0x31be: 0x00c0, 0x31bf: 0x00c0, + // Block 0xc7, offset 0x31c0 + 0x31c0: 0x00c0, 0x31c1: 0x0080, 0x31c2: 0x00c0, 0x31c3: 0x00c0, 0x31c4: 0x00c0, 0x31c5: 0x00c0, + 0x31c6: 0x00c0, 0x31c7: 0x00c0, 0x31c8: 0x00c0, 0x31c9: 0x00c0, 0x31ca: 0x0080, + 0x31d0: 0x00c0, 0x31d1: 0x00c0, + 0x31d2: 0x00c0, 0x31d3: 0x00c0, 0x31d4: 0x00c0, 0x31d5: 0x00c0, 0x31d6: 0x00c0, 0x31d7: 0x00c0, + 0x31d8: 0x00c0, 0x31d9: 0x00c0, 0x31da: 0x00c0, 0x31db: 0x00c0, 0x31dc: 0x00c0, 0x31dd: 0x00c0, + 0x31de: 0x00c0, 0x31df: 0x00c0, 0x31e0: 0x00c0, 0x31e1: 0x00c0, 0x31e2: 0x00c0, 0x31e3: 0x00c0, + 0x31e4: 0x00c0, 0x31e5: 0x00c0, 0x31e6: 0x00c0, 0x31e7: 0x00c0, 0x31e8: 0x00c0, 0x31e9: 0x00c0, + 0x31ea: 0x00c0, 0x31eb: 0x00c0, 0x31ec: 0x00c0, 0x31ed: 0x00c0, 0x31ee: 0x00c0, 0x31ef: 0x00c0, + 0x31f0: 0x00c0, 0x31f1: 0x00c0, 0x31f2: 0x00c0, 0x31f3: 0x00c0, 0x31f4: 0x00c0, 0x31f5: 0x00c0, + 0x31f6: 0x00c3, 0x31f7: 0x00c3, 0x31f8: 0x00c3, 0x31f9: 0x00c3, 0x31fa: 0x00c3, + // Block 0xc8, offset 0x3200 + 0x3200: 0x00c0, 0x3201: 0x00c0, 0x3202: 0x00c0, 0x3203: 0x00c0, 0x3204: 0x00c0, 0x3205: 0x00c0, + 0x3206: 0x00c0, 0x3207: 0x00c0, 0x3208: 0x00c0, 0x3209: 0x00c0, 0x320a: 0x00c0, 0x320b: 0x00c0, + 0x320c: 0x00c0, 0x320d: 0x00c0, 0x320e: 0x00c0, 0x320f: 0x00c0, 0x3210: 0x00c0, 0x3211: 0x00c0, + 0x3212: 0x00c0, 0x3213: 0x00c0, 0x3214: 0x00c0, 0x3215: 0x00c0, 0x3216: 0x00c0, 0x3217: 0x00c0, + 0x3218: 0x00c0, 0x3219: 0x00c0, 0x321a: 0x00c0, 0x321b: 0x00c0, 0x321c: 0x00c0, 0x321d: 0x00c0, + 0x321f: 0x0080, 0x3220: 0x00c0, 0x3221: 0x00c0, 0x3222: 0x00c0, 0x3223: 0x00c0, + 0x3224: 0x00c0, 0x3225: 0x00c0, 0x3226: 0x00c0, 0x3227: 0x00c0, 0x3228: 0x00c0, 0x3229: 0x00c0, + 0x322a: 0x00c0, 0x322b: 0x00c0, 0x322c: 0x00c0, 0x322d: 0x00c0, 0x322e: 0x00c0, 0x322f: 0x00c0, + 0x3230: 0x00c0, 0x3231: 0x00c0, 0x3232: 0x00c0, 0x3233: 0x00c0, 0x3234: 0x00c0, 0x3235: 0x00c0, + 0x3236: 0x00c0, 0x3237: 0x00c0, 0x3238: 0x00c0, 0x3239: 0x00c0, 0x323a: 0x00c0, 0x323b: 0x00c0, + 0x323c: 0x00c0, 0x323d: 0x00c0, 0x323e: 0x00c0, 0x323f: 0x00c0, + // Block 0xc9, offset 0x3240 + 0x3240: 0x00c0, 0x3241: 0x00c0, 0x3242: 0x00c0, 0x3243: 0x00c0, + 0x3248: 0x00c0, 0x3249: 0x00c0, 0x324a: 0x00c0, 0x324b: 0x00c0, + 0x324c: 0x00c0, 0x324d: 0x00c0, 0x324e: 0x00c0, 0x324f: 0x00c0, 0x3250: 0x0080, 0x3251: 0x0080, + 0x3252: 0x0080, 0x3253: 0x0080, 0x3254: 0x0080, 0x3255: 0x0080, + // Block 0xca, offset 0x3280 + 0x3280: 0x00c0, 0x3281: 0x00c0, 0x3282: 0x00c0, 0x3283: 0x00c0, 0x3284: 0x00c0, 0x3285: 0x00c0, + 0x3286: 0x00c0, 0x3287: 0x00c0, 0x3288: 0x00c0, 0x3289: 0x00c0, 0x328a: 0x00c0, 0x328b: 0x00c0, + 0x328c: 0x00c0, 0x328d: 0x00c0, 0x328e: 0x00c0, 0x328f: 0x00c0, 0x3290: 0x00c0, 0x3291: 0x00c0, + 0x3292: 0x00c0, 0x3293: 0x00c0, 0x3294: 0x00c0, 0x3295: 0x00c0, 0x3296: 0x00c0, 0x3297: 0x00c0, + 0x3298: 0x00c0, 0x3299: 0x00c0, 0x329a: 0x00c0, 0x329b: 0x00c0, 0x329c: 0x00c0, 0x329d: 0x00c0, + 0x32a0: 0x00c0, 0x32a1: 0x00c0, 0x32a2: 0x00c0, 0x32a3: 0x00c0, + 0x32a4: 0x00c0, 0x32a5: 0x00c0, 0x32a6: 0x00c0, 0x32a7: 0x00c0, 0x32a8: 0x00c0, 0x32a9: 0x00c0, + 0x32b0: 0x00c0, 0x32b1: 0x00c0, 0x32b2: 0x00c0, 0x32b3: 0x00c0, 0x32b4: 0x00c0, 0x32b5: 0x00c0, + 0x32b6: 0x00c0, 0x32b7: 0x00c0, 0x32b8: 0x00c0, 0x32b9: 0x00c0, 0x32ba: 0x00c0, 0x32bb: 0x00c0, + 0x32bc: 0x00c0, 0x32bd: 0x00c0, 0x32be: 0x00c0, 0x32bf: 0x00c0, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x00c0, 0x32c1: 0x00c0, 0x32c2: 0x00c0, 0x32c3: 0x00c0, 0x32c4: 0x00c0, 0x32c5: 0x00c0, + 0x32c6: 0x00c0, 0x32c7: 0x00c0, 0x32c8: 0x00c0, 0x32c9: 0x00c0, 0x32ca: 0x00c0, 0x32cb: 0x00c0, + 0x32cc: 0x00c0, 0x32cd: 0x00c0, 0x32ce: 0x00c0, 0x32cf: 0x00c0, 0x32d0: 0x00c0, 0x32d1: 0x00c0, + 0x32d2: 0x00c0, 0x32d3: 0x00c0, + 0x32d8: 0x00c0, 0x32d9: 0x00c0, 0x32da: 0x00c0, 0x32db: 0x00c0, 0x32dc: 0x00c0, 0x32dd: 0x00c0, + 0x32de: 0x00c0, 0x32df: 0x00c0, 0x32e0: 0x00c0, 0x32e1: 0x00c0, 0x32e2: 0x00c0, 0x32e3: 0x00c0, + 0x32e4: 0x00c0, 0x32e5: 0x00c0, 0x32e6: 0x00c0, 0x32e7: 0x00c0, 0x32e8: 0x00c0, 0x32e9: 0x00c0, + 0x32ea: 0x00c0, 0x32eb: 0x00c0, 0x32ec: 0x00c0, 0x32ed: 0x00c0, 0x32ee: 0x00c0, 0x32ef: 0x00c0, + 0x32f0: 0x00c0, 0x32f1: 0x00c0, 0x32f2: 0x00c0, 0x32f3: 0x00c0, 0x32f4: 0x00c0, 0x32f5: 0x00c0, + 0x32f6: 0x00c0, 0x32f7: 0x00c0, 0x32f8: 0x00c0, 0x32f9: 0x00c0, 0x32fa: 0x00c0, 0x32fb: 0x00c0, + // Block 0xcc, offset 0x3300 + 0x3300: 0x00c0, 0x3301: 0x00c0, 0x3302: 0x00c0, 0x3303: 0x00c0, 0x3304: 0x00c0, 0x3305: 0x00c0, + 0x3306: 0x00c0, 0x3307: 0x00c0, 0x3308: 0x00c0, 0x3309: 0x00c0, 0x330a: 0x00c0, 0x330b: 0x00c0, + 0x330c: 0x00c0, 0x330d: 0x00c0, 0x330e: 0x00c0, 0x330f: 0x00c0, 0x3310: 0x00c0, 0x3311: 0x00c0, + 0x3312: 0x00c0, 0x3313: 0x00c0, 0x3314: 0x00c0, 0x3315: 0x00c0, 0x3316: 0x00c0, 0x3317: 0x00c0, + 0x3318: 0x00c0, 0x3319: 0x00c0, 0x331a: 0x00c0, 0x331b: 0x00c0, 0x331c: 0x00c0, 0x331d: 0x00c0, + 0x331e: 0x00c0, 0x331f: 0x00c0, 0x3320: 0x00c0, 0x3321: 0x00c0, 0x3322: 0x00c0, 0x3323: 0x00c0, + 0x3324: 0x00c0, 0x3325: 0x00c0, 0x3326: 0x00c0, 0x3327: 0x00c0, + 0x3330: 0x00c0, 0x3331: 0x00c0, 0x3332: 0x00c0, 0x3333: 0x00c0, 0x3334: 0x00c0, 0x3335: 0x00c0, + 0x3336: 0x00c0, 0x3337: 0x00c0, 0x3338: 0x00c0, 0x3339: 0x00c0, 0x333a: 0x00c0, 0x333b: 0x00c0, + 0x333c: 0x00c0, 0x333d: 0x00c0, 0x333e: 0x00c0, 0x333f: 0x00c0, + // Block 0xcd, offset 0x3340 + 0x3340: 0x00c0, 0x3341: 0x00c0, 0x3342: 0x00c0, 0x3343: 0x00c0, 0x3344: 0x00c0, 0x3345: 0x00c0, + 0x3346: 0x00c0, 0x3347: 0x00c0, 0x3348: 0x00c0, 0x3349: 0x00c0, 0x334a: 0x00c0, 0x334b: 0x00c0, + 0x334c: 0x00c0, 0x334d: 0x00c0, 0x334e: 0x00c0, 0x334f: 0x00c0, 0x3350: 0x00c0, 0x3351: 0x00c0, + 0x3352: 0x00c0, 0x3353: 0x00c0, 0x3354: 0x00c0, 0x3355: 0x00c0, 0x3356: 0x00c0, 0x3357: 0x00c0, + 0x3358: 0x00c0, 0x3359: 0x00c0, 0x335a: 0x00c0, 0x335b: 0x00c0, 0x335c: 0x00c0, 0x335d: 0x00c0, + 0x335e: 0x00c0, 0x335f: 0x00c0, 0x3360: 0x00c0, 0x3361: 0x00c0, 0x3362: 0x00c0, 0x3363: 0x00c0, + 0x336f: 0x0080, + // Block 0xce, offset 0x3380 + 0x3380: 0x00c0, 0x3381: 0x00c0, 0x3382: 0x00c0, 0x3383: 0x00c0, 0x3384: 0x00c0, 0x3385: 0x00c0, + 0x3386: 0x00c0, 0x3387: 0x00c0, 0x3388: 0x00c0, 0x3389: 0x00c0, 0x338a: 0x00c0, 0x338b: 0x00c0, + 0x338c: 0x00c0, 0x338d: 0x00c0, 0x338e: 0x00c0, 0x338f: 0x00c0, 0x3390: 0x00c0, 0x3391: 0x00c0, + 0x3392: 0x00c0, 0x3393: 0x00c0, 0x3394: 0x00c0, 0x3395: 0x00c0, 0x3396: 0x00c0, 0x3397: 0x00c0, + 0x3398: 0x00c0, 0x3399: 0x00c0, 0x339a: 0x00c0, 0x339b: 0x00c0, 0x339c: 0x00c0, 0x339d: 0x00c0, + 0x339e: 0x00c0, 0x339f: 0x00c0, 0x33a0: 0x00c0, 0x33a1: 0x00c0, 0x33a2: 0x00c0, 0x33a3: 0x00c0, + 0x33a4: 0x00c0, 0x33a5: 0x00c0, 0x33a6: 0x00c0, 0x33a7: 0x00c0, 0x33a8: 0x00c0, 0x33a9: 0x00c0, + 0x33aa: 0x00c0, 0x33ab: 0x00c0, 0x33ac: 0x00c0, 0x33ad: 0x00c0, 0x33ae: 0x00c0, 0x33af: 0x00c0, + 0x33b0: 0x00c0, 0x33b1: 0x00c0, 0x33b2: 0x00c0, 0x33b3: 0x00c0, 0x33b4: 0x00c0, 0x33b5: 0x00c0, + 0x33b6: 0x00c0, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x00c0, 0x33c1: 0x00c0, 0x33c2: 0x00c0, 0x33c3: 0x00c0, 0x33c4: 0x00c0, 0x33c5: 0x00c0, + 0x33c6: 0x00c0, 0x33c7: 0x00c0, 0x33c8: 0x00c0, 0x33c9: 0x00c0, 0x33ca: 0x00c0, 0x33cb: 0x00c0, + 0x33cc: 0x00c0, 0x33cd: 0x00c0, 0x33ce: 0x00c0, 0x33cf: 0x00c0, 0x33d0: 0x00c0, 0x33d1: 0x00c0, + 0x33d2: 0x00c0, 0x33d3: 0x00c0, 0x33d4: 0x00c0, 0x33d5: 0x00c0, + 0x33e0: 0x00c0, 0x33e1: 0x00c0, 0x33e2: 0x00c0, 0x33e3: 0x00c0, + 0x33e4: 0x00c0, 0x33e5: 0x00c0, 0x33e6: 0x00c0, 0x33e7: 0x00c0, + // Block 0xd0, offset 0x3400 + 0x3400: 0x00c0, 0x3401: 0x00c0, 0x3402: 0x00c0, 0x3403: 0x00c0, 0x3404: 0x00c0, 0x3405: 0x00c0, + 0x3408: 0x00c0, 0x340a: 0x00c0, 0x340b: 0x00c0, + 0x340c: 0x00c0, 0x340d: 0x00c0, 0x340e: 0x00c0, 0x340f: 0x00c0, 0x3410: 0x00c0, 0x3411: 0x00c0, + 0x3412: 0x00c0, 0x3413: 0x00c0, 0x3414: 0x00c0, 0x3415: 0x00c0, 0x3416: 0x00c0, 0x3417: 0x00c0, + 0x3418: 0x00c0, 0x3419: 0x00c0, 0x341a: 0x00c0, 0x341b: 0x00c0, 0x341c: 0x00c0, 0x341d: 0x00c0, + 0x341e: 0x00c0, 0x341f: 0x00c0, 0x3420: 0x00c0, 0x3421: 0x00c0, 0x3422: 0x00c0, 0x3423: 0x00c0, + 0x3424: 0x00c0, 0x3425: 0x00c0, 0x3426: 0x00c0, 0x3427: 0x00c0, 0x3428: 0x00c0, 0x3429: 0x00c0, + 0x342a: 0x00c0, 0x342b: 0x00c0, 0x342c: 0x00c0, 0x342d: 0x00c0, 0x342e: 0x00c0, 0x342f: 0x00c0, + 0x3430: 0x00c0, 0x3431: 0x00c0, 0x3432: 0x00c0, 0x3433: 0x00c0, 0x3434: 0x00c0, 0x3435: 0x00c0, + 0x3437: 0x00c0, 0x3438: 0x00c0, + 0x343c: 0x00c0, 0x343f: 0x00c0, + // Block 0xd1, offset 0x3440 + 0x3440: 0x00c0, 0x3441: 0x00c0, 0x3442: 0x00c0, 0x3443: 0x00c0, 0x3444: 0x00c0, 0x3445: 0x00c0, + 0x3446: 0x00c0, 0x3447: 0x00c0, 0x3448: 0x00c0, 0x3449: 0x00c0, 0x344a: 0x00c0, 0x344b: 0x00c0, + 0x344c: 0x00c0, 0x344d: 0x00c0, 0x344e: 0x00c0, 0x344f: 0x00c0, 0x3450: 0x00c0, 0x3451: 0x00c0, + 0x3452: 0x00c0, 0x3453: 0x00c0, 0x3454: 0x00c0, 0x3455: 0x00c0, 0x3457: 0x0080, + 0x3458: 0x0080, 0x3459: 0x0080, 0x345a: 0x0080, 0x345b: 0x0080, 0x345c: 0x0080, 0x345d: 0x0080, + 0x345e: 0x0080, 0x345f: 0x0080, 0x3460: 0x00c0, 0x3461: 0x00c0, 0x3462: 0x00c0, 0x3463: 0x00c0, + 0x3464: 0x00c0, 0x3465: 0x00c0, 0x3466: 0x00c0, 0x3467: 0x00c0, 0x3468: 0x00c0, 0x3469: 0x00c0, + 0x346a: 0x00c0, 0x346b: 0x00c0, 0x346c: 0x00c0, 0x346d: 0x00c0, 0x346e: 0x00c0, 0x346f: 0x00c0, + 0x3470: 0x00c0, 0x3471: 0x00c0, 0x3472: 0x00c0, 0x3473: 0x00c0, 0x3474: 0x00c0, 0x3475: 0x00c0, + 0x3476: 0x00c0, 0x3477: 0x0080, 0x3478: 0x0080, 0x3479: 0x0080, 0x347a: 0x0080, 0x347b: 0x0080, + 0x347c: 0x0080, 0x347d: 0x0080, 0x347e: 0x0080, 0x347f: 0x0080, + // Block 0xd2, offset 0x3480 + 0x3480: 0x00c0, 0x3481: 0x00c0, 0x3482: 0x00c0, 0x3483: 0x00c0, 0x3484: 0x00c0, 0x3485: 0x00c0, + 0x3486: 0x00c0, 0x3487: 0x00c0, 0x3488: 0x00c0, 0x3489: 0x00c0, 0x348a: 0x00c0, 0x348b: 0x00c0, + 0x348c: 0x00c0, 0x348d: 0x00c0, 0x348e: 0x00c0, 0x348f: 0x00c0, 0x3490: 0x00c0, 0x3491: 0x00c0, + 0x3492: 0x00c0, 0x3493: 0x00c0, 0x3494: 0x00c0, 0x3495: 0x00c0, 0x3496: 0x00c0, 0x3497: 0x00c0, + 0x3498: 0x00c0, 0x3499: 0x00c0, 0x349a: 0x00c0, 0x349b: 0x00c0, 0x349c: 0x00c0, 0x349d: 0x00c0, + 0x349e: 0x00c0, + 0x34a7: 0x0080, 0x34a8: 0x0080, 0x34a9: 0x0080, + 0x34aa: 0x0080, 0x34ab: 0x0080, 0x34ac: 0x0080, 0x34ad: 0x0080, 0x34ae: 0x0080, 0x34af: 0x0080, + // Block 0xd3, offset 0x34c0 + 0x34e0: 0x00c0, 0x34e1: 0x00c0, 0x34e2: 0x00c0, 0x34e3: 0x00c0, + 0x34e4: 0x00c0, 0x34e5: 0x00c0, 0x34e6: 0x00c0, 0x34e7: 0x00c0, 0x34e8: 0x00c0, 0x34e9: 0x00c0, + 0x34ea: 0x00c0, 0x34eb: 0x00c0, 0x34ec: 0x00c0, 0x34ed: 0x00c0, 0x34ee: 0x00c0, 0x34ef: 0x00c0, + 0x34f0: 0x00c0, 0x34f1: 0x00c0, 0x34f2: 0x00c0, 0x34f4: 0x00c0, 0x34f5: 0x00c0, + 0x34fb: 0x0080, + 0x34fc: 0x0080, 0x34fd: 0x0080, 0x34fe: 0x0080, 0x34ff: 0x0080, + // Block 0xd4, offset 0x3500 + 0x3500: 0x00c0, 0x3501: 0x00c0, 0x3502: 0x00c0, 0x3503: 0x00c0, 0x3504: 0x00c0, 0x3505: 0x00c0, + 0x3506: 0x00c0, 0x3507: 0x00c0, 0x3508: 0x00c0, 0x3509: 0x00c0, 0x350a: 0x00c0, 0x350b: 0x00c0, + 0x350c: 0x00c0, 0x350d: 0x00c0, 0x350e: 0x00c0, 0x350f: 0x00c0, 0x3510: 0x00c0, 0x3511: 0x00c0, + 0x3512: 0x00c0, 0x3513: 0x00c0, 0x3514: 0x00c0, 0x3515: 0x00c0, 0x3516: 0x0080, 0x3517: 0x0080, + 0x3518: 0x0080, 0x3519: 0x0080, 0x351a: 0x0080, 0x351b: 0x0080, + 0x351f: 0x0080, 0x3520: 0x00c0, 0x3521: 0x00c0, 0x3522: 0x00c0, 0x3523: 0x00c0, + 0x3524: 0x00c0, 0x3525: 0x00c0, 0x3526: 0x00c0, 0x3527: 0x00c0, 0x3528: 0x00c0, 0x3529: 0x00c0, + 0x352a: 0x00c0, 0x352b: 0x00c0, 0x352c: 0x00c0, 0x352d: 0x00c0, 0x352e: 0x00c0, 0x352f: 0x00c0, + 0x3530: 0x00c0, 0x3531: 0x00c0, 0x3532: 0x00c0, 0x3533: 0x00c0, 0x3534: 0x00c0, 0x3535: 0x00c0, + 0x3536: 0x00c0, 0x3537: 0x00c0, 0x3538: 0x00c0, 0x3539: 0x00c0, + 0x353f: 0x0080, + // Block 0xd5, offset 0x3540 + 0x3540: 0x00c0, 0x3541: 0x00c0, 0x3542: 0x00c0, 0x3543: 0x00c0, 0x3544: 0x00c0, 0x3545: 0x00c0, + 0x3546: 0x00c0, 0x3547: 0x00c0, 0x3548: 0x00c0, 0x3549: 0x00c0, 0x354a: 0x00c0, 0x354b: 0x00c0, + 0x354c: 0x00c0, 0x354d: 0x00c0, 0x354e: 0x00c0, 0x354f: 0x00c0, 0x3550: 0x00c0, 0x3551: 0x00c0, + 0x3552: 0x00c0, 0x3553: 0x00c0, 0x3554: 0x00c0, 0x3555: 0x00c0, 0x3556: 0x00c0, 0x3557: 0x00c0, + 0x3558: 0x00c0, 0x3559: 0x00c0, 0x355a: 0x00c0, 0x355b: 0x00c0, 0x355c: 0x00c0, 0x355d: 0x00c0, + 0x355e: 0x00c0, 0x355f: 0x00c0, 0x3560: 0x00c0, 0x3561: 0x00c0, 0x3562: 0x00c0, 0x3563: 0x00c0, + 0x3564: 0x00c0, 0x3565: 0x00c0, 0x3566: 0x00c0, 0x3567: 0x00c0, 0x3568: 0x00c0, 0x3569: 0x00c0, + 0x356a: 0x00c0, 0x356b: 0x00c0, 0x356c: 0x00c0, 0x356d: 0x00c0, 0x356e: 0x00c0, 0x356f: 0x00c0, + 0x3570: 0x00c0, 0x3571: 0x00c0, 0x3572: 0x00c0, 0x3573: 0x00c0, 0x3574: 0x00c0, 0x3575: 0x00c0, + 0x3576: 0x00c0, 0x3577: 0x00c0, + 0x357c: 0x0080, 0x357d: 0x0080, 0x357e: 0x00c0, 0x357f: 0x00c0, + // Block 0xd6, offset 0x3580 + 0x3580: 0x00c0, 0x3581: 0x00c3, 0x3582: 0x00c3, 0x3583: 0x00c3, 0x3585: 0x00c3, + 0x3586: 0x00c3, + 0x358c: 0x00c3, 0x358d: 0x00c3, 0x358e: 0x00c3, 0x358f: 0x00c3, 0x3590: 0x00c0, 0x3591: 0x00c0, + 0x3592: 0x00c0, 0x3593: 0x00c0, 0x3595: 0x00c0, 0x3596: 0x00c0, 0x3597: 0x00c0, + 0x3599: 0x00c0, 0x359a: 0x00c0, 0x359b: 0x00c0, 0x359c: 0x00c0, 0x359d: 0x00c0, + 0x359e: 0x00c0, 0x359f: 0x00c0, 0x35a0: 0x00c0, 0x35a1: 0x00c0, 0x35a2: 0x00c0, 0x35a3: 0x00c0, + 0x35a4: 0x00c0, 0x35a5: 0x00c0, 0x35a6: 0x00c0, 0x35a7: 0x00c0, 0x35a8: 0x00c0, 0x35a9: 0x00c0, + 0x35aa: 0x00c0, 0x35ab: 0x00c0, 0x35ac: 0x00c0, 0x35ad: 0x00c0, 0x35ae: 0x00c0, 0x35af: 0x00c0, + 0x35b0: 0x00c0, 0x35b1: 0x00c0, 0x35b2: 0x00c0, 0x35b3: 0x00c0, 0x35b4: 0x00c0, 0x35b5: 0x00c0, + 0x35b8: 0x00c3, 0x35b9: 0x00c3, 0x35ba: 0x00c3, + 0x35bf: 0x00c6, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x0080, 0x35c1: 0x0080, 0x35c2: 0x0080, 0x35c3: 0x0080, 0x35c4: 0x0080, 0x35c5: 0x0080, + 0x35c6: 0x0080, 0x35c7: 0x0080, 0x35c8: 0x0080, + 0x35d0: 0x0080, 0x35d1: 0x0080, + 0x35d2: 0x0080, 0x35d3: 0x0080, 0x35d4: 0x0080, 0x35d5: 0x0080, 0x35d6: 0x0080, 0x35d7: 0x0080, + 0x35d8: 0x0080, + 0x35e0: 0x00c0, 0x35e1: 0x00c0, 0x35e2: 0x00c0, 0x35e3: 0x00c0, + 0x35e4: 0x00c0, 0x35e5: 0x00c0, 0x35e6: 0x00c0, 0x35e7: 0x00c0, 0x35e8: 0x00c0, 0x35e9: 0x00c0, + 0x35ea: 0x00c0, 0x35eb: 0x00c0, 0x35ec: 0x00c0, 0x35ed: 0x00c0, 0x35ee: 0x00c0, 0x35ef: 0x00c0, + 0x35f0: 0x00c0, 0x35f1: 0x00c0, 0x35f2: 0x00c0, 0x35f3: 0x00c0, 0x35f4: 0x00c0, 0x35f5: 0x00c0, + 0x35f6: 0x00c0, 0x35f7: 0x00c0, 0x35f8: 0x00c0, 0x35f9: 0x00c0, 0x35fa: 0x00c0, 0x35fb: 0x00c0, + 0x35fc: 0x00c0, 0x35fd: 0x0080, 0x35fe: 0x0080, 0x35ff: 0x0080, + // Block 0xd8, offset 0x3600 + 0x3600: 0x00c0, 0x3601: 0x00c0, 0x3602: 0x00c0, 0x3603: 0x00c0, 0x3604: 0x00c0, 0x3605: 0x00c0, + 0x3606: 0x00c0, 0x3607: 0x00c0, 0x3608: 0x00c0, 0x3609: 0x00c0, 0x360a: 0x00c0, 0x360b: 0x00c0, + 0x360c: 0x00c0, 0x360d: 0x00c0, 0x360e: 0x00c0, 0x360f: 0x00c0, 0x3610: 0x00c0, 0x3611: 0x00c0, + 0x3612: 0x00c0, 0x3613: 0x00c0, 0x3614: 0x00c0, 0x3615: 0x00c0, 0x3616: 0x00c0, 0x3617: 0x00c0, + 0x3618: 0x00c0, 0x3619: 0x00c0, 0x361a: 0x00c0, 0x361b: 0x00c0, 0x361c: 0x00c0, 0x361d: 0x0080, + 0x361e: 0x0080, 0x361f: 0x0080, + // Block 0xd9, offset 0x3640 + 0x3640: 0x00c2, 0x3641: 0x00c2, 0x3642: 0x00c2, 0x3643: 0x00c2, 0x3644: 0x00c2, 0x3645: 0x00c4, + 0x3646: 0x00c0, 0x3647: 0x00c4, 0x3648: 0x0080, 0x3649: 0x00c4, 0x364a: 0x00c4, 0x364b: 0x00c0, + 0x364c: 0x00c0, 0x364d: 0x00c1, 0x364e: 0x00c4, 0x364f: 0x00c4, 0x3650: 0x00c4, 0x3651: 0x00c4, + 0x3652: 0x00c4, 0x3653: 0x00c2, 0x3654: 0x00c2, 0x3655: 0x00c2, 0x3656: 0x00c2, 0x3657: 0x00c1, + 0x3658: 0x00c2, 0x3659: 0x00c2, 0x365a: 0x00c2, 0x365b: 0x00c2, 0x365c: 0x00c2, 0x365d: 0x00c4, + 0x365e: 0x00c2, 0x365f: 0x00c2, 0x3660: 0x00c2, 0x3661: 0x00c4, 0x3662: 0x00c0, 0x3663: 0x00c0, + 0x3664: 0x00c4, 0x3665: 0x00c3, 0x3666: 0x00c3, + 0x366b: 0x0082, 0x366c: 0x0082, 0x366d: 0x0082, 0x366e: 0x0082, 0x366f: 0x0084, + 0x3670: 0x0080, 0x3671: 0x0080, 0x3672: 0x0080, 0x3673: 0x0080, 0x3674: 0x0080, 0x3675: 0x0080, + 0x3676: 0x0080, + // Block 0xda, offset 0x3680 + 0x3680: 0x00c0, 0x3681: 0x00c0, 0x3682: 0x00c0, 0x3683: 0x00c0, 0x3684: 0x00c0, 0x3685: 0x00c0, + 0x3686: 0x00c0, 0x3687: 0x00c0, 0x3688: 0x00c0, 0x3689: 0x00c0, 0x368a: 0x00c0, 0x368b: 0x00c0, + 0x368c: 0x00c0, 0x368d: 0x00c0, 0x368e: 0x00c0, 0x368f: 0x00c0, 0x3690: 0x00c0, 0x3691: 0x00c0, + 0x3692: 0x00c0, 0x3693: 0x00c0, 0x3694: 0x00c0, 0x3695: 0x00c0, 0x3696: 0x00c0, 0x3697: 0x00c0, + 0x3698: 0x00c0, 0x3699: 0x00c0, 0x369a: 0x00c0, 0x369b: 0x00c0, 0x369c: 0x00c0, 0x369d: 0x00c0, + 0x369e: 0x00c0, 0x369f: 0x00c0, 0x36a0: 0x00c0, 0x36a1: 0x00c0, 0x36a2: 0x00c0, 0x36a3: 0x00c0, + 0x36a4: 0x00c0, 0x36a5: 0x00c0, 0x36a6: 0x00c0, 0x36a7: 0x00c0, 0x36a8: 0x00c0, 0x36a9: 0x00c0, + 0x36aa: 0x00c0, 0x36ab: 0x00c0, 0x36ac: 0x00c0, 0x36ad: 0x00c0, 0x36ae: 0x00c0, 0x36af: 0x00c0, + 0x36b0: 0x00c0, 0x36b1: 0x00c0, 0x36b2: 0x00c0, 0x36b3: 0x00c0, 0x36b4: 0x00c0, 0x36b5: 0x00c0, + 0x36b9: 0x0080, 0x36ba: 0x0080, 0x36bb: 0x0080, + 0x36bc: 0x0080, 0x36bd: 0x0080, 0x36be: 0x0080, 0x36bf: 0x0080, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x00c0, 0x36c1: 0x00c0, 0x36c2: 0x00c0, 0x36c3: 0x00c0, 0x36c4: 0x00c0, 0x36c5: 0x00c0, + 0x36c6: 0x00c0, 0x36c7: 0x00c0, 0x36c8: 0x00c0, 0x36c9: 0x00c0, 0x36ca: 0x00c0, 0x36cb: 0x00c0, + 0x36cc: 0x00c0, 0x36cd: 0x00c0, 0x36ce: 0x00c0, 0x36cf: 0x00c0, 0x36d0: 0x00c0, 0x36d1: 0x00c0, + 0x36d2: 0x00c0, 0x36d3: 0x00c0, 0x36d4: 0x00c0, 0x36d5: 0x00c0, + 0x36d8: 0x0080, 0x36d9: 0x0080, 0x36da: 0x0080, 0x36db: 0x0080, 0x36dc: 0x0080, 0x36dd: 0x0080, + 0x36de: 0x0080, 0x36df: 0x0080, 0x36e0: 0x00c0, 0x36e1: 0x00c0, 0x36e2: 0x00c0, 0x36e3: 0x00c0, + 0x36e4: 0x00c0, 0x36e5: 0x00c0, 0x36e6: 0x00c0, 0x36e7: 0x00c0, 0x36e8: 0x00c0, 0x36e9: 0x00c0, + 0x36ea: 0x00c0, 0x36eb: 0x00c0, 0x36ec: 0x00c0, 0x36ed: 0x00c0, 0x36ee: 0x00c0, 0x36ef: 0x00c0, + 0x36f0: 0x00c0, 0x36f1: 0x00c0, 0x36f2: 0x00c0, + 0x36f8: 0x0080, 0x36f9: 0x0080, 0x36fa: 0x0080, 0x36fb: 0x0080, + 0x36fc: 0x0080, 0x36fd: 0x0080, 0x36fe: 0x0080, 0x36ff: 0x0080, + // Block 0xdc, offset 0x3700 + 0x3700: 0x00c2, 0x3701: 0x00c4, 0x3702: 0x00c2, 0x3703: 0x00c4, 0x3704: 0x00c4, 0x3705: 0x00c4, + 0x3706: 0x00c2, 0x3707: 0x00c2, 0x3708: 0x00c2, 0x3709: 0x00c4, 0x370a: 0x00c2, 0x370b: 0x00c2, + 0x370c: 0x00c4, 0x370d: 0x00c2, 0x370e: 0x00c4, 0x370f: 0x00c4, 0x3710: 0x00c2, 0x3711: 0x00c4, + 0x3719: 0x0080, 0x371a: 0x0080, 0x371b: 0x0080, 0x371c: 0x0080, + 0x3729: 0x0084, + 0x372a: 0x0084, 0x372b: 0x0084, 0x372c: 0x0084, 0x372d: 0x0082, 0x372e: 0x0082, 0x372f: 0x0080, + // Block 0xdd, offset 0x3740 + 0x3740: 0x00c0, 0x3741: 0x00c0, 0x3742: 0x00c0, 0x3743: 0x00c0, 0x3744: 0x00c0, 0x3745: 0x00c0, + 0x3746: 0x00c0, 0x3747: 0x00c0, 0x3748: 0x00c0, + // Block 0xde, offset 0x3780 + 0x3780: 0x00c0, 0x3781: 0x00c0, 0x3782: 0x00c0, 0x3783: 0x00c0, 0x3784: 0x00c0, 0x3785: 0x00c0, + 0x3786: 0x00c0, 0x3787: 0x00c0, 0x3788: 0x00c0, 0x3789: 0x00c0, 0x378a: 0x00c0, 0x378b: 0x00c0, + 0x378c: 0x00c0, 0x378d: 0x00c0, 0x378e: 0x00c0, 0x378f: 0x00c0, 0x3790: 0x00c0, 0x3791: 0x00c0, + 0x3792: 0x00c0, 0x3793: 0x00c0, 0x3794: 0x00c0, 0x3795: 0x00c0, 0x3796: 0x00c0, 0x3797: 0x00c0, + 0x3798: 0x00c0, 0x3799: 0x00c0, 0x379a: 0x00c0, 0x379b: 0x00c0, 0x379c: 0x00c0, 0x379d: 0x00c0, + 0x379e: 0x00c0, 0x379f: 0x00c0, 0x37a0: 0x00c0, 0x37a1: 0x00c0, 0x37a2: 0x00c0, 0x37a3: 0x00c0, + 0x37a4: 0x00c0, 0x37a5: 0x00c0, 0x37a6: 0x00c0, 0x37a7: 0x00c0, 0x37a8: 0x00c0, 0x37a9: 0x00c0, + 0x37aa: 0x00c0, 0x37ab: 0x00c0, 0x37ac: 0x00c0, 0x37ad: 0x00c0, 0x37ae: 0x00c0, 0x37af: 0x00c0, + 0x37b0: 0x00c0, 0x37b1: 0x00c0, 0x37b2: 0x00c0, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x00c0, 0x37c1: 0x00c0, 0x37c2: 0x00c0, 0x37c3: 0x00c0, 0x37c4: 0x00c0, 0x37c5: 0x00c0, + 0x37c6: 0x00c0, 0x37c7: 0x00c0, 0x37c8: 0x00c0, 0x37c9: 0x00c0, 0x37ca: 0x00c0, 0x37cb: 0x00c0, + 0x37cc: 0x00c0, 0x37cd: 0x00c0, 0x37ce: 0x00c0, 0x37cf: 0x00c0, 0x37d0: 0x00c0, 0x37d1: 0x00c0, + 0x37d2: 0x00c0, 0x37d3: 0x00c0, 0x37d4: 0x00c0, 0x37d5: 0x00c0, 0x37d6: 0x00c0, 0x37d7: 0x00c0, + 0x37d8: 0x00c0, 0x37d9: 0x00c0, 0x37da: 0x00c0, 0x37db: 0x00c0, 0x37dc: 0x00c0, 0x37dd: 0x00c0, + 0x37de: 0x00c0, 0x37df: 0x00c0, 0x37e0: 0x00c0, 0x37e1: 0x00c0, 0x37e2: 0x00c0, 0x37e3: 0x00c0, + 0x37e4: 0x00c0, 0x37e5: 0x00c0, 0x37e6: 0x00c0, 0x37e7: 0x00c0, 0x37e8: 0x00c0, 0x37e9: 0x00c0, + 0x37ea: 0x00c0, 0x37eb: 0x00c0, 0x37ec: 0x00c0, 0x37ed: 0x00c0, 0x37ee: 0x00c0, 0x37ef: 0x00c0, + 0x37f0: 0x00c0, 0x37f1: 0x00c0, 0x37f2: 0x00c0, + 0x37fa: 0x0080, 0x37fb: 0x0080, + 0x37fc: 0x0080, 0x37fd: 0x0080, 0x37fe: 0x0080, 0x37ff: 0x0080, + // Block 0xe0, offset 0x3800 + 0x3800: 0x00c1, 0x3801: 0x00c2, 0x3802: 0x00c2, 0x3803: 0x00c2, 0x3804: 0x00c2, 0x3805: 0x00c2, + 0x3806: 0x00c2, 0x3807: 0x00c2, 0x3808: 0x00c2, 0x3809: 0x00c2, 0x380a: 0x00c2, 0x380b: 0x00c2, + 0x380c: 0x00c2, 0x380d: 0x00c2, 0x380e: 0x00c2, 0x380f: 0x00c2, 0x3810: 0x00c2, 0x3811: 0x00c2, + 0x3812: 0x00c2, 0x3813: 0x00c2, 0x3814: 0x00c2, 0x3815: 0x00c2, 0x3816: 0x00c2, 0x3817: 0x00c2, + 0x3818: 0x00c2, 0x3819: 0x00c2, 0x381a: 0x00c2, 0x381b: 0x00c2, 0x381c: 0x00c2, 0x381d: 0x00c2, + 0x381e: 0x00c2, 0x381f: 0x00c2, 0x3820: 0x00c2, 0x3821: 0x00c2, 0x3822: 0x00c4, 0x3823: 0x00c2, + 0x3824: 0x00c3, 0x3825: 0x00c3, 0x3826: 0x00c3, 0x3827: 0x00c3, + 0x3830: 0x00c0, 0x3831: 0x00c0, 0x3832: 0x00c0, 0x3833: 0x00c0, 0x3834: 0x00c0, 0x3835: 0x00c0, + 0x3836: 0x00c0, 0x3837: 0x00c0, 0x3838: 0x00c0, 0x3839: 0x00c0, + // Block 0xe1, offset 0x3840 + 0x3860: 0x0080, 0x3861: 0x0080, 0x3862: 0x0080, 0x3863: 0x0080, + 0x3864: 0x0080, 0x3865: 0x0080, 0x3866: 0x0080, 0x3867: 0x0080, 0x3868: 0x0080, 0x3869: 0x0080, + 0x386a: 0x0080, 0x386b: 0x0080, 0x386c: 0x0080, 0x386d: 0x0080, 0x386e: 0x0080, 0x386f: 0x0080, + 0x3870: 0x0080, 0x3871: 0x0080, 0x3872: 0x0080, 0x3873: 0x0080, 0x3874: 0x0080, 0x3875: 0x0080, + 0x3876: 0x0080, 0x3877: 0x0080, 0x3878: 0x0080, 0x3879: 0x0080, 0x387a: 0x0080, 0x387b: 0x0080, + 0x387c: 0x0080, 0x387d: 0x0080, 0x387e: 0x0080, + // Block 0xe2, offset 0x3880 + 0x3880: 0x00c0, 0x3881: 0x00c0, 0x3882: 0x00c0, 0x3883: 0x00c0, 0x3884: 0x00c0, 0x3885: 0x00c0, + 0x3886: 0x00c0, 0x3887: 0x00c0, 0x3888: 0x00c0, 0x3889: 0x00c0, 0x388a: 0x00c0, 0x388b: 0x00c0, + 0x388c: 0x00c0, 0x388d: 0x00c0, 0x388e: 0x00c0, 0x388f: 0x00c0, 0x3890: 0x00c0, 0x3891: 0x00c0, + 0x3892: 0x00c0, 0x3893: 0x00c0, 0x3894: 0x00c0, 0x3895: 0x00c0, 0x3896: 0x00c0, 0x3897: 0x00c0, + 0x3898: 0x00c0, 0x3899: 0x00c0, 0x389a: 0x00c0, 0x389b: 0x00c0, 0x389c: 0x00c0, 0x389d: 0x00c0, + 0x389e: 0x00c0, 0x389f: 0x00c0, 0x38a0: 0x00c0, 0x38a1: 0x00c0, 0x38a2: 0x00c0, 0x38a3: 0x00c0, + 0x38a4: 0x00c0, 0x38a5: 0x00c0, 0x38a6: 0x00c0, 0x38a7: 0x00c0, 0x38a8: 0x00c0, 0x38a9: 0x00c0, + 0x38ab: 0x00c3, 0x38ac: 0x00c3, 0x38ad: 0x0080, + 0x38b0: 0x00c0, 0x38b1: 0x00c0, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x00c0, 0x38c1: 0x00c0, 0x38c2: 0x00c0, 0x38c3: 0x00c0, 0x38c4: 0x00c0, 0x38c5: 0x00c0, + 0x38c6: 0x00c0, 0x38c7: 0x00c0, 0x38c8: 0x00c0, 0x38c9: 0x00c0, 0x38ca: 0x00c0, 0x38cb: 0x00c0, + 0x38cc: 0x00c0, 0x38cd: 0x00c0, 0x38ce: 0x00c0, 0x38cf: 0x00c0, 0x38d0: 0x00c0, 0x38d1: 0x00c0, + 0x38d2: 0x00c0, 0x38d3: 0x00c0, 0x38d4: 0x00c0, 0x38d5: 0x00c0, 0x38d6: 0x00c0, 0x38d7: 0x00c0, + 0x38d8: 0x00c0, 0x38d9: 0x00c0, 0x38da: 0x00c0, 0x38db: 0x00c0, 0x38dc: 0x00c0, 0x38dd: 0x0080, + 0x38de: 0x0080, 0x38df: 0x0080, 0x38e0: 0x0080, 0x38e1: 0x0080, 0x38e2: 0x0080, 0x38e3: 0x0080, + 0x38e4: 0x0080, 0x38e5: 0x0080, 0x38e6: 0x0080, 0x38e7: 0x00c0, + 0x38f0: 0x00c2, 0x38f1: 0x00c2, 0x38f2: 0x00c2, 0x38f3: 0x00c4, 0x38f4: 0x00c2, 0x38f5: 0x00c2, + 0x38f6: 0x00c2, 0x38f7: 0x00c2, 0x38f8: 0x00c2, 0x38f9: 0x00c2, 0x38fa: 0x00c2, 0x38fb: 0x00c2, + 0x38fc: 0x00c2, 0x38fd: 0x00c2, 0x38fe: 0x00c2, 0x38ff: 0x00c2, + // Block 0xe4, offset 0x3900 + 0x3900: 0x00c2, 0x3901: 0x00c2, 0x3902: 0x00c2, 0x3903: 0x00c2, 0x3904: 0x00c2, 0x3905: 0x00c0, + 0x3906: 0x00c3, 0x3907: 0x00c3, 0x3908: 0x00c3, 0x3909: 0x00c3, 0x390a: 0x00c3, 0x390b: 0x00c3, + 0x390c: 0x00c3, 0x390d: 0x00c3, 0x390e: 0x00c3, 0x390f: 0x00c3, 0x3910: 0x00c3, 0x3911: 0x0082, + 0x3912: 0x0082, 0x3913: 0x0082, 0x3914: 0x0084, 0x3915: 0x0080, 0x3916: 0x0080, 0x3917: 0x0080, + 0x3918: 0x0080, 0x3919: 0x0080, + // Block 0xe5, offset 0x3940 + 0x3970: 0x00c2, 0x3971: 0x00c0, 0x3972: 0x00c2, 0x3973: 0x00c2, 0x3974: 0x00c4, 0x3975: 0x00c4, + 0x3976: 0x00c4, 0x3977: 0x00c0, 0x3978: 0x00c2, 0x3979: 0x00c4, 0x397a: 0x00c4, 0x397b: 0x00c2, + 0x397c: 0x00c2, 0x397d: 0x00c4, 0x397e: 0x00c2, 0x397f: 0x00c2, + // Block 0xe6, offset 0x3980 + 0x3980: 0x00c0, 0x3981: 0x00c2, 0x3982: 0x00c4, 0x3983: 0x00c4, 0x3984: 0x00c2, 0x3985: 0x0080, + 0x3986: 0x0080, 0x3987: 0x0080, 0x3988: 0x0080, 0x3989: 0x0084, 0x398a: 0x0082, 0x398b: 0x0081, + 0x39a0: 0x00c0, 0x39a1: 0x00c0, 0x39a2: 0x00c0, 0x39a3: 0x00c0, + 0x39a4: 0x00c0, 0x39a5: 0x00c0, 0x39a6: 0x00c0, 0x39a7: 0x00c0, 0x39a8: 0x00c0, 0x39a9: 0x00c0, + 0x39aa: 0x00c0, 0x39ab: 0x00c0, 0x39ac: 0x00c0, 0x39ad: 0x00c0, 0x39ae: 0x00c0, 0x39af: 0x00c0, + 0x39b0: 0x00c0, 0x39b1: 0x00c0, 0x39b2: 0x00c0, 0x39b3: 0x00c0, 0x39b4: 0x00c0, 0x39b5: 0x00c0, + 0x39b6: 0x00c0, + // Block 0xe7, offset 0x39c0 + 0x39c0: 0x00c0, 0x39c1: 0x00c3, 0x39c2: 0x00c0, 0x39c3: 0x00c0, 0x39c4: 0x00c0, 0x39c5: 0x00c0, + 0x39c6: 0x00c0, 0x39c7: 0x00c0, 0x39c8: 0x00c0, 0x39c9: 0x00c0, 0x39ca: 0x00c0, 0x39cb: 0x00c0, + 0x39cc: 0x00c0, 0x39cd: 0x00c0, 0x39ce: 0x00c0, 0x39cf: 0x00c0, 0x39d0: 0x00c0, 0x39d1: 0x00c0, + 0x39d2: 0x00c0, 0x39d3: 0x00c0, 0x39d4: 0x00c0, 0x39d5: 0x00c0, 0x39d6: 0x00c0, 0x39d7: 0x00c0, + 0x39d8: 0x00c0, 0x39d9: 0x00c0, 0x39da: 0x00c0, 0x39db: 0x00c0, 0x39dc: 0x00c0, 0x39dd: 0x00c0, + 0x39de: 0x00c0, 0x39df: 0x00c0, 0x39e0: 0x00c0, 0x39e1: 0x00c0, 0x39e2: 0x00c0, 0x39e3: 0x00c0, + 0x39e4: 0x00c0, 0x39e5: 0x00c0, 0x39e6: 0x00c0, 0x39e7: 0x00c0, 0x39e8: 0x00c0, 0x39e9: 0x00c0, + 0x39ea: 0x00c0, 0x39eb: 0x00c0, 0x39ec: 0x00c0, 0x39ed: 0x00c0, 0x39ee: 0x00c0, 0x39ef: 0x00c0, + 0x39f0: 0x00c0, 0x39f1: 0x00c0, 0x39f2: 0x00c0, 0x39f3: 0x00c0, 0x39f4: 0x00c0, 0x39f5: 0x00c0, + 0x39f6: 0x00c0, 0x39f7: 0x00c0, 0x39f8: 0x00c3, 0x39f9: 0x00c3, 0x39fa: 0x00c3, 0x39fb: 0x00c3, + 0x39fc: 0x00c3, 0x39fd: 0x00c3, 0x39fe: 0x00c3, 0x39ff: 0x00c3, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0x00c3, 0x3a01: 0x00c3, 0x3a02: 0x00c3, 0x3a03: 0x00c3, 0x3a04: 0x00c3, 0x3a05: 0x00c3, + 0x3a06: 0x00c6, 0x3a07: 0x0080, 0x3a08: 0x0080, 0x3a09: 0x0080, 0x3a0a: 0x0080, 0x3a0b: 0x0080, + 0x3a0c: 0x0080, 0x3a0d: 0x0080, + 0x3a12: 0x0080, 0x3a13: 0x0080, 0x3a14: 0x0080, 0x3a15: 0x0080, 0x3a16: 0x0080, 0x3a17: 0x0080, + 0x3a18: 0x0080, 0x3a19: 0x0080, 0x3a1a: 0x0080, 0x3a1b: 0x0080, 0x3a1c: 0x0080, 0x3a1d: 0x0080, + 0x3a1e: 0x0080, 0x3a1f: 0x0080, 0x3a20: 0x0080, 0x3a21: 0x0080, 0x3a22: 0x0080, 0x3a23: 0x0080, + 0x3a24: 0x0080, 0x3a25: 0x0080, 0x3a26: 0x00c0, 0x3a27: 0x00c0, 0x3a28: 0x00c0, 0x3a29: 0x00c0, + 0x3a2a: 0x00c0, 0x3a2b: 0x00c0, 0x3a2c: 0x00c0, 0x3a2d: 0x00c0, 0x3a2e: 0x00c0, 0x3a2f: 0x00c0, + 0x3a3f: 0x00c6, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x00c3, 0x3a41: 0x00c3, 0x3a42: 0x00c0, 0x3a43: 0x00c0, 0x3a44: 0x00c0, 0x3a45: 0x00c0, + 0x3a46: 0x00c0, 0x3a47: 0x00c0, 0x3a48: 0x00c0, 0x3a49: 0x00c0, 0x3a4a: 0x00c0, 0x3a4b: 0x00c0, + 0x3a4c: 0x00c0, 0x3a4d: 0x00c0, 0x3a4e: 0x00c0, 0x3a4f: 0x00c0, 0x3a50: 0x00c0, 0x3a51: 0x00c0, + 0x3a52: 0x00c0, 0x3a53: 0x00c0, 0x3a54: 0x00c0, 0x3a55: 0x00c0, 0x3a56: 0x00c0, 0x3a57: 0x00c0, + 0x3a58: 0x00c0, 0x3a59: 0x00c0, 0x3a5a: 0x00c0, 0x3a5b: 0x00c0, 0x3a5c: 0x00c0, 0x3a5d: 0x00c0, + 0x3a5e: 0x00c0, 0x3a5f: 0x00c0, 0x3a60: 0x00c0, 0x3a61: 0x00c0, 0x3a62: 0x00c0, 0x3a63: 0x00c0, + 0x3a64: 0x00c0, 0x3a65: 0x00c0, 0x3a66: 0x00c0, 0x3a67: 0x00c0, 0x3a68: 0x00c0, 0x3a69: 0x00c0, + 0x3a6a: 0x00c0, 0x3a6b: 0x00c0, 0x3a6c: 0x00c0, 0x3a6d: 0x00c0, 0x3a6e: 0x00c0, 0x3a6f: 0x00c0, + 0x3a70: 0x00c0, 0x3a71: 0x00c0, 0x3a72: 0x00c0, 0x3a73: 0x00c3, 0x3a74: 0x00c3, 0x3a75: 0x00c3, + 0x3a76: 0x00c3, 0x3a77: 0x00c0, 0x3a78: 0x00c0, 0x3a79: 0x00c6, 0x3a7a: 0x00c3, 0x3a7b: 0x0080, + 0x3a7c: 0x0080, 0x3a7d: 0x0040, 0x3a7e: 0x0080, 0x3a7f: 0x0080, + // Block 0xea, offset 0x3a80 + 0x3a80: 0x0080, 0x3a81: 0x0080, + 0x3a8d: 0x0040, 0x3a90: 0x00c0, 0x3a91: 0x00c0, + 0x3a92: 0x00c0, 0x3a93: 0x00c0, 0x3a94: 0x00c0, 0x3a95: 0x00c0, 0x3a96: 0x00c0, 0x3a97: 0x00c0, + 0x3a98: 0x00c0, 0x3a99: 0x00c0, 0x3a9a: 0x00c0, 0x3a9b: 0x00c0, 0x3a9c: 0x00c0, 0x3a9d: 0x00c0, + 0x3a9e: 0x00c0, 0x3a9f: 0x00c0, 0x3aa0: 0x00c0, 0x3aa1: 0x00c0, 0x3aa2: 0x00c0, 0x3aa3: 0x00c0, + 0x3aa4: 0x00c0, 0x3aa5: 0x00c0, 0x3aa6: 0x00c0, 0x3aa7: 0x00c0, 0x3aa8: 0x00c0, + 0x3ab0: 0x00c0, 0x3ab1: 0x00c0, 0x3ab2: 0x00c0, 0x3ab3: 0x00c0, 0x3ab4: 0x00c0, 0x3ab5: 0x00c0, + 0x3ab6: 0x00c0, 0x3ab7: 0x00c0, 0x3ab8: 0x00c0, 0x3ab9: 0x00c0, + // Block 0xeb, offset 0x3ac0 + 0x3ac0: 0x00c3, 0x3ac1: 0x00c3, 0x3ac2: 0x00c3, 0x3ac3: 0x00c0, 0x3ac4: 0x00c0, 0x3ac5: 0x00c0, + 0x3ac6: 0x00c0, 0x3ac7: 0x00c0, 0x3ac8: 0x00c0, 0x3ac9: 0x00c0, 0x3aca: 0x00c0, 0x3acb: 0x00c0, + 0x3acc: 0x00c0, 0x3acd: 0x00c0, 0x3ace: 0x00c0, 0x3acf: 0x00c0, 0x3ad0: 0x00c0, 0x3ad1: 0x00c0, + 0x3ad2: 0x00c0, 0x3ad3: 0x00c0, 0x3ad4: 0x00c0, 0x3ad5: 0x00c0, 0x3ad6: 0x00c0, 0x3ad7: 0x00c0, + 0x3ad8: 0x00c0, 0x3ad9: 0x00c0, 0x3ada: 0x00c0, 0x3adb: 0x00c0, 0x3adc: 0x00c0, 0x3add: 0x00c0, + 0x3ade: 0x00c0, 0x3adf: 0x00c0, 0x3ae0: 0x00c0, 0x3ae1: 0x00c0, 0x3ae2: 0x00c0, 0x3ae3: 0x00c0, + 0x3ae4: 0x00c0, 0x3ae5: 0x00c0, 0x3ae6: 0x00c0, 0x3ae7: 0x00c3, 0x3ae8: 0x00c3, 0x3ae9: 0x00c3, + 0x3aea: 0x00c3, 0x3aeb: 0x00c3, 0x3aec: 0x00c0, 0x3aed: 0x00c3, 0x3aee: 0x00c3, 0x3aef: 0x00c3, + 0x3af0: 0x00c3, 0x3af1: 0x00c3, 0x3af2: 0x00c3, 0x3af3: 0x00c6, 0x3af4: 0x00c6, + 0x3af6: 0x00c0, 0x3af7: 0x00c0, 0x3af8: 0x00c0, 0x3af9: 0x00c0, 0x3afa: 0x00c0, 0x3afb: 0x00c0, + 0x3afc: 0x00c0, 0x3afd: 0x00c0, 0x3afe: 0x00c0, 0x3aff: 0x00c0, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x0080, 0x3b01: 0x0080, 0x3b02: 0x0080, 0x3b03: 0x0080, 0x3b04: 0x00c0, 0x3b05: 0x00c0, + 0x3b06: 0x00c0, 0x3b07: 0x00c0, + 0x3b10: 0x00c0, 0x3b11: 0x00c0, + 0x3b12: 0x00c0, 0x3b13: 0x00c0, 0x3b14: 0x00c0, 0x3b15: 0x00c0, 0x3b16: 0x00c0, 0x3b17: 0x00c0, + 0x3b18: 0x00c0, 0x3b19: 0x00c0, 0x3b1a: 0x00c0, 0x3b1b: 0x00c0, 0x3b1c: 0x00c0, 0x3b1d: 0x00c0, + 0x3b1e: 0x00c0, 0x3b1f: 0x00c0, 0x3b20: 0x00c0, 0x3b21: 0x00c0, 0x3b22: 0x00c0, 0x3b23: 0x00c0, + 0x3b24: 0x00c0, 0x3b25: 0x00c0, 0x3b26: 0x00c0, 0x3b27: 0x00c0, 0x3b28: 0x00c0, 0x3b29: 0x00c0, + 0x3b2a: 0x00c0, 0x3b2b: 0x00c0, 0x3b2c: 0x00c0, 0x3b2d: 0x00c0, 0x3b2e: 0x00c0, 0x3b2f: 0x00c0, + 0x3b30: 0x00c0, 0x3b31: 0x00c0, 0x3b32: 0x00c0, 0x3b33: 0x00c3, 0x3b34: 0x0080, 0x3b35: 0x0080, + 0x3b36: 0x00c0, + // Block 0xed, offset 0x3b40 + 0x3b40: 0x00c3, 0x3b41: 0x00c3, 0x3b42: 0x00c0, 0x3b43: 0x00c0, 0x3b44: 0x00c0, 0x3b45: 0x00c0, + 0x3b46: 0x00c0, 0x3b47: 0x00c0, 0x3b48: 0x00c0, 0x3b49: 0x00c0, 0x3b4a: 0x00c0, 0x3b4b: 0x00c0, + 0x3b4c: 0x00c0, 0x3b4d: 0x00c0, 0x3b4e: 0x00c0, 0x3b4f: 0x00c0, 0x3b50: 0x00c0, 0x3b51: 0x00c0, + 0x3b52: 0x00c0, 0x3b53: 0x00c0, 0x3b54: 0x00c0, 0x3b55: 0x00c0, 0x3b56: 0x00c0, 0x3b57: 0x00c0, + 0x3b58: 0x00c0, 0x3b59: 0x00c0, 0x3b5a: 0x00c0, 0x3b5b: 0x00c0, 0x3b5c: 0x00c0, 0x3b5d: 0x00c0, + 0x3b5e: 0x00c0, 0x3b5f: 0x00c0, 0x3b60: 0x00c0, 0x3b61: 0x00c0, 0x3b62: 0x00c0, 0x3b63: 0x00c0, + 0x3b64: 0x00c0, 0x3b65: 0x00c0, 0x3b66: 0x00c0, 0x3b67: 0x00c0, 0x3b68: 0x00c0, 0x3b69: 0x00c0, + 0x3b6a: 0x00c0, 0x3b6b: 0x00c0, 0x3b6c: 0x00c0, 0x3b6d: 0x00c0, 0x3b6e: 0x00c0, 0x3b6f: 0x00c0, + 0x3b70: 0x00c0, 0x3b71: 0x00c0, 0x3b72: 0x00c0, 0x3b73: 0x00c0, 0x3b74: 0x00c0, 0x3b75: 0x00c0, + 0x3b76: 0x00c3, 0x3b77: 0x00c3, 0x3b78: 0x00c3, 0x3b79: 0x00c3, 0x3b7a: 0x00c3, 0x3b7b: 0x00c3, + 0x3b7c: 0x00c3, 0x3b7d: 0x00c3, 0x3b7e: 0x00c3, 0x3b7f: 0x00c0, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x00c5, 0x3b81: 0x00c0, 0x3b82: 0x00c0, 0x3b83: 0x00c0, 0x3b84: 0x00c0, 0x3b85: 0x0080, + 0x3b86: 0x0080, 0x3b87: 0x0080, 0x3b88: 0x0080, 0x3b89: 0x00c3, 0x3b8a: 0x00c3, 0x3b8b: 0x00c3, + 0x3b8c: 0x00c3, 0x3b8d: 0x0080, 0x3b8e: 0x00c0, 0x3b8f: 0x00c3, 0x3b90: 0x00c0, 0x3b91: 0x00c0, + 0x3b92: 0x00c0, 0x3b93: 0x00c0, 0x3b94: 0x00c0, 0x3b95: 0x00c0, 0x3b96: 0x00c0, 0x3b97: 0x00c0, + 0x3b98: 0x00c0, 0x3b99: 0x00c0, 0x3b9a: 0x00c0, 0x3b9b: 0x0080, 0x3b9c: 0x00c0, 0x3b9d: 0x0080, + 0x3b9e: 0x0080, 0x3b9f: 0x0080, 0x3ba1: 0x0080, 0x3ba2: 0x0080, 0x3ba3: 0x0080, + 0x3ba4: 0x0080, 0x3ba5: 0x0080, 0x3ba6: 0x0080, 0x3ba7: 0x0080, 0x3ba8: 0x0080, 0x3ba9: 0x0080, + 0x3baa: 0x0080, 0x3bab: 0x0080, 0x3bac: 0x0080, 0x3bad: 0x0080, 0x3bae: 0x0080, 0x3baf: 0x0080, + 0x3bb0: 0x0080, 0x3bb1: 0x0080, 0x3bb2: 0x0080, 0x3bb3: 0x0080, 0x3bb4: 0x0080, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x00c0, 0x3bc1: 0x00c0, 0x3bc2: 0x00c0, 0x3bc3: 0x00c0, 0x3bc4: 0x00c0, 0x3bc5: 0x00c0, + 0x3bc6: 0x00c0, 0x3bc7: 0x00c0, 0x3bc8: 0x00c0, 0x3bc9: 0x00c0, 0x3bca: 0x00c0, 0x3bcb: 0x00c0, + 0x3bcc: 0x00c0, 0x3bcd: 0x00c0, 0x3bce: 0x00c0, 0x3bcf: 0x00c0, 0x3bd0: 0x00c0, 0x3bd1: 0x00c0, + 0x3bd3: 0x00c0, 0x3bd4: 0x00c0, 0x3bd5: 0x00c0, 0x3bd6: 0x00c0, 0x3bd7: 0x00c0, + 0x3bd8: 0x00c0, 0x3bd9: 0x00c0, 0x3bda: 0x00c0, 0x3bdb: 0x00c0, 0x3bdc: 0x00c0, 0x3bdd: 0x00c0, + 0x3bde: 0x00c0, 0x3bdf: 0x00c0, 0x3be0: 0x00c0, 0x3be1: 0x00c0, 0x3be2: 0x00c0, 0x3be3: 0x00c0, + 0x3be4: 0x00c0, 0x3be5: 0x00c0, 0x3be6: 0x00c0, 0x3be7: 0x00c0, 0x3be8: 0x00c0, 0x3be9: 0x00c0, + 0x3bea: 0x00c0, 0x3beb: 0x00c0, 0x3bec: 0x00c0, 0x3bed: 0x00c0, 0x3bee: 0x00c0, 0x3bef: 0x00c3, + 0x3bf0: 0x00c3, 0x3bf1: 0x00c3, 0x3bf2: 0x00c0, 0x3bf3: 0x00c0, 0x3bf4: 0x00c3, 0x3bf5: 0x00c5, + 0x3bf6: 0x00c3, 0x3bf7: 0x00c3, 0x3bf8: 0x0080, 0x3bf9: 0x0080, 0x3bfa: 0x0080, 0x3bfb: 0x0080, + 0x3bfc: 0x0080, 0x3bfd: 0x0080, 0x3bfe: 0x00c3, + // Block 0xf0, offset 0x3c00 + 0x3c00: 0x00c0, 0x3c01: 0x00c0, 0x3c02: 0x00c0, 0x3c03: 0x00c0, 0x3c04: 0x00c0, 0x3c05: 0x00c0, + 0x3c06: 0x00c0, 0x3c08: 0x00c0, 0x3c0a: 0x00c0, 0x3c0b: 0x00c0, + 0x3c0c: 0x00c0, 0x3c0d: 0x00c0, 0x3c0f: 0x00c0, 0x3c10: 0x00c0, 0x3c11: 0x00c0, + 0x3c12: 0x00c0, 0x3c13: 0x00c0, 0x3c14: 0x00c0, 0x3c15: 0x00c0, 0x3c16: 0x00c0, 0x3c17: 0x00c0, + 0x3c18: 0x00c0, 0x3c19: 0x00c0, 0x3c1a: 0x00c0, 0x3c1b: 0x00c0, 0x3c1c: 0x00c0, 0x3c1d: 0x00c0, + 0x3c1f: 0x00c0, 0x3c20: 0x00c0, 0x3c21: 0x00c0, 0x3c22: 0x00c0, 0x3c23: 0x00c0, + 0x3c24: 0x00c0, 0x3c25: 0x00c0, 0x3c26: 0x00c0, 0x3c27: 0x00c0, 0x3c28: 0x00c0, 0x3c29: 0x0080, + 0x3c30: 0x00c0, 0x3c31: 0x00c0, 0x3c32: 0x00c0, 0x3c33: 0x00c0, 0x3c34: 0x00c0, 0x3c35: 0x00c0, + 0x3c36: 0x00c0, 0x3c37: 0x00c0, 0x3c38: 0x00c0, 0x3c39: 0x00c0, 0x3c3a: 0x00c0, 0x3c3b: 0x00c0, + 0x3c3c: 0x00c0, 0x3c3d: 0x00c0, 0x3c3e: 0x00c0, 0x3c3f: 0x00c0, + // Block 0xf1, offset 0x3c40 + 0x3c40: 0x00c0, 0x3c41: 0x00c0, 0x3c42: 0x00c0, 0x3c43: 0x00c0, 0x3c44: 0x00c0, 0x3c45: 0x00c0, + 0x3c46: 0x00c0, 0x3c47: 0x00c0, 0x3c48: 0x00c0, 0x3c49: 0x00c0, 0x3c4a: 0x00c0, 0x3c4b: 0x00c0, + 0x3c4c: 0x00c0, 0x3c4d: 0x00c0, 0x3c4e: 0x00c0, 0x3c4f: 0x00c0, 0x3c50: 0x00c0, 0x3c51: 0x00c0, + 0x3c52: 0x00c0, 0x3c53: 0x00c0, 0x3c54: 0x00c0, 0x3c55: 0x00c0, 0x3c56: 0x00c0, 0x3c57: 0x00c0, + 0x3c58: 0x00c0, 0x3c59: 0x00c0, 0x3c5a: 0x00c0, 0x3c5b: 0x00c0, 0x3c5c: 0x00c0, 0x3c5d: 0x00c0, + 0x3c5e: 0x00c0, 0x3c5f: 0x00c3, 0x3c60: 0x00c0, 0x3c61: 0x00c0, 0x3c62: 0x00c0, 0x3c63: 0x00c3, + 0x3c64: 0x00c3, 0x3c65: 0x00c3, 0x3c66: 0x00c3, 0x3c67: 0x00c3, 0x3c68: 0x00c3, 0x3c69: 0x00c3, + 0x3c6a: 0x00c6, + 0x3c70: 0x00c0, 0x3c71: 0x00c0, 0x3c72: 0x00c0, 0x3c73: 0x00c0, 0x3c74: 0x00c0, 0x3c75: 0x00c0, + 0x3c76: 0x00c0, 0x3c77: 0x00c0, 0x3c78: 0x00c0, 0x3c79: 0x00c0, + // Block 0xf2, offset 0x3c80 + 0x3c80: 0x00c3, 0x3c81: 0x00c3, 0x3c82: 0x00c0, 0x3c83: 0x00c0, 0x3c85: 0x00c0, + 0x3c86: 0x00c0, 0x3c87: 0x00c0, 0x3c88: 0x00c0, 0x3c89: 0x00c0, 0x3c8a: 0x00c0, 0x3c8b: 0x00c0, + 0x3c8c: 0x00c0, 0x3c8f: 0x00c0, 0x3c90: 0x00c0, + 0x3c93: 0x00c0, 0x3c94: 0x00c0, 0x3c95: 0x00c0, 0x3c96: 0x00c0, 0x3c97: 0x00c0, + 0x3c98: 0x00c0, 0x3c99: 0x00c0, 0x3c9a: 0x00c0, 0x3c9b: 0x00c0, 0x3c9c: 0x00c0, 0x3c9d: 0x00c0, + 0x3c9e: 0x00c0, 0x3c9f: 0x00c0, 0x3ca0: 0x00c0, 0x3ca1: 0x00c0, 0x3ca2: 0x00c0, 0x3ca3: 0x00c0, + 0x3ca4: 0x00c0, 0x3ca5: 0x00c0, 0x3ca6: 0x00c0, 0x3ca7: 0x00c0, 0x3ca8: 0x00c0, + 0x3caa: 0x00c0, 0x3cab: 0x00c0, 0x3cac: 0x00c0, 0x3cad: 0x00c0, 0x3cae: 0x00c0, 0x3caf: 0x00c0, + 0x3cb0: 0x00c0, 0x3cb2: 0x00c0, 0x3cb3: 0x00c0, 0x3cb5: 0x00c0, + 0x3cb6: 0x00c0, 0x3cb7: 0x00c0, 0x3cb8: 0x00c0, 0x3cb9: 0x00c0, 0x3cbb: 0x00c3, + 0x3cbc: 0x00c3, 0x3cbd: 0x00c0, 0x3cbe: 0x00c0, 0x3cbf: 0x00c0, + // Block 0xf3, offset 0x3cc0 + 0x3cc0: 0x00c3, 0x3cc1: 0x00c0, 0x3cc2: 0x00c0, 0x3cc3: 0x00c0, 0x3cc4: 0x00c0, + 0x3cc7: 0x00c0, 0x3cc8: 0x00c0, 0x3ccb: 0x00c0, + 0x3ccc: 0x00c0, 0x3ccd: 0x00c5, 0x3cd0: 0x00c0, + 0x3cd7: 0x00c0, + 0x3cdd: 0x00c0, + 0x3cde: 0x00c0, 0x3cdf: 0x00c0, 0x3ce0: 0x00c0, 0x3ce1: 0x00c0, 0x3ce2: 0x00c0, 0x3ce3: 0x00c0, + 0x3ce6: 0x00c3, 0x3ce7: 0x00c3, 0x3ce8: 0x00c3, 0x3ce9: 0x00c3, + 0x3cea: 0x00c3, 0x3ceb: 0x00c3, 0x3cec: 0x00c3, + 0x3cf0: 0x00c3, 0x3cf1: 0x00c3, 0x3cf2: 0x00c3, 0x3cf3: 0x00c3, 0x3cf4: 0x00c3, + // Block 0xf4, offset 0x3d00 + 0x3d00: 0x00c0, 0x3d01: 0x00c0, 0x3d02: 0x00c0, 0x3d03: 0x00c0, 0x3d04: 0x00c0, 0x3d05: 0x00c0, + 0x3d06: 0x00c0, 0x3d07: 0x00c0, 0x3d08: 0x00c0, 0x3d09: 0x00c0, 0x3d0a: 0x00c0, 0x3d0b: 0x00c0, + 0x3d0c: 0x00c0, 0x3d0d: 0x00c0, 0x3d0e: 0x00c0, 0x3d0f: 0x00c0, 0x3d10: 0x00c0, 0x3d11: 0x00c0, + 0x3d12: 0x00c0, 0x3d13: 0x00c0, 0x3d14: 0x00c0, 0x3d15: 0x00c0, 0x3d16: 0x00c0, 0x3d17: 0x00c0, + 0x3d18: 0x00c0, 0x3d19: 0x00c0, 0x3d1a: 0x00c0, 0x3d1b: 0x00c0, 0x3d1c: 0x00c0, 0x3d1d: 0x00c0, + 0x3d1e: 0x00c0, 0x3d1f: 0x00c0, 0x3d20: 0x00c0, 0x3d21: 0x00c0, 0x3d22: 0x00c0, 0x3d23: 0x00c0, + 0x3d24: 0x00c0, 0x3d25: 0x00c0, 0x3d26: 0x00c0, 0x3d27: 0x00c0, 0x3d28: 0x00c0, 0x3d29: 0x00c0, + 0x3d2a: 0x00c0, 0x3d2b: 0x00c0, 0x3d2c: 0x00c0, 0x3d2d: 0x00c0, 0x3d2e: 0x00c0, 0x3d2f: 0x00c0, + 0x3d30: 0x00c0, 0x3d31: 0x00c0, 0x3d32: 0x00c0, 0x3d33: 0x00c0, 0x3d34: 0x00c0, 0x3d35: 0x00c0, + 0x3d36: 0x00c0, 0x3d37: 0x00c0, 0x3d38: 0x00c3, 0x3d39: 0x00c3, 0x3d3a: 0x00c3, 0x3d3b: 0x00c3, + 0x3d3c: 0x00c3, 0x3d3d: 0x00c3, 0x3d3e: 0x00c3, 0x3d3f: 0x00c3, + // Block 0xf5, offset 0x3d40 + 0x3d40: 0x00c0, 0x3d41: 0x00c0, 0x3d42: 0x00c6, 0x3d43: 0x00c3, 0x3d44: 0x00c3, 0x3d45: 0x00c0, + 0x3d46: 0x00c3, 0x3d47: 0x00c0, 0x3d48: 0x00c0, 0x3d49: 0x00c0, 0x3d4a: 0x00c0, 0x3d4b: 0x0080, + 0x3d4c: 0x0080, 0x3d4d: 0x0080, 0x3d4e: 0x0080, 0x3d4f: 0x0080, 0x3d50: 0x00c0, 0x3d51: 0x00c0, + 0x3d52: 0x00c0, 0x3d53: 0x00c0, 0x3d54: 0x00c0, 0x3d55: 0x00c0, 0x3d56: 0x00c0, 0x3d57: 0x00c0, + 0x3d58: 0x00c0, 0x3d59: 0x00c0, 0x3d5a: 0x0080, 0x3d5b: 0x0080, 0x3d5d: 0x0080, + 0x3d5e: 0x00c3, 0x3d5f: 0x00c0, 0x3d60: 0x00c0, 0x3d61: 0x00c0, + // Block 0xf6, offset 0x3d80 + 0x3d80: 0x00c0, 0x3d81: 0x00c0, 0x3d82: 0x00c0, 0x3d83: 0x00c0, 0x3d84: 0x00c0, 0x3d85: 0x00c0, + 0x3d86: 0x00c0, 0x3d87: 0x00c0, 0x3d88: 0x00c0, 0x3d89: 0x00c0, 0x3d8a: 0x00c0, 0x3d8b: 0x00c0, + 0x3d8c: 0x00c0, 0x3d8d: 0x00c0, 0x3d8e: 0x00c0, 0x3d8f: 0x00c0, 0x3d90: 0x00c0, 0x3d91: 0x00c0, + 0x3d92: 0x00c0, 0x3d93: 0x00c0, 0x3d94: 0x00c0, 0x3d95: 0x00c0, 0x3d96: 0x00c0, 0x3d97: 0x00c0, + 0x3d98: 0x00c0, 0x3d99: 0x00c0, 0x3d9a: 0x00c0, 0x3d9b: 0x00c0, 0x3d9c: 0x00c0, 0x3d9d: 0x00c0, + 0x3d9e: 0x00c0, 0x3d9f: 0x00c0, 0x3da0: 0x00c0, 0x3da1: 0x00c0, 0x3da2: 0x00c0, 0x3da3: 0x00c0, + 0x3da4: 0x00c0, 0x3da5: 0x00c0, 0x3da6: 0x00c0, 0x3da7: 0x00c0, 0x3da8: 0x00c0, 0x3da9: 0x00c0, + 0x3daa: 0x00c0, 0x3dab: 0x00c0, 0x3dac: 0x00c0, 0x3dad: 0x00c0, 0x3dae: 0x00c0, 0x3daf: 0x00c0, + 0x3db0: 0x00c0, 0x3db1: 0x00c0, 0x3db2: 0x00c0, 0x3db3: 0x00c3, 0x3db4: 0x00c3, 0x3db5: 0x00c3, + 0x3db6: 0x00c3, 0x3db7: 0x00c3, 0x3db8: 0x00c3, 0x3db9: 0x00c0, 0x3dba: 0x00c3, 0x3dbb: 0x00c0, + 0x3dbc: 0x00c0, 0x3dbd: 0x00c0, 0x3dbe: 0x00c0, 0x3dbf: 0x00c3, + // Block 0xf7, offset 0x3dc0 + 0x3dc0: 0x00c3, 0x3dc1: 0x00c0, 0x3dc2: 0x00c6, 0x3dc3: 0x00c3, 0x3dc4: 0x00c0, 0x3dc5: 0x00c0, + 0x3dc6: 0x0080, 0x3dc7: 0x00c0, + 0x3dd0: 0x00c0, 0x3dd1: 0x00c0, + 0x3dd2: 0x00c0, 0x3dd3: 0x00c0, 0x3dd4: 0x00c0, 0x3dd5: 0x00c0, 0x3dd6: 0x00c0, 0x3dd7: 0x00c0, + 0x3dd8: 0x00c0, 0x3dd9: 0x00c0, + // Block 0xf8, offset 0x3e00 + 0x3e00: 0x00c0, 0x3e01: 0x00c0, 0x3e02: 0x00c0, 0x3e03: 0x00c0, 0x3e04: 0x00c0, 0x3e05: 0x00c0, + 0x3e06: 0x00c0, 0x3e07: 0x00c0, 0x3e08: 0x00c0, 0x3e09: 0x00c0, 0x3e0a: 0x00c0, 0x3e0b: 0x00c0, + 0x3e0c: 0x00c0, 0x3e0d: 0x00c0, 0x3e0e: 0x00c0, 0x3e0f: 0x00c0, 0x3e10: 0x00c0, 0x3e11: 0x00c0, + 0x3e12: 0x00c0, 0x3e13: 0x00c0, 0x3e14: 0x00c0, 0x3e15: 0x00c0, 0x3e16: 0x00c0, 0x3e17: 0x00c0, + 0x3e18: 0x00c0, 0x3e19: 0x00c0, 0x3e1a: 0x00c0, 0x3e1b: 0x00c0, 0x3e1c: 0x00c0, 0x3e1d: 0x00c0, + 0x3e1e: 0x00c0, 0x3e1f: 0x00c0, 0x3e20: 0x00c0, 0x3e21: 0x00c0, 0x3e22: 0x00c0, 0x3e23: 0x00c0, + 0x3e24: 0x00c0, 0x3e25: 0x00c0, 0x3e26: 0x00c0, 0x3e27: 0x00c0, 0x3e28: 0x00c0, 0x3e29: 0x00c0, + 0x3e2a: 0x00c0, 0x3e2b: 0x00c0, 0x3e2c: 0x00c0, 0x3e2d: 0x00c0, 0x3e2e: 0x00c0, 0x3e2f: 0x00c0, + 0x3e30: 0x00c0, 0x3e31: 0x00c0, 0x3e32: 0x00c3, 0x3e33: 0x00c3, 0x3e34: 0x00c3, 0x3e35: 0x00c3, + 0x3e38: 0x00c0, 0x3e39: 0x00c0, 0x3e3a: 0x00c0, 0x3e3b: 0x00c0, + 0x3e3c: 0x00c3, 0x3e3d: 0x00c3, 0x3e3e: 0x00c0, 0x3e3f: 0x00c6, + // Block 0xf9, offset 0x3e40 + 0x3e40: 0x00c3, 0x3e41: 0x0080, 0x3e42: 0x0080, 0x3e43: 0x0080, 0x3e44: 0x0080, 0x3e45: 0x0080, + 0x3e46: 0x0080, 0x3e47: 0x0080, 0x3e48: 0x0080, 0x3e49: 0x0080, 0x3e4a: 0x0080, 0x3e4b: 0x0080, + 0x3e4c: 0x0080, 0x3e4d: 0x0080, 0x3e4e: 0x0080, 0x3e4f: 0x0080, 0x3e50: 0x0080, 0x3e51: 0x0080, + 0x3e52: 0x0080, 0x3e53: 0x0080, 0x3e54: 0x0080, 0x3e55: 0x0080, 0x3e56: 0x0080, 0x3e57: 0x0080, + 0x3e58: 0x00c0, 0x3e59: 0x00c0, 0x3e5a: 0x00c0, 0x3e5b: 0x00c0, 0x3e5c: 0x00c3, 0x3e5d: 0x00c3, + // Block 0xfa, offset 0x3e80 + 0x3e80: 0x00c0, 0x3e81: 0x00c0, 0x3e82: 0x00c0, 0x3e83: 0x00c0, 0x3e84: 0x00c0, 0x3e85: 0x00c0, + 0x3e86: 0x00c0, 0x3e87: 0x00c0, 0x3e88: 0x00c0, 0x3e89: 0x00c0, 0x3e8a: 0x00c0, 0x3e8b: 0x00c0, + 0x3e8c: 0x00c0, 0x3e8d: 0x00c0, 0x3e8e: 0x00c0, 0x3e8f: 0x00c0, 0x3e90: 0x00c0, 0x3e91: 0x00c0, + 0x3e92: 0x00c0, 0x3e93: 0x00c0, 0x3e94: 0x00c0, 0x3e95: 0x00c0, 0x3e96: 0x00c0, 0x3e97: 0x00c0, + 0x3e98: 0x00c0, 0x3e99: 0x00c0, 0x3e9a: 0x00c0, 0x3e9b: 0x00c0, 0x3e9c: 0x00c0, 0x3e9d: 0x00c0, + 0x3e9e: 0x00c0, 0x3e9f: 0x00c0, 0x3ea0: 0x00c0, 0x3ea1: 0x00c0, 0x3ea2: 0x00c0, 0x3ea3: 0x00c0, + 0x3ea4: 0x00c0, 0x3ea5: 0x00c0, 0x3ea6: 0x00c0, 0x3ea7: 0x00c0, 0x3ea8: 0x00c0, 0x3ea9: 0x00c0, + 0x3eaa: 0x00c0, 0x3eab: 0x00c0, 0x3eac: 0x00c0, 0x3ead: 0x00c0, 0x3eae: 0x00c0, 0x3eaf: 0x00c0, + 0x3eb0: 0x00c0, 0x3eb1: 0x00c0, 0x3eb2: 0x00c0, 0x3eb3: 0x00c3, 0x3eb4: 0x00c3, 0x3eb5: 0x00c3, + 0x3eb6: 0x00c3, 0x3eb7: 0x00c3, 0x3eb8: 0x00c3, 0x3eb9: 0x00c3, 0x3eba: 0x00c3, 0x3ebb: 0x00c0, + 0x3ebc: 0x00c0, 0x3ebd: 0x00c3, 0x3ebe: 0x00c0, 0x3ebf: 0x00c6, + // Block 0xfb, offset 0x3ec0 + 0x3ec0: 0x00c3, 0x3ec1: 0x0080, 0x3ec2: 0x0080, 0x3ec3: 0x0080, 0x3ec4: 0x00c0, + 0x3ed0: 0x00c0, 0x3ed1: 0x00c0, + 0x3ed2: 0x00c0, 0x3ed3: 0x00c0, 0x3ed4: 0x00c0, 0x3ed5: 0x00c0, 0x3ed6: 0x00c0, 0x3ed7: 0x00c0, + 0x3ed8: 0x00c0, 0x3ed9: 0x00c0, + 0x3ee0: 0x0080, 0x3ee1: 0x0080, 0x3ee2: 0x0080, 0x3ee3: 0x0080, + 0x3ee4: 0x0080, 0x3ee5: 0x0080, 0x3ee6: 0x0080, 0x3ee7: 0x0080, 0x3ee8: 0x0080, 0x3ee9: 0x0080, + 0x3eea: 0x0080, 0x3eeb: 0x0080, 0x3eec: 0x0080, + // Block 0xfc, offset 0x3f00 + 0x3f00: 0x00c0, 0x3f01: 0x00c0, 0x3f02: 0x00c0, 0x3f03: 0x00c0, 0x3f04: 0x00c0, 0x3f05: 0x00c0, + 0x3f06: 0x00c0, 0x3f07: 0x00c0, 0x3f08: 0x00c0, 0x3f09: 0x00c0, 0x3f0a: 0x00c0, 0x3f0b: 0x00c0, + 0x3f0c: 0x00c0, 0x3f0d: 0x00c0, 0x3f0e: 0x00c0, 0x3f0f: 0x00c0, 0x3f10: 0x00c0, 0x3f11: 0x00c0, + 0x3f12: 0x00c0, 0x3f13: 0x00c0, 0x3f14: 0x00c0, 0x3f15: 0x00c0, 0x3f16: 0x00c0, 0x3f17: 0x00c0, + 0x3f18: 0x00c0, 0x3f19: 0x00c0, 0x3f1a: 0x00c0, 0x3f1b: 0x00c0, 0x3f1c: 0x00c0, 0x3f1d: 0x00c0, + 0x3f1e: 0x00c0, 0x3f1f: 0x00c0, 0x3f20: 0x00c0, 0x3f21: 0x00c0, 0x3f22: 0x00c0, 0x3f23: 0x00c0, + 0x3f24: 0x00c0, 0x3f25: 0x00c0, 0x3f26: 0x00c0, 0x3f27: 0x00c0, 0x3f28: 0x00c0, 0x3f29: 0x00c0, + 0x3f2a: 0x00c0, 0x3f2b: 0x00c3, 0x3f2c: 0x00c0, 0x3f2d: 0x00c3, 0x3f2e: 0x00c0, 0x3f2f: 0x00c0, + 0x3f30: 0x00c3, 0x3f31: 0x00c3, 0x3f32: 0x00c3, 0x3f33: 0x00c3, 0x3f34: 0x00c3, 0x3f35: 0x00c3, + 0x3f36: 0x00c5, 0x3f37: 0x00c3, 0x3f38: 0x00c0, + // Block 0xfd, offset 0x3f40 + 0x3f40: 0x00c0, 0x3f41: 0x00c0, 0x3f42: 0x00c0, 0x3f43: 0x00c0, 0x3f44: 0x00c0, 0x3f45: 0x00c0, + 0x3f46: 0x00c0, 0x3f47: 0x00c0, 0x3f48: 0x00c0, 0x3f49: 0x00c0, + // Block 0xfe, offset 0x3f80 + 0x3f80: 0x00c0, 0x3f81: 0x00c0, 0x3f82: 0x00c0, 0x3f83: 0x00c0, 0x3f84: 0x00c0, 0x3f85: 0x00c0, + 0x3f86: 0x00c0, 0x3f87: 0x00c0, 0x3f88: 0x00c0, 0x3f89: 0x00c0, 0x3f8a: 0x00c0, 0x3f8b: 0x00c0, + 0x3f8c: 0x00c0, 0x3f8d: 0x00c0, 0x3f8e: 0x00c0, 0x3f8f: 0x00c0, 0x3f90: 0x00c0, 0x3f91: 0x00c0, + 0x3f92: 0x00c0, 0x3f93: 0x00c0, 0x3f94: 0x00c0, 0x3f95: 0x00c0, 0x3f96: 0x00c0, 0x3f97: 0x00c0, + 0x3f98: 0x00c0, 0x3f99: 0x00c0, 0x3f9a: 0x00c0, 0x3f9d: 0x00c3, + 0x3f9e: 0x00c3, 0x3f9f: 0x00c3, 0x3fa0: 0x00c0, 0x3fa1: 0x00c0, 0x3fa2: 0x00c3, 0x3fa3: 0x00c3, + 0x3fa4: 0x00c3, 0x3fa5: 0x00c3, 0x3fa6: 0x00c0, 0x3fa7: 0x00c3, 0x3fa8: 0x00c3, 0x3fa9: 0x00c3, + 0x3faa: 0x00c3, 0x3fab: 0x00c6, + 0x3fb0: 0x00c0, 0x3fb1: 0x00c0, 0x3fb2: 0x00c0, 0x3fb3: 0x00c0, 0x3fb4: 0x00c0, 0x3fb5: 0x00c0, + 0x3fb6: 0x00c0, 0x3fb7: 0x00c0, 0x3fb8: 0x00c0, 0x3fb9: 0x00c0, 0x3fba: 0x0080, 0x3fbb: 0x0080, + 0x3fbc: 0x0080, 0x3fbd: 0x0080, 0x3fbe: 0x0080, 0x3fbf: 0x0080, + // Block 0xff, offset 0x3fc0 + 0x3fc0: 0x00c0, 0x3fc1: 0x00c0, 0x3fc2: 0x00c0, 0x3fc3: 0x00c0, 0x3fc4: 0x00c0, 0x3fc5: 0x00c0, + 0x3fc6: 0x00c0, 0x3fc7: 0x00c0, 0x3fc8: 0x00c0, 0x3fc9: 0x00c0, 0x3fca: 0x00c0, 0x3fcb: 0x00c0, + 0x3fcc: 0x00c0, 0x3fcd: 0x00c0, 0x3fce: 0x00c0, 0x3fcf: 0x00c0, 0x3fd0: 0x00c0, 0x3fd1: 0x00c0, + 0x3fd2: 0x00c0, 0x3fd3: 0x00c0, 0x3fd4: 0x00c0, 0x3fd5: 0x00c0, 0x3fd6: 0x00c0, 0x3fd7: 0x00c0, + 0x3fd8: 0x00c0, 0x3fd9: 0x00c0, 0x3fda: 0x00c0, 0x3fdb: 0x00c0, 0x3fdc: 0x00c0, 0x3fdd: 0x00c0, + 0x3fde: 0x00c0, 0x3fdf: 0x00c0, 0x3fe0: 0x00c0, 0x3fe1: 0x00c0, 0x3fe2: 0x00c0, 0x3fe3: 0x00c0, + 0x3fe4: 0x00c0, 0x3fe5: 0x00c0, 0x3fe6: 0x00c0, 0x3fe7: 0x00c0, 0x3fe8: 0x00c0, 0x3fe9: 0x00c0, + 0x3fea: 0x00c0, 0x3feb: 0x00c0, 0x3fec: 0x00c0, 0x3fed: 0x00c0, 0x3fee: 0x00c0, 0x3fef: 0x00c3, + 0x3ff0: 0x00c3, 0x3ff1: 0x00c3, 0x3ff2: 0x00c3, 0x3ff3: 0x00c3, 0x3ff4: 0x00c3, 0x3ff5: 0x00c3, + 0x3ff6: 0x00c3, 0x3ff7: 0x00c3, 0x3ff8: 0x00c0, 0x3ff9: 0x00c6, 0x3ffa: 0x00c3, 0x3ffb: 0x0080, + // Block 0x100, offset 0x4000 + 0x4020: 0x00c0, 0x4021: 0x00c0, 0x4022: 0x00c0, 0x4023: 0x00c0, + 0x4024: 0x00c0, 0x4025: 0x00c0, 0x4026: 0x00c0, 0x4027: 0x00c0, 0x4028: 0x00c0, 0x4029: 0x00c0, + 0x402a: 0x00c0, 0x402b: 0x00c0, 0x402c: 0x00c0, 0x402d: 0x00c0, 0x402e: 0x00c0, 0x402f: 0x00c0, + 0x4030: 0x00c0, 0x4031: 0x00c0, 0x4032: 0x00c0, 0x4033: 0x00c0, 0x4034: 0x00c0, 0x4035: 0x00c0, + 0x4036: 0x00c0, 0x4037: 0x00c0, 0x4038: 0x00c0, 0x4039: 0x00c0, 0x403a: 0x00c0, 0x403b: 0x00c0, + 0x403c: 0x00c0, 0x403d: 0x00c0, 0x403e: 0x00c0, 0x403f: 0x00c0, + // Block 0x101, offset 0x4040 + 0x4040: 0x00c0, 0x4041: 0x00c0, 0x4042: 0x00c0, 0x4043: 0x00c0, 0x4044: 0x00c0, 0x4045: 0x00c0, + 0x4046: 0x00c0, 0x4047: 0x00c0, 0x4048: 0x00c0, 0x4049: 0x00c0, 0x404a: 0x00c0, 0x404b: 0x00c0, + 0x404c: 0x00c0, 0x404d: 0x00c0, 0x404e: 0x00c0, 0x404f: 0x00c0, 0x4050: 0x00c0, 0x4051: 0x00c0, + 0x4052: 0x00c0, 0x4053: 0x00c0, 0x4054: 0x00c0, 0x4055: 0x00c0, 0x4056: 0x00c0, 0x4057: 0x00c0, + 0x4058: 0x00c0, 0x4059: 0x00c0, 0x405a: 0x00c0, 0x405b: 0x00c0, 0x405c: 0x00c0, 0x405d: 0x00c0, + 0x405e: 0x00c0, 0x405f: 0x00c0, 0x4060: 0x00c0, 0x4061: 0x00c0, 0x4062: 0x00c0, 0x4063: 0x00c0, + 0x4064: 0x00c0, 0x4065: 0x00c0, 0x4066: 0x00c0, 0x4067: 0x00c0, 0x4068: 0x00c0, 0x4069: 0x00c0, + 0x406a: 0x0080, 0x406b: 0x0080, 0x406c: 0x0080, 0x406d: 0x0080, 0x406e: 0x0080, 0x406f: 0x0080, + 0x4070: 0x0080, 0x4071: 0x0080, 0x4072: 0x0080, + 0x407f: 0x00c0, + // Block 0x102, offset 0x4080 + 0x4080: 0x00c0, 0x4081: 0x00c0, 0x4082: 0x00c0, 0x4083: 0x00c0, 0x4084: 0x00c0, 0x4085: 0x00c0, + 0x4086: 0x00c0, 0x4089: 0x00c0, + 0x408c: 0x00c0, 0x408d: 0x00c0, 0x408e: 0x00c0, 0x408f: 0x00c0, 0x4090: 0x00c0, 0x4091: 0x00c0, + 0x4092: 0x00c0, 0x4093: 0x00c0, 0x4095: 0x00c0, 0x4096: 0x00c0, + 0x4098: 0x00c0, 0x4099: 0x00c0, 0x409a: 0x00c0, 0x409b: 0x00c0, 0x409c: 0x00c0, 0x409d: 0x00c0, + 0x409e: 0x00c0, 0x409f: 0x00c0, 0x40a0: 0x00c0, 0x40a1: 0x00c0, 0x40a2: 0x00c0, 0x40a3: 0x00c0, + 0x40a4: 0x00c0, 0x40a5: 0x00c0, 0x40a6: 0x00c0, 0x40a7: 0x00c0, 0x40a8: 0x00c0, 0x40a9: 0x00c0, + 0x40aa: 0x00c0, 0x40ab: 0x00c0, 0x40ac: 0x00c0, 0x40ad: 0x00c0, 0x40ae: 0x00c0, 0x40af: 0x00c0, + 0x40b0: 0x00c0, 0x40b1: 0x00c0, 0x40b2: 0x00c0, 0x40b3: 0x00c0, 0x40b4: 0x00c0, 0x40b5: 0x00c0, + 0x40b7: 0x00c0, 0x40b8: 0x00c0, 0x40bb: 0x00c3, + 0x40bc: 0x00c3, 0x40bd: 0x00c5, 0x40be: 0x00c6, 0x40bf: 0x00c0, + // Block 0x103, offset 0x40c0 + 0x40c0: 0x00c0, 0x40c1: 0x00c0, 0x40c2: 0x00c0, 0x40c3: 0x00c3, 0x40c4: 0x0080, 0x40c5: 0x0080, + 0x40c6: 0x0080, + 0x40d0: 0x00c0, 0x40d1: 0x00c0, + 0x40d2: 0x00c0, 0x40d3: 0x00c0, 0x40d4: 0x00c0, 0x40d5: 0x00c0, 0x40d6: 0x00c0, 0x40d7: 0x00c0, + 0x40d8: 0x00c0, 0x40d9: 0x00c0, + // Block 0x104, offset 0x4100 + 0x4120: 0x00c0, 0x4121: 0x00c0, 0x4122: 0x00c0, 0x4123: 0x00c0, + 0x4124: 0x00c0, 0x4125: 0x00c0, 0x4126: 0x00c0, 0x4127: 0x00c0, + 0x412a: 0x00c0, 0x412b: 0x00c0, 0x412c: 0x00c0, 0x412d: 0x00c0, 0x412e: 0x00c0, 0x412f: 0x00c0, + 0x4130: 0x00c0, 0x4131: 0x00c0, 0x4132: 0x00c0, 0x4133: 0x00c0, 0x4134: 0x00c0, 0x4135: 0x00c0, + 0x4136: 0x00c0, 0x4137: 0x00c0, 0x4138: 0x00c0, 0x4139: 0x00c0, 0x413a: 0x00c0, 0x413b: 0x00c0, + 0x413c: 0x00c0, 0x413d: 0x00c0, 0x413e: 0x00c0, 0x413f: 0x00c0, + // Block 0x105, offset 0x4140 + 0x4140: 0x00c0, 0x4141: 0x00c0, 0x4142: 0x00c0, 0x4143: 0x00c0, 0x4144: 0x00c0, 0x4145: 0x00c0, + 0x4146: 0x00c0, 0x4147: 0x00c0, 0x4148: 0x00c0, 0x4149: 0x00c0, 0x414a: 0x00c0, 0x414b: 0x00c0, + 0x414c: 0x00c0, 0x414d: 0x00c0, 0x414e: 0x00c0, 0x414f: 0x00c0, 0x4150: 0x00c0, 0x4151: 0x00c0, + 0x4152: 0x00c0, 0x4153: 0x00c0, 0x4154: 0x00c3, 0x4155: 0x00c3, 0x4156: 0x00c3, 0x4157: 0x00c3, + 0x415a: 0x00c3, 0x415b: 0x00c3, 0x415c: 0x00c0, 0x415d: 0x00c0, + 0x415e: 0x00c0, 0x415f: 0x00c0, 0x4160: 0x00c6, 0x4161: 0x00c0, 0x4162: 0x0080, 0x4163: 0x00c0, + 0x4164: 0x00c0, + // Block 0x106, offset 0x4180 + 0x4180: 0x00c0, 0x4181: 0x00c3, 0x4182: 0x00c3, 0x4183: 0x00c3, 0x4184: 0x00c3, 0x4185: 0x00c3, + 0x4186: 0x00c3, 0x4187: 0x00c3, 0x4188: 0x00c3, 0x4189: 0x00c3, 0x418a: 0x00c3, 0x418b: 0x00c0, + 0x418c: 0x00c0, 0x418d: 0x00c0, 0x418e: 0x00c0, 0x418f: 0x00c0, 0x4190: 0x00c0, 0x4191: 0x00c0, + 0x4192: 0x00c0, 0x4193: 0x00c0, 0x4194: 0x00c0, 0x4195: 0x00c0, 0x4196: 0x00c0, 0x4197: 0x00c0, + 0x4198: 0x00c0, 0x4199: 0x00c0, 0x419a: 0x00c0, 0x419b: 0x00c0, 0x419c: 0x00c0, 0x419d: 0x00c0, + 0x419e: 0x00c0, 0x419f: 0x00c0, 0x41a0: 0x00c0, 0x41a1: 0x00c0, 0x41a2: 0x00c0, 0x41a3: 0x00c0, + 0x41a4: 0x00c0, 0x41a5: 0x00c0, 0x41a6: 0x00c0, 0x41a7: 0x00c0, 0x41a8: 0x00c0, 0x41a9: 0x00c0, + 0x41aa: 0x00c0, 0x41ab: 0x00c0, 0x41ac: 0x00c0, 0x41ad: 0x00c0, 0x41ae: 0x00c0, 0x41af: 0x00c0, + 0x41b0: 0x00c0, 0x41b1: 0x00c0, 0x41b2: 0x00c0, 0x41b3: 0x00c3, 0x41b4: 0x00c6, 0x41b5: 0x00c3, + 0x41b6: 0x00c3, 0x41b7: 0x00c3, 0x41b8: 0x00c3, 0x41b9: 0x00c0, 0x41ba: 0x00c0, 0x41bb: 0x00c3, + 0x41bc: 0x00c3, 0x41bd: 0x00c3, 0x41be: 0x00c3, 0x41bf: 0x0080, + // Block 0x107, offset 0x41c0 + 0x41c0: 0x0080, 0x41c1: 0x0080, 0x41c2: 0x0080, 0x41c3: 0x0080, 0x41c4: 0x0080, 0x41c5: 0x0080, + 0x41c6: 0x0080, 0x41c7: 0x00c6, + 0x41d0: 0x00c0, 0x41d1: 0x00c3, + 0x41d2: 0x00c3, 0x41d3: 0x00c3, 0x41d4: 0x00c3, 0x41d5: 0x00c3, 0x41d6: 0x00c3, 0x41d7: 0x00c0, + 0x41d8: 0x00c0, 0x41d9: 0x00c3, 0x41da: 0x00c3, 0x41db: 0x00c3, 0x41dc: 0x00c0, 0x41dd: 0x00c0, + 0x41de: 0x00c0, 0x41df: 0x00c0, 0x41e0: 0x00c0, 0x41e1: 0x00c0, 0x41e2: 0x00c0, 0x41e3: 0x00c0, + 0x41e4: 0x00c0, 0x41e5: 0x00c0, 0x41e6: 0x00c0, 0x41e7: 0x00c0, 0x41e8: 0x00c0, 0x41e9: 0x00c0, + 0x41ea: 0x00c0, 0x41eb: 0x00c0, 0x41ec: 0x00c0, 0x41ed: 0x00c0, 0x41ee: 0x00c0, 0x41ef: 0x00c0, + 0x41f0: 0x00c0, 0x41f1: 0x00c0, 0x41f2: 0x00c0, 0x41f3: 0x00c0, 0x41f4: 0x00c0, 0x41f5: 0x00c0, + 0x41f6: 0x00c0, 0x41f7: 0x00c0, 0x41f8: 0x00c0, 0x41f9: 0x00c0, 0x41fa: 0x00c0, 0x41fb: 0x00c0, + 0x41fc: 0x00c0, 0x41fd: 0x00c0, 0x41fe: 0x00c0, 0x41ff: 0x00c0, + // Block 0x108, offset 0x4200 + 0x4200: 0x00c0, 0x4201: 0x00c0, 0x4202: 0x00c0, 0x4203: 0x00c0, 0x4204: 0x00c0, 0x4205: 0x00c0, + 0x4206: 0x00c0, 0x4207: 0x00c0, 0x4208: 0x00c0, 0x4209: 0x00c0, 0x420a: 0x00c3, 0x420b: 0x00c3, + 0x420c: 0x00c3, 0x420d: 0x00c3, 0x420e: 0x00c3, 0x420f: 0x00c3, 0x4210: 0x00c3, 0x4211: 0x00c3, + 0x4212: 0x00c3, 0x4213: 0x00c3, 0x4214: 0x00c3, 0x4215: 0x00c3, 0x4216: 0x00c3, 0x4217: 0x00c0, + 0x4218: 0x00c3, 0x4219: 0x00c6, 0x421a: 0x0080, 0x421b: 0x0080, 0x421c: 0x0080, 0x421d: 0x00c0, + 0x421e: 0x0080, 0x421f: 0x0080, 0x4220: 0x0080, 0x4221: 0x0080, 0x4222: 0x0080, + // Block 0x109, offset 0x4240 + 0x4240: 0x00c0, 0x4241: 0x00c0, 0x4242: 0x00c0, 0x4243: 0x00c0, 0x4244: 0x00c0, 0x4245: 0x00c0, + 0x4246: 0x00c0, 0x4247: 0x00c0, 0x4248: 0x00c0, 0x4249: 0x00c0, 0x424a: 0x00c0, 0x424b: 0x00c0, + 0x424c: 0x00c0, 0x424d: 0x00c0, 0x424e: 0x00c0, 0x424f: 0x00c0, 0x4250: 0x00c0, 0x4251: 0x00c0, + 0x4252: 0x00c0, 0x4253: 0x00c0, 0x4254: 0x00c0, 0x4255: 0x00c0, 0x4256: 0x00c0, 0x4257: 0x00c0, + 0x4258: 0x00c0, 0x4259: 0x00c0, 0x425a: 0x00c0, 0x425b: 0x00c0, 0x425c: 0x00c0, 0x425d: 0x00c0, + 0x425e: 0x00c0, 0x425f: 0x00c0, 0x4260: 0x00c0, 0x4261: 0x00c0, 0x4262: 0x00c0, 0x4263: 0x00c0, + 0x4264: 0x00c0, 0x4265: 0x00c0, 0x4266: 0x00c0, 0x4267: 0x00c0, 0x4268: 0x00c0, 0x4269: 0x00c0, + 0x426a: 0x00c0, 0x426b: 0x00c0, 0x426c: 0x00c0, 0x426d: 0x00c0, 0x426e: 0x00c0, 0x426f: 0x00c0, + 0x4270: 0x00c0, 0x4271: 0x00c0, 0x4272: 0x00c0, 0x4273: 0x00c0, 0x4274: 0x00c0, 0x4275: 0x00c0, + 0x4276: 0x00c0, 0x4277: 0x00c0, 0x4278: 0x00c0, + // Block 0x10a, offset 0x4280 + 0x4280: 0x00c0, 0x4281: 0x00c0, 0x4282: 0x00c0, 0x4283: 0x00c0, 0x4284: 0x00c0, 0x4285: 0x00c0, + 0x4286: 0x00c0, 0x4287: 0x00c0, 0x4288: 0x00c0, 0x428a: 0x00c0, 0x428b: 0x00c0, + 0x428c: 0x00c0, 0x428d: 0x00c0, 0x428e: 0x00c0, 0x428f: 0x00c0, 0x4290: 0x00c0, 0x4291: 0x00c0, + 0x4292: 0x00c0, 0x4293: 0x00c0, 0x4294: 0x00c0, 0x4295: 0x00c0, 0x4296: 0x00c0, 0x4297: 0x00c0, + 0x4298: 0x00c0, 0x4299: 0x00c0, 0x429a: 0x00c0, 0x429b: 0x00c0, 0x429c: 0x00c0, 0x429d: 0x00c0, + 0x429e: 0x00c0, 0x429f: 0x00c0, 0x42a0: 0x00c0, 0x42a1: 0x00c0, 0x42a2: 0x00c0, 0x42a3: 0x00c0, + 0x42a4: 0x00c0, 0x42a5: 0x00c0, 0x42a6: 0x00c0, 0x42a7: 0x00c0, 0x42a8: 0x00c0, 0x42a9: 0x00c0, + 0x42aa: 0x00c0, 0x42ab: 0x00c0, 0x42ac: 0x00c0, 0x42ad: 0x00c0, 0x42ae: 0x00c0, 0x42af: 0x00c0, + 0x42b0: 0x00c3, 0x42b1: 0x00c3, 0x42b2: 0x00c3, 0x42b3: 0x00c3, 0x42b4: 0x00c3, 0x42b5: 0x00c3, + 0x42b6: 0x00c3, 0x42b8: 0x00c3, 0x42b9: 0x00c3, 0x42ba: 0x00c3, 0x42bb: 0x00c3, + 0x42bc: 0x00c3, 0x42bd: 0x00c3, 0x42be: 0x00c0, 0x42bf: 0x00c6, + // Block 0x10b, offset 0x42c0 + 0x42c0: 0x00c0, 0x42c1: 0x0080, 0x42c2: 0x0080, 0x42c3: 0x0080, 0x42c4: 0x0080, 0x42c5: 0x0080, + 0x42d0: 0x00c0, 0x42d1: 0x00c0, + 0x42d2: 0x00c0, 0x42d3: 0x00c0, 0x42d4: 0x00c0, 0x42d5: 0x00c0, 0x42d6: 0x00c0, 0x42d7: 0x00c0, + 0x42d8: 0x00c0, 0x42d9: 0x00c0, 0x42da: 0x0080, 0x42db: 0x0080, 0x42dc: 0x0080, 0x42dd: 0x0080, + 0x42de: 0x0080, 0x42df: 0x0080, 0x42e0: 0x0080, 0x42e1: 0x0080, 0x42e2: 0x0080, 0x42e3: 0x0080, + 0x42e4: 0x0080, 0x42e5: 0x0080, 0x42e6: 0x0080, 0x42e7: 0x0080, 0x42e8: 0x0080, 0x42e9: 0x0080, + 0x42ea: 0x0080, 0x42eb: 0x0080, 0x42ec: 0x0080, + 0x42f0: 0x0080, 0x42f1: 0x0080, 0x42f2: 0x00c0, 0x42f3: 0x00c0, 0x42f4: 0x00c0, 0x42f5: 0x00c0, + 0x42f6: 0x00c0, 0x42f7: 0x00c0, 0x42f8: 0x00c0, 0x42f9: 0x00c0, 0x42fa: 0x00c0, 0x42fb: 0x00c0, + 0x42fc: 0x00c0, 0x42fd: 0x00c0, 0x42fe: 0x00c0, 0x42ff: 0x00c0, + // Block 0x10c, offset 0x4300 + 0x4300: 0x00c0, 0x4301: 0x00c0, 0x4302: 0x00c0, 0x4303: 0x00c0, 0x4304: 0x00c0, 0x4305: 0x00c0, + 0x4306: 0x00c0, 0x4307: 0x00c0, 0x4308: 0x00c0, 0x4309: 0x00c0, 0x430a: 0x00c0, 0x430b: 0x00c0, + 0x430c: 0x00c0, 0x430d: 0x00c0, 0x430e: 0x00c0, 0x430f: 0x00c0, + 0x4312: 0x00c3, 0x4313: 0x00c3, 0x4314: 0x00c3, 0x4315: 0x00c3, 0x4316: 0x00c3, 0x4317: 0x00c3, + 0x4318: 0x00c3, 0x4319: 0x00c3, 0x431a: 0x00c3, 0x431b: 0x00c3, 0x431c: 0x00c3, 0x431d: 0x00c3, + 0x431e: 0x00c3, 0x431f: 0x00c3, 0x4320: 0x00c3, 0x4321: 0x00c3, 0x4322: 0x00c3, 0x4323: 0x00c3, + 0x4324: 0x00c3, 0x4325: 0x00c3, 0x4326: 0x00c3, 0x4327: 0x00c3, 0x4329: 0x00c0, + 0x432a: 0x00c3, 0x432b: 0x00c3, 0x432c: 0x00c3, 0x432d: 0x00c3, 0x432e: 0x00c3, 0x432f: 0x00c3, + 0x4330: 0x00c3, 0x4331: 0x00c0, 0x4332: 0x00c3, 0x4333: 0x00c3, 0x4334: 0x00c0, 0x4335: 0x00c3, + 0x4336: 0x00c3, + // Block 0x10d, offset 0x4340 + 0x4340: 0x00c0, 0x4341: 0x00c0, 0x4342: 0x00c0, 0x4343: 0x00c0, 0x4344: 0x00c0, 0x4345: 0x00c0, + 0x4346: 0x00c0, 0x4348: 0x00c0, 0x4349: 0x00c0, 0x434b: 0x00c0, + 0x434c: 0x00c0, 0x434d: 0x00c0, 0x434e: 0x00c0, 0x434f: 0x00c0, 0x4350: 0x00c0, 0x4351: 0x00c0, + 0x4352: 0x00c0, 0x4353: 0x00c0, 0x4354: 0x00c0, 0x4355: 0x00c0, 0x4356: 0x00c0, 0x4357: 0x00c0, + 0x4358: 0x00c0, 0x4359: 0x00c0, 0x435a: 0x00c0, 0x435b: 0x00c0, 0x435c: 0x00c0, 0x435d: 0x00c0, + 0x435e: 0x00c0, 0x435f: 0x00c0, 0x4360: 0x00c0, 0x4361: 0x00c0, 0x4362: 0x00c0, 0x4363: 0x00c0, + 0x4364: 0x00c0, 0x4365: 0x00c0, 0x4366: 0x00c0, 0x4367: 0x00c0, 0x4368: 0x00c0, 0x4369: 0x00c0, + 0x436a: 0x00c0, 0x436b: 0x00c0, 0x436c: 0x00c0, 0x436d: 0x00c0, 0x436e: 0x00c0, 0x436f: 0x00c0, + 0x4370: 0x00c0, 0x4371: 0x00c3, 0x4372: 0x00c3, 0x4373: 0x00c3, 0x4374: 0x00c3, 0x4375: 0x00c3, + 0x4376: 0x00c3, 0x437a: 0x00c3, + 0x437c: 0x00c3, 0x437d: 0x00c3, 0x437f: 0x00c3, + // Block 0x10e, offset 0x4380 + 0x4380: 0x00c3, 0x4381: 0x00c3, 0x4382: 0x00c3, 0x4383: 0x00c3, 0x4384: 0x00c6, 0x4385: 0x00c6, + 0x4386: 0x00c0, 0x4387: 0x00c3, + 0x4390: 0x00c0, 0x4391: 0x00c0, + 0x4392: 0x00c0, 0x4393: 0x00c0, 0x4394: 0x00c0, 0x4395: 0x00c0, 0x4396: 0x00c0, 0x4397: 0x00c0, + 0x4398: 0x00c0, 0x4399: 0x00c0, + 0x43a0: 0x00c0, 0x43a1: 0x00c0, 0x43a2: 0x00c0, 0x43a3: 0x00c0, + 0x43a4: 0x00c0, 0x43a5: 0x00c0, 0x43a7: 0x00c0, 0x43a8: 0x00c0, + 0x43aa: 0x00c0, 0x43ab: 0x00c0, 0x43ac: 0x00c0, 0x43ad: 0x00c0, 0x43ae: 0x00c0, 0x43af: 0x00c0, + 0x43b0: 0x00c0, 0x43b1: 0x00c0, 0x43b2: 0x00c0, 0x43b3: 0x00c0, 0x43b4: 0x00c0, 0x43b5: 0x00c0, + 0x43b6: 0x00c0, 0x43b7: 0x00c0, 0x43b8: 0x00c0, 0x43b9: 0x00c0, 0x43ba: 0x00c0, 0x43bb: 0x00c0, + 0x43bc: 0x00c0, 0x43bd: 0x00c0, 0x43be: 0x00c0, 0x43bf: 0x00c0, + // Block 0x10f, offset 0x43c0 + 0x43c0: 0x00c0, 0x43c1: 0x00c0, 0x43c2: 0x00c0, 0x43c3: 0x00c0, 0x43c4: 0x00c0, 0x43c5: 0x00c0, + 0x43c6: 0x00c0, 0x43c7: 0x00c0, 0x43c8: 0x00c0, 0x43c9: 0x00c0, 0x43ca: 0x00c0, 0x43cb: 0x00c0, + 0x43cc: 0x00c0, 0x43cd: 0x00c0, 0x43ce: 0x00c0, 0x43d0: 0x00c3, 0x43d1: 0x00c3, + 0x43d3: 0x00c0, 0x43d4: 0x00c0, 0x43d5: 0x00c3, 0x43d6: 0x00c0, 0x43d7: 0x00c6, + 0x43d8: 0x00c0, + 0x43e0: 0x00c0, 0x43e1: 0x00c0, 0x43e2: 0x00c0, 0x43e3: 0x00c0, + 0x43e4: 0x00c0, 0x43e5: 0x00c0, 0x43e6: 0x00c0, 0x43e7: 0x00c0, 0x43e8: 0x00c0, 0x43e9: 0x00c0, + // Block 0x110, offset 0x4400 + 0x4420: 0x00c0, 0x4421: 0x00c0, 0x4422: 0x00c0, 0x4423: 0x00c0, + 0x4424: 0x00c0, 0x4425: 0x00c0, 0x4426: 0x00c0, 0x4427: 0x00c0, 0x4428: 0x00c0, 0x4429: 0x00c0, + 0x442a: 0x00c0, 0x442b: 0x00c0, 0x442c: 0x00c0, 0x442d: 0x00c0, 0x442e: 0x00c0, 0x442f: 0x00c0, + 0x4430: 0x00c0, 0x4431: 0x00c0, 0x4432: 0x00c0, 0x4433: 0x00c3, 0x4434: 0x00c3, 0x4435: 0x00c0, + 0x4436: 0x00c0, 0x4437: 0x0080, 0x4438: 0x0080, + // Block 0x111, offset 0x4440 + 0x4470: 0x00c0, + // Block 0x112, offset 0x4480 + 0x4480: 0x0080, 0x4481: 0x0080, 0x4482: 0x0080, 0x4483: 0x0080, 0x4484: 0x0080, 0x4485: 0x0080, + 0x4486: 0x0080, 0x4487: 0x0080, 0x4488: 0x0080, 0x4489: 0x0080, 0x448a: 0x0080, 0x448b: 0x0080, + 0x448c: 0x0080, 0x448d: 0x0080, 0x448e: 0x0080, 0x448f: 0x0080, 0x4490: 0x0080, 0x4491: 0x0080, + 0x4492: 0x0080, 0x4493: 0x0080, 0x4494: 0x0080, 0x4495: 0x0080, 0x4496: 0x0080, 0x4497: 0x0080, + 0x4498: 0x0080, 0x4499: 0x0080, 0x449a: 0x0080, 0x449b: 0x0080, 0x449c: 0x0080, 0x449d: 0x0080, + 0x449e: 0x0080, 0x449f: 0x0080, 0x44a0: 0x0080, 0x44a1: 0x0080, 0x44a2: 0x0080, 0x44a3: 0x0080, + 0x44a4: 0x0080, 0x44a5: 0x0080, 0x44a6: 0x0080, 0x44a7: 0x0080, 0x44a8: 0x0080, 0x44a9: 0x0080, + 0x44aa: 0x0080, 0x44ab: 0x0080, 0x44ac: 0x0080, 0x44ad: 0x0080, 0x44ae: 0x0080, 0x44af: 0x0080, + 0x44b0: 0x0080, 0x44b1: 0x0080, + 0x44bf: 0x0080, + // Block 0x113, offset 0x44c0 + 0x44c0: 0x00c0, 0x44c1: 0x00c0, 0x44c2: 0x00c0, 0x44c3: 0x00c0, 0x44c4: 0x00c0, 0x44c5: 0x00c0, + 0x44c6: 0x00c0, 0x44c7: 0x00c0, 0x44c8: 0x00c0, 0x44c9: 0x00c0, 0x44ca: 0x00c0, 0x44cb: 0x00c0, + 0x44cc: 0x00c0, 0x44cd: 0x00c0, 0x44ce: 0x00c0, 0x44cf: 0x00c0, 0x44d0: 0x00c0, 0x44d1: 0x00c0, + 0x44d2: 0x00c0, 0x44d3: 0x00c0, 0x44d4: 0x00c0, 0x44d5: 0x00c0, 0x44d6: 0x00c0, 0x44d7: 0x00c0, + 0x44d8: 0x00c0, 0x44d9: 0x00c0, + // Block 0x114, offset 0x4500 + 0x4500: 0x0080, 0x4501: 0x0080, 0x4502: 0x0080, 0x4503: 0x0080, 0x4504: 0x0080, 0x4505: 0x0080, + 0x4506: 0x0080, 0x4507: 0x0080, 0x4508: 0x0080, 0x4509: 0x0080, 0x450a: 0x0080, 0x450b: 0x0080, + 0x450c: 0x0080, 0x450d: 0x0080, 0x450e: 0x0080, 0x450f: 0x0080, 0x4510: 0x0080, 0x4511: 0x0080, + 0x4512: 0x0080, 0x4513: 0x0080, 0x4514: 0x0080, 0x4515: 0x0080, 0x4516: 0x0080, 0x4517: 0x0080, + 0x4518: 0x0080, 0x4519: 0x0080, 0x451a: 0x0080, 0x451b: 0x0080, 0x451c: 0x0080, 0x451d: 0x0080, + 0x451e: 0x0080, 0x451f: 0x0080, 0x4520: 0x0080, 0x4521: 0x0080, 0x4522: 0x0080, 0x4523: 0x0080, + 0x4524: 0x0080, 0x4525: 0x0080, 0x4526: 0x0080, 0x4527: 0x0080, 0x4528: 0x0080, 0x4529: 0x0080, + 0x452a: 0x0080, 0x452b: 0x0080, 0x452c: 0x0080, 0x452d: 0x0080, 0x452e: 0x0080, + 0x4530: 0x0080, 0x4531: 0x0080, 0x4532: 0x0080, 0x4533: 0x0080, 0x4534: 0x0080, + // Block 0x115, offset 0x4540 + 0x4540: 0x00c0, 0x4541: 0x00c0, 0x4542: 0x00c0, 0x4543: 0x00c0, + // Block 0x116, offset 0x4580 + 0x4580: 0x00c0, 0x4581: 0x00c0, 0x4582: 0x00c0, 0x4583: 0x00c0, 0x4584: 0x00c0, 0x4585: 0x00c0, + 0x4586: 0x00c0, 0x4587: 0x00c0, 0x4588: 0x00c0, 0x4589: 0x00c0, 0x458a: 0x00c0, 0x458b: 0x00c0, + 0x458c: 0x00c0, 0x458d: 0x00c0, 0x458e: 0x00c0, 0x458f: 0x00c0, 0x4590: 0x00c0, 0x4591: 0x00c0, + 0x4592: 0x00c0, 0x4593: 0x00c0, 0x4594: 0x00c0, 0x4595: 0x00c0, 0x4596: 0x00c0, 0x4597: 0x00c0, + 0x4598: 0x00c0, 0x4599: 0x00c0, 0x459a: 0x00c0, 0x459b: 0x00c0, 0x459c: 0x00c0, 0x459d: 0x00c0, + 0x459e: 0x00c0, 0x459f: 0x00c0, 0x45a0: 0x00c0, 0x45a1: 0x00c0, 0x45a2: 0x00c0, 0x45a3: 0x00c0, + 0x45a4: 0x00c0, 0x45a5: 0x00c0, 0x45a6: 0x00c0, 0x45a7: 0x00c0, 0x45a8: 0x00c0, 0x45a9: 0x00c0, + 0x45aa: 0x00c0, 0x45ab: 0x00c0, 0x45ac: 0x00c0, 0x45ad: 0x00c0, 0x45ae: 0x00c0, + 0x45b0: 0x0040, 0x45b1: 0x0040, 0x45b2: 0x0040, 0x45b3: 0x0040, 0x45b4: 0x0040, 0x45b5: 0x0040, + 0x45b6: 0x0040, 0x45b7: 0x0040, 0x45b8: 0x0040, + // Block 0x117, offset 0x45c0 + 0x45c0: 0x00c0, 0x45c1: 0x00c0, 0x45c2: 0x00c0, 0x45c3: 0x00c0, 0x45c4: 0x00c0, 0x45c5: 0x00c0, + 0x45c6: 0x00c0, + // Block 0x118, offset 0x4600 + 0x4600: 0x00c0, 0x4601: 0x00c0, 0x4602: 0x00c0, 0x4603: 0x00c0, 0x4604: 0x00c0, 0x4605: 0x00c0, + 0x4606: 0x00c0, 0x4607: 0x00c0, 0x4608: 0x00c0, 0x4609: 0x00c0, 0x460a: 0x00c0, 0x460b: 0x00c0, + 0x460c: 0x00c0, 0x460d: 0x00c0, 0x460e: 0x00c0, 0x460f: 0x00c0, 0x4610: 0x00c0, 0x4611: 0x00c0, + 0x4612: 0x00c0, 0x4613: 0x00c0, 0x4614: 0x00c0, 0x4615: 0x00c0, 0x4616: 0x00c0, 0x4617: 0x00c0, + 0x4618: 0x00c0, 0x4619: 0x00c0, 0x461a: 0x00c0, 0x461b: 0x00c0, 0x461c: 0x00c0, 0x461d: 0x00c0, + 0x461e: 0x00c0, 0x4620: 0x00c0, 0x4621: 0x00c0, 0x4622: 0x00c0, 0x4623: 0x00c0, + 0x4624: 0x00c0, 0x4625: 0x00c0, 0x4626: 0x00c0, 0x4627: 0x00c0, 0x4628: 0x00c0, 0x4629: 0x00c0, + 0x462e: 0x0080, 0x462f: 0x0080, + // Block 0x119, offset 0x4640 + 0x4650: 0x00c0, 0x4651: 0x00c0, + 0x4652: 0x00c0, 0x4653: 0x00c0, 0x4654: 0x00c0, 0x4655: 0x00c0, 0x4656: 0x00c0, 0x4657: 0x00c0, + 0x4658: 0x00c0, 0x4659: 0x00c0, 0x465a: 0x00c0, 0x465b: 0x00c0, 0x465c: 0x00c0, 0x465d: 0x00c0, + 0x465e: 0x00c0, 0x465f: 0x00c0, 0x4660: 0x00c0, 0x4661: 0x00c0, 0x4662: 0x00c0, 0x4663: 0x00c0, + 0x4664: 0x00c0, 0x4665: 0x00c0, 0x4666: 0x00c0, 0x4667: 0x00c0, 0x4668: 0x00c0, 0x4669: 0x00c0, + 0x466a: 0x00c0, 0x466b: 0x00c0, 0x466c: 0x00c0, 0x466d: 0x00c0, + 0x4670: 0x00c3, 0x4671: 0x00c3, 0x4672: 0x00c3, 0x4673: 0x00c3, 0x4674: 0x00c3, 0x4675: 0x0080, + // Block 0x11a, offset 0x4680 + 0x4680: 0x00c0, 0x4681: 0x00c0, 0x4682: 0x00c0, 0x4683: 0x00c0, 0x4684: 0x00c0, 0x4685: 0x00c0, + 0x4686: 0x00c0, 0x4687: 0x00c0, 0x4688: 0x00c0, 0x4689: 0x00c0, 0x468a: 0x00c0, 0x468b: 0x00c0, + 0x468c: 0x00c0, 0x468d: 0x00c0, 0x468e: 0x00c0, 0x468f: 0x00c0, 0x4690: 0x00c0, 0x4691: 0x00c0, + 0x4692: 0x00c0, 0x4693: 0x00c0, 0x4694: 0x00c0, 0x4695: 0x00c0, 0x4696: 0x00c0, 0x4697: 0x00c0, + 0x4698: 0x00c0, 0x4699: 0x00c0, 0x469a: 0x00c0, 0x469b: 0x00c0, 0x469c: 0x00c0, 0x469d: 0x00c0, + 0x469e: 0x00c0, 0x469f: 0x00c0, 0x46a0: 0x00c0, 0x46a1: 0x00c0, 0x46a2: 0x00c0, 0x46a3: 0x00c0, + 0x46a4: 0x00c0, 0x46a5: 0x00c0, 0x46a6: 0x00c0, 0x46a7: 0x00c0, 0x46a8: 0x00c0, 0x46a9: 0x00c0, + 0x46aa: 0x00c0, 0x46ab: 0x00c0, 0x46ac: 0x00c0, 0x46ad: 0x00c0, 0x46ae: 0x00c0, 0x46af: 0x00c0, + 0x46b0: 0x00c3, 0x46b1: 0x00c3, 0x46b2: 0x00c3, 0x46b3: 0x00c3, 0x46b4: 0x00c3, 0x46b5: 0x00c3, + 0x46b6: 0x00c3, 0x46b7: 0x0080, 0x46b8: 0x0080, 0x46b9: 0x0080, 0x46ba: 0x0080, 0x46bb: 0x0080, + 0x46bc: 0x0080, 0x46bd: 0x0080, 0x46be: 0x0080, 0x46bf: 0x0080, + // Block 0x11b, offset 0x46c0 + 0x46c0: 0x00c0, 0x46c1: 0x00c0, 0x46c2: 0x00c0, 0x46c3: 0x00c0, 0x46c4: 0x0080, 0x46c5: 0x0080, + 0x46d0: 0x00c0, 0x46d1: 0x00c0, + 0x46d2: 0x00c0, 0x46d3: 0x00c0, 0x46d4: 0x00c0, 0x46d5: 0x00c0, 0x46d6: 0x00c0, 0x46d7: 0x00c0, + 0x46d8: 0x00c0, 0x46d9: 0x00c0, 0x46db: 0x0080, 0x46dc: 0x0080, 0x46dd: 0x0080, + 0x46de: 0x0080, 0x46df: 0x0080, 0x46e0: 0x0080, 0x46e1: 0x0080, 0x46e3: 0x00c0, + 0x46e4: 0x00c0, 0x46e5: 0x00c0, 0x46e6: 0x00c0, 0x46e7: 0x00c0, 0x46e8: 0x00c0, 0x46e9: 0x00c0, + 0x46ea: 0x00c0, 0x46eb: 0x00c0, 0x46ec: 0x00c0, 0x46ed: 0x00c0, 0x46ee: 0x00c0, 0x46ef: 0x00c0, + 0x46f0: 0x00c0, 0x46f1: 0x00c0, 0x46f2: 0x00c0, 0x46f3: 0x00c0, 0x46f4: 0x00c0, 0x46f5: 0x00c0, + 0x46f6: 0x00c0, 0x46f7: 0x00c0, + 0x46fd: 0x00c0, 0x46fe: 0x00c0, 0x46ff: 0x00c0, + // Block 0x11c, offset 0x4700 + 0x4700: 0x00c0, 0x4701: 0x00c0, 0x4702: 0x00c0, 0x4703: 0x00c0, 0x4704: 0x00c0, 0x4705: 0x00c0, + 0x4706: 0x00c0, 0x4707: 0x00c0, 0x4708: 0x00c0, 0x4709: 0x00c0, 0x470a: 0x00c0, 0x470b: 0x00c0, + 0x470c: 0x00c0, 0x470d: 0x00c0, 0x470e: 0x00c0, 0x470f: 0x00c0, + // Block 0x11d, offset 0x4740 + 0x4740: 0x0080, 0x4741: 0x0080, 0x4742: 0x0080, 0x4743: 0x0080, 0x4744: 0x0080, 0x4745: 0x0080, + 0x4746: 0x0080, 0x4747: 0x0080, 0x4748: 0x0080, 0x4749: 0x0080, 0x474a: 0x0080, 0x474b: 0x0080, + 0x474c: 0x0080, 0x474d: 0x0080, 0x474e: 0x0080, 0x474f: 0x0080, 0x4750: 0x0080, 0x4751: 0x0080, + 0x4752: 0x0080, 0x4753: 0x0080, 0x4754: 0x0080, 0x4755: 0x0080, 0x4756: 0x0080, 0x4757: 0x0080, + 0x4758: 0x0080, 0x4759: 0x0080, 0x475a: 0x0080, + // Block 0x11e, offset 0x4780 + 0x4780: 0x00c0, 0x4781: 0x00c0, 0x4782: 0x00c0, 0x4783: 0x00c0, 0x4784: 0x00c0, 0x4785: 0x00c0, + 0x4786: 0x00c0, 0x4787: 0x00c0, 0x4788: 0x00c0, 0x4789: 0x00c0, 0x478a: 0x00c0, + 0x478f: 0x00c3, 0x4790: 0x00c0, 0x4791: 0x00c0, + 0x4792: 0x00c0, 0x4793: 0x00c0, 0x4794: 0x00c0, 0x4795: 0x00c0, 0x4796: 0x00c0, 0x4797: 0x00c0, + 0x4798: 0x00c0, 0x4799: 0x00c0, 0x479a: 0x00c0, 0x479b: 0x00c0, 0x479c: 0x00c0, 0x479d: 0x00c0, + 0x479e: 0x00c0, 0x479f: 0x00c0, 0x47a0: 0x00c0, 0x47a1: 0x00c0, 0x47a2: 0x00c0, 0x47a3: 0x00c0, + 0x47a4: 0x00c0, 0x47a5: 0x00c0, 0x47a6: 0x00c0, 0x47a7: 0x00c0, 0x47a8: 0x00c0, 0x47a9: 0x00c0, + 0x47aa: 0x00c0, 0x47ab: 0x00c0, 0x47ac: 0x00c0, 0x47ad: 0x00c0, 0x47ae: 0x00c0, 0x47af: 0x00c0, + 0x47b0: 0x00c0, 0x47b1: 0x00c0, 0x47b2: 0x00c0, 0x47b3: 0x00c0, 0x47b4: 0x00c0, 0x47b5: 0x00c0, + 0x47b6: 0x00c0, 0x47b7: 0x00c0, 0x47b8: 0x00c0, 0x47b9: 0x00c0, 0x47ba: 0x00c0, 0x47bb: 0x00c0, + 0x47bc: 0x00c0, 0x47bd: 0x00c0, 0x47be: 0x00c0, 0x47bf: 0x00c0, + // Block 0x11f, offset 0x47c0 + 0x47c0: 0x00c0, 0x47c1: 0x00c0, 0x47c2: 0x00c0, 0x47c3: 0x00c0, 0x47c4: 0x00c0, 0x47c5: 0x00c0, + 0x47c6: 0x00c0, 0x47c7: 0x00c0, + 0x47cf: 0x00c3, 0x47d0: 0x00c3, 0x47d1: 0x00c3, + 0x47d2: 0x00c3, 0x47d3: 0x00c0, 0x47d4: 0x00c0, 0x47d5: 0x00c0, 0x47d6: 0x00c0, 0x47d7: 0x00c0, + 0x47d8: 0x00c0, 0x47d9: 0x00c0, 0x47da: 0x00c0, 0x47db: 0x00c0, 0x47dc: 0x00c0, 0x47dd: 0x00c0, + 0x47de: 0x00c0, 0x47df: 0x00c0, + // Block 0x120, offset 0x4800 + 0x4820: 0x00c0, 0x4821: 0x00c0, 0x4822: 0x0080, 0x4823: 0x00c0, + 0x4824: 0x00c3, + 0x4830: 0x00cc, 0x4831: 0x00cc, + // Block 0x121, offset 0x4840 + 0x4840: 0x00c0, 0x4841: 0x00c0, 0x4842: 0x00c0, 0x4843: 0x00c0, 0x4844: 0x00c0, 0x4845: 0x00c0, + 0x4846: 0x00c0, 0x4847: 0x00c0, 0x4848: 0x00c0, 0x4849: 0x00c0, 0x484a: 0x00c0, 0x484b: 0x00c0, + 0x484c: 0x00c0, 0x484d: 0x00c0, 0x484e: 0x00c0, 0x484f: 0x00c0, 0x4850: 0x00c0, 0x4851: 0x00c0, + 0x4852: 0x00c0, 0x4853: 0x00c0, 0x4854: 0x00c0, 0x4855: 0x00c0, 0x4856: 0x00c0, 0x4857: 0x00c0, + 0x4858: 0x00c0, 0x4859: 0x00c0, 0x485a: 0x00c0, 0x485b: 0x00c0, 0x485c: 0x00c0, 0x485d: 0x00c0, + 0x485e: 0x00c0, 0x485f: 0x00c0, 0x4860: 0x00c0, 0x4861: 0x00c0, 0x4862: 0x00c0, 0x4863: 0x00c0, + 0x4864: 0x00c0, 0x4865: 0x00c0, 0x4866: 0x00c0, 0x4867: 0x00c0, 0x4868: 0x00c0, 0x4869: 0x00c0, + 0x486a: 0x00c0, 0x486b: 0x00c0, 0x486c: 0x00c0, 0x486d: 0x00c0, 0x486e: 0x00c0, 0x486f: 0x00c0, + 0x4870: 0x00c0, 0x4871: 0x00c0, 0x4872: 0x00c0, 0x4873: 0x00c0, 0x4874: 0x00c0, 0x4875: 0x00c0, + 0x4876: 0x00c0, 0x4877: 0x00c0, + // Block 0x122, offset 0x4880 + 0x4880: 0x00c0, 0x4881: 0x00c0, 0x4882: 0x00c0, 0x4883: 0x00c0, 0x4884: 0x00c0, 0x4885: 0x00c0, + 0x4886: 0x00c0, 0x4887: 0x00c0, 0x4888: 0x00c0, 0x4889: 0x00c0, 0x488a: 0x00c0, 0x488b: 0x00c0, + 0x488c: 0x00c0, 0x488d: 0x00c0, 0x488e: 0x00c0, 0x488f: 0x00c0, 0x4890: 0x00c0, 0x4891: 0x00c0, + 0x4892: 0x00c0, 0x4893: 0x00c0, 0x4894: 0x00c0, 0x4895: 0x00c0, + // Block 0x123, offset 0x48c0 + 0x48c0: 0x00cc, 0x48c1: 0x00cc, 0x48c2: 0x00cc, 0x48c3: 0x00cc, 0x48c4: 0x00cc, 0x48c5: 0x00cc, + 0x48c6: 0x00cc, 0x48c7: 0x00cc, 0x48c8: 0x00cc, 0x48c9: 0x00cc, 0x48ca: 0x00cc, 0x48cb: 0x00cc, + 0x48cc: 0x00cc, 0x48cd: 0x00cc, 0x48ce: 0x00cc, 0x48cf: 0x00cc, 0x48d0: 0x00cc, 0x48d1: 0x00cc, + 0x48d2: 0x00cc, 0x48d3: 0x00cc, 0x48d4: 0x00cc, 0x48d5: 0x00cc, 0x48d6: 0x00cc, 0x48d7: 0x00cc, + 0x48d8: 0x00cc, 0x48d9: 0x00cc, 0x48da: 0x00cc, 0x48db: 0x00cc, 0x48dc: 0x00cc, 0x48dd: 0x00cc, + 0x48de: 0x00cc, + // Block 0x124, offset 0x4900 + 0x4910: 0x00cc, 0x4911: 0x00cc, + 0x4912: 0x00cc, + 0x4924: 0x00cc, 0x4925: 0x00cc, 0x4926: 0x00cc, 0x4927: 0x00cc, + 0x4930: 0x00c0, 0x4931: 0x00c0, 0x4932: 0x00c0, 0x4933: 0x00c0, 0x4934: 0x00c0, 0x4935: 0x00c0, + 0x4936: 0x00c0, 0x4937: 0x00c0, 0x4938: 0x00c0, 0x4939: 0x00c0, 0x493a: 0x00c0, 0x493b: 0x00c0, + 0x493c: 0x00c0, 0x493d: 0x00c0, 0x493e: 0x00c0, 0x493f: 0x00c0, + // Block 0x125, offset 0x4940 + 0x4940: 0x00c0, 0x4941: 0x00c0, 0x4942: 0x00c0, 0x4943: 0x00c0, 0x4944: 0x00c0, 0x4945: 0x00c0, + 0x4946: 0x00c0, 0x4947: 0x00c0, 0x4948: 0x00c0, 0x4949: 0x00c0, 0x494a: 0x00c0, 0x494b: 0x00c0, + 0x494c: 0x00c0, 0x494d: 0x00c0, 0x494e: 0x00c0, 0x494f: 0x00c0, 0x4950: 0x00c0, 0x4951: 0x00c0, + 0x4952: 0x00c0, 0x4953: 0x00c0, 0x4954: 0x00c0, 0x4955: 0x00c0, 0x4956: 0x00c0, 0x4957: 0x00c0, + 0x4958: 0x00c0, 0x4959: 0x00c0, 0x495a: 0x00c0, 0x495b: 0x00c0, 0x495c: 0x00c0, 0x495d: 0x00c0, + 0x495e: 0x00c0, 0x495f: 0x00c0, 0x4960: 0x00c0, 0x4961: 0x00c0, 0x4962: 0x00c0, 0x4963: 0x00c0, + 0x4964: 0x00c0, 0x4965: 0x00c0, 0x4966: 0x00c0, 0x4967: 0x00c0, 0x4968: 0x00c0, 0x4969: 0x00c0, + 0x496a: 0x00c0, 0x496b: 0x00c0, 0x496c: 0x00c0, 0x496d: 0x00c0, 0x496e: 0x00c0, 0x496f: 0x00c0, + 0x4970: 0x00c0, 0x4971: 0x00c0, 0x4972: 0x00c0, 0x4973: 0x00c0, 0x4974: 0x00c0, 0x4975: 0x00c0, + 0x4976: 0x00c0, 0x4977: 0x00c0, 0x4978: 0x00c0, 0x4979: 0x00c0, 0x497a: 0x00c0, 0x497b: 0x00c0, + // Block 0x126, offset 0x4980 + 0x4980: 0x00c0, 0x4981: 0x00c0, 0x4982: 0x00c0, 0x4983: 0x00c0, 0x4984: 0x00c0, 0x4985: 0x00c0, + 0x4986: 0x00c0, 0x4987: 0x00c0, 0x4988: 0x00c0, 0x4989: 0x00c0, 0x498a: 0x00c0, 0x498b: 0x00c0, + 0x498c: 0x00c0, 0x498d: 0x00c0, 0x498e: 0x00c0, 0x498f: 0x00c0, 0x4990: 0x00c0, 0x4991: 0x00c0, + 0x4992: 0x00c0, 0x4993: 0x00c0, 0x4994: 0x00c0, 0x4995: 0x00c0, 0x4996: 0x00c0, 0x4997: 0x00c0, + 0x4998: 0x00c0, 0x4999: 0x00c0, 0x499a: 0x00c0, 0x499b: 0x00c0, 0x499c: 0x00c0, 0x499d: 0x00c0, + 0x499e: 0x00c0, 0x499f: 0x00c0, 0x49a0: 0x00c0, 0x49a1: 0x00c0, 0x49a2: 0x00c0, 0x49a3: 0x00c0, + 0x49a4: 0x00c0, 0x49a5: 0x00c0, 0x49a6: 0x00c0, 0x49a7: 0x00c0, 0x49a8: 0x00c0, 0x49a9: 0x00c0, + 0x49aa: 0x00c0, + 0x49b0: 0x00c0, 0x49b1: 0x00c0, 0x49b2: 0x00c0, 0x49b3: 0x00c0, 0x49b4: 0x00c0, 0x49b5: 0x00c0, + 0x49b6: 0x00c0, 0x49b7: 0x00c0, 0x49b8: 0x00c0, 0x49b9: 0x00c0, 0x49ba: 0x00c0, 0x49bb: 0x00c0, + 0x49bc: 0x00c0, + // Block 0x127, offset 0x49c0 + 0x49c0: 0x00c0, 0x49c1: 0x00c0, 0x49c2: 0x00c0, 0x49c3: 0x00c0, 0x49c4: 0x00c0, 0x49c5: 0x00c0, + 0x49c6: 0x00c0, 0x49c7: 0x00c0, 0x49c8: 0x00c0, + 0x49d0: 0x00c0, 0x49d1: 0x00c0, + 0x49d2: 0x00c0, 0x49d3: 0x00c0, 0x49d4: 0x00c0, 0x49d5: 0x00c0, 0x49d6: 0x00c0, 0x49d7: 0x00c0, + 0x49d8: 0x00c0, 0x49d9: 0x00c0, 0x49dc: 0x0080, 0x49dd: 0x00c3, + 0x49de: 0x00c3, 0x49df: 0x0080, 0x49e0: 0x0040, 0x49e1: 0x0040, 0x49e2: 0x0040, 0x49e3: 0x0040, + // Block 0x128, offset 0x4a00 + 0x4a00: 0x0080, 0x4a01: 0x0080, 0x4a02: 0x0080, 0x4a03: 0x0080, 0x4a04: 0x0080, 0x4a05: 0x0080, + 0x4a06: 0x0080, 0x4a07: 0x0080, 0x4a08: 0x0080, 0x4a09: 0x0080, 0x4a0a: 0x0080, 0x4a0b: 0x0080, + 0x4a0c: 0x0080, 0x4a0d: 0x0080, 0x4a0e: 0x0080, 0x4a0f: 0x0080, 0x4a10: 0x0080, 0x4a11: 0x0080, + 0x4a12: 0x0080, 0x4a13: 0x0080, 0x4a14: 0x0080, 0x4a15: 0x0080, 0x4a16: 0x0080, 0x4a17: 0x0080, + 0x4a18: 0x0080, 0x4a19: 0x0080, 0x4a1a: 0x0080, 0x4a1b: 0x0080, 0x4a1c: 0x0080, 0x4a1d: 0x0080, + 0x4a1e: 0x0080, 0x4a1f: 0x0080, 0x4a20: 0x0080, 0x4a21: 0x0080, 0x4a22: 0x0080, 0x4a23: 0x0080, + 0x4a24: 0x0080, 0x4a25: 0x0080, 0x4a26: 0x0080, 0x4a27: 0x0080, 0x4a28: 0x0080, 0x4a29: 0x0080, + 0x4a2a: 0x0080, 0x4a2b: 0x0080, 0x4a2c: 0x0080, 0x4a2d: 0x0080, 0x4a2e: 0x0080, 0x4a2f: 0x0080, + 0x4a30: 0x0080, 0x4a31: 0x0080, 0x4a32: 0x0080, 0x4a33: 0x0080, 0x4a34: 0x0080, 0x4a35: 0x0080, + // Block 0x129, offset 0x4a40 + 0x4a40: 0x0080, 0x4a41: 0x0080, 0x4a42: 0x0080, 0x4a43: 0x0080, 0x4a44: 0x0080, 0x4a45: 0x0080, + 0x4a46: 0x0080, 0x4a47: 0x0080, 0x4a48: 0x0080, 0x4a49: 0x0080, 0x4a4a: 0x0080, 0x4a4b: 0x0080, + 0x4a4c: 0x0080, 0x4a4d: 0x0080, 0x4a4e: 0x0080, 0x4a4f: 0x0080, 0x4a50: 0x0080, 0x4a51: 0x0080, + 0x4a52: 0x0080, 0x4a53: 0x0080, 0x4a54: 0x0080, 0x4a55: 0x0080, 0x4a56: 0x0080, 0x4a57: 0x0080, + 0x4a58: 0x0080, 0x4a59: 0x0080, 0x4a5a: 0x0080, 0x4a5b: 0x0080, 0x4a5c: 0x0080, 0x4a5d: 0x0080, + 0x4a5e: 0x0080, 0x4a5f: 0x0080, 0x4a60: 0x0080, 0x4a61: 0x0080, 0x4a62: 0x0080, 0x4a63: 0x0080, + 0x4a64: 0x0080, 0x4a65: 0x0080, 0x4a66: 0x0080, 0x4a69: 0x0080, + 0x4a6a: 0x0080, 0x4a6b: 0x0080, 0x4a6c: 0x0080, 0x4a6d: 0x0080, 0x4a6e: 0x0080, 0x4a6f: 0x0080, + 0x4a70: 0x0080, 0x4a71: 0x0080, 0x4a72: 0x0080, 0x4a73: 0x0080, 0x4a74: 0x0080, 0x4a75: 0x0080, + 0x4a76: 0x0080, 0x4a77: 0x0080, 0x4a78: 0x0080, 0x4a79: 0x0080, 0x4a7a: 0x0080, 0x4a7b: 0x0080, + 0x4a7c: 0x0080, 0x4a7d: 0x0080, 0x4a7e: 0x0080, 0x4a7f: 0x0080, + // Block 0x12a, offset 0x4a80 + 0x4a80: 0x0080, 0x4a81: 0x0080, 0x4a82: 0x0080, 0x4a83: 0x0080, 0x4a84: 0x0080, 0x4a85: 0x0080, + 0x4a86: 0x0080, 0x4a87: 0x0080, 0x4a88: 0x0080, 0x4a89: 0x0080, 0x4a8a: 0x0080, 0x4a8b: 0x0080, + 0x4a8c: 0x0080, 0x4a8d: 0x0080, 0x4a8e: 0x0080, 0x4a8f: 0x0080, 0x4a90: 0x0080, 0x4a91: 0x0080, + 0x4a92: 0x0080, 0x4a93: 0x0080, 0x4a94: 0x0080, 0x4a95: 0x0080, 0x4a96: 0x0080, 0x4a97: 0x0080, + 0x4a98: 0x0080, 0x4a99: 0x0080, 0x4a9a: 0x0080, 0x4a9b: 0x0080, 0x4a9c: 0x0080, 0x4a9d: 0x0080, + 0x4a9e: 0x0080, 0x4a9f: 0x0080, 0x4aa0: 0x0080, 0x4aa1: 0x0080, 0x4aa2: 0x0080, 0x4aa3: 0x0080, + 0x4aa4: 0x0080, 0x4aa5: 0x00c0, 0x4aa6: 0x00c0, 0x4aa7: 0x00c3, 0x4aa8: 0x00c3, 0x4aa9: 0x00c3, + 0x4aaa: 0x0080, 0x4aab: 0x0080, 0x4aac: 0x0080, 0x4aad: 0x00c0, 0x4aae: 0x00c0, 0x4aaf: 0x00c0, + 0x4ab0: 0x00c0, 0x4ab1: 0x00c0, 0x4ab2: 0x00c0, 0x4ab3: 0x0040, 0x4ab4: 0x0040, 0x4ab5: 0x0040, + 0x4ab6: 0x0040, 0x4ab7: 0x0040, 0x4ab8: 0x0040, 0x4ab9: 0x0040, 0x4aba: 0x0040, 0x4abb: 0x00c3, + 0x4abc: 0x00c3, 0x4abd: 0x00c3, 0x4abe: 0x00c3, 0x4abf: 0x00c3, + // Block 0x12b, offset 0x4ac0 + 0x4ac0: 0x00c3, 0x4ac1: 0x00c3, 0x4ac2: 0x00c3, 0x4ac3: 0x0080, 0x4ac4: 0x0080, 0x4ac5: 0x00c3, + 0x4ac6: 0x00c3, 0x4ac7: 0x00c3, 0x4ac8: 0x00c3, 0x4ac9: 0x00c3, 0x4aca: 0x00c3, 0x4acb: 0x00c3, + 0x4acc: 0x0080, 0x4acd: 0x0080, 0x4ace: 0x0080, 0x4acf: 0x0080, 0x4ad0: 0x0080, 0x4ad1: 0x0080, + 0x4ad2: 0x0080, 0x4ad3: 0x0080, 0x4ad4: 0x0080, 0x4ad5: 0x0080, 0x4ad6: 0x0080, 0x4ad7: 0x0080, + 0x4ad8: 0x0080, 0x4ad9: 0x0080, 0x4ada: 0x0080, 0x4adb: 0x0080, 0x4adc: 0x0080, 0x4add: 0x0080, + 0x4ade: 0x0080, 0x4adf: 0x0080, 0x4ae0: 0x0080, 0x4ae1: 0x0080, 0x4ae2: 0x0080, 0x4ae3: 0x0080, + 0x4ae4: 0x0080, 0x4ae5: 0x0080, 0x4ae6: 0x0080, 0x4ae7: 0x0080, 0x4ae8: 0x0080, 0x4ae9: 0x0080, + 0x4aea: 0x00c3, 0x4aeb: 0x00c3, 0x4aec: 0x00c3, 0x4aed: 0x00c3, 0x4aee: 0x0080, 0x4aef: 0x0080, + 0x4af0: 0x0080, 0x4af1: 0x0080, 0x4af2: 0x0080, 0x4af3: 0x0080, 0x4af4: 0x0080, 0x4af5: 0x0080, + 0x4af6: 0x0080, 0x4af7: 0x0080, 0x4af8: 0x0080, 0x4af9: 0x0080, 0x4afa: 0x0080, 0x4afb: 0x0080, + 0x4afc: 0x0080, 0x4afd: 0x0080, 0x4afe: 0x0080, 0x4aff: 0x0080, + // Block 0x12c, offset 0x4b00 + 0x4b00: 0x0080, 0x4b01: 0x0080, 0x4b02: 0x0080, 0x4b03: 0x0080, 0x4b04: 0x0080, 0x4b05: 0x0080, + 0x4b06: 0x0080, 0x4b07: 0x0080, 0x4b08: 0x0080, 0x4b09: 0x0080, 0x4b0a: 0x0080, 0x4b0b: 0x0080, + 0x4b0c: 0x0080, 0x4b0d: 0x0080, 0x4b0e: 0x0080, 0x4b0f: 0x0080, 0x4b10: 0x0080, 0x4b11: 0x0080, + 0x4b12: 0x0080, 0x4b13: 0x0080, 0x4b14: 0x0080, 0x4b15: 0x0080, 0x4b16: 0x0080, 0x4b17: 0x0080, + 0x4b18: 0x0080, 0x4b19: 0x0080, 0x4b1a: 0x0080, 0x4b1b: 0x0080, 0x4b1c: 0x0080, 0x4b1d: 0x0080, + 0x4b1e: 0x0080, 0x4b1f: 0x0080, 0x4b20: 0x0080, 0x4b21: 0x0080, 0x4b22: 0x0080, 0x4b23: 0x0080, + 0x4b24: 0x0080, 0x4b25: 0x0080, 0x4b26: 0x0080, 0x4b27: 0x0080, 0x4b28: 0x0080, + // Block 0x12d, offset 0x4b40 + 0x4b40: 0x0088, 0x4b41: 0x0088, 0x4b42: 0x00c9, 0x4b43: 0x00c9, 0x4b44: 0x00c9, 0x4b45: 0x0088, + // Block 0x12e, offset 0x4b80 + 0x4ba0: 0x0080, 0x4ba1: 0x0080, 0x4ba2: 0x0080, 0x4ba3: 0x0080, + 0x4ba4: 0x0080, 0x4ba5: 0x0080, 0x4ba6: 0x0080, 0x4ba7: 0x0080, 0x4ba8: 0x0080, 0x4ba9: 0x0080, + 0x4baa: 0x0080, 0x4bab: 0x0080, 0x4bac: 0x0080, 0x4bad: 0x0080, 0x4bae: 0x0080, 0x4baf: 0x0080, + 0x4bb0: 0x0080, 0x4bb1: 0x0080, 0x4bb2: 0x0080, 0x4bb3: 0x0080, + // Block 0x12f, offset 0x4bc0 + 0x4bc0: 0x0080, 0x4bc1: 0x0080, 0x4bc2: 0x0080, 0x4bc3: 0x0080, 0x4bc4: 0x0080, 0x4bc5: 0x0080, + 0x4bc6: 0x0080, 0x4bc7: 0x0080, 0x4bc8: 0x0080, 0x4bc9: 0x0080, 0x4bca: 0x0080, 0x4bcb: 0x0080, + 0x4bcc: 0x0080, 0x4bcd: 0x0080, 0x4bce: 0x0080, 0x4bcf: 0x0080, 0x4bd0: 0x0080, 0x4bd1: 0x0080, + 0x4bd2: 0x0080, 0x4bd3: 0x0080, 0x4bd4: 0x0080, 0x4bd5: 0x0080, 0x4bd6: 0x0080, + 0x4be0: 0x0080, 0x4be1: 0x0080, 0x4be2: 0x0080, 0x4be3: 0x0080, + 0x4be4: 0x0080, 0x4be5: 0x0080, 0x4be6: 0x0080, 0x4be7: 0x0080, 0x4be8: 0x0080, 0x4be9: 0x0080, + 0x4bea: 0x0080, 0x4beb: 0x0080, 0x4bec: 0x0080, 0x4bed: 0x0080, 0x4bee: 0x0080, 0x4bef: 0x0080, + 0x4bf0: 0x0080, 0x4bf1: 0x0080, 0x4bf2: 0x0080, 0x4bf3: 0x0080, 0x4bf4: 0x0080, 0x4bf5: 0x0080, + 0x4bf6: 0x0080, 0x4bf7: 0x0080, 0x4bf8: 0x0080, + // Block 0x130, offset 0x4c00 + 0x4c00: 0x0080, 0x4c01: 0x0080, 0x4c02: 0x0080, 0x4c03: 0x0080, 0x4c04: 0x0080, 0x4c05: 0x0080, + 0x4c06: 0x0080, 0x4c07: 0x0080, 0x4c08: 0x0080, 0x4c09: 0x0080, 0x4c0a: 0x0080, 0x4c0b: 0x0080, + 0x4c0c: 0x0080, 0x4c0d: 0x0080, 0x4c0e: 0x0080, 0x4c0f: 0x0080, 0x4c10: 0x0080, 0x4c11: 0x0080, + 0x4c12: 0x0080, 0x4c13: 0x0080, 0x4c14: 0x0080, 0x4c16: 0x0080, 0x4c17: 0x0080, + 0x4c18: 0x0080, 0x4c19: 0x0080, 0x4c1a: 0x0080, 0x4c1b: 0x0080, 0x4c1c: 0x0080, 0x4c1d: 0x0080, + 0x4c1e: 0x0080, 0x4c1f: 0x0080, 0x4c20: 0x0080, 0x4c21: 0x0080, 0x4c22: 0x0080, 0x4c23: 0x0080, + 0x4c24: 0x0080, 0x4c25: 0x0080, 0x4c26: 0x0080, 0x4c27: 0x0080, 0x4c28: 0x0080, 0x4c29: 0x0080, + 0x4c2a: 0x0080, 0x4c2b: 0x0080, 0x4c2c: 0x0080, 0x4c2d: 0x0080, 0x4c2e: 0x0080, 0x4c2f: 0x0080, + 0x4c30: 0x0080, 0x4c31: 0x0080, 0x4c32: 0x0080, 0x4c33: 0x0080, 0x4c34: 0x0080, 0x4c35: 0x0080, + 0x4c36: 0x0080, 0x4c37: 0x0080, 0x4c38: 0x0080, 0x4c39: 0x0080, 0x4c3a: 0x0080, 0x4c3b: 0x0080, + 0x4c3c: 0x0080, 0x4c3d: 0x0080, 0x4c3e: 0x0080, 0x4c3f: 0x0080, + // Block 0x131, offset 0x4c40 + 0x4c40: 0x0080, 0x4c41: 0x0080, 0x4c42: 0x0080, 0x4c43: 0x0080, 0x4c44: 0x0080, 0x4c45: 0x0080, + 0x4c46: 0x0080, 0x4c47: 0x0080, 0x4c48: 0x0080, 0x4c49: 0x0080, 0x4c4a: 0x0080, 0x4c4b: 0x0080, + 0x4c4c: 0x0080, 0x4c4d: 0x0080, 0x4c4e: 0x0080, 0x4c4f: 0x0080, 0x4c50: 0x0080, 0x4c51: 0x0080, + 0x4c52: 0x0080, 0x4c53: 0x0080, 0x4c54: 0x0080, 0x4c55: 0x0080, 0x4c56: 0x0080, 0x4c57: 0x0080, + 0x4c58: 0x0080, 0x4c59: 0x0080, 0x4c5a: 0x0080, 0x4c5b: 0x0080, 0x4c5c: 0x0080, + 0x4c5e: 0x0080, 0x4c5f: 0x0080, 0x4c62: 0x0080, + 0x4c65: 0x0080, 0x4c66: 0x0080, 0x4c69: 0x0080, + 0x4c6a: 0x0080, 0x4c6b: 0x0080, 0x4c6c: 0x0080, 0x4c6e: 0x0080, 0x4c6f: 0x0080, + 0x4c70: 0x0080, 0x4c71: 0x0080, 0x4c72: 0x0080, 0x4c73: 0x0080, 0x4c74: 0x0080, 0x4c75: 0x0080, + 0x4c76: 0x0080, 0x4c77: 0x0080, 0x4c78: 0x0080, 0x4c79: 0x0080, 0x4c7b: 0x0080, + 0x4c7d: 0x0080, 0x4c7e: 0x0080, 0x4c7f: 0x0080, + // Block 0x132, offset 0x4c80 + 0x4c80: 0x0080, 0x4c81: 0x0080, 0x4c82: 0x0080, 0x4c83: 0x0080, 0x4c85: 0x0080, + 0x4c86: 0x0080, 0x4c87: 0x0080, 0x4c88: 0x0080, 0x4c89: 0x0080, 0x4c8a: 0x0080, 0x4c8b: 0x0080, + 0x4c8c: 0x0080, 0x4c8d: 0x0080, 0x4c8e: 0x0080, 0x4c8f: 0x0080, 0x4c90: 0x0080, 0x4c91: 0x0080, + 0x4c92: 0x0080, 0x4c93: 0x0080, 0x4c94: 0x0080, 0x4c95: 0x0080, 0x4c96: 0x0080, 0x4c97: 0x0080, + 0x4c98: 0x0080, 0x4c99: 0x0080, 0x4c9a: 0x0080, 0x4c9b: 0x0080, 0x4c9c: 0x0080, 0x4c9d: 0x0080, + 0x4c9e: 0x0080, 0x4c9f: 0x0080, 0x4ca0: 0x0080, 0x4ca1: 0x0080, 0x4ca2: 0x0080, 0x4ca3: 0x0080, + 0x4ca4: 0x0080, 0x4ca5: 0x0080, 0x4ca6: 0x0080, 0x4ca7: 0x0080, 0x4ca8: 0x0080, 0x4ca9: 0x0080, + 0x4caa: 0x0080, 0x4cab: 0x0080, 0x4cac: 0x0080, 0x4cad: 0x0080, 0x4cae: 0x0080, 0x4caf: 0x0080, + 0x4cb0: 0x0080, 0x4cb1: 0x0080, 0x4cb2: 0x0080, 0x4cb3: 0x0080, 0x4cb4: 0x0080, 0x4cb5: 0x0080, + 0x4cb6: 0x0080, 0x4cb7: 0x0080, 0x4cb8: 0x0080, 0x4cb9: 0x0080, 0x4cba: 0x0080, 0x4cbb: 0x0080, + 0x4cbc: 0x0080, 0x4cbd: 0x0080, 0x4cbe: 0x0080, 0x4cbf: 0x0080, + // Block 0x133, offset 0x4cc0 + 0x4cc0: 0x0080, 0x4cc1: 0x0080, 0x4cc2: 0x0080, 0x4cc3: 0x0080, 0x4cc4: 0x0080, 0x4cc5: 0x0080, + 0x4cc7: 0x0080, 0x4cc8: 0x0080, 0x4cc9: 0x0080, 0x4cca: 0x0080, + 0x4ccd: 0x0080, 0x4cce: 0x0080, 0x4ccf: 0x0080, 0x4cd0: 0x0080, 0x4cd1: 0x0080, + 0x4cd2: 0x0080, 0x4cd3: 0x0080, 0x4cd4: 0x0080, 0x4cd6: 0x0080, 0x4cd7: 0x0080, + 0x4cd8: 0x0080, 0x4cd9: 0x0080, 0x4cda: 0x0080, 0x4cdb: 0x0080, 0x4cdc: 0x0080, + 0x4cde: 0x0080, 0x4cdf: 0x0080, 0x4ce0: 0x0080, 0x4ce1: 0x0080, 0x4ce2: 0x0080, 0x4ce3: 0x0080, + 0x4ce4: 0x0080, 0x4ce5: 0x0080, 0x4ce6: 0x0080, 0x4ce7: 0x0080, 0x4ce8: 0x0080, 0x4ce9: 0x0080, + 0x4cea: 0x0080, 0x4ceb: 0x0080, 0x4cec: 0x0080, 0x4ced: 0x0080, 0x4cee: 0x0080, 0x4cef: 0x0080, + 0x4cf0: 0x0080, 0x4cf1: 0x0080, 0x4cf2: 0x0080, 0x4cf3: 0x0080, 0x4cf4: 0x0080, 0x4cf5: 0x0080, + 0x4cf6: 0x0080, 0x4cf7: 0x0080, 0x4cf8: 0x0080, 0x4cf9: 0x0080, 0x4cfb: 0x0080, + 0x4cfc: 0x0080, 0x4cfd: 0x0080, 0x4cfe: 0x0080, + // Block 0x134, offset 0x4d00 + 0x4d00: 0x0080, 0x4d01: 0x0080, 0x4d02: 0x0080, 0x4d03: 0x0080, 0x4d04: 0x0080, + 0x4d06: 0x0080, 0x4d0a: 0x0080, 0x4d0b: 0x0080, + 0x4d0c: 0x0080, 0x4d0d: 0x0080, 0x4d0e: 0x0080, 0x4d0f: 0x0080, 0x4d10: 0x0080, + 0x4d12: 0x0080, 0x4d13: 0x0080, 0x4d14: 0x0080, 0x4d15: 0x0080, 0x4d16: 0x0080, 0x4d17: 0x0080, + 0x4d18: 0x0080, 0x4d19: 0x0080, 0x4d1a: 0x0080, 0x4d1b: 0x0080, 0x4d1c: 0x0080, 0x4d1d: 0x0080, + 0x4d1e: 0x0080, 0x4d1f: 0x0080, 0x4d20: 0x0080, 0x4d21: 0x0080, 0x4d22: 0x0080, 0x4d23: 0x0080, + 0x4d24: 0x0080, 0x4d25: 0x0080, 0x4d26: 0x0080, 0x4d27: 0x0080, 0x4d28: 0x0080, 0x4d29: 0x0080, + 0x4d2a: 0x0080, 0x4d2b: 0x0080, 0x4d2c: 0x0080, 0x4d2d: 0x0080, 0x4d2e: 0x0080, 0x4d2f: 0x0080, + 0x4d30: 0x0080, 0x4d31: 0x0080, 0x4d32: 0x0080, 0x4d33: 0x0080, 0x4d34: 0x0080, 0x4d35: 0x0080, + 0x4d36: 0x0080, 0x4d37: 0x0080, 0x4d38: 0x0080, 0x4d39: 0x0080, 0x4d3a: 0x0080, 0x4d3b: 0x0080, + 0x4d3c: 0x0080, 0x4d3d: 0x0080, 0x4d3e: 0x0080, 0x4d3f: 0x0080, + // Block 0x135, offset 0x4d40 + 0x4d40: 0x0080, 0x4d41: 0x0080, 0x4d42: 0x0080, 0x4d43: 0x0080, 0x4d44: 0x0080, 0x4d45: 0x0080, + 0x4d46: 0x0080, 0x4d47: 0x0080, 0x4d48: 0x0080, 0x4d49: 0x0080, 0x4d4a: 0x0080, 0x4d4b: 0x0080, + 0x4d4c: 0x0080, 0x4d4d: 0x0080, 0x4d4e: 0x0080, 0x4d4f: 0x0080, 0x4d50: 0x0080, 0x4d51: 0x0080, + 0x4d52: 0x0080, 0x4d53: 0x0080, 0x4d54: 0x0080, 0x4d55: 0x0080, 0x4d56: 0x0080, 0x4d57: 0x0080, + 0x4d58: 0x0080, 0x4d59: 0x0080, 0x4d5a: 0x0080, 0x4d5b: 0x0080, 0x4d5c: 0x0080, 0x4d5d: 0x0080, + 0x4d5e: 0x0080, 0x4d5f: 0x0080, 0x4d60: 0x0080, 0x4d61: 0x0080, 0x4d62: 0x0080, 0x4d63: 0x0080, + 0x4d64: 0x0080, 0x4d65: 0x0080, 0x4d68: 0x0080, 0x4d69: 0x0080, + 0x4d6a: 0x0080, 0x4d6b: 0x0080, 0x4d6c: 0x0080, 0x4d6d: 0x0080, 0x4d6e: 0x0080, 0x4d6f: 0x0080, + 0x4d70: 0x0080, 0x4d71: 0x0080, 0x4d72: 0x0080, 0x4d73: 0x0080, 0x4d74: 0x0080, 0x4d75: 0x0080, + 0x4d76: 0x0080, 0x4d77: 0x0080, 0x4d78: 0x0080, 0x4d79: 0x0080, 0x4d7a: 0x0080, 0x4d7b: 0x0080, + 0x4d7c: 0x0080, 0x4d7d: 0x0080, 0x4d7e: 0x0080, 0x4d7f: 0x0080, + // Block 0x136, offset 0x4d80 + 0x4d80: 0x0080, 0x4d81: 0x0080, 0x4d82: 0x0080, 0x4d83: 0x0080, 0x4d84: 0x0080, 0x4d85: 0x0080, + 0x4d86: 0x0080, 0x4d87: 0x0080, 0x4d88: 0x0080, 0x4d89: 0x0080, 0x4d8a: 0x0080, 0x4d8b: 0x0080, + 0x4d8e: 0x0080, 0x4d8f: 0x0080, 0x4d90: 0x0080, 0x4d91: 0x0080, + 0x4d92: 0x0080, 0x4d93: 0x0080, 0x4d94: 0x0080, 0x4d95: 0x0080, 0x4d96: 0x0080, 0x4d97: 0x0080, + 0x4d98: 0x0080, 0x4d99: 0x0080, 0x4d9a: 0x0080, 0x4d9b: 0x0080, 0x4d9c: 0x0080, 0x4d9d: 0x0080, + 0x4d9e: 0x0080, 0x4d9f: 0x0080, 0x4da0: 0x0080, 0x4da1: 0x0080, 0x4da2: 0x0080, 0x4da3: 0x0080, + 0x4da4: 0x0080, 0x4da5: 0x0080, 0x4da6: 0x0080, 0x4da7: 0x0080, 0x4da8: 0x0080, 0x4da9: 0x0080, + 0x4daa: 0x0080, 0x4dab: 0x0080, 0x4dac: 0x0080, 0x4dad: 0x0080, 0x4dae: 0x0080, 0x4daf: 0x0080, + 0x4db0: 0x0080, 0x4db1: 0x0080, 0x4db2: 0x0080, 0x4db3: 0x0080, 0x4db4: 0x0080, 0x4db5: 0x0080, + 0x4db6: 0x0080, 0x4db7: 0x0080, 0x4db8: 0x0080, 0x4db9: 0x0080, 0x4dba: 0x0080, 0x4dbb: 0x0080, + 0x4dbc: 0x0080, 0x4dbd: 0x0080, 0x4dbe: 0x0080, 0x4dbf: 0x0080, + // Block 0x137, offset 0x4dc0 + 0x4dc0: 0x00c3, 0x4dc1: 0x00c3, 0x4dc2: 0x00c3, 0x4dc3: 0x00c3, 0x4dc4: 0x00c3, 0x4dc5: 0x00c3, + 0x4dc6: 0x00c3, 0x4dc7: 0x00c3, 0x4dc8: 0x00c3, 0x4dc9: 0x00c3, 0x4dca: 0x00c3, 0x4dcb: 0x00c3, + 0x4dcc: 0x00c3, 0x4dcd: 0x00c3, 0x4dce: 0x00c3, 0x4dcf: 0x00c3, 0x4dd0: 0x00c3, 0x4dd1: 0x00c3, + 0x4dd2: 0x00c3, 0x4dd3: 0x00c3, 0x4dd4: 0x00c3, 0x4dd5: 0x00c3, 0x4dd6: 0x00c3, 0x4dd7: 0x00c3, + 0x4dd8: 0x00c3, 0x4dd9: 0x00c3, 0x4dda: 0x00c3, 0x4ddb: 0x00c3, 0x4ddc: 0x00c3, 0x4ddd: 0x00c3, + 0x4dde: 0x00c3, 0x4ddf: 0x00c3, 0x4de0: 0x00c3, 0x4de1: 0x00c3, 0x4de2: 0x00c3, 0x4de3: 0x00c3, + 0x4de4: 0x00c3, 0x4de5: 0x00c3, 0x4de6: 0x00c3, 0x4de7: 0x00c3, 0x4de8: 0x00c3, 0x4de9: 0x00c3, + 0x4dea: 0x00c3, 0x4deb: 0x00c3, 0x4dec: 0x00c3, 0x4ded: 0x00c3, 0x4dee: 0x00c3, 0x4def: 0x00c3, + 0x4df0: 0x00c3, 0x4df1: 0x00c3, 0x4df2: 0x00c3, 0x4df3: 0x00c3, 0x4df4: 0x00c3, 0x4df5: 0x00c3, + 0x4df6: 0x00c3, 0x4df7: 0x0080, 0x4df8: 0x0080, 0x4df9: 0x0080, 0x4dfa: 0x0080, 0x4dfb: 0x00c3, + 0x4dfc: 0x00c3, 0x4dfd: 0x00c3, 0x4dfe: 0x00c3, 0x4dff: 0x00c3, + // Block 0x138, offset 0x4e00 + 0x4e00: 0x00c3, 0x4e01: 0x00c3, 0x4e02: 0x00c3, 0x4e03: 0x00c3, 0x4e04: 0x00c3, 0x4e05: 0x00c3, + 0x4e06: 0x00c3, 0x4e07: 0x00c3, 0x4e08: 0x00c3, 0x4e09: 0x00c3, 0x4e0a: 0x00c3, 0x4e0b: 0x00c3, + 0x4e0c: 0x00c3, 0x4e0d: 0x00c3, 0x4e0e: 0x00c3, 0x4e0f: 0x00c3, 0x4e10: 0x00c3, 0x4e11: 0x00c3, + 0x4e12: 0x00c3, 0x4e13: 0x00c3, 0x4e14: 0x00c3, 0x4e15: 0x00c3, 0x4e16: 0x00c3, 0x4e17: 0x00c3, + 0x4e18: 0x00c3, 0x4e19: 0x00c3, 0x4e1a: 0x00c3, 0x4e1b: 0x00c3, 0x4e1c: 0x00c3, 0x4e1d: 0x00c3, + 0x4e1e: 0x00c3, 0x4e1f: 0x00c3, 0x4e20: 0x00c3, 0x4e21: 0x00c3, 0x4e22: 0x00c3, 0x4e23: 0x00c3, + 0x4e24: 0x00c3, 0x4e25: 0x00c3, 0x4e26: 0x00c3, 0x4e27: 0x00c3, 0x4e28: 0x00c3, 0x4e29: 0x00c3, + 0x4e2a: 0x00c3, 0x4e2b: 0x00c3, 0x4e2c: 0x00c3, 0x4e2d: 0x0080, 0x4e2e: 0x0080, 0x4e2f: 0x0080, + 0x4e30: 0x0080, 0x4e31: 0x0080, 0x4e32: 0x0080, 0x4e33: 0x0080, 0x4e34: 0x0080, 0x4e35: 0x00c3, + 0x4e36: 0x0080, 0x4e37: 0x0080, 0x4e38: 0x0080, 0x4e39: 0x0080, 0x4e3a: 0x0080, 0x4e3b: 0x0080, + 0x4e3c: 0x0080, 0x4e3d: 0x0080, 0x4e3e: 0x0080, 0x4e3f: 0x0080, + // Block 0x139, offset 0x4e40 + 0x4e40: 0x0080, 0x4e41: 0x0080, 0x4e42: 0x0080, 0x4e43: 0x0080, 0x4e44: 0x00c3, 0x4e45: 0x0080, + 0x4e46: 0x0080, 0x4e47: 0x0080, 0x4e48: 0x0080, 0x4e49: 0x0080, 0x4e4a: 0x0080, 0x4e4b: 0x0080, + 0x4e5b: 0x00c3, 0x4e5c: 0x00c3, 0x4e5d: 0x00c3, + 0x4e5e: 0x00c3, 0x4e5f: 0x00c3, 0x4e61: 0x00c3, 0x4e62: 0x00c3, 0x4e63: 0x00c3, + 0x4e64: 0x00c3, 0x4e65: 0x00c3, 0x4e66: 0x00c3, 0x4e67: 0x00c3, 0x4e68: 0x00c3, 0x4e69: 0x00c3, + 0x4e6a: 0x00c3, 0x4e6b: 0x00c3, 0x4e6c: 0x00c3, 0x4e6d: 0x00c3, 0x4e6e: 0x00c3, 0x4e6f: 0x00c3, + // Block 0x13a, offset 0x4e80 + 0x4e80: 0x00c3, 0x4e81: 0x00c3, 0x4e82: 0x00c3, 0x4e83: 0x00c3, 0x4e84: 0x00c3, 0x4e85: 0x00c3, + 0x4e86: 0x00c3, 0x4e88: 0x00c3, 0x4e89: 0x00c3, 0x4e8a: 0x00c3, 0x4e8b: 0x00c3, + 0x4e8c: 0x00c3, 0x4e8d: 0x00c3, 0x4e8e: 0x00c3, 0x4e8f: 0x00c3, 0x4e90: 0x00c3, 0x4e91: 0x00c3, + 0x4e92: 0x00c3, 0x4e93: 0x00c3, 0x4e94: 0x00c3, 0x4e95: 0x00c3, 0x4e96: 0x00c3, 0x4e97: 0x00c3, + 0x4e98: 0x00c3, 0x4e9b: 0x00c3, 0x4e9c: 0x00c3, 0x4e9d: 0x00c3, + 0x4e9e: 0x00c3, 0x4e9f: 0x00c3, 0x4ea0: 0x00c3, 0x4ea1: 0x00c3, 0x4ea3: 0x00c3, + 0x4ea4: 0x00c3, 0x4ea6: 0x00c3, 0x4ea7: 0x00c3, 0x4ea8: 0x00c3, 0x4ea9: 0x00c3, + 0x4eaa: 0x00c3, + // Block 0x13b, offset 0x4ec0 + 0x4ec0: 0x00c0, 0x4ec1: 0x00c0, 0x4ec2: 0x00c0, 0x4ec3: 0x00c0, 0x4ec4: 0x00c0, 0x4ec5: 0x00c0, + 0x4ec6: 0x00c0, 0x4ec7: 0x00c0, 0x4ec8: 0x00c0, 0x4ec9: 0x00c0, 0x4eca: 0x00c0, 0x4ecb: 0x00c0, + 0x4ecc: 0x00c0, 0x4ecd: 0x00c0, 0x4ece: 0x00c0, 0x4ecf: 0x00c0, 0x4ed0: 0x00c0, 0x4ed1: 0x00c0, + 0x4ed2: 0x00c0, 0x4ed3: 0x00c0, 0x4ed4: 0x00c0, 0x4ed5: 0x00c0, 0x4ed6: 0x00c0, 0x4ed7: 0x00c0, + 0x4ed8: 0x00c0, 0x4ed9: 0x00c0, 0x4eda: 0x00c0, 0x4edb: 0x00c0, 0x4edc: 0x00c0, 0x4edd: 0x00c0, + 0x4ede: 0x00c0, 0x4edf: 0x00c0, 0x4ee0: 0x00c0, 0x4ee1: 0x00c0, 0x4ee2: 0x00c0, 0x4ee3: 0x00c0, + 0x4ee4: 0x00c0, 0x4ee5: 0x00c0, 0x4ee6: 0x00c0, 0x4ee7: 0x00c0, 0x4ee8: 0x00c0, 0x4ee9: 0x00c0, + 0x4eea: 0x00c0, 0x4eeb: 0x00c0, 0x4eec: 0x00c0, + 0x4ef0: 0x00c3, 0x4ef1: 0x00c3, 0x4ef2: 0x00c3, 0x4ef3: 0x00c3, 0x4ef4: 0x00c3, 0x4ef5: 0x00c3, + 0x4ef6: 0x00c3, 0x4ef7: 0x00c0, 0x4ef8: 0x00c0, 0x4ef9: 0x00c0, 0x4efa: 0x00c0, 0x4efb: 0x00c0, + 0x4efc: 0x00c0, 0x4efd: 0x00c0, + // Block 0x13c, offset 0x4f00 + 0x4f00: 0x00c0, 0x4f01: 0x00c0, 0x4f02: 0x00c0, 0x4f03: 0x00c0, 0x4f04: 0x00c0, 0x4f05: 0x00c0, + 0x4f06: 0x00c0, 0x4f07: 0x00c0, 0x4f08: 0x00c0, 0x4f09: 0x00c0, + 0x4f0e: 0x00c0, 0x4f0f: 0x0080, + // Block 0x13d, offset 0x4f40 + 0x4f40: 0x00c0, 0x4f41: 0x00c0, 0x4f42: 0x00c0, 0x4f43: 0x00c0, 0x4f44: 0x00c0, 0x4f45: 0x00c0, + 0x4f46: 0x00c0, 0x4f47: 0x00c0, 0x4f48: 0x00c0, 0x4f49: 0x00c0, 0x4f4a: 0x00c0, 0x4f4b: 0x00c0, + 0x4f4c: 0x00c0, 0x4f4d: 0x00c0, 0x4f4e: 0x00c0, 0x4f4f: 0x00c0, 0x4f50: 0x00c0, 0x4f51: 0x00c0, + 0x4f52: 0x00c0, 0x4f53: 0x00c0, 0x4f54: 0x00c0, 0x4f55: 0x00c0, 0x4f56: 0x00c0, 0x4f57: 0x00c0, + 0x4f58: 0x00c0, 0x4f59: 0x00c0, 0x4f5a: 0x00c0, 0x4f5b: 0x00c0, 0x4f5c: 0x00c0, 0x4f5d: 0x00c0, + 0x4f5e: 0x00c0, 0x4f5f: 0x00c0, 0x4f60: 0x00c0, 0x4f61: 0x00c0, 0x4f62: 0x00c0, 0x4f63: 0x00c0, + 0x4f64: 0x00c0, 0x4f65: 0x00c0, 0x4f66: 0x00c0, 0x4f67: 0x00c0, 0x4f68: 0x00c0, 0x4f69: 0x00c0, + 0x4f6a: 0x00c0, 0x4f6b: 0x00c0, 0x4f6c: 0x00c3, 0x4f6d: 0x00c3, 0x4f6e: 0x00c3, 0x4f6f: 0x00c3, + 0x4f70: 0x00c0, 0x4f71: 0x00c0, 0x4f72: 0x00c0, 0x4f73: 0x00c0, 0x4f74: 0x00c0, 0x4f75: 0x00c0, + 0x4f76: 0x00c0, 0x4f77: 0x00c0, 0x4f78: 0x00c0, 0x4f79: 0x00c0, + 0x4f7f: 0x0080, + // Block 0x13e, offset 0x4f80 + 0x4f80: 0x00c0, 0x4f81: 0x00c0, 0x4f82: 0x00c0, 0x4f83: 0x00c0, 0x4f84: 0x00c0, + 0x4f87: 0x0080, 0x4f88: 0x0080, 0x4f89: 0x0080, 0x4f8a: 0x0080, 0x4f8b: 0x0080, + 0x4f8c: 0x0080, 0x4f8d: 0x0080, 0x4f8e: 0x0080, 0x4f8f: 0x0080, 0x4f90: 0x00c3, 0x4f91: 0x00c3, + 0x4f92: 0x00c3, 0x4f93: 0x00c3, 0x4f94: 0x00c3, 0x4f95: 0x00c3, 0x4f96: 0x00c3, + // Block 0x13f, offset 0x4fc0 + 0x4fc0: 0x00c2, 0x4fc1: 0x00c2, 0x4fc2: 0x00c2, 0x4fc3: 0x00c2, 0x4fc4: 0x00c2, 0x4fc5: 0x00c2, + 0x4fc6: 0x00c2, 0x4fc7: 0x00c2, 0x4fc8: 0x00c2, 0x4fc9: 0x00c2, 0x4fca: 0x00c2, 0x4fcb: 0x00c2, + 0x4fcc: 0x00c2, 0x4fcd: 0x00c2, 0x4fce: 0x00c2, 0x4fcf: 0x00c2, 0x4fd0: 0x00c2, 0x4fd1: 0x00c2, + 0x4fd2: 0x00c2, 0x4fd3: 0x00c2, 0x4fd4: 0x00c2, 0x4fd5: 0x00c2, 0x4fd6: 0x00c2, 0x4fd7: 0x00c2, + 0x4fd8: 0x00c2, 0x4fd9: 0x00c2, 0x4fda: 0x00c2, 0x4fdb: 0x00c2, 0x4fdc: 0x00c2, 0x4fdd: 0x00c2, + 0x4fde: 0x00c2, 0x4fdf: 0x00c2, 0x4fe0: 0x00c2, 0x4fe1: 0x00c2, 0x4fe2: 0x00c2, 0x4fe3: 0x00c2, + 0x4fe4: 0x00c2, 0x4fe5: 0x00c2, 0x4fe6: 0x00c2, 0x4fe7: 0x00c2, 0x4fe8: 0x00c2, 0x4fe9: 0x00c2, + 0x4fea: 0x00c2, 0x4feb: 0x00c2, 0x4fec: 0x00c2, 0x4fed: 0x00c2, 0x4fee: 0x00c2, 0x4fef: 0x00c2, + 0x4ff0: 0x00c2, 0x4ff1: 0x00c2, 0x4ff2: 0x00c2, 0x4ff3: 0x00c2, 0x4ff4: 0x00c2, 0x4ff5: 0x00c2, + 0x4ff6: 0x00c2, 0x4ff7: 0x00c2, 0x4ff8: 0x00c2, 0x4ff9: 0x00c2, 0x4ffa: 0x00c2, 0x4ffb: 0x00c2, + 0x4ffc: 0x00c2, 0x4ffd: 0x00c2, 0x4ffe: 0x00c2, 0x4fff: 0x00c2, + // Block 0x140, offset 0x5000 + 0x5000: 0x00c2, 0x5001: 0x00c2, 0x5002: 0x00c2, 0x5003: 0x00c2, 0x5004: 0x00c3, 0x5005: 0x00c3, + 0x5006: 0x00c3, 0x5007: 0x00c3, 0x5008: 0x00c3, 0x5009: 0x00c3, 0x500a: 0x00c3, 0x500b: 0x00c3, + 0x5010: 0x00c0, 0x5011: 0x00c0, + 0x5012: 0x00c0, 0x5013: 0x00c0, 0x5014: 0x00c0, 0x5015: 0x00c0, 0x5016: 0x00c0, 0x5017: 0x00c0, + 0x5018: 0x00c0, 0x5019: 0x00c0, + 0x501e: 0x0080, 0x501f: 0x0080, + // Block 0x141, offset 0x5040 + 0x5071: 0x0080, 0x5072: 0x0080, 0x5073: 0x0080, 0x5074: 0x0080, 0x5075: 0x0080, + 0x5076: 0x0080, 0x5077: 0x0080, 0x5078: 0x0080, 0x5079: 0x0080, 0x507a: 0x0080, 0x507b: 0x0080, + 0x507c: 0x0080, 0x507d: 0x0080, 0x507e: 0x0080, 0x507f: 0x0080, + // Block 0x142, offset 0x5080 + 0x5080: 0x0080, 0x5081: 0x0080, 0x5082: 0x0080, 0x5083: 0x0080, 0x5084: 0x0080, 0x5085: 0x0080, + 0x5086: 0x0080, 0x5087: 0x0080, 0x5088: 0x0080, 0x5089: 0x0080, 0x508a: 0x0080, 0x508b: 0x0080, + 0x508c: 0x0080, 0x508d: 0x0080, 0x508e: 0x0080, 0x508f: 0x0080, 0x5090: 0x0080, 0x5091: 0x0080, + 0x5092: 0x0080, 0x5093: 0x0080, 0x5094: 0x0080, 0x5095: 0x0080, 0x5096: 0x0080, 0x5097: 0x0080, + 0x5098: 0x0080, 0x5099: 0x0080, 0x509a: 0x0080, 0x509b: 0x0080, 0x509c: 0x0080, 0x509d: 0x0080, + 0x509e: 0x0080, 0x509f: 0x0080, 0x50a0: 0x0080, 0x50a1: 0x0080, 0x50a2: 0x0080, 0x50a3: 0x0080, + 0x50a4: 0x0080, 0x50a5: 0x0080, 0x50a6: 0x0080, 0x50a7: 0x0080, 0x50a8: 0x0080, 0x50a9: 0x0080, + 0x50aa: 0x0080, 0x50ab: 0x0080, 0x50ac: 0x0080, 0x50ad: 0x0080, 0x50ae: 0x0080, 0x50af: 0x0080, + 0x50b0: 0x0080, 0x50b1: 0x0080, 0x50b2: 0x0080, 0x50b3: 0x0080, 0x50b4: 0x0080, + // Block 0x143, offset 0x50c0 + 0x50c1: 0x0080, 0x50c2: 0x0080, 0x50c3: 0x0080, 0x50c4: 0x0080, 0x50c5: 0x0080, + 0x50c6: 0x0080, 0x50c7: 0x0080, 0x50c8: 0x0080, 0x50c9: 0x0080, 0x50ca: 0x0080, 0x50cb: 0x0080, + 0x50cc: 0x0080, 0x50cd: 0x0080, 0x50ce: 0x0080, 0x50cf: 0x0080, 0x50d0: 0x0080, 0x50d1: 0x0080, + 0x50d2: 0x0080, 0x50d3: 0x0080, 0x50d4: 0x0080, 0x50d5: 0x0080, 0x50d6: 0x0080, 0x50d7: 0x0080, + 0x50d8: 0x0080, 0x50d9: 0x0080, 0x50da: 0x0080, 0x50db: 0x0080, 0x50dc: 0x0080, 0x50dd: 0x0080, + 0x50de: 0x0080, 0x50df: 0x0080, 0x50e0: 0x0080, 0x50e1: 0x0080, 0x50e2: 0x0080, 0x50e3: 0x0080, + 0x50e4: 0x0080, 0x50e5: 0x0080, 0x50e6: 0x0080, 0x50e7: 0x0080, 0x50e8: 0x0080, 0x50e9: 0x0080, + 0x50ea: 0x0080, 0x50eb: 0x0080, 0x50ec: 0x0080, 0x50ed: 0x0080, 0x50ee: 0x0080, 0x50ef: 0x0080, + 0x50f0: 0x0080, 0x50f1: 0x0080, 0x50f2: 0x0080, 0x50f3: 0x0080, 0x50f4: 0x0080, 0x50f5: 0x0080, + 0x50f6: 0x0080, 0x50f7: 0x0080, 0x50f8: 0x0080, 0x50f9: 0x0080, 0x50fa: 0x0080, 0x50fb: 0x0080, + 0x50fc: 0x0080, 0x50fd: 0x0080, + // Block 0x144, offset 0x5100 + 0x5100: 0x0080, 0x5101: 0x0080, 0x5102: 0x0080, 0x5103: 0x0080, 0x5105: 0x0080, + 0x5106: 0x0080, 0x5107: 0x0080, 0x5108: 0x0080, 0x5109: 0x0080, 0x510a: 0x0080, 0x510b: 0x0080, + 0x510c: 0x0080, 0x510d: 0x0080, 0x510e: 0x0080, 0x510f: 0x0080, 0x5110: 0x0080, 0x5111: 0x0080, + 0x5112: 0x0080, 0x5113: 0x0080, 0x5114: 0x0080, 0x5115: 0x0080, 0x5116: 0x0080, 0x5117: 0x0080, + 0x5118: 0x0080, 0x5119: 0x0080, 0x511a: 0x0080, 0x511b: 0x0080, 0x511c: 0x0080, 0x511d: 0x0080, + 0x511e: 0x0080, 0x511f: 0x0080, 0x5121: 0x0080, 0x5122: 0x0080, + 0x5124: 0x0080, 0x5127: 0x0080, 0x5129: 0x0080, + 0x512a: 0x0080, 0x512b: 0x0080, 0x512c: 0x0080, 0x512d: 0x0080, 0x512e: 0x0080, 0x512f: 0x0080, + 0x5130: 0x0080, 0x5131: 0x0080, 0x5132: 0x0080, 0x5134: 0x0080, 0x5135: 0x0080, + 0x5136: 0x0080, 0x5137: 0x0080, 0x5139: 0x0080, 0x513b: 0x0080, + // Block 0x145, offset 0x5140 + 0x5142: 0x0080, + 0x5147: 0x0080, 0x5149: 0x0080, 0x514b: 0x0080, + 0x514d: 0x0080, 0x514e: 0x0080, 0x514f: 0x0080, 0x5151: 0x0080, + 0x5152: 0x0080, 0x5154: 0x0080, 0x5157: 0x0080, + 0x5159: 0x0080, 0x515b: 0x0080, 0x515d: 0x0080, + 0x515f: 0x0080, 0x5161: 0x0080, 0x5162: 0x0080, + 0x5164: 0x0080, 0x5167: 0x0080, 0x5168: 0x0080, 0x5169: 0x0080, + 0x516a: 0x0080, 0x516c: 0x0080, 0x516d: 0x0080, 0x516e: 0x0080, 0x516f: 0x0080, + 0x5170: 0x0080, 0x5171: 0x0080, 0x5172: 0x0080, 0x5174: 0x0080, 0x5175: 0x0080, + 0x5176: 0x0080, 0x5177: 0x0080, 0x5179: 0x0080, 0x517a: 0x0080, 0x517b: 0x0080, + 0x517c: 0x0080, 0x517e: 0x0080, + // Block 0x146, offset 0x5180 + 0x5180: 0x0080, 0x5181: 0x0080, 0x5182: 0x0080, 0x5183: 0x0080, 0x5184: 0x0080, 0x5185: 0x0080, + 0x5186: 0x0080, 0x5187: 0x0080, 0x5188: 0x0080, 0x5189: 0x0080, 0x518b: 0x0080, + 0x518c: 0x0080, 0x518d: 0x0080, 0x518e: 0x0080, 0x518f: 0x0080, 0x5190: 0x0080, 0x5191: 0x0080, + 0x5192: 0x0080, 0x5193: 0x0080, 0x5194: 0x0080, 0x5195: 0x0080, 0x5196: 0x0080, 0x5197: 0x0080, + 0x5198: 0x0080, 0x5199: 0x0080, 0x519a: 0x0080, 0x519b: 0x0080, + 0x51a1: 0x0080, 0x51a2: 0x0080, 0x51a3: 0x0080, + 0x51a5: 0x0080, 0x51a6: 0x0080, 0x51a7: 0x0080, 0x51a8: 0x0080, 0x51a9: 0x0080, + 0x51ab: 0x0080, 0x51ac: 0x0080, 0x51ad: 0x0080, 0x51ae: 0x0080, 0x51af: 0x0080, + 0x51b0: 0x0080, 0x51b1: 0x0080, 0x51b2: 0x0080, 0x51b3: 0x0080, 0x51b4: 0x0080, 0x51b5: 0x0080, + 0x51b6: 0x0080, 0x51b7: 0x0080, 0x51b8: 0x0080, 0x51b9: 0x0080, 0x51ba: 0x0080, 0x51bb: 0x0080, + // Block 0x147, offset 0x51c0 + 0x51f0: 0x0080, 0x51f1: 0x0080, + // Block 0x148, offset 0x5200 + 0x5200: 0x0080, 0x5201: 0x0080, 0x5202: 0x0080, 0x5203: 0x0080, 0x5204: 0x0080, 0x5205: 0x0080, + 0x5206: 0x0080, 0x5207: 0x0080, 0x5208: 0x0080, 0x5209: 0x0080, 0x520a: 0x0080, 0x520b: 0x0080, + 0x520c: 0x0080, 0x520d: 0x0080, 0x520e: 0x0080, 0x520f: 0x0080, 0x5210: 0x0080, 0x5211: 0x0080, + 0x5212: 0x0080, 0x5213: 0x0080, 0x5214: 0x0080, 0x5215: 0x0080, 0x5216: 0x0080, 0x5217: 0x0080, + 0x5218: 0x0080, 0x5219: 0x0080, 0x521a: 0x0080, 0x521b: 0x0080, 0x521c: 0x0080, 0x521d: 0x0080, + 0x521e: 0x0080, 0x521f: 0x0080, 0x5220: 0x0080, 0x5221: 0x0080, 0x5222: 0x0080, 0x5223: 0x0080, + 0x5224: 0x0080, 0x5225: 0x0080, 0x5226: 0x0080, 0x5227: 0x0080, 0x5228: 0x0080, 0x5229: 0x0080, + 0x522a: 0x0080, 0x522b: 0x0080, + 0x5230: 0x0080, 0x5231: 0x0080, 0x5232: 0x0080, 0x5233: 0x0080, 0x5234: 0x0080, 0x5235: 0x0080, + 0x5236: 0x0080, 0x5237: 0x0080, 0x5238: 0x0080, 0x5239: 0x0080, 0x523a: 0x0080, 0x523b: 0x0080, + 0x523c: 0x0080, 0x523d: 0x0080, 0x523e: 0x0080, 0x523f: 0x0080, + // Block 0x149, offset 0x5240 + 0x5240: 0x0080, 0x5241: 0x0080, 0x5242: 0x0080, 0x5243: 0x0080, 0x5244: 0x0080, 0x5245: 0x0080, + 0x5246: 0x0080, 0x5247: 0x0080, 0x5248: 0x0080, 0x5249: 0x0080, 0x524a: 0x0080, 0x524b: 0x0080, + 0x524c: 0x0080, 0x524d: 0x0080, 0x524e: 0x0080, 0x524f: 0x0080, 0x5250: 0x0080, 0x5251: 0x0080, + 0x5252: 0x0080, 0x5253: 0x0080, + 0x5260: 0x0080, 0x5261: 0x0080, 0x5262: 0x0080, 0x5263: 0x0080, + 0x5264: 0x0080, 0x5265: 0x0080, 0x5266: 0x0080, 0x5267: 0x0080, 0x5268: 0x0080, 0x5269: 0x0080, + 0x526a: 0x0080, 0x526b: 0x0080, 0x526c: 0x0080, 0x526d: 0x0080, 0x526e: 0x0080, + 0x5271: 0x0080, 0x5272: 0x0080, 0x5273: 0x0080, 0x5274: 0x0080, 0x5275: 0x0080, + 0x5276: 0x0080, 0x5277: 0x0080, 0x5278: 0x0080, 0x5279: 0x0080, 0x527a: 0x0080, 0x527b: 0x0080, + 0x527c: 0x0080, 0x527d: 0x0080, 0x527e: 0x0080, 0x527f: 0x0080, + // Block 0x14a, offset 0x5280 + 0x5281: 0x0080, 0x5282: 0x0080, 0x5283: 0x0080, 0x5284: 0x0080, 0x5285: 0x0080, + 0x5286: 0x0080, 0x5287: 0x0080, 0x5288: 0x0080, 0x5289: 0x0080, 0x528a: 0x0080, 0x528b: 0x0080, + 0x528c: 0x0080, 0x528d: 0x0080, 0x528e: 0x0080, 0x528f: 0x0080, 0x5291: 0x0080, + 0x5292: 0x0080, 0x5293: 0x0080, 0x5294: 0x0080, 0x5295: 0x0080, 0x5296: 0x0080, 0x5297: 0x0080, + 0x5298: 0x0080, 0x5299: 0x0080, 0x529a: 0x0080, 0x529b: 0x0080, 0x529c: 0x0080, 0x529d: 0x0080, + 0x529e: 0x0080, 0x529f: 0x0080, 0x52a0: 0x0080, 0x52a1: 0x0080, 0x52a2: 0x0080, 0x52a3: 0x0080, + 0x52a4: 0x0080, 0x52a5: 0x0080, 0x52a6: 0x0080, 0x52a7: 0x0080, 0x52a8: 0x0080, 0x52a9: 0x0080, + 0x52aa: 0x0080, 0x52ab: 0x0080, 0x52ac: 0x0080, 0x52ad: 0x0080, 0x52ae: 0x0080, 0x52af: 0x0080, + 0x52b0: 0x0080, 0x52b1: 0x0080, 0x52b2: 0x0080, 0x52b3: 0x0080, 0x52b4: 0x0080, 0x52b5: 0x0080, + // Block 0x14b, offset 0x52c0 + 0x52c0: 0x0080, 0x52c1: 0x0080, 0x52c2: 0x0080, 0x52c3: 0x0080, 0x52c4: 0x0080, 0x52c5: 0x0080, + 0x52c6: 0x0080, 0x52c7: 0x0080, 0x52c8: 0x0080, 0x52c9: 0x0080, 0x52ca: 0x0080, 0x52cb: 0x0080, + 0x52cc: 0x0080, 0x52cd: 0x0080, 0x52ce: 0x0080, 0x52cf: 0x0080, 0x52d0: 0x0080, 0x52d1: 0x0080, + 0x52d2: 0x0080, 0x52d3: 0x0080, 0x52d4: 0x0080, 0x52d5: 0x0080, 0x52d6: 0x0080, 0x52d7: 0x0080, + 0x52d8: 0x0080, 0x52d9: 0x0080, 0x52da: 0x0080, 0x52db: 0x0080, 0x52dc: 0x0080, 0x52dd: 0x0080, + 0x52de: 0x0080, 0x52df: 0x0080, 0x52e0: 0x0080, 0x52e1: 0x0080, 0x52e2: 0x0080, 0x52e3: 0x0080, + 0x52e4: 0x0080, 0x52e5: 0x0080, 0x52e6: 0x0080, 0x52e7: 0x0080, 0x52e8: 0x0080, 0x52e9: 0x0080, + 0x52ea: 0x0080, 0x52eb: 0x0080, 0x52ec: 0x0080, 0x52ed: 0x0080, + // Block 0x14c, offset 0x5300 + 0x5326: 0x0080, 0x5327: 0x0080, 0x5328: 0x0080, 0x5329: 0x0080, + 0x532a: 0x0080, 0x532b: 0x0080, 0x532c: 0x0080, 0x532d: 0x0080, 0x532e: 0x0080, 0x532f: 0x0080, + 0x5330: 0x0080, 0x5331: 0x0080, 0x5332: 0x0080, 0x5333: 0x0080, 0x5334: 0x0080, 0x5335: 0x0080, + 0x5336: 0x0080, 0x5337: 0x0080, 0x5338: 0x0080, 0x5339: 0x0080, 0x533a: 0x0080, 0x533b: 0x0080, + 0x533c: 0x0080, 0x533d: 0x0080, 0x533e: 0x0080, 0x533f: 0x0080, + // Block 0x14d, offset 0x5340 + 0x5340: 0x008c, 0x5341: 0x0080, 0x5342: 0x0080, + 0x5350: 0x0080, 0x5351: 0x0080, + 0x5352: 0x0080, 0x5353: 0x0080, 0x5354: 0x0080, 0x5355: 0x0080, 0x5356: 0x0080, 0x5357: 0x0080, + 0x5358: 0x0080, 0x5359: 0x0080, 0x535a: 0x0080, 0x535b: 0x0080, 0x535c: 0x0080, 0x535d: 0x0080, + 0x535e: 0x0080, 0x535f: 0x0080, 0x5360: 0x0080, 0x5361: 0x0080, 0x5362: 0x0080, 0x5363: 0x0080, + 0x5364: 0x0080, 0x5365: 0x0080, 0x5366: 0x0080, 0x5367: 0x0080, 0x5368: 0x0080, 0x5369: 0x0080, + 0x536a: 0x0080, 0x536b: 0x0080, 0x536c: 0x0080, 0x536d: 0x0080, 0x536e: 0x0080, 0x536f: 0x0080, + 0x5370: 0x0080, 0x5371: 0x0080, 0x5372: 0x0080, 0x5373: 0x0080, 0x5374: 0x0080, 0x5375: 0x0080, + 0x5376: 0x0080, 0x5377: 0x0080, 0x5378: 0x0080, 0x5379: 0x0080, 0x537a: 0x0080, 0x537b: 0x0080, + // Block 0x14e, offset 0x5380 + 0x5380: 0x0080, 0x5381: 0x0080, 0x5382: 0x0080, 0x5383: 0x0080, 0x5384: 0x0080, 0x5385: 0x0080, + 0x5386: 0x0080, 0x5387: 0x0080, 0x5388: 0x0080, + 0x5390: 0x0080, 0x5391: 0x0080, + 0x53a0: 0x0080, 0x53a1: 0x0080, 0x53a2: 0x0080, 0x53a3: 0x0080, + 0x53a4: 0x0080, 0x53a5: 0x0080, + // Block 0x14f, offset 0x53c0 + 0x53c0: 0x0080, 0x53c1: 0x0080, 0x53c2: 0x0080, 0x53c3: 0x0080, 0x53c4: 0x0080, 0x53c5: 0x0080, + 0x53c6: 0x0080, 0x53c7: 0x0080, 0x53c8: 0x0080, 0x53c9: 0x0080, 0x53ca: 0x0080, 0x53cb: 0x0080, + 0x53cc: 0x0080, 0x53cd: 0x0080, 0x53ce: 0x0080, 0x53cf: 0x0080, 0x53d0: 0x0080, 0x53d1: 0x0080, + 0x53d2: 0x0080, 0x53d3: 0x0080, 0x53d4: 0x0080, 0x53d5: 0x0080, 0x53d6: 0x0080, 0x53d7: 0x0080, + 0x53e0: 0x0080, 0x53e1: 0x0080, 0x53e2: 0x0080, 0x53e3: 0x0080, + 0x53e4: 0x0080, 0x53e5: 0x0080, 0x53e6: 0x0080, 0x53e7: 0x0080, 0x53e8: 0x0080, 0x53e9: 0x0080, + 0x53ea: 0x0080, 0x53eb: 0x0080, 0x53ec: 0x0080, + 0x53f0: 0x0080, 0x53f1: 0x0080, 0x53f2: 0x0080, 0x53f3: 0x0080, 0x53f4: 0x0080, 0x53f5: 0x0080, + 0x53f6: 0x0080, 0x53f7: 0x0080, 0x53f8: 0x0080, 0x53f9: 0x0080, 0x53fa: 0x0080, 0x53fb: 0x0080, + 0x53fc: 0x0080, + // Block 0x150, offset 0x5400 + 0x5400: 0x0080, 0x5401: 0x0080, 0x5402: 0x0080, 0x5403: 0x0080, 0x5404: 0x0080, 0x5405: 0x0080, + 0x5406: 0x0080, 0x5407: 0x0080, 0x5408: 0x0080, 0x5409: 0x0080, 0x540a: 0x0080, 0x540b: 0x0080, + 0x540c: 0x0080, 0x540d: 0x0080, 0x540e: 0x0080, 0x540f: 0x0080, 0x5410: 0x0080, 0x5411: 0x0080, + 0x5412: 0x0080, 0x5413: 0x0080, 0x5414: 0x0080, 0x5415: 0x0080, 0x5416: 0x0080, 0x5417: 0x0080, + 0x5418: 0x0080, 0x5419: 0x0080, 0x541a: 0x0080, 0x541b: 0x0080, 0x541c: 0x0080, 0x541d: 0x0080, + 0x541e: 0x0080, 0x541f: 0x0080, 0x5420: 0x0080, 0x5421: 0x0080, 0x5422: 0x0080, 0x5423: 0x0080, + 0x5424: 0x0080, 0x5425: 0x0080, 0x5426: 0x0080, 0x5427: 0x0080, 0x5428: 0x0080, 0x5429: 0x0080, + 0x542a: 0x0080, 0x542b: 0x0080, 0x542c: 0x0080, 0x542d: 0x0080, 0x542e: 0x0080, 0x542f: 0x0080, + 0x5430: 0x0080, 0x5431: 0x0080, 0x5432: 0x0080, 0x5433: 0x0080, + // Block 0x151, offset 0x5440 + 0x5440: 0x0080, 0x5441: 0x0080, 0x5442: 0x0080, 0x5443: 0x0080, 0x5444: 0x0080, 0x5445: 0x0080, + 0x5446: 0x0080, 0x5447: 0x0080, 0x5448: 0x0080, 0x5449: 0x0080, 0x544a: 0x0080, 0x544b: 0x0080, + 0x544c: 0x0080, 0x544d: 0x0080, 0x544e: 0x0080, 0x544f: 0x0080, 0x5450: 0x0080, 0x5451: 0x0080, + 0x5452: 0x0080, 0x5453: 0x0080, 0x5454: 0x0080, 0x5455: 0x0080, 0x5456: 0x0080, 0x5457: 0x0080, + 0x5458: 0x0080, + 0x5460: 0x0080, 0x5461: 0x0080, 0x5462: 0x0080, 0x5463: 0x0080, + 0x5464: 0x0080, 0x5465: 0x0080, 0x5466: 0x0080, 0x5467: 0x0080, 0x5468: 0x0080, 0x5469: 0x0080, + 0x546a: 0x0080, 0x546b: 0x0080, + // Block 0x152, offset 0x5480 + 0x5480: 0x0080, 0x5481: 0x0080, 0x5482: 0x0080, 0x5483: 0x0080, 0x5484: 0x0080, 0x5485: 0x0080, + 0x5486: 0x0080, 0x5487: 0x0080, 0x5488: 0x0080, 0x5489: 0x0080, 0x548a: 0x0080, 0x548b: 0x0080, + 0x5490: 0x0080, 0x5491: 0x0080, + 0x5492: 0x0080, 0x5493: 0x0080, 0x5494: 0x0080, 0x5495: 0x0080, 0x5496: 0x0080, 0x5497: 0x0080, + 0x5498: 0x0080, 0x5499: 0x0080, 0x549a: 0x0080, 0x549b: 0x0080, 0x549c: 0x0080, 0x549d: 0x0080, + 0x549e: 0x0080, 0x549f: 0x0080, 0x54a0: 0x0080, 0x54a1: 0x0080, 0x54a2: 0x0080, 0x54a3: 0x0080, + 0x54a4: 0x0080, 0x54a5: 0x0080, 0x54a6: 0x0080, 0x54a7: 0x0080, 0x54a8: 0x0080, 0x54a9: 0x0080, + 0x54aa: 0x0080, 0x54ab: 0x0080, 0x54ac: 0x0080, 0x54ad: 0x0080, 0x54ae: 0x0080, 0x54af: 0x0080, + 0x54b0: 0x0080, 0x54b1: 0x0080, 0x54b2: 0x0080, 0x54b3: 0x0080, 0x54b4: 0x0080, 0x54b5: 0x0080, + 0x54b6: 0x0080, 0x54b7: 0x0080, 0x54b8: 0x0080, 0x54b9: 0x0080, 0x54ba: 0x0080, 0x54bb: 0x0080, + 0x54bc: 0x0080, 0x54bd: 0x0080, 0x54be: 0x0080, 0x54bf: 0x0080, + // Block 0x153, offset 0x54c0 + 0x54c0: 0x0080, 0x54c1: 0x0080, 0x54c2: 0x0080, 0x54c3: 0x0080, 0x54c4: 0x0080, 0x54c5: 0x0080, + 0x54c6: 0x0080, 0x54c7: 0x0080, + 0x54d0: 0x0080, 0x54d1: 0x0080, + 0x54d2: 0x0080, 0x54d3: 0x0080, 0x54d4: 0x0080, 0x54d5: 0x0080, 0x54d6: 0x0080, 0x54d7: 0x0080, + 0x54d8: 0x0080, 0x54d9: 0x0080, + 0x54e0: 0x0080, 0x54e1: 0x0080, 0x54e2: 0x0080, 0x54e3: 0x0080, + 0x54e4: 0x0080, 0x54e5: 0x0080, 0x54e6: 0x0080, 0x54e7: 0x0080, 0x54e8: 0x0080, 0x54e9: 0x0080, + 0x54ea: 0x0080, 0x54eb: 0x0080, 0x54ec: 0x0080, 0x54ed: 0x0080, 0x54ee: 0x0080, 0x54ef: 0x0080, + 0x54f0: 0x0080, 0x54f1: 0x0080, 0x54f2: 0x0080, 0x54f3: 0x0080, 0x54f4: 0x0080, 0x54f5: 0x0080, + 0x54f6: 0x0080, 0x54f7: 0x0080, 0x54f8: 0x0080, 0x54f9: 0x0080, 0x54fa: 0x0080, 0x54fb: 0x0080, + 0x54fc: 0x0080, 0x54fd: 0x0080, 0x54fe: 0x0080, 0x54ff: 0x0080, + // Block 0x154, offset 0x5500 + 0x5500: 0x0080, 0x5501: 0x0080, 0x5502: 0x0080, 0x5503: 0x0080, 0x5504: 0x0080, 0x5505: 0x0080, + 0x5506: 0x0080, 0x5507: 0x0080, + 0x5510: 0x0080, 0x5511: 0x0080, + 0x5512: 0x0080, 0x5513: 0x0080, 0x5514: 0x0080, 0x5515: 0x0080, 0x5516: 0x0080, 0x5517: 0x0080, + 0x5518: 0x0080, 0x5519: 0x0080, 0x551a: 0x0080, 0x551b: 0x0080, 0x551c: 0x0080, 0x551d: 0x0080, + 0x551e: 0x0080, 0x551f: 0x0080, 0x5520: 0x0080, 0x5521: 0x0080, 0x5522: 0x0080, 0x5523: 0x0080, + 0x5524: 0x0080, 0x5525: 0x0080, 0x5526: 0x0080, 0x5527: 0x0080, 0x5528: 0x0080, 0x5529: 0x0080, + 0x552a: 0x0080, 0x552b: 0x0080, 0x552c: 0x0080, 0x552d: 0x0080, + 0x5530: 0x0080, 0x5531: 0x0080, + // Block 0x155, offset 0x5540 + 0x5540: 0x0080, 0x5541: 0x0080, 0x5542: 0x0080, 0x5543: 0x0080, 0x5544: 0x0080, 0x5545: 0x0080, + 0x5546: 0x0080, 0x5547: 0x0080, 0x5548: 0x0080, 0x5549: 0x0080, 0x554a: 0x0080, 0x554b: 0x0080, + 0x554c: 0x0080, 0x554d: 0x0080, 0x554e: 0x0080, 0x554f: 0x0080, 0x5550: 0x0080, 0x5551: 0x0080, + 0x5552: 0x0080, 0x5553: 0x0080, 0x5554: 0x0080, 0x5555: 0x0080, 0x5556: 0x0080, 0x5557: 0x0080, + 0x5558: 0x0080, 0x5559: 0x0080, 0x555a: 0x0080, 0x555b: 0x0080, 0x555c: 0x0080, 0x555d: 0x0080, + 0x555e: 0x0080, 0x555f: 0x0080, 0x5560: 0x0080, 0x5561: 0x0080, 0x5562: 0x0080, 0x5563: 0x0080, + 0x5564: 0x0080, 0x5565: 0x0080, 0x5566: 0x0080, 0x5567: 0x0080, 0x5568: 0x0080, 0x5569: 0x0080, + 0x556a: 0x0080, 0x556b: 0x0080, 0x556c: 0x0080, 0x556d: 0x0080, 0x556e: 0x0080, 0x556f: 0x0080, + 0x5570: 0x0080, 0x5571: 0x0080, 0x5572: 0x0080, 0x5573: 0x0080, 0x5574: 0x0080, 0x5575: 0x0080, + 0x5576: 0x0080, 0x5577: 0x0080, 0x5578: 0x0080, 0x557a: 0x0080, 0x557b: 0x0080, + 0x557c: 0x0080, 0x557d: 0x0080, 0x557e: 0x0080, 0x557f: 0x0080, + // Block 0x156, offset 0x5580 + 0x5580: 0x0080, 0x5581: 0x0080, 0x5582: 0x0080, 0x5583: 0x0080, 0x5584: 0x0080, 0x5585: 0x0080, + 0x5586: 0x0080, 0x5587: 0x0080, 0x5588: 0x0080, 0x5589: 0x0080, 0x558a: 0x0080, 0x558b: 0x0080, + 0x558d: 0x0080, 0x558e: 0x0080, 0x558f: 0x0080, 0x5590: 0x0080, 0x5591: 0x0080, + 0x5592: 0x0080, 0x5593: 0x0080, 0x5594: 0x0080, 0x5595: 0x0080, 0x5596: 0x0080, 0x5597: 0x0080, + 0x5598: 0x0080, 0x5599: 0x0080, 0x559a: 0x0080, 0x559b: 0x0080, 0x559c: 0x0080, 0x559d: 0x0080, + 0x559e: 0x0080, 0x559f: 0x0080, 0x55a0: 0x0080, 0x55a1: 0x0080, 0x55a2: 0x0080, 0x55a3: 0x0080, + 0x55a4: 0x0080, 0x55a5: 0x0080, 0x55a6: 0x0080, 0x55a7: 0x0080, 0x55a8: 0x0080, 0x55a9: 0x0080, + 0x55aa: 0x0080, 0x55ab: 0x0080, 0x55ac: 0x0080, 0x55ad: 0x0080, 0x55ae: 0x0080, 0x55af: 0x0080, + 0x55b0: 0x0080, 0x55b1: 0x0080, 0x55b2: 0x0080, 0x55b3: 0x0080, 0x55b4: 0x0080, 0x55b5: 0x0080, + 0x55b6: 0x0080, 0x55b7: 0x0080, 0x55b8: 0x0080, 0x55b9: 0x0080, 0x55ba: 0x0080, 0x55bb: 0x0080, + 0x55bc: 0x0080, 0x55bd: 0x0080, 0x55be: 0x0080, 0x55bf: 0x0080, + // Block 0x157, offset 0x55c0 + 0x55c0: 0x0080, 0x55c1: 0x0080, 0x55c2: 0x0080, 0x55c3: 0x0080, 0x55c4: 0x0080, 0x55c5: 0x0080, + 0x55c6: 0x0080, 0x55c7: 0x0080, 0x55c8: 0x0080, 0x55c9: 0x0080, 0x55ca: 0x0080, 0x55cb: 0x0080, + 0x55cc: 0x0080, 0x55cd: 0x0080, 0x55ce: 0x0080, 0x55cf: 0x0080, 0x55d0: 0x0080, 0x55d1: 0x0080, + 0x55d2: 0x0080, 0x55d3: 0x0080, + 0x55e0: 0x0080, 0x55e1: 0x0080, 0x55e2: 0x0080, 0x55e3: 0x0080, + 0x55e4: 0x0080, 0x55e5: 0x0080, 0x55e6: 0x0080, 0x55e7: 0x0080, 0x55e8: 0x0080, 0x55e9: 0x0080, + 0x55ea: 0x0080, 0x55eb: 0x0080, 0x55ec: 0x0080, 0x55ed: 0x0080, + 0x55f0: 0x0080, 0x55f1: 0x0080, 0x55f2: 0x0080, 0x55f3: 0x0080, 0x55f4: 0x0080, + 0x55f8: 0x0080, 0x55f9: 0x0080, 0x55fa: 0x0080, + // Block 0x158, offset 0x5600 + 0x5600: 0x0080, 0x5601: 0x0080, 0x5602: 0x0080, 0x5603: 0x0080, 0x5604: 0x0080, 0x5605: 0x0080, + 0x5606: 0x0080, + 0x5610: 0x0080, 0x5611: 0x0080, + 0x5612: 0x0080, 0x5613: 0x0080, 0x5614: 0x0080, 0x5615: 0x0080, 0x5616: 0x0080, 0x5617: 0x0080, + 0x5618: 0x0080, 0x5619: 0x0080, 0x561a: 0x0080, 0x561b: 0x0080, 0x561c: 0x0080, 0x561d: 0x0080, + 0x561e: 0x0080, 0x561f: 0x0080, 0x5620: 0x0080, 0x5621: 0x0080, 0x5622: 0x0080, 0x5623: 0x0080, + 0x5624: 0x0080, 0x5625: 0x0080, 0x5626: 0x0080, 0x5627: 0x0080, 0x5628: 0x0080, + 0x5630: 0x0080, 0x5631: 0x0080, 0x5632: 0x0080, 0x5633: 0x0080, 0x5634: 0x0080, 0x5635: 0x0080, + 0x5636: 0x0080, + // Block 0x159, offset 0x5640 + 0x5640: 0x0080, 0x5641: 0x0080, 0x5642: 0x0080, + 0x5650: 0x0080, 0x5651: 0x0080, + 0x5652: 0x0080, 0x5653: 0x0080, 0x5654: 0x0080, 0x5655: 0x0080, 0x5656: 0x0080, + // Block 0x15a, offset 0x5680 + 0x5680: 0x0080, 0x5681: 0x0080, 0x5682: 0x0080, 0x5683: 0x0080, 0x5684: 0x0080, 0x5685: 0x0080, + 0x5686: 0x0080, 0x5687: 0x0080, 0x5688: 0x0080, 0x5689: 0x0080, 0x568a: 0x0080, 0x568b: 0x0080, + 0x568c: 0x0080, 0x568d: 0x0080, 0x568e: 0x0080, 0x568f: 0x0080, 0x5690: 0x0080, 0x5691: 0x0080, + 0x5692: 0x0080, 0x5694: 0x0080, 0x5695: 0x0080, 0x5696: 0x0080, 0x5697: 0x0080, + 0x5698: 0x0080, 0x5699: 0x0080, 0x569a: 0x0080, 0x569b: 0x0080, 0x569c: 0x0080, 0x569d: 0x0080, + 0x569e: 0x0080, 0x569f: 0x0080, 0x56a0: 0x0080, 0x56a1: 0x0080, 0x56a2: 0x0080, 0x56a3: 0x0080, + 0x56a4: 0x0080, 0x56a5: 0x0080, 0x56a6: 0x0080, 0x56a7: 0x0080, 0x56a8: 0x0080, 0x56a9: 0x0080, + 0x56aa: 0x0080, 0x56ab: 0x0080, 0x56ac: 0x0080, 0x56ad: 0x0080, 0x56ae: 0x0080, 0x56af: 0x0080, + 0x56b0: 0x0080, 0x56b1: 0x0080, 0x56b2: 0x0080, 0x56b3: 0x0080, 0x56b4: 0x0080, 0x56b5: 0x0080, + 0x56b6: 0x0080, 0x56b7: 0x0080, 0x56b8: 0x0080, 0x56b9: 0x0080, 0x56ba: 0x0080, 0x56bb: 0x0080, + 0x56bc: 0x0080, 0x56bd: 0x0080, 0x56be: 0x0080, 0x56bf: 0x0080, + // Block 0x15b, offset 0x56c0 + 0x56c0: 0x0080, 0x56c1: 0x0080, 0x56c2: 0x0080, 0x56c3: 0x0080, 0x56c4: 0x0080, 0x56c5: 0x0080, + 0x56c6: 0x0080, 0x56c7: 0x0080, 0x56c8: 0x0080, 0x56c9: 0x0080, 0x56ca: 0x0080, + 0x56f0: 0x0080, 0x56f1: 0x0080, 0x56f2: 0x0080, 0x56f3: 0x0080, 0x56f4: 0x0080, 0x56f5: 0x0080, + 0x56f6: 0x0080, 0x56f7: 0x0080, 0x56f8: 0x0080, 0x56f9: 0x0080, + // Block 0x15c, offset 0x5700 + 0x5700: 0x00cc, 0x5701: 0x00cc, 0x5702: 0x00cc, 0x5703: 0x00cc, 0x5704: 0x00cc, 0x5705: 0x00cc, + 0x5706: 0x00cc, 0x5707: 0x00cc, 0x5708: 0x00cc, 0x5709: 0x00cc, 0x570a: 0x00cc, 0x570b: 0x00cc, + 0x570c: 0x00cc, 0x570d: 0x00cc, 0x570e: 0x00cc, 0x570f: 0x00cc, 0x5710: 0x00cc, 0x5711: 0x00cc, + 0x5712: 0x00cc, 0x5713: 0x00cc, 0x5714: 0x00cc, 0x5715: 0x00cc, 0x5716: 0x00cc, 0x5717: 0x00cc, + 0x5718: 0x00cc, 0x5719: 0x00cc, 0x571a: 0x00cc, 0x571b: 0x00cc, 0x571c: 0x00cc, 0x571d: 0x00cc, + // Block 0x15d, offset 0x5740 + 0x5740: 0x00cc, 0x5741: 0x00cc, 0x5742: 0x00cc, 0x5743: 0x00cc, 0x5744: 0x00cc, 0x5745: 0x00cc, + 0x5746: 0x00cc, 0x5747: 0x00cc, 0x5748: 0x00cc, 0x5749: 0x00cc, 0x574a: 0x00cc, 0x574b: 0x00cc, + 0x574c: 0x00cc, 0x574d: 0x00cc, 0x574e: 0x00cc, 0x574f: 0x00cc, 0x5750: 0x00cc, 0x5751: 0x00cc, + 0x5752: 0x00cc, 0x5753: 0x00cc, 0x5754: 0x00cc, 0x5755: 0x00cc, 0x5756: 0x00cc, 0x5757: 0x00cc, + 0x5758: 0x00cc, 0x5759: 0x00cc, 0x575a: 0x00cc, 0x575b: 0x00cc, 0x575c: 0x00cc, 0x575d: 0x00cc, + 0x575e: 0x00cc, 0x575f: 0x00cc, 0x5760: 0x00cc, 0x5761: 0x00cc, 0x5762: 0x00cc, 0x5763: 0x00cc, + 0x5764: 0x00cc, 0x5765: 0x00cc, 0x5766: 0x00cc, 0x5767: 0x00cc, 0x5768: 0x00cc, 0x5769: 0x00cc, + 0x576a: 0x00cc, 0x576b: 0x00cc, 0x576c: 0x00cc, 0x576d: 0x00cc, 0x576e: 0x00cc, 0x576f: 0x00cc, + 0x5770: 0x00cc, 0x5771: 0x00cc, 0x5772: 0x00cc, 0x5773: 0x00cc, 0x5774: 0x00cc, + // Block 0x15e, offset 0x5780 + 0x5780: 0x00cc, 0x5781: 0x00cc, 0x5782: 0x00cc, 0x5783: 0x00cc, 0x5784: 0x00cc, 0x5785: 0x00cc, + 0x5786: 0x00cc, 0x5787: 0x00cc, 0x5788: 0x00cc, 0x5789: 0x00cc, 0x578a: 0x00cc, 0x578b: 0x00cc, + 0x578c: 0x00cc, 0x578d: 0x00cc, 0x578e: 0x00cc, 0x578f: 0x00cc, 0x5790: 0x00cc, 0x5791: 0x00cc, + 0x5792: 0x00cc, 0x5793: 0x00cc, 0x5794: 0x00cc, 0x5795: 0x00cc, 0x5796: 0x00cc, 0x5797: 0x00cc, + 0x5798: 0x00cc, 0x5799: 0x00cc, 0x579a: 0x00cc, 0x579b: 0x00cc, 0x579c: 0x00cc, 0x579d: 0x00cc, + 0x57a0: 0x00cc, 0x57a1: 0x00cc, 0x57a2: 0x00cc, 0x57a3: 0x00cc, + 0x57a4: 0x00cc, 0x57a5: 0x00cc, 0x57a6: 0x00cc, 0x57a7: 0x00cc, 0x57a8: 0x00cc, 0x57a9: 0x00cc, + 0x57aa: 0x00cc, 0x57ab: 0x00cc, 0x57ac: 0x00cc, 0x57ad: 0x00cc, 0x57ae: 0x00cc, 0x57af: 0x00cc, + 0x57b0: 0x00cc, 0x57b1: 0x00cc, 0x57b2: 0x00cc, 0x57b3: 0x00cc, 0x57b4: 0x00cc, 0x57b5: 0x00cc, + 0x57b6: 0x00cc, 0x57b7: 0x00cc, 0x57b8: 0x00cc, 0x57b9: 0x00cc, 0x57ba: 0x00cc, 0x57bb: 0x00cc, + 0x57bc: 0x00cc, 0x57bd: 0x00cc, 0x57be: 0x00cc, 0x57bf: 0x00cc, + // Block 0x15f, offset 0x57c0 + 0x57c0: 0x00cc, 0x57c1: 0x00cc, 0x57c2: 0x00cc, 0x57c3: 0x00cc, 0x57c4: 0x00cc, 0x57c5: 0x00cc, + 0x57c6: 0x00cc, 0x57c7: 0x00cc, 0x57c8: 0x00cc, 0x57c9: 0x00cc, 0x57ca: 0x00cc, 0x57cb: 0x00cc, + 0x57cc: 0x00cc, 0x57cd: 0x00cc, 0x57ce: 0x00cc, 0x57cf: 0x00cc, 0x57d0: 0x00cc, 0x57d1: 0x00cc, + 0x57d2: 0x00cc, 0x57d3: 0x00cc, 0x57d4: 0x00cc, 0x57d5: 0x00cc, 0x57d6: 0x00cc, 0x57d7: 0x00cc, + 0x57d8: 0x00cc, 0x57d9: 0x00cc, 0x57da: 0x00cc, 0x57db: 0x00cc, 0x57dc: 0x00cc, 0x57dd: 0x00cc, + 0x57de: 0x00cc, 0x57df: 0x00cc, 0x57e0: 0x00cc, 0x57e1: 0x00cc, + 0x57f0: 0x00cc, 0x57f1: 0x00cc, 0x57f2: 0x00cc, 0x57f3: 0x00cc, 0x57f4: 0x00cc, 0x57f5: 0x00cc, + 0x57f6: 0x00cc, 0x57f7: 0x00cc, 0x57f8: 0x00cc, 0x57f9: 0x00cc, 0x57fa: 0x00cc, 0x57fb: 0x00cc, + 0x57fc: 0x00cc, 0x57fd: 0x00cc, 0x57fe: 0x00cc, 0x57ff: 0x00cc, + // Block 0x160, offset 0x5800 + 0x5800: 0x00cc, 0x5801: 0x00cc, 0x5802: 0x00cc, 0x5803: 0x00cc, 0x5804: 0x00cc, 0x5805: 0x00cc, + 0x5806: 0x00cc, 0x5807: 0x00cc, 0x5808: 0x00cc, 0x5809: 0x00cc, 0x580a: 0x00cc, 0x580b: 0x00cc, + 0x580c: 0x00cc, 0x580d: 0x00cc, 0x580e: 0x00cc, 0x580f: 0x00cc, 0x5810: 0x00cc, 0x5811: 0x00cc, + 0x5812: 0x00cc, 0x5813: 0x00cc, 0x5814: 0x00cc, 0x5815: 0x00cc, 0x5816: 0x00cc, 0x5817: 0x00cc, + 0x5818: 0x00cc, 0x5819: 0x00cc, 0x581a: 0x00cc, 0x581b: 0x00cc, 0x581c: 0x00cc, 0x581d: 0x00cc, + 0x581e: 0x00cc, 0x581f: 0x00cc, 0x5820: 0x00cc, + // Block 0x161, offset 0x5840 + 0x5840: 0x008c, 0x5841: 0x008c, 0x5842: 0x008c, 0x5843: 0x008c, 0x5844: 0x008c, 0x5845: 0x008c, + 0x5846: 0x008c, 0x5847: 0x008c, 0x5848: 0x008c, 0x5849: 0x008c, 0x584a: 0x008c, 0x584b: 0x008c, + 0x584c: 0x008c, 0x584d: 0x008c, 0x584e: 0x008c, 0x584f: 0x008c, 0x5850: 0x008c, 0x5851: 0x008c, + 0x5852: 0x008c, 0x5853: 0x008c, 0x5854: 0x008c, 0x5855: 0x008c, 0x5856: 0x008c, 0x5857: 0x008c, + 0x5858: 0x008c, 0x5859: 0x008c, 0x585a: 0x008c, 0x585b: 0x008c, 0x585c: 0x008c, 0x585d: 0x008c, + // Block 0x162, offset 0x5880 + 0x5880: 0x00cc, 0x5881: 0x00cc, 0x5882: 0x00cc, 0x5883: 0x00cc, 0x5884: 0x00cc, 0x5885: 0x00cc, + 0x5886: 0x00cc, 0x5887: 0x00cc, 0x5888: 0x00cc, 0x5889: 0x00cc, 0x588a: 0x00cc, + // Block 0x163, offset 0x58c0 + 0x58c1: 0x0040, + 0x58e0: 0x0040, 0x58e1: 0x0040, 0x58e2: 0x0040, 0x58e3: 0x0040, + 0x58e4: 0x0040, 0x58e5: 0x0040, 0x58e6: 0x0040, 0x58e7: 0x0040, 0x58e8: 0x0040, 0x58e9: 0x0040, + 0x58ea: 0x0040, 0x58eb: 0x0040, 0x58ec: 0x0040, 0x58ed: 0x0040, 0x58ee: 0x0040, 0x58ef: 0x0040, + 0x58f0: 0x0040, 0x58f1: 0x0040, 0x58f2: 0x0040, 0x58f3: 0x0040, 0x58f4: 0x0040, 0x58f5: 0x0040, + 0x58f6: 0x0040, 0x58f7: 0x0040, 0x58f8: 0x0040, 0x58f9: 0x0040, 0x58fa: 0x0040, 0x58fb: 0x0040, + 0x58fc: 0x0040, 0x58fd: 0x0040, 0x58fe: 0x0040, 0x58ff: 0x0040, + // Block 0x164, offset 0x5900 + 0x5900: 0x0040, 0x5901: 0x0040, 0x5902: 0x0040, 0x5903: 0x0040, 0x5904: 0x0040, 0x5905: 0x0040, + 0x5906: 0x0040, 0x5907: 0x0040, 0x5908: 0x0040, 0x5909: 0x0040, 0x590a: 0x0040, 0x590b: 0x0040, + 0x590c: 0x0040, 0x590d: 0x0040, 0x590e: 0x0040, 0x590f: 0x0040, 0x5910: 0x0040, 0x5911: 0x0040, + 0x5912: 0x0040, 0x5913: 0x0040, 0x5914: 0x0040, 0x5915: 0x0040, 0x5916: 0x0040, 0x5917: 0x0040, + 0x5918: 0x0040, 0x5919: 0x0040, 0x591a: 0x0040, 0x591b: 0x0040, 0x591c: 0x0040, 0x591d: 0x0040, + 0x591e: 0x0040, 0x591f: 0x0040, 0x5920: 0x0040, 0x5921: 0x0040, 0x5922: 0x0040, 0x5923: 0x0040, + 0x5924: 0x0040, 0x5925: 0x0040, 0x5926: 0x0040, 0x5927: 0x0040, 0x5928: 0x0040, 0x5929: 0x0040, + 0x592a: 0x0040, 0x592b: 0x0040, 0x592c: 0x0040, 0x592d: 0x0040, 0x592e: 0x0040, 0x592f: 0x0040, + // Block 0x165, offset 0x5940 + 0x5940: 0x0040, 0x5941: 0x0040, 0x5942: 0x0040, 0x5943: 0x0040, 0x5944: 0x0040, 0x5945: 0x0040, + 0x5946: 0x0040, 0x5947: 0x0040, 0x5948: 0x0040, 0x5949: 0x0040, 0x594a: 0x0040, 0x594b: 0x0040, + 0x594c: 0x0040, 0x594d: 0x0040, 0x594e: 0x0040, 0x594f: 0x0040, 0x5950: 0x0040, 0x5951: 0x0040, + 0x5952: 0x0040, 0x5953: 0x0040, 0x5954: 0x0040, 0x5955: 0x0040, 0x5956: 0x0040, 0x5957: 0x0040, + 0x5958: 0x0040, 0x5959: 0x0040, 0x595a: 0x0040, 0x595b: 0x0040, 0x595c: 0x0040, 0x595d: 0x0040, + 0x595e: 0x0040, 0x595f: 0x0040, 0x5960: 0x0040, 0x5961: 0x0040, 0x5962: 0x0040, 0x5963: 0x0040, + 0x5964: 0x0040, 0x5965: 0x0040, 0x5966: 0x0040, 0x5967: 0x0040, 0x5968: 0x0040, 0x5969: 0x0040, + 0x596a: 0x0040, 0x596b: 0x0040, 0x596c: 0x0040, 0x596d: 0x0040, 0x596e: 0x0040, 0x596f: 0x0040, + 0x5970: 0x0040, 0x5971: 0x0040, 0x5972: 0x0040, 0x5973: 0x0040, 0x5974: 0x0040, 0x5975: 0x0040, + 0x5976: 0x0040, 0x5977: 0x0040, 0x5978: 0x0040, 0x5979: 0x0040, 0x597a: 0x0040, 0x597b: 0x0040, + 0x597c: 0x0040, 0x597d: 0x0040, +} + +// derivedPropertiesIndex: 38 blocks, 2432 entries, 4864 bytes +// Block 0 is the zero block. +var derivedPropertiesIndex = [2432]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc6: 0x05, 0xc7: 0x06, + 0xc8: 0x05, 0xc9: 0x05, 0xca: 0x07, 0xcb: 0x08, 0xcc: 0x09, 0xcd: 0x0a, 0xce: 0x0b, 0xcf: 0x0c, + 0xd0: 0x05, 0xd1: 0x05, 0xd2: 0x0d, 0xd3: 0x05, 0xd4: 0x0e, 0xd5: 0x0f, 0xd6: 0x10, 0xd7: 0x11, + 0xd8: 0x12, 0xd9: 0x13, 0xda: 0x14, 0xdb: 0x15, 0xdc: 0x16, 0xdd: 0x17, 0xde: 0x18, 0xdf: 0x19, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x0a, 0xec: 0x0a, 0xed: 0x0b, 0xee: 0x0c, 0xef: 0x0d, + 0xf0: 0x1f, 0xf3: 0x22, 0xf4: 0x23, + // Block 0x4, offset 0x100 + 0x120: 0x1a, 0x121: 0x1b, 0x122: 0x1c, 0x123: 0x1d, 0x124: 0x1e, 0x125: 0x1f, 0x126: 0x20, 0x127: 0x21, + 0x128: 0x22, 0x129: 0x23, 0x12a: 0x24, 0x12b: 0x25, 0x12c: 0x26, 0x12d: 0x27, 0x12e: 0x28, 0x12f: 0x29, + 0x130: 0x2a, 0x131: 0x2b, 0x132: 0x2c, 0x133: 0x2d, 0x134: 0x2e, 0x135: 0x2f, 0x136: 0x30, 0x137: 0x31, + 0x138: 0x32, 0x139: 0x33, 0x13a: 0x34, 0x13b: 0x35, 0x13c: 0x36, 0x13d: 0x37, 0x13e: 0x38, 0x13f: 0x39, + // Block 0x5, offset 0x140 + 0x140: 0x3a, 0x141: 0x3b, 0x142: 0x3c, 0x143: 0x3d, 0x144: 0x3e, 0x145: 0x3e, 0x146: 0x3e, 0x147: 0x3e, + 0x148: 0x05, 0x149: 0x3f, 0x14a: 0x40, 0x14b: 0x41, 0x14c: 0x42, 0x14d: 0x43, 0x14e: 0x44, 0x14f: 0x45, + 0x150: 0x46, 0x151: 0x05, 0x152: 0x05, 0x153: 0x05, 0x154: 0x05, 0x155: 0x05, 0x156: 0x05, 0x157: 0x05, + 0x158: 0x05, 0x159: 0x47, 0x15a: 0x48, 0x15b: 0x49, 0x15c: 0x4a, 0x15d: 0x4b, 0x15e: 0x4c, 0x15f: 0x4d, + 0x160: 0x4e, 0x161: 0x4f, 0x162: 0x50, 0x163: 0x51, 0x164: 0x52, 0x165: 0x53, 0x166: 0x54, 0x167: 0x55, + 0x168: 0x56, 0x169: 0x57, 0x16a: 0x58, 0x16b: 0x59, 0x16c: 0x5a, 0x16d: 0x5b, 0x16e: 0x5c, 0x16f: 0x5d, + 0x170: 0x5e, 0x171: 0x5f, 0x172: 0x60, 0x173: 0x61, 0x174: 0x62, 0x175: 0x63, 0x176: 0x64, 0x177: 0x65, + 0x178: 0x05, 0x179: 0x05, 0x17a: 0x66, 0x17b: 0x05, 0x17c: 0x67, 0x17d: 0x68, 0x17e: 0x69, 0x17f: 0x6a, + // Block 0x6, offset 0x180 + 0x180: 0x6b, 0x181: 0x6c, 0x182: 0x6d, 0x183: 0x6e, 0x184: 0x6f, 0x185: 0x70, 0x186: 0x71, 0x187: 0x72, + 0x188: 0x72, 0x189: 0x72, 0x18a: 0x72, 0x18b: 0x72, 0x18c: 0x72, 0x18d: 0x72, 0x18e: 0x72, 0x18f: 0x72, + 0x190: 0x73, 0x191: 0x74, 0x192: 0x72, 0x193: 0x72, 0x194: 0x72, 0x195: 0x72, 0x196: 0x72, 0x197: 0x72, + 0x198: 0x72, 0x199: 0x72, 0x19a: 0x72, 0x19b: 0x72, 0x19c: 0x72, 0x19d: 0x72, 0x19e: 0x72, 0x19f: 0x72, + 0x1a0: 0x72, 0x1a1: 0x72, 0x1a2: 0x72, 0x1a3: 0x72, 0x1a4: 0x72, 0x1a5: 0x72, 0x1a6: 0x72, 0x1a7: 0x72, + 0x1a8: 0x72, 0x1a9: 0x72, 0x1aa: 0x72, 0x1ab: 0x72, 0x1ac: 0x72, 0x1ad: 0x75, 0x1ae: 0x76, 0x1af: 0x72, + 0x1b0: 0x77, 0x1b1: 0x78, 0x1b2: 0x05, 0x1b3: 0x79, 0x1b4: 0x7a, 0x1b5: 0x7b, 0x1b6: 0x7c, 0x1b7: 0x7d, + 0x1b8: 0x7e, 0x1b9: 0x7f, 0x1ba: 0x80, 0x1bb: 0x81, 0x1bc: 0x82, 0x1bd: 0x82, 0x1be: 0x82, 0x1bf: 0x83, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x84, 0x1c1: 0x85, 0x1c2: 0x86, 0x1c3: 0x87, 0x1c4: 0x88, 0x1c5: 0x89, 0x1c6: 0x8a, 0x1c7: 0x8b, + 0x1c8: 0x8c, 0x1c9: 0x72, 0x1ca: 0x72, 0x1cb: 0x8d, 0x1cc: 0x82, 0x1cd: 0x8e, 0x1ce: 0x72, 0x1cf: 0x72, + 0x1d0: 0x8f, 0x1d1: 0x8f, 0x1d2: 0x8f, 0x1d3: 0x8f, 0x1d4: 0x8f, 0x1d5: 0x8f, 0x1d6: 0x8f, 0x1d7: 0x8f, + 0x1d8: 0x8f, 0x1d9: 0x8f, 0x1da: 0x8f, 0x1db: 0x8f, 0x1dc: 0x8f, 0x1dd: 0x8f, 0x1de: 0x8f, 0x1df: 0x8f, + 0x1e0: 0x8f, 0x1e1: 0x8f, 0x1e2: 0x8f, 0x1e3: 0x8f, 0x1e4: 0x8f, 0x1e5: 0x8f, 0x1e6: 0x8f, 0x1e7: 0x8f, + 0x1e8: 0x8f, 0x1e9: 0x8f, 0x1ea: 0x8f, 0x1eb: 0x8f, 0x1ec: 0x8f, 0x1ed: 0x8f, 0x1ee: 0x8f, 0x1ef: 0x8f, + 0x1f0: 0x8f, 0x1f1: 0x8f, 0x1f2: 0x8f, 0x1f3: 0x8f, 0x1f4: 0x8f, 0x1f5: 0x8f, 0x1f6: 0x8f, 0x1f7: 0x8f, + 0x1f8: 0x8f, 0x1f9: 0x8f, 0x1fa: 0x8f, 0x1fb: 0x8f, 0x1fc: 0x8f, 0x1fd: 0x8f, 0x1fe: 0x8f, 0x1ff: 0x8f, + // Block 0x8, offset 0x200 + 0x200: 0x8f, 0x201: 0x8f, 0x202: 0x8f, 0x203: 0x8f, 0x204: 0x8f, 0x205: 0x8f, 0x206: 0x8f, 0x207: 0x8f, + 0x208: 0x8f, 0x209: 0x8f, 0x20a: 0x8f, 0x20b: 0x8f, 0x20c: 0x8f, 0x20d: 0x8f, 0x20e: 0x8f, 0x20f: 0x8f, + 0x210: 0x8f, 0x211: 0x8f, 0x212: 0x8f, 0x213: 0x8f, 0x214: 0x8f, 0x215: 0x8f, 0x216: 0x8f, 0x217: 0x8f, + 0x218: 0x8f, 0x219: 0x8f, 0x21a: 0x8f, 0x21b: 0x8f, 0x21c: 0x8f, 0x21d: 0x8f, 0x21e: 0x8f, 0x21f: 0x8f, + 0x220: 0x8f, 0x221: 0x8f, 0x222: 0x8f, 0x223: 0x8f, 0x224: 0x8f, 0x225: 0x8f, 0x226: 0x8f, 0x227: 0x8f, + 0x228: 0x8f, 0x229: 0x8f, 0x22a: 0x8f, 0x22b: 0x8f, 0x22c: 0x8f, 0x22d: 0x8f, 0x22e: 0x8f, 0x22f: 0x8f, + 0x230: 0x8f, 0x231: 0x8f, 0x232: 0x8f, 0x233: 0x8f, 0x234: 0x8f, 0x235: 0x8f, 0x236: 0x8f, 0x237: 0x72, + 0x238: 0x8f, 0x239: 0x8f, 0x23a: 0x8f, 0x23b: 0x8f, 0x23c: 0x8f, 0x23d: 0x8f, 0x23e: 0x8f, 0x23f: 0x8f, + // Block 0x9, offset 0x240 + 0x240: 0x8f, 0x241: 0x8f, 0x242: 0x8f, 0x243: 0x8f, 0x244: 0x8f, 0x245: 0x8f, 0x246: 0x8f, 0x247: 0x8f, + 0x248: 0x8f, 0x249: 0x8f, 0x24a: 0x8f, 0x24b: 0x8f, 0x24c: 0x8f, 0x24d: 0x8f, 0x24e: 0x8f, 0x24f: 0x8f, + 0x250: 0x8f, 0x251: 0x8f, 0x252: 0x8f, 0x253: 0x8f, 0x254: 0x8f, 0x255: 0x8f, 0x256: 0x8f, 0x257: 0x8f, + 0x258: 0x8f, 0x259: 0x8f, 0x25a: 0x8f, 0x25b: 0x8f, 0x25c: 0x8f, 0x25d: 0x8f, 0x25e: 0x8f, 0x25f: 0x8f, + 0x260: 0x8f, 0x261: 0x8f, 0x262: 0x8f, 0x263: 0x8f, 0x264: 0x8f, 0x265: 0x8f, 0x266: 0x8f, 0x267: 0x8f, + 0x268: 0x8f, 0x269: 0x8f, 0x26a: 0x8f, 0x26b: 0x8f, 0x26c: 0x8f, 0x26d: 0x8f, 0x26e: 0x8f, 0x26f: 0x8f, + 0x270: 0x8f, 0x271: 0x8f, 0x272: 0x8f, 0x273: 0x8f, 0x274: 0x8f, 0x275: 0x8f, 0x276: 0x8f, 0x277: 0x8f, + 0x278: 0x8f, 0x279: 0x8f, 0x27a: 0x8f, 0x27b: 0x8f, 0x27c: 0x8f, 0x27d: 0x8f, 0x27e: 0x8f, 0x27f: 0x8f, + // Block 0xa, offset 0x280 + 0x280: 0x8f, 0x281: 0x8f, 0x282: 0x8f, 0x283: 0x8f, 0x284: 0x8f, 0x285: 0x8f, 0x286: 0x8f, 0x287: 0x8f, + 0x288: 0x8f, 0x289: 0x8f, 0x28a: 0x8f, 0x28b: 0x8f, 0x28c: 0x8f, 0x28d: 0x8f, 0x28e: 0x8f, 0x28f: 0x8f, + 0x290: 0x8f, 0x291: 0x8f, 0x292: 0x8f, 0x293: 0x8f, 0x294: 0x8f, 0x295: 0x8f, 0x296: 0x8f, 0x297: 0x8f, + 0x298: 0x8f, 0x299: 0x8f, 0x29a: 0x8f, 0x29b: 0x8f, 0x29c: 0x8f, 0x29d: 0x8f, 0x29e: 0x8f, 0x29f: 0x8f, + 0x2a0: 0x8f, 0x2a1: 0x8f, 0x2a2: 0x8f, 0x2a3: 0x8f, 0x2a4: 0x8f, 0x2a5: 0x8f, 0x2a6: 0x8f, 0x2a7: 0x8f, + 0x2a8: 0x8f, 0x2a9: 0x8f, 0x2aa: 0x8f, 0x2ab: 0x8f, 0x2ac: 0x8f, 0x2ad: 0x8f, 0x2ae: 0x8f, 0x2af: 0x8f, + 0x2b0: 0x8f, 0x2b1: 0x8f, 0x2b2: 0x8f, 0x2b3: 0x8f, 0x2b4: 0x8f, 0x2b5: 0x8f, 0x2b6: 0x8f, 0x2b7: 0x8f, + 0x2b8: 0x8f, 0x2b9: 0x8f, 0x2ba: 0x8f, 0x2bb: 0x8f, 0x2bc: 0x8f, 0x2bd: 0x8f, 0x2be: 0x8f, 0x2bf: 0x90, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x05, 0x2c1: 0x05, 0x2c2: 0x05, 0x2c3: 0x05, 0x2c4: 0x05, 0x2c5: 0x05, 0x2c6: 0x05, 0x2c7: 0x05, + 0x2c8: 0x05, 0x2c9: 0x05, 0x2ca: 0x05, 0x2cb: 0x05, 0x2cc: 0x05, 0x2cd: 0x05, 0x2ce: 0x05, 0x2cf: 0x05, + 0x2d0: 0x05, 0x2d1: 0x05, 0x2d2: 0x91, 0x2d3: 0x92, 0x2d4: 0x05, 0x2d5: 0x05, 0x2d6: 0x05, 0x2d7: 0x05, + 0x2d8: 0x93, 0x2d9: 0x94, 0x2da: 0x95, 0x2db: 0x96, 0x2dc: 0x97, 0x2dd: 0x98, 0x2de: 0x99, 0x2df: 0x9a, + 0x2e0: 0x9b, 0x2e1: 0x9c, 0x2e2: 0x05, 0x2e3: 0x9d, 0x2e4: 0x9e, 0x2e5: 0x9f, 0x2e6: 0xa0, 0x2e7: 0xa1, + 0x2e8: 0xa2, 0x2e9: 0xa3, 0x2ea: 0xa4, 0x2eb: 0xa5, 0x2ec: 0xa6, 0x2ed: 0xa7, 0x2ee: 0x05, 0x2ef: 0xa8, + 0x2f0: 0x05, 0x2f1: 0x05, 0x2f2: 0x05, 0x2f3: 0x05, 0x2f4: 0x05, 0x2f5: 0x05, 0x2f6: 0x05, 0x2f7: 0x05, + 0x2f8: 0x05, 0x2f9: 0x05, 0x2fa: 0x05, 0x2fb: 0x05, 0x2fc: 0x05, 0x2fd: 0x05, 0x2fe: 0x05, 0x2ff: 0x05, + // Block 0xc, offset 0x300 + 0x300: 0x05, 0x301: 0x05, 0x302: 0x05, 0x303: 0x05, 0x304: 0x05, 0x305: 0x05, 0x306: 0x05, 0x307: 0x05, + 0x308: 0x05, 0x309: 0x05, 0x30a: 0x05, 0x30b: 0x05, 0x30c: 0x05, 0x30d: 0x05, 0x30e: 0x05, 0x30f: 0x05, + 0x310: 0x05, 0x311: 0x05, 0x312: 0x05, 0x313: 0x05, 0x314: 0x05, 0x315: 0x05, 0x316: 0x05, 0x317: 0x05, + 0x318: 0x05, 0x319: 0x05, 0x31a: 0x05, 0x31b: 0x05, 0x31c: 0x05, 0x31d: 0x05, 0x31e: 0x05, 0x31f: 0x05, + 0x320: 0x05, 0x321: 0x05, 0x322: 0x05, 0x323: 0x05, 0x324: 0x05, 0x325: 0x05, 0x326: 0x05, 0x327: 0x05, + 0x328: 0x05, 0x329: 0x05, 0x32a: 0x05, 0x32b: 0x05, 0x32c: 0x05, 0x32d: 0x05, 0x32e: 0x05, 0x32f: 0x05, + 0x330: 0x05, 0x331: 0x05, 0x332: 0x05, 0x333: 0x05, 0x334: 0x05, 0x335: 0x05, 0x336: 0x05, 0x337: 0x05, + 0x338: 0x05, 0x339: 0x05, 0x33a: 0x05, 0x33b: 0x05, 0x33c: 0x05, 0x33d: 0x05, 0x33e: 0x05, 0x33f: 0x05, + // Block 0xd, offset 0x340 + 0x340: 0x05, 0x341: 0x05, 0x342: 0x05, 0x343: 0x05, 0x344: 0x05, 0x345: 0x05, 0x346: 0x05, 0x347: 0x05, + 0x348: 0x05, 0x349: 0x05, 0x34a: 0x05, 0x34b: 0x05, 0x34c: 0x05, 0x34d: 0x05, 0x34e: 0x05, 0x34f: 0x05, + 0x350: 0x05, 0x351: 0x05, 0x352: 0x05, 0x353: 0x05, 0x354: 0x05, 0x355: 0x05, 0x356: 0x05, 0x357: 0x05, + 0x358: 0x05, 0x359: 0x05, 0x35a: 0x05, 0x35b: 0x05, 0x35c: 0x05, 0x35d: 0x05, 0x35e: 0xa9, 0x35f: 0xaa, + // Block 0xe, offset 0x380 + 0x380: 0x3e, 0x381: 0x3e, 0x382: 0x3e, 0x383: 0x3e, 0x384: 0x3e, 0x385: 0x3e, 0x386: 0x3e, 0x387: 0x3e, + 0x388: 0x3e, 0x389: 0x3e, 0x38a: 0x3e, 0x38b: 0x3e, 0x38c: 0x3e, 0x38d: 0x3e, 0x38e: 0x3e, 0x38f: 0x3e, + 0x390: 0x3e, 0x391: 0x3e, 0x392: 0x3e, 0x393: 0x3e, 0x394: 0x3e, 0x395: 0x3e, 0x396: 0x3e, 0x397: 0x3e, + 0x398: 0x3e, 0x399: 0x3e, 0x39a: 0x3e, 0x39b: 0x3e, 0x39c: 0x3e, 0x39d: 0x3e, 0x39e: 0x3e, 0x39f: 0x3e, + 0x3a0: 0x3e, 0x3a1: 0x3e, 0x3a2: 0x3e, 0x3a3: 0x3e, 0x3a4: 0x3e, 0x3a5: 0x3e, 0x3a6: 0x3e, 0x3a7: 0x3e, + 0x3a8: 0x3e, 0x3a9: 0x3e, 0x3aa: 0x3e, 0x3ab: 0x3e, 0x3ac: 0x3e, 0x3ad: 0x3e, 0x3ae: 0x3e, 0x3af: 0x3e, + 0x3b0: 0x3e, 0x3b1: 0x3e, 0x3b2: 0x3e, 0x3b3: 0x3e, 0x3b4: 0x3e, 0x3b5: 0x3e, 0x3b6: 0x3e, 0x3b7: 0x3e, + 0x3b8: 0x3e, 0x3b9: 0x3e, 0x3ba: 0x3e, 0x3bb: 0x3e, 0x3bc: 0x3e, 0x3bd: 0x3e, 0x3be: 0x3e, 0x3bf: 0x3e, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x3e, 0x3c1: 0x3e, 0x3c2: 0x3e, 0x3c3: 0x3e, 0x3c4: 0x3e, 0x3c5: 0x3e, 0x3c6: 0x3e, 0x3c7: 0x3e, + 0x3c8: 0x3e, 0x3c9: 0x3e, 0x3ca: 0x3e, 0x3cb: 0x3e, 0x3cc: 0x3e, 0x3cd: 0x3e, 0x3ce: 0x3e, 0x3cf: 0x3e, + 0x3d0: 0x3e, 0x3d1: 0x3e, 0x3d2: 0x3e, 0x3d3: 0x3e, 0x3d4: 0x3e, 0x3d5: 0x3e, 0x3d6: 0x3e, 0x3d7: 0x3e, + 0x3d8: 0x3e, 0x3d9: 0x3e, 0x3da: 0x3e, 0x3db: 0x3e, 0x3dc: 0x3e, 0x3dd: 0x3e, 0x3de: 0x3e, 0x3df: 0x3e, + 0x3e0: 0x3e, 0x3e1: 0x3e, 0x3e2: 0x3e, 0x3e3: 0x3e, 0x3e4: 0x82, 0x3e5: 0x82, 0x3e6: 0x82, 0x3e7: 0x82, + 0x3e8: 0xab, 0x3e9: 0xac, 0x3ea: 0x82, 0x3eb: 0xad, 0x3ec: 0xae, 0x3ed: 0xaf, 0x3ee: 0x72, 0x3ef: 0xb0, + 0x3f0: 0x72, 0x3f1: 0x72, 0x3f2: 0x72, 0x3f3: 0x72, 0x3f4: 0x72, 0x3f5: 0xb1, 0x3f6: 0xb2, 0x3f7: 0xb3, + 0x3f8: 0xb4, 0x3f9: 0xb5, 0x3fa: 0x72, 0x3fb: 0xb6, 0x3fc: 0xb7, 0x3fd: 0xb8, 0x3fe: 0xb9, 0x3ff: 0xba, + // Block 0x10, offset 0x400 + 0x400: 0xbb, 0x401: 0xbc, 0x402: 0x05, 0x403: 0xbd, 0x404: 0xbe, 0x405: 0xbf, 0x406: 0xc0, 0x407: 0xc1, + 0x40a: 0xc2, 0x40b: 0xc3, 0x40c: 0xc4, 0x40d: 0xc5, 0x40e: 0xc6, 0x40f: 0xc7, + 0x410: 0x05, 0x411: 0x05, 0x412: 0xc8, 0x413: 0xc9, 0x414: 0xca, 0x415: 0xcb, + 0x418: 0x05, 0x419: 0x05, 0x41a: 0x05, 0x41b: 0x05, 0x41c: 0xcc, 0x41d: 0xcd, + 0x420: 0xce, 0x421: 0xcf, 0x422: 0xd0, 0x423: 0xd1, 0x424: 0xd2, 0x426: 0xd3, 0x427: 0xb2, + 0x428: 0xd4, 0x429: 0xd5, 0x42a: 0xd6, 0x42b: 0xd7, 0x42c: 0xd8, 0x42d: 0xd9, 0x42e: 0xda, + 0x430: 0x05, 0x431: 0xdb, 0x432: 0xdc, 0x433: 0xdd, 0x434: 0xde, + 0x439: 0xdf, 0x43a: 0xe0, 0x43c: 0xe1, 0x43d: 0xe2, 0x43e: 0xe3, 0x43f: 0xe4, + // Block 0x11, offset 0x440 + 0x440: 0xe5, 0x441: 0xe6, 0x442: 0xe7, 0x443: 0xe8, 0x444: 0xe9, 0x445: 0xea, 0x446: 0xeb, 0x447: 0xec, + 0x448: 0xed, 0x44a: 0xee, 0x44b: 0xef, 0x44c: 0xf0, 0x44d: 0xf1, + 0x450: 0xf2, 0x451: 0xf3, 0x452: 0xf4, 0x453: 0xf5, 0x456: 0xf6, 0x457: 0xf7, + 0x458: 0xf8, 0x459: 0xf9, 0x45a: 0xfa, 0x45b: 0xfb, 0x45c: 0xfc, + 0x460: 0xfd, 0x462: 0xfe, 0x463: 0xff, 0x464: 0x100, 0x465: 0x101, 0x466: 0x102, 0x467: 0x103, + 0x468: 0x104, 0x469: 0x105, 0x46a: 0x106, 0x46b: 0x107, + 0x470: 0x108, 0x471: 0x109, 0x472: 0x10a, 0x474: 0x10b, 0x475: 0x10c, 0x476: 0x10d, + 0x47b: 0x10e, 0x47e: 0x10f, 0x47f: 0x110, + // Block 0x12, offset 0x480 + 0x480: 0x05, 0x481: 0x05, 0x482: 0x05, 0x483: 0x05, 0x484: 0x05, 0x485: 0x05, 0x486: 0x05, 0x487: 0x05, + 0x488: 0x05, 0x489: 0x05, 0x48a: 0x05, 0x48b: 0x05, 0x48c: 0x05, 0x48d: 0x05, 0x48e: 0x111, + 0x490: 0x72, 0x491: 0x112, 0x492: 0x05, 0x493: 0x05, 0x494: 0x05, 0x495: 0x113, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x05, 0x4c1: 0x05, 0x4c2: 0x05, 0x4c3: 0x05, 0x4c4: 0x05, 0x4c5: 0x05, 0x4c6: 0x05, 0x4c7: 0x05, + 0x4c8: 0x05, 0x4c9: 0x05, 0x4ca: 0x05, 0x4cb: 0x05, 0x4cc: 0x05, 0x4cd: 0x05, 0x4ce: 0x05, 0x4cf: 0x05, + 0x4d0: 0x114, + // Block 0x14, offset 0x500 + 0x510: 0x05, 0x511: 0x05, 0x512: 0x05, 0x513: 0x05, 0x514: 0x05, 0x515: 0x05, 0x516: 0x05, 0x517: 0x05, + 0x518: 0x05, 0x519: 0x115, + // Block 0x15, offset 0x540 + 0x560: 0x05, 0x561: 0x05, 0x562: 0x05, 0x563: 0x05, 0x564: 0x05, 0x565: 0x05, 0x566: 0x05, 0x567: 0x05, + 0x568: 0x107, 0x569: 0x116, 0x56b: 0x117, 0x56c: 0x118, 0x56d: 0x119, 0x56e: 0x11a, + 0x579: 0x05, 0x57a: 0x11b, 0x57c: 0x05, 0x57d: 0x11c, 0x57e: 0x11d, 0x57f: 0x11e, + // Block 0x16, offset 0x580 + 0x580: 0x05, 0x581: 0x05, 0x582: 0x05, 0x583: 0x05, 0x584: 0x05, 0x585: 0x05, 0x586: 0x05, 0x587: 0x05, + 0x588: 0x05, 0x589: 0x05, 0x58a: 0x05, 0x58b: 0x05, 0x58c: 0x05, 0x58d: 0x05, 0x58e: 0x05, 0x58f: 0x05, + 0x590: 0x05, 0x591: 0x05, 0x592: 0x05, 0x593: 0x05, 0x594: 0x05, 0x595: 0x05, 0x596: 0x05, 0x597: 0x05, + 0x598: 0x05, 0x599: 0x05, 0x59a: 0x05, 0x59b: 0x05, 0x59c: 0x05, 0x59d: 0x05, 0x59e: 0x05, 0x59f: 0x11f, + 0x5a0: 0x05, 0x5a1: 0x05, 0x5a2: 0x05, 0x5a3: 0x05, 0x5a4: 0x05, 0x5a5: 0x05, 0x5a6: 0x05, 0x5a7: 0x05, + 0x5a8: 0x05, 0x5a9: 0x05, 0x5aa: 0x05, 0x5ab: 0x05, 0x5ac: 0x05, 0x5ad: 0x05, 0x5ae: 0x05, 0x5af: 0x05, + 0x5b0: 0x05, 0x5b1: 0x05, 0x5b2: 0x05, 0x5b3: 0x120, 0x5b4: 0xdb, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x8f, 0x5c1: 0x8f, 0x5c2: 0x8f, 0x5c3: 0x8f, 0x5c4: 0x121, 0x5c5: 0x122, 0x5c6: 0x05, 0x5c7: 0x05, + 0x5c8: 0x05, 0x5c9: 0x05, 0x5ca: 0x05, 0x5cb: 0x123, + 0x5f0: 0x05, 0x5f1: 0x124, 0x5f2: 0x125, + // Block 0x18, offset 0x600 + 0x600: 0x72, 0x601: 0x72, 0x602: 0x72, 0x603: 0x126, 0x604: 0x127, 0x605: 0x128, 0x606: 0x129, 0x607: 0x12a, + 0x608: 0xbf, 0x609: 0x12b, 0x60b: 0x12c, 0x60c: 0x72, 0x60d: 0x12d, + 0x610: 0x72, 0x611: 0x12e, 0x612: 0x12f, 0x613: 0x130, 0x614: 0x131, 0x615: 0x132, 0x616: 0x72, 0x617: 0x72, + 0x618: 0x72, 0x619: 0x72, 0x61a: 0x133, 0x61b: 0x72, 0x61c: 0x72, 0x61d: 0x72, 0x61e: 0x72, 0x61f: 0x134, + 0x620: 0x72, 0x621: 0x72, 0x622: 0x72, 0x623: 0x72, 0x624: 0x72, 0x625: 0x72, 0x626: 0x72, 0x627: 0x72, + 0x628: 0x135, 0x629: 0x136, 0x62a: 0x137, + // Block 0x19, offset 0x640 + 0x640: 0x138, 0x644: 0x139, 0x645: 0x13a, + 0x64b: 0x13b, + 0x660: 0x05, 0x661: 0x05, 0x662: 0x05, 0x663: 0x13c, 0x664: 0x13d, 0x665: 0x13e, + 0x671: 0x13f, 0x672: 0x140, 0x674: 0x141, + 0x678: 0x142, 0x679: 0x143, 0x67a: 0x144, 0x67b: 0x145, + // Block 0x1a, offset 0x680 + 0x680: 0x146, 0x681: 0x72, 0x682: 0x147, 0x683: 0x148, 0x684: 0x72, 0x685: 0x72, 0x686: 0x149, 0x687: 0x14a, + 0x688: 0x14b, 0x689: 0x14c, 0x68c: 0x72, 0x68d: 0x72, 0x68e: 0x72, 0x68f: 0x72, + 0x690: 0x72, 0x691: 0x72, 0x692: 0x72, 0x693: 0x72, 0x694: 0x72, 0x695: 0x72, 0x696: 0x72, 0x697: 0x72, + 0x698: 0x72, 0x699: 0x72, 0x69a: 0x72, 0x69b: 0x14d, 0x69c: 0x72, 0x69d: 0x14e, 0x69e: 0x72, 0x69f: 0x14f, + 0x6a0: 0x150, 0x6a1: 0x151, 0x6a2: 0x152, 0x6a4: 0x72, 0x6a5: 0x153, 0x6a6: 0x72, 0x6a7: 0x154, + 0x6a8: 0x72, 0x6a9: 0x155, 0x6aa: 0x156, 0x6ab: 0x157, 0x6ac: 0x72, 0x6ad: 0x72, 0x6ae: 0x158, 0x6af: 0x159, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x8f, 0x6c1: 0x8f, 0x6c2: 0x8f, 0x6c3: 0x8f, 0x6c4: 0x8f, 0x6c5: 0x8f, 0x6c6: 0x8f, 0x6c7: 0x8f, + 0x6c8: 0x8f, 0x6c9: 0x8f, 0x6ca: 0x8f, 0x6cb: 0x8f, 0x6cc: 0x8f, 0x6cd: 0x8f, 0x6ce: 0x8f, 0x6cf: 0x8f, + 0x6d0: 0x8f, 0x6d1: 0x8f, 0x6d2: 0x8f, 0x6d3: 0x8f, 0x6d4: 0x8f, 0x6d5: 0x8f, 0x6d6: 0x8f, 0x6d7: 0x8f, + 0x6d8: 0x8f, 0x6d9: 0x8f, 0x6da: 0x8f, 0x6db: 0x15a, 0x6dc: 0x8f, 0x6dd: 0x8f, 0x6de: 0x8f, 0x6df: 0x8f, + 0x6e0: 0x8f, 0x6e1: 0x8f, 0x6e2: 0x8f, 0x6e3: 0x8f, 0x6e4: 0x8f, 0x6e5: 0x8f, 0x6e6: 0x8f, 0x6e7: 0x8f, + 0x6e8: 0x8f, 0x6e9: 0x8f, 0x6ea: 0x8f, 0x6eb: 0x8f, 0x6ec: 0x8f, 0x6ed: 0x8f, 0x6ee: 0x8f, 0x6ef: 0x8f, + 0x6f0: 0x8f, 0x6f1: 0x8f, 0x6f2: 0x8f, 0x6f3: 0x8f, 0x6f4: 0x8f, 0x6f5: 0x8f, 0x6f6: 0x8f, 0x6f7: 0x8f, + 0x6f8: 0x8f, 0x6f9: 0x8f, 0x6fa: 0x8f, 0x6fb: 0x8f, 0x6fc: 0x8f, 0x6fd: 0x8f, 0x6fe: 0x8f, 0x6ff: 0x8f, + // Block 0x1c, offset 0x700 + 0x700: 0x8f, 0x701: 0x8f, 0x702: 0x8f, 0x703: 0x8f, 0x704: 0x8f, 0x705: 0x8f, 0x706: 0x8f, 0x707: 0x8f, + 0x708: 0x8f, 0x709: 0x8f, 0x70a: 0x8f, 0x70b: 0x8f, 0x70c: 0x8f, 0x70d: 0x8f, 0x70e: 0x8f, 0x70f: 0x8f, + 0x710: 0x8f, 0x711: 0x8f, 0x712: 0x8f, 0x713: 0x8f, 0x714: 0x8f, 0x715: 0x8f, 0x716: 0x8f, 0x717: 0x8f, + 0x718: 0x8f, 0x719: 0x8f, 0x71a: 0x8f, 0x71b: 0x8f, 0x71c: 0x15b, 0x71d: 0x8f, 0x71e: 0x8f, 0x71f: 0x8f, + 0x720: 0x15c, 0x721: 0x8f, 0x722: 0x8f, 0x723: 0x8f, 0x724: 0x8f, 0x725: 0x8f, 0x726: 0x8f, 0x727: 0x8f, + 0x728: 0x8f, 0x729: 0x8f, 0x72a: 0x8f, 0x72b: 0x8f, 0x72c: 0x8f, 0x72d: 0x8f, 0x72e: 0x8f, 0x72f: 0x8f, + 0x730: 0x8f, 0x731: 0x8f, 0x732: 0x8f, 0x733: 0x8f, 0x734: 0x8f, 0x735: 0x8f, 0x736: 0x8f, 0x737: 0x8f, + 0x738: 0x8f, 0x739: 0x8f, 0x73a: 0x8f, 0x73b: 0x8f, 0x73c: 0x8f, 0x73d: 0x8f, 0x73e: 0x8f, 0x73f: 0x8f, + // Block 0x1d, offset 0x740 + 0x740: 0x8f, 0x741: 0x8f, 0x742: 0x8f, 0x743: 0x8f, 0x744: 0x8f, 0x745: 0x8f, 0x746: 0x8f, 0x747: 0x8f, + 0x748: 0x8f, 0x749: 0x8f, 0x74a: 0x8f, 0x74b: 0x8f, 0x74c: 0x8f, 0x74d: 0x8f, 0x74e: 0x8f, 0x74f: 0x8f, + 0x750: 0x8f, 0x751: 0x8f, 0x752: 0x8f, 0x753: 0x8f, 0x754: 0x8f, 0x755: 0x8f, 0x756: 0x8f, 0x757: 0x8f, + 0x758: 0x8f, 0x759: 0x8f, 0x75a: 0x8f, 0x75b: 0x8f, 0x75c: 0x8f, 0x75d: 0x8f, 0x75e: 0x8f, 0x75f: 0x8f, + 0x760: 0x8f, 0x761: 0x8f, 0x762: 0x8f, 0x763: 0x8f, 0x764: 0x8f, 0x765: 0x8f, 0x766: 0x8f, 0x767: 0x8f, + 0x768: 0x8f, 0x769: 0x8f, 0x76a: 0x8f, 0x76b: 0x8f, 0x76c: 0x8f, 0x76d: 0x8f, 0x76e: 0x8f, 0x76f: 0x8f, + 0x770: 0x8f, 0x771: 0x8f, 0x772: 0x8f, 0x773: 0x8f, 0x774: 0x8f, 0x775: 0x8f, 0x776: 0x8f, 0x777: 0x8f, + 0x778: 0x8f, 0x779: 0x8f, 0x77a: 0x15d, 0x77b: 0x8f, 0x77c: 0x8f, 0x77d: 0x8f, 0x77e: 0x8f, 0x77f: 0x8f, + // Block 0x1e, offset 0x780 + 0x780: 0x8f, 0x781: 0x8f, 0x782: 0x8f, 0x783: 0x8f, 0x784: 0x8f, 0x785: 0x8f, 0x786: 0x8f, 0x787: 0x8f, + 0x788: 0x8f, 0x789: 0x8f, 0x78a: 0x8f, 0x78b: 0x8f, 0x78c: 0x8f, 0x78d: 0x8f, 0x78e: 0x8f, 0x78f: 0x8f, + 0x790: 0x8f, 0x791: 0x8f, 0x792: 0x8f, 0x793: 0x8f, 0x794: 0x8f, 0x795: 0x8f, 0x796: 0x8f, 0x797: 0x8f, + 0x798: 0x8f, 0x799: 0x8f, 0x79a: 0x8f, 0x79b: 0x8f, 0x79c: 0x8f, 0x79d: 0x8f, 0x79e: 0x8f, 0x79f: 0x8f, + 0x7a0: 0x8f, 0x7a1: 0x8f, 0x7a2: 0x8f, 0x7a3: 0x8f, 0x7a4: 0x8f, 0x7a5: 0x8f, 0x7a6: 0x8f, 0x7a7: 0x8f, + 0x7a8: 0x8f, 0x7a9: 0x8f, 0x7aa: 0x8f, 0x7ab: 0x8f, 0x7ac: 0x8f, 0x7ad: 0x8f, 0x7ae: 0x8f, 0x7af: 0x15e, + // Block 0x1f, offset 0x7c0 + 0x7e0: 0x82, 0x7e1: 0x82, 0x7e2: 0x82, 0x7e3: 0x82, 0x7e4: 0x82, 0x7e5: 0x82, 0x7e6: 0x82, 0x7e7: 0x82, + 0x7e8: 0x15f, + // Block 0x20, offset 0x800 + 0x800: 0x8f, 0x801: 0x8f, 0x802: 0x8f, 0x803: 0x8f, 0x804: 0x8f, 0x805: 0x8f, 0x806: 0x8f, 0x807: 0x8f, + 0x808: 0x8f, 0x809: 0x8f, 0x80a: 0x8f, 0x80b: 0x8f, 0x80c: 0x8f, 0x80d: 0x160, + // Block 0x21, offset 0x840 + 0x850: 0x0e, 0x851: 0x0f, 0x852: 0x10, 0x853: 0x11, 0x854: 0x12, 0x856: 0x13, 0x857: 0x0a, + 0x858: 0x14, 0x85b: 0x15, 0x85d: 0x16, 0x85e: 0x17, 0x85f: 0x18, + 0x860: 0x07, 0x861: 0x07, 0x862: 0x07, 0x863: 0x07, 0x864: 0x07, 0x865: 0x07, 0x866: 0x07, 0x867: 0x07, + 0x868: 0x07, 0x869: 0x07, 0x86a: 0x19, 0x86b: 0x1a, 0x86c: 0x1b, 0x86d: 0x07, 0x86e: 0x1c, 0x86f: 0x1d, + 0x870: 0x07, 0x871: 0x1e, + // Block 0x22, offset 0x880 + 0x880: 0x161, 0x881: 0x3e, 0x884: 0x3e, 0x885: 0x3e, 0x886: 0x3e, 0x887: 0x162, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x3e, 0x8c1: 0x3e, 0x8c2: 0x3e, 0x8c3: 0x3e, 0x8c4: 0x3e, 0x8c5: 0x3e, 0x8c6: 0x3e, 0x8c7: 0x3e, + 0x8c8: 0x3e, 0x8c9: 0x3e, 0x8ca: 0x3e, 0x8cb: 0x3e, 0x8cc: 0x3e, 0x8cd: 0x3e, 0x8ce: 0x3e, 0x8cf: 0x3e, + 0x8d0: 0x3e, 0x8d1: 0x3e, 0x8d2: 0x3e, 0x8d3: 0x3e, 0x8d4: 0x3e, 0x8d5: 0x3e, 0x8d6: 0x3e, 0x8d7: 0x3e, + 0x8d8: 0x3e, 0x8d9: 0x3e, 0x8da: 0x3e, 0x8db: 0x3e, 0x8dc: 0x3e, 0x8dd: 0x3e, 0x8de: 0x3e, 0x8df: 0x3e, + 0x8e0: 0x3e, 0x8e1: 0x3e, 0x8e2: 0x3e, 0x8e3: 0x3e, 0x8e4: 0x3e, 0x8e5: 0x3e, 0x8e6: 0x3e, 0x8e7: 0x3e, + 0x8e8: 0x3e, 0x8e9: 0x3e, 0x8ea: 0x3e, 0x8eb: 0x3e, 0x8ec: 0x3e, 0x8ed: 0x3e, 0x8ee: 0x3e, 0x8ef: 0x3e, + 0x8f0: 0x3e, 0x8f1: 0x3e, 0x8f2: 0x3e, 0x8f3: 0x3e, 0x8f4: 0x3e, 0x8f5: 0x3e, 0x8f6: 0x3e, 0x8f7: 0x3e, + 0x8f8: 0x3e, 0x8f9: 0x3e, 0x8fa: 0x3e, 0x8fb: 0x3e, 0x8fc: 0x3e, 0x8fd: 0x3e, 0x8fe: 0x3e, 0x8ff: 0x163, + // Block 0x24, offset 0x900 + 0x920: 0x20, + 0x930: 0x0c, 0x931: 0x0c, 0x932: 0x0c, 0x933: 0x0c, 0x934: 0x0c, 0x935: 0x0c, 0x936: 0x0c, 0x937: 0x0c, + 0x938: 0x0c, 0x939: 0x0c, 0x93a: 0x0c, 0x93b: 0x0c, 0x93c: 0x0c, 0x93d: 0x0c, 0x93e: 0x0c, 0x93f: 0x21, + // Block 0x25, offset 0x940 + 0x940: 0x0c, 0x941: 0x0c, 0x942: 0x0c, 0x943: 0x0c, 0x944: 0x0c, 0x945: 0x0c, 0x946: 0x0c, 0x947: 0x0c, + 0x948: 0x0c, 0x949: 0x0c, 0x94a: 0x0c, 0x94b: 0x0c, 0x94c: 0x0c, 0x94d: 0x0c, 0x94e: 0x0c, 0x94f: 0x21, +} + +// Total table size 27776 bytes (27KiB); checksum: 811C9DC5 diff --git a/vendor/golang.org/x/text/secure/precis/tables9.0.0.go b/vendor/golang.org/x/text/secure/precis/tables9.0.0.go new file mode 100644 index 00000000000..2292b7cb0ce --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/tables9.0.0.go @@ -0,0 +1,3791 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +//go:build !go1.10 +// +build !go1.10 + +package precis + +// UnicodeVersion is the Unicode version from which the tables in this package are derived. +const UnicodeVersion = "9.0.0" + +// lookup returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookup(s []byte) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupUnsafe(s []byte) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// lookupString returns the trie value for the first UTF-8 encoding in s and +// the width in bytes of this encoding. The size will be 0 if s does not +// hold enough bytes to complete the encoding. len(s) must be greater than 0. +func (t *derivedPropertiesTrie) lookupString(s string) (v uint8, sz int) { + c0 := s[0] + switch { + case c0 < 0x80: // is ASCII + return derivedPropertiesValues[c0], 1 + case c0 < 0xC2: + return 0, 1 // Illegal UTF-8: not a starter, not ASCII. + case c0 < 0xE0: // 2-byte UTF-8 + if len(s) < 2 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c1), 2 + case c0 < 0xF0: // 3-byte UTF-8 + if len(s) < 3 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c2), 3 + case c0 < 0xF8: // 4-byte UTF-8 + if len(s) < 4 { + return 0, 0 + } + i := derivedPropertiesIndex[c0] + c1 := s[1] + if c1 < 0x80 || 0xC0 <= c1 { + return 0, 1 // Illegal UTF-8: not a continuation byte. + } + o := uint32(i)<<6 + uint32(c1) + i = derivedPropertiesIndex[o] + c2 := s[2] + if c2 < 0x80 || 0xC0 <= c2 { + return 0, 2 // Illegal UTF-8: not a continuation byte. + } + o = uint32(i)<<6 + uint32(c2) + i = derivedPropertiesIndex[o] + c3 := s[3] + if c3 < 0x80 || 0xC0 <= c3 { + return 0, 3 // Illegal UTF-8: not a continuation byte. + } + return t.lookupValue(uint32(i), c3), 4 + } + // Illegal rune + return 0, 1 +} + +// lookupStringUnsafe returns the trie value for the first UTF-8 encoding in s. +// s must start with a full and valid UTF-8 encoded rune. +func (t *derivedPropertiesTrie) lookupStringUnsafe(s string) uint8 { + c0 := s[0] + if c0 < 0x80 { // is ASCII + return derivedPropertiesValues[c0] + } + i := derivedPropertiesIndex[c0] + if c0 < 0xE0 { // 2-byte UTF-8 + return t.lookupValue(uint32(i), s[1]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[1])] + if c0 < 0xF0 { // 3-byte UTF-8 + return t.lookupValue(uint32(i), s[2]) + } + i = derivedPropertiesIndex[uint32(i)<<6+uint32(s[2])] + if c0 < 0xF8 { // 4-byte UTF-8 + return t.lookupValue(uint32(i), s[3]) + } + return 0 +} + +// derivedPropertiesTrie. Total size: 25344 bytes (24.75 KiB). Checksum: c5b977d76d42d8a. +type derivedPropertiesTrie struct{} + +func newDerivedPropertiesTrie(i int) *derivedPropertiesTrie { + return &derivedPropertiesTrie{} +} + +// lookupValue determines the type of block n and looks up the value for b. +func (t *derivedPropertiesTrie) lookupValue(n uint32, b byte) uint8 { + switch { + default: + return uint8(derivedPropertiesValues[n<<6+uint32(b)]) + } +} + +// derivedPropertiesValues: 324 blocks, 20736 entries, 20736 bytes +// The third block is the zero block. +var derivedPropertiesValues = [20736]uint8{ + // Block 0x0, offset 0x0 + 0x00: 0x0040, 0x01: 0x0040, 0x02: 0x0040, 0x03: 0x0040, 0x04: 0x0040, 0x05: 0x0040, + 0x06: 0x0040, 0x07: 0x0040, 0x08: 0x0040, 0x09: 0x0040, 0x0a: 0x0040, 0x0b: 0x0040, + 0x0c: 0x0040, 0x0d: 0x0040, 0x0e: 0x0040, 0x0f: 0x0040, 0x10: 0x0040, 0x11: 0x0040, + 0x12: 0x0040, 0x13: 0x0040, 0x14: 0x0040, 0x15: 0x0040, 0x16: 0x0040, 0x17: 0x0040, + 0x18: 0x0040, 0x19: 0x0040, 0x1a: 0x0040, 0x1b: 0x0040, 0x1c: 0x0040, 0x1d: 0x0040, + 0x1e: 0x0040, 0x1f: 0x0040, 0x20: 0x0080, 0x21: 0x00c0, 0x22: 0x00c0, 0x23: 0x00c0, + 0x24: 0x00c0, 0x25: 0x00c0, 0x26: 0x00c0, 0x27: 0x00c0, 0x28: 0x00c0, 0x29: 0x00c0, + 0x2a: 0x00c0, 0x2b: 0x00c0, 0x2c: 0x00c0, 0x2d: 0x00c0, 0x2e: 0x00c0, 0x2f: 0x00c0, + 0x30: 0x00c0, 0x31: 0x00c0, 0x32: 0x00c0, 0x33: 0x00c0, 0x34: 0x00c0, 0x35: 0x00c0, + 0x36: 0x00c0, 0x37: 0x00c0, 0x38: 0x00c0, 0x39: 0x00c0, 0x3a: 0x00c0, 0x3b: 0x00c0, + 0x3c: 0x00c0, 0x3d: 0x00c0, 0x3e: 0x00c0, 0x3f: 0x00c0, + // Block 0x1, offset 0x40 + 0x40: 0x00c0, 0x41: 0x00c0, 0x42: 0x00c0, 0x43: 0x00c0, 0x44: 0x00c0, 0x45: 0x00c0, + 0x46: 0x00c0, 0x47: 0x00c0, 0x48: 0x00c0, 0x49: 0x00c0, 0x4a: 0x00c0, 0x4b: 0x00c0, + 0x4c: 0x00c0, 0x4d: 0x00c0, 0x4e: 0x00c0, 0x4f: 0x00c0, 0x50: 0x00c0, 0x51: 0x00c0, + 0x52: 0x00c0, 0x53: 0x00c0, 0x54: 0x00c0, 0x55: 0x00c0, 0x56: 0x00c0, 0x57: 0x00c0, + 0x58: 0x00c0, 0x59: 0x00c0, 0x5a: 0x00c0, 0x5b: 0x00c0, 0x5c: 0x00c0, 0x5d: 0x00c0, + 0x5e: 0x00c0, 0x5f: 0x00c0, 0x60: 0x00c0, 0x61: 0x00c0, 0x62: 0x00c0, 0x63: 0x00c0, + 0x64: 0x00c0, 0x65: 0x00c0, 0x66: 0x00c0, 0x67: 0x00c0, 0x68: 0x00c0, 0x69: 0x00c0, + 0x6a: 0x00c0, 0x6b: 0x00c0, 0x6c: 0x00c7, 0x6d: 0x00c0, 0x6e: 0x00c0, 0x6f: 0x00c0, + 0x70: 0x00c0, 0x71: 0x00c0, 0x72: 0x00c0, 0x73: 0x00c0, 0x74: 0x00c0, 0x75: 0x00c0, + 0x76: 0x00c0, 0x77: 0x00c0, 0x78: 0x00c0, 0x79: 0x00c0, 0x7a: 0x00c0, 0x7b: 0x00c0, + 0x7c: 0x00c0, 0x7d: 0x00c0, 0x7e: 0x00c0, 0x7f: 0x0040, + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc0: 0x0040, 0xc1: 0x0040, 0xc2: 0x0040, 0xc3: 0x0040, 0xc4: 0x0040, 0xc5: 0x0040, + 0xc6: 0x0040, 0xc7: 0x0040, 0xc8: 0x0040, 0xc9: 0x0040, 0xca: 0x0040, 0xcb: 0x0040, + 0xcc: 0x0040, 0xcd: 0x0040, 0xce: 0x0040, 0xcf: 0x0040, 0xd0: 0x0040, 0xd1: 0x0040, + 0xd2: 0x0040, 0xd3: 0x0040, 0xd4: 0x0040, 0xd5: 0x0040, 0xd6: 0x0040, 0xd7: 0x0040, + 0xd8: 0x0040, 0xd9: 0x0040, 0xda: 0x0040, 0xdb: 0x0040, 0xdc: 0x0040, 0xdd: 0x0040, + 0xde: 0x0040, 0xdf: 0x0040, 0xe0: 0x0080, 0xe1: 0x0080, 0xe2: 0x0080, 0xe3: 0x0080, + 0xe4: 0x0080, 0xe5: 0x0080, 0xe6: 0x0080, 0xe7: 0x0080, 0xe8: 0x0080, 0xe9: 0x0080, + 0xea: 0x0080, 0xeb: 0x0080, 0xec: 0x0080, 0xed: 0x0040, 0xee: 0x0080, 0xef: 0x0080, + 0xf0: 0x0080, 0xf1: 0x0080, 0xf2: 0x0080, 0xf3: 0x0080, 0xf4: 0x0080, 0xf5: 0x0080, + 0xf6: 0x0080, 0xf7: 0x004f, 0xf8: 0x0080, 0xf9: 0x0080, 0xfa: 0x0080, 0xfb: 0x0080, + 0xfc: 0x0080, 0xfd: 0x0080, 0xfe: 0x0080, 0xff: 0x0080, + // Block 0x4, offset 0x100 + 0x100: 0x00c0, 0x101: 0x00c0, 0x102: 0x00c0, 0x103: 0x00c0, 0x104: 0x00c0, 0x105: 0x00c0, + 0x106: 0x00c0, 0x107: 0x00c0, 0x108: 0x00c0, 0x109: 0x00c0, 0x10a: 0x00c0, 0x10b: 0x00c0, + 0x10c: 0x00c0, 0x10d: 0x00c0, 0x10e: 0x00c0, 0x10f: 0x00c0, 0x110: 0x00c0, 0x111: 0x00c0, + 0x112: 0x00c0, 0x113: 0x00c0, 0x114: 0x00c0, 0x115: 0x00c0, 0x116: 0x00c0, 0x117: 0x0080, + 0x118: 0x00c0, 0x119: 0x00c0, 0x11a: 0x00c0, 0x11b: 0x00c0, 0x11c: 0x00c0, 0x11d: 0x00c0, + 0x11e: 0x00c0, 0x11f: 0x00c0, 0x120: 0x00c0, 0x121: 0x00c0, 0x122: 0x00c0, 0x123: 0x00c0, + 0x124: 0x00c0, 0x125: 0x00c0, 0x126: 0x00c0, 0x127: 0x00c0, 0x128: 0x00c0, 0x129: 0x00c0, + 0x12a: 0x00c0, 0x12b: 0x00c0, 0x12c: 0x00c0, 0x12d: 0x00c0, 0x12e: 0x00c0, 0x12f: 0x00c0, + 0x130: 0x00c0, 0x131: 0x00c0, 0x132: 0x00c0, 0x133: 0x00c0, 0x134: 0x00c0, 0x135: 0x00c0, + 0x136: 0x00c0, 0x137: 0x0080, 0x138: 0x00c0, 0x139: 0x00c0, 0x13a: 0x00c0, 0x13b: 0x00c0, + 0x13c: 0x00c0, 0x13d: 0x00c0, 0x13e: 0x00c0, 0x13f: 0x00c0, + // Block 0x5, offset 0x140 + 0x140: 0x00c0, 0x141: 0x00c0, 0x142: 0x00c0, 0x143: 0x00c0, 0x144: 0x00c0, 0x145: 0x00c0, + 0x146: 0x00c0, 0x147: 0x00c0, 0x148: 0x00c0, 0x149: 0x00c0, 0x14a: 0x00c0, 0x14b: 0x00c0, + 0x14c: 0x00c0, 0x14d: 0x00c0, 0x14e: 0x00c0, 0x14f: 0x00c0, 0x150: 0x00c0, 0x151: 0x00c0, + 0x152: 0x00c0, 0x153: 0x00c0, 0x154: 0x00c0, 0x155: 0x00c0, 0x156: 0x00c0, 0x157: 0x00c0, + 0x158: 0x00c0, 0x159: 0x00c0, 0x15a: 0x00c0, 0x15b: 0x00c0, 0x15c: 0x00c0, 0x15d: 0x00c0, + 0x15e: 0x00c0, 0x15f: 0x00c0, 0x160: 0x00c0, 0x161: 0x00c0, 0x162: 0x00c0, 0x163: 0x00c0, + 0x164: 0x00c0, 0x165: 0x00c0, 0x166: 0x00c0, 0x167: 0x00c0, 0x168: 0x00c0, 0x169: 0x00c0, + 0x16a: 0x00c0, 0x16b: 0x00c0, 0x16c: 0x00c0, 0x16d: 0x00c0, 0x16e: 0x00c0, 0x16f: 0x00c0, + 0x170: 0x00c0, 0x171: 0x00c0, 0x172: 0x0080, 0x173: 0x0080, 0x174: 0x00c0, 0x175: 0x00c0, + 0x176: 0x00c0, 0x177: 0x00c0, 0x178: 0x00c0, 0x179: 0x00c0, 0x17a: 0x00c0, 0x17b: 0x00c0, + 0x17c: 0x00c0, 0x17d: 0x00c0, 0x17e: 0x00c0, 0x17f: 0x0080, + // Block 0x6, offset 0x180 + 0x180: 0x0080, 0x181: 0x00c0, 0x182: 0x00c0, 0x183: 0x00c0, 0x184: 0x00c0, 0x185: 0x00c0, + 0x186: 0x00c0, 0x187: 0x00c0, 0x188: 0x00c0, 0x189: 0x0080, 0x18a: 0x00c0, 0x18b: 0x00c0, + 0x18c: 0x00c0, 0x18d: 0x00c0, 0x18e: 0x00c0, 0x18f: 0x00c0, 0x190: 0x00c0, 0x191: 0x00c0, + 0x192: 0x00c0, 0x193: 0x00c0, 0x194: 0x00c0, 0x195: 0x00c0, 0x196: 0x00c0, 0x197: 0x00c0, + 0x198: 0x00c0, 0x199: 0x00c0, 0x19a: 0x00c0, 0x19b: 0x00c0, 0x19c: 0x00c0, 0x19d: 0x00c0, + 0x19e: 0x00c0, 0x19f: 0x00c0, 0x1a0: 0x00c0, 0x1a1: 0x00c0, 0x1a2: 0x00c0, 0x1a3: 0x00c0, + 0x1a4: 0x00c0, 0x1a5: 0x00c0, 0x1a6: 0x00c0, 0x1a7: 0x00c0, 0x1a8: 0x00c0, 0x1a9: 0x00c0, + 0x1aa: 0x00c0, 0x1ab: 0x00c0, 0x1ac: 0x00c0, 0x1ad: 0x00c0, 0x1ae: 0x00c0, 0x1af: 0x00c0, + 0x1b0: 0x00c0, 0x1b1: 0x00c0, 0x1b2: 0x00c0, 0x1b3: 0x00c0, 0x1b4: 0x00c0, 0x1b5: 0x00c0, + 0x1b6: 0x00c0, 0x1b7: 0x00c0, 0x1b8: 0x00c0, 0x1b9: 0x00c0, 0x1ba: 0x00c0, 0x1bb: 0x00c0, + 0x1bc: 0x00c0, 0x1bd: 0x00c0, 0x1be: 0x00c0, 0x1bf: 0x0080, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x00c0, 0x1c1: 0x00c0, 0x1c2: 0x00c0, 0x1c3: 0x00c0, 0x1c4: 0x00c0, 0x1c5: 0x00c0, + 0x1c6: 0x00c0, 0x1c7: 0x00c0, 0x1c8: 0x00c0, 0x1c9: 0x00c0, 0x1ca: 0x00c0, 0x1cb: 0x00c0, + 0x1cc: 0x00c0, 0x1cd: 0x00c0, 0x1ce: 0x00c0, 0x1cf: 0x00c0, 0x1d0: 0x00c0, 0x1d1: 0x00c0, + 0x1d2: 0x00c0, 0x1d3: 0x00c0, 0x1d4: 0x00c0, 0x1d5: 0x00c0, 0x1d6: 0x00c0, 0x1d7: 0x00c0, + 0x1d8: 0x00c0, 0x1d9: 0x00c0, 0x1da: 0x00c0, 0x1db: 0x00c0, 0x1dc: 0x00c0, 0x1dd: 0x00c0, + 0x1de: 0x00c0, 0x1df: 0x00c0, 0x1e0: 0x00c0, 0x1e1: 0x00c0, 0x1e2: 0x00c0, 0x1e3: 0x00c0, + 0x1e4: 0x00c0, 0x1e5: 0x00c0, 0x1e6: 0x00c0, 0x1e7: 0x00c0, 0x1e8: 0x00c0, 0x1e9: 0x00c0, + 0x1ea: 0x00c0, 0x1eb: 0x00c0, 0x1ec: 0x00c0, 0x1ed: 0x00c0, 0x1ee: 0x00c0, 0x1ef: 0x00c0, + 0x1f0: 0x00c0, 0x1f1: 0x00c0, 0x1f2: 0x00c0, 0x1f3: 0x00c0, 0x1f4: 0x00c0, 0x1f5: 0x00c0, + 0x1f6: 0x00c0, 0x1f7: 0x00c0, 0x1f8: 0x00c0, 0x1f9: 0x00c0, 0x1fa: 0x00c0, 0x1fb: 0x00c0, + 0x1fc: 0x00c0, 0x1fd: 0x00c0, 0x1fe: 0x00c0, 0x1ff: 0x00c0, + // Block 0x8, offset 0x200 + 0x200: 0x00c0, 0x201: 0x00c0, 0x202: 0x00c0, 0x203: 0x00c0, 0x204: 0x0080, 0x205: 0x0080, + 0x206: 0x0080, 0x207: 0x0080, 0x208: 0x0080, 0x209: 0x0080, 0x20a: 0x0080, 0x20b: 0x0080, + 0x20c: 0x0080, 0x20d: 0x00c0, 0x20e: 0x00c0, 0x20f: 0x00c0, 0x210: 0x00c0, 0x211: 0x00c0, + 0x212: 0x00c0, 0x213: 0x00c0, 0x214: 0x00c0, 0x215: 0x00c0, 0x216: 0x00c0, 0x217: 0x00c0, + 0x218: 0x00c0, 0x219: 0x00c0, 0x21a: 0x00c0, 0x21b: 0x00c0, 0x21c: 0x00c0, 0x21d: 0x00c0, + 0x21e: 0x00c0, 0x21f: 0x00c0, 0x220: 0x00c0, 0x221: 0x00c0, 0x222: 0x00c0, 0x223: 0x00c0, + 0x224: 0x00c0, 0x225: 0x00c0, 0x226: 0x00c0, 0x227: 0x00c0, 0x228: 0x00c0, 0x229: 0x00c0, + 0x22a: 0x00c0, 0x22b: 0x00c0, 0x22c: 0x00c0, 0x22d: 0x00c0, 0x22e: 0x00c0, 0x22f: 0x00c0, + 0x230: 0x00c0, 0x231: 0x0080, 0x232: 0x0080, 0x233: 0x0080, 0x234: 0x00c0, 0x235: 0x00c0, + 0x236: 0x00c0, 0x237: 0x00c0, 0x238: 0x00c0, 0x239: 0x00c0, 0x23a: 0x00c0, 0x23b: 0x00c0, + 0x23c: 0x00c0, 0x23d: 0x00c0, 0x23e: 0x00c0, 0x23f: 0x00c0, + // Block 0x9, offset 0x240 + 0x240: 0x00c0, 0x241: 0x00c0, 0x242: 0x00c0, 0x243: 0x00c0, 0x244: 0x00c0, 0x245: 0x00c0, + 0x246: 0x00c0, 0x247: 0x00c0, 0x248: 0x00c0, 0x249: 0x00c0, 0x24a: 0x00c0, 0x24b: 0x00c0, + 0x24c: 0x00c0, 0x24d: 0x00c0, 0x24e: 0x00c0, 0x24f: 0x00c0, 0x250: 0x00c0, 0x251: 0x00c0, + 0x252: 0x00c0, 0x253: 0x00c0, 0x254: 0x00c0, 0x255: 0x00c0, 0x256: 0x00c0, 0x257: 0x00c0, + 0x258: 0x00c0, 0x259: 0x00c0, 0x25a: 0x00c0, 0x25b: 0x00c0, 0x25c: 0x00c0, 0x25d: 0x00c0, + 0x25e: 0x00c0, 0x25f: 0x00c0, 0x260: 0x00c0, 0x261: 0x00c0, 0x262: 0x00c0, 0x263: 0x00c0, + 0x264: 0x00c0, 0x265: 0x00c0, 0x266: 0x00c0, 0x267: 0x00c0, 0x268: 0x00c0, 0x269: 0x00c0, + 0x26a: 0x00c0, 0x26b: 0x00c0, 0x26c: 0x00c0, 0x26d: 0x00c0, 0x26e: 0x00c0, 0x26f: 0x00c0, + 0x270: 0x0080, 0x271: 0x0080, 0x272: 0x0080, 0x273: 0x0080, 0x274: 0x0080, 0x275: 0x0080, + 0x276: 0x0080, 0x277: 0x0080, 0x278: 0x0080, 0x279: 0x00c0, 0x27a: 0x00c0, 0x27b: 0x00c0, + 0x27c: 0x00c0, 0x27d: 0x00c0, 0x27e: 0x00c0, 0x27f: 0x00c0, + // Block 0xa, offset 0x280 + 0x280: 0x00c0, 0x281: 0x00c0, 0x282: 0x0080, 0x283: 0x0080, 0x284: 0x0080, 0x285: 0x0080, + 0x286: 0x00c0, 0x287: 0x00c0, 0x288: 0x00c0, 0x289: 0x00c0, 0x28a: 0x00c0, 0x28b: 0x00c0, + 0x28c: 0x00c0, 0x28d: 0x00c0, 0x28e: 0x00c0, 0x28f: 0x00c0, 0x290: 0x00c0, 0x291: 0x00c0, + 0x292: 0x0080, 0x293: 0x0080, 0x294: 0x0080, 0x295: 0x0080, 0x296: 0x0080, 0x297: 0x0080, + 0x298: 0x0080, 0x299: 0x0080, 0x29a: 0x0080, 0x29b: 0x0080, 0x29c: 0x0080, 0x29d: 0x0080, + 0x29e: 0x0080, 0x29f: 0x0080, 0x2a0: 0x0080, 0x2a1: 0x0080, 0x2a2: 0x0080, 0x2a3: 0x0080, + 0x2a4: 0x0080, 0x2a5: 0x0080, 0x2a6: 0x0080, 0x2a7: 0x0080, 0x2a8: 0x0080, 0x2a9: 0x0080, + 0x2aa: 0x0080, 0x2ab: 0x0080, 0x2ac: 0x00c0, 0x2ad: 0x0080, 0x2ae: 0x00c0, 0x2af: 0x0080, + 0x2b0: 0x0080, 0x2b1: 0x0080, 0x2b2: 0x0080, 0x2b3: 0x0080, 0x2b4: 0x0080, 0x2b5: 0x0080, + 0x2b6: 0x0080, 0x2b7: 0x0080, 0x2b8: 0x0080, 0x2b9: 0x0080, 0x2ba: 0x0080, 0x2bb: 0x0080, + 0x2bc: 0x0080, 0x2bd: 0x0080, 0x2be: 0x0080, 0x2bf: 0x0080, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x00c3, 0x2c1: 0x00c3, 0x2c2: 0x00c3, 0x2c3: 0x00c3, 0x2c4: 0x00c3, 0x2c5: 0x00c3, + 0x2c6: 0x00c3, 0x2c7: 0x00c3, 0x2c8: 0x00c3, 0x2c9: 0x00c3, 0x2ca: 0x00c3, 0x2cb: 0x00c3, + 0x2cc: 0x00c3, 0x2cd: 0x00c3, 0x2ce: 0x00c3, 0x2cf: 0x00c3, 0x2d0: 0x00c3, 0x2d1: 0x00c3, + 0x2d2: 0x00c3, 0x2d3: 0x00c3, 0x2d4: 0x00c3, 0x2d5: 0x00c3, 0x2d6: 0x00c3, 0x2d7: 0x00c3, + 0x2d8: 0x00c3, 0x2d9: 0x00c3, 0x2da: 0x00c3, 0x2db: 0x00c3, 0x2dc: 0x00c3, 0x2dd: 0x00c3, + 0x2de: 0x00c3, 0x2df: 0x00c3, 0x2e0: 0x00c3, 0x2e1: 0x00c3, 0x2e2: 0x00c3, 0x2e3: 0x00c3, + 0x2e4: 0x00c3, 0x2e5: 0x00c3, 0x2e6: 0x00c3, 0x2e7: 0x00c3, 0x2e8: 0x00c3, 0x2e9: 0x00c3, + 0x2ea: 0x00c3, 0x2eb: 0x00c3, 0x2ec: 0x00c3, 0x2ed: 0x00c3, 0x2ee: 0x00c3, 0x2ef: 0x00c3, + 0x2f0: 0x00c3, 0x2f1: 0x00c3, 0x2f2: 0x00c3, 0x2f3: 0x00c3, 0x2f4: 0x00c3, 0x2f5: 0x00c3, + 0x2f6: 0x00c3, 0x2f7: 0x00c3, 0x2f8: 0x00c3, 0x2f9: 0x00c3, 0x2fa: 0x00c3, 0x2fb: 0x00c3, + 0x2fc: 0x00c3, 0x2fd: 0x00c3, 0x2fe: 0x00c3, 0x2ff: 0x00c3, + // Block 0xc, offset 0x300 + 0x300: 0x0083, 0x301: 0x0083, 0x302: 0x00c3, 0x303: 0x0083, 0x304: 0x0083, 0x305: 0x00c3, + 0x306: 0x00c3, 0x307: 0x00c3, 0x308: 0x00c3, 0x309: 0x00c3, 0x30a: 0x00c3, 0x30b: 0x00c3, + 0x30c: 0x00c3, 0x30d: 0x00c3, 0x30e: 0x00c3, 0x30f: 0x0040, 0x310: 0x00c3, 0x311: 0x00c3, + 0x312: 0x00c3, 0x313: 0x00c3, 0x314: 0x00c3, 0x315: 0x00c3, 0x316: 0x00c3, 0x317: 0x00c3, + 0x318: 0x00c3, 0x319: 0x00c3, 0x31a: 0x00c3, 0x31b: 0x00c3, 0x31c: 0x00c3, 0x31d: 0x00c3, + 0x31e: 0x00c3, 0x31f: 0x00c3, 0x320: 0x00c3, 0x321: 0x00c3, 0x322: 0x00c3, 0x323: 0x00c3, + 0x324: 0x00c3, 0x325: 0x00c3, 0x326: 0x00c3, 0x327: 0x00c3, 0x328: 0x00c3, 0x329: 0x00c3, + 0x32a: 0x00c3, 0x32b: 0x00c3, 0x32c: 0x00c3, 0x32d: 0x00c3, 0x32e: 0x00c3, 0x32f: 0x00c3, + 0x330: 0x00c8, 0x331: 0x00c8, 0x332: 0x00c8, 0x333: 0x00c8, 0x334: 0x0080, 0x335: 0x0050, + 0x336: 0x00c8, 0x337: 0x00c8, 0x33a: 0x0088, 0x33b: 0x00c8, + 0x33c: 0x00c8, 0x33d: 0x00c8, 0x33e: 0x0080, 0x33f: 0x00c8, + // Block 0xd, offset 0x340 + 0x344: 0x0088, 0x345: 0x0080, + 0x346: 0x00c8, 0x347: 0x0080, 0x348: 0x00c8, 0x349: 0x00c8, 0x34a: 0x00c8, + 0x34c: 0x00c8, 0x34e: 0x00c8, 0x34f: 0x00c8, 0x350: 0x00c8, 0x351: 0x00c8, + 0x352: 0x00c8, 0x353: 0x00c8, 0x354: 0x00c8, 0x355: 0x00c8, 0x356: 0x00c8, 0x357: 0x00c8, + 0x358: 0x00c8, 0x359: 0x00c8, 0x35a: 0x00c8, 0x35b: 0x00c8, 0x35c: 0x00c8, 0x35d: 0x00c8, + 0x35e: 0x00c8, 0x35f: 0x00c8, 0x360: 0x00c8, 0x361: 0x00c8, 0x363: 0x00c8, + 0x364: 0x00c8, 0x365: 0x00c8, 0x366: 0x00c8, 0x367: 0x00c8, 0x368: 0x00c8, 0x369: 0x00c8, + 0x36a: 0x00c8, 0x36b: 0x00c8, 0x36c: 0x00c8, 0x36d: 0x00c8, 0x36e: 0x00c8, 0x36f: 0x00c8, + 0x370: 0x00c8, 0x371: 0x00c8, 0x372: 0x00c8, 0x373: 0x00c8, 0x374: 0x00c8, 0x375: 0x00c8, + 0x376: 0x00c8, 0x377: 0x00c8, 0x378: 0x00c8, 0x379: 0x00c8, 0x37a: 0x00c8, 0x37b: 0x00c8, + 0x37c: 0x00c8, 0x37d: 0x00c8, 0x37e: 0x00c8, 0x37f: 0x00c8, + // Block 0xe, offset 0x380 + 0x380: 0x00c8, 0x381: 0x00c8, 0x382: 0x00c8, 0x383: 0x00c8, 0x384: 0x00c8, 0x385: 0x00c8, + 0x386: 0x00c8, 0x387: 0x00c8, 0x388: 0x00c8, 0x389: 0x00c8, 0x38a: 0x00c8, 0x38b: 0x00c8, + 0x38c: 0x00c8, 0x38d: 0x00c8, 0x38e: 0x00c8, 0x38f: 0x00c8, 0x390: 0x0088, 0x391: 0x0088, + 0x392: 0x0088, 0x393: 0x0088, 0x394: 0x0088, 0x395: 0x0088, 0x396: 0x0088, 0x397: 0x00c8, + 0x398: 0x00c8, 0x399: 0x00c8, 0x39a: 0x00c8, 0x39b: 0x00c8, 0x39c: 0x00c8, 0x39d: 0x00c8, + 0x39e: 0x00c8, 0x39f: 0x00c8, 0x3a0: 0x00c8, 0x3a1: 0x00c8, 0x3a2: 0x00c0, 0x3a3: 0x00c0, + 0x3a4: 0x00c0, 0x3a5: 0x00c0, 0x3a6: 0x00c0, 0x3a7: 0x00c0, 0x3a8: 0x00c0, 0x3a9: 0x00c0, + 0x3aa: 0x00c0, 0x3ab: 0x00c0, 0x3ac: 0x00c0, 0x3ad: 0x00c0, 0x3ae: 0x00c0, 0x3af: 0x00c0, + 0x3b0: 0x0088, 0x3b1: 0x0088, 0x3b2: 0x0088, 0x3b3: 0x00c8, 0x3b4: 0x0088, 0x3b5: 0x0088, + 0x3b6: 0x0088, 0x3b7: 0x00c8, 0x3b8: 0x00c8, 0x3b9: 0x0088, 0x3ba: 0x00c8, 0x3bb: 0x00c8, + 0x3bc: 0x00c8, 0x3bd: 0x00c8, 0x3be: 0x00c8, 0x3bf: 0x00c8, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x00c0, 0x3c1: 0x00c0, 0x3c2: 0x0080, 0x3c3: 0x00c3, 0x3c4: 0x00c3, 0x3c5: 0x00c3, + 0x3c6: 0x00c3, 0x3c7: 0x00c3, 0x3c8: 0x0083, 0x3c9: 0x0083, 0x3ca: 0x00c0, 0x3cb: 0x00c0, + 0x3cc: 0x00c0, 0x3cd: 0x00c0, 0x3ce: 0x00c0, 0x3cf: 0x00c0, 0x3d0: 0x00c0, 0x3d1: 0x00c0, + 0x3d2: 0x00c0, 0x3d3: 0x00c0, 0x3d4: 0x00c0, 0x3d5: 0x00c0, 0x3d6: 0x00c0, 0x3d7: 0x00c0, + 0x3d8: 0x00c0, 0x3d9: 0x00c0, 0x3da: 0x00c0, 0x3db: 0x00c0, 0x3dc: 0x00c0, 0x3dd: 0x00c0, + 0x3de: 0x00c0, 0x3df: 0x00c0, 0x3e0: 0x00c0, 0x3e1: 0x00c0, 0x3e2: 0x00c0, 0x3e3: 0x00c0, + 0x3e4: 0x00c0, 0x3e5: 0x00c0, 0x3e6: 0x00c0, 0x3e7: 0x00c0, 0x3e8: 0x00c0, 0x3e9: 0x00c0, + 0x3ea: 0x00c0, 0x3eb: 0x00c0, 0x3ec: 0x00c0, 0x3ed: 0x00c0, 0x3ee: 0x00c0, 0x3ef: 0x00c0, + 0x3f0: 0x00c0, 0x3f1: 0x00c0, 0x3f2: 0x00c0, 0x3f3: 0x00c0, 0x3f4: 0x00c0, 0x3f5: 0x00c0, + 0x3f6: 0x00c0, 0x3f7: 0x00c0, 0x3f8: 0x00c0, 0x3f9: 0x00c0, 0x3fa: 0x00c0, 0x3fb: 0x00c0, + 0x3fc: 0x00c0, 0x3fd: 0x00c0, 0x3fe: 0x00c0, 0x3ff: 0x00c0, + // Block 0x10, offset 0x400 + 0x400: 0x00c0, 0x401: 0x00c0, 0x402: 0x00c0, 0x403: 0x00c0, 0x404: 0x00c0, 0x405: 0x00c0, + 0x406: 0x00c0, 0x407: 0x00c0, 0x408: 0x00c0, 0x409: 0x00c0, 0x40a: 0x00c0, 0x40b: 0x00c0, + 0x40c: 0x00c0, 0x40d: 0x00c0, 0x40e: 0x00c0, 0x40f: 0x00c0, 0x410: 0x00c0, 0x411: 0x00c0, + 0x412: 0x00c0, 0x413: 0x00c0, 0x414: 0x00c0, 0x415: 0x00c0, 0x416: 0x00c0, 0x417: 0x00c0, + 0x418: 0x00c0, 0x419: 0x00c0, 0x41a: 0x00c0, 0x41b: 0x00c0, 0x41c: 0x00c0, 0x41d: 0x00c0, + 0x41e: 0x00c0, 0x41f: 0x00c0, 0x420: 0x00c0, 0x421: 0x00c0, 0x422: 0x00c0, 0x423: 0x00c0, + 0x424: 0x00c0, 0x425: 0x00c0, 0x426: 0x00c0, 0x427: 0x00c0, 0x428: 0x00c0, 0x429: 0x00c0, + 0x42a: 0x00c0, 0x42b: 0x00c0, 0x42c: 0x00c0, 0x42d: 0x00c0, 0x42e: 0x00c0, 0x42f: 0x00c0, + 0x431: 0x00c0, 0x432: 0x00c0, 0x433: 0x00c0, 0x434: 0x00c0, 0x435: 0x00c0, + 0x436: 0x00c0, 0x437: 0x00c0, 0x438: 0x00c0, 0x439: 0x00c0, 0x43a: 0x00c0, 0x43b: 0x00c0, + 0x43c: 0x00c0, 0x43d: 0x00c0, 0x43e: 0x00c0, 0x43f: 0x00c0, + // Block 0x11, offset 0x440 + 0x440: 0x00c0, 0x441: 0x00c0, 0x442: 0x00c0, 0x443: 0x00c0, 0x444: 0x00c0, 0x445: 0x00c0, + 0x446: 0x00c0, 0x447: 0x00c0, 0x448: 0x00c0, 0x449: 0x00c0, 0x44a: 0x00c0, 0x44b: 0x00c0, + 0x44c: 0x00c0, 0x44d: 0x00c0, 0x44e: 0x00c0, 0x44f: 0x00c0, 0x450: 0x00c0, 0x451: 0x00c0, + 0x452: 0x00c0, 0x453: 0x00c0, 0x454: 0x00c0, 0x455: 0x00c0, 0x456: 0x00c0, + 0x459: 0x00c0, 0x45a: 0x0080, 0x45b: 0x0080, 0x45c: 0x0080, 0x45d: 0x0080, + 0x45e: 0x0080, 0x45f: 0x0080, 0x461: 0x00c0, 0x462: 0x00c0, 0x463: 0x00c0, + 0x464: 0x00c0, 0x465: 0x00c0, 0x466: 0x00c0, 0x467: 0x00c0, 0x468: 0x00c0, 0x469: 0x00c0, + 0x46a: 0x00c0, 0x46b: 0x00c0, 0x46c: 0x00c0, 0x46d: 0x00c0, 0x46e: 0x00c0, 0x46f: 0x00c0, + 0x470: 0x00c0, 0x471: 0x00c0, 0x472: 0x00c0, 0x473: 0x00c0, 0x474: 0x00c0, 0x475: 0x00c0, + 0x476: 0x00c0, 0x477: 0x00c0, 0x478: 0x00c0, 0x479: 0x00c0, 0x47a: 0x00c0, 0x47b: 0x00c0, + 0x47c: 0x00c0, 0x47d: 0x00c0, 0x47e: 0x00c0, 0x47f: 0x00c0, + // Block 0x12, offset 0x480 + 0x480: 0x00c0, 0x481: 0x00c0, 0x482: 0x00c0, 0x483: 0x00c0, 0x484: 0x00c0, 0x485: 0x00c0, + 0x486: 0x00c0, 0x487: 0x0080, 0x489: 0x0080, 0x48a: 0x0080, + 0x48d: 0x0080, 0x48e: 0x0080, 0x48f: 0x0080, 0x491: 0x00cb, + 0x492: 0x00cb, 0x493: 0x00cb, 0x494: 0x00cb, 0x495: 0x00cb, 0x496: 0x00cb, 0x497: 0x00cb, + 0x498: 0x00cb, 0x499: 0x00cb, 0x49a: 0x00cb, 0x49b: 0x00cb, 0x49c: 0x00cb, 0x49d: 0x00cb, + 0x49e: 0x00cb, 0x49f: 0x00cb, 0x4a0: 0x00cb, 0x4a1: 0x00cb, 0x4a2: 0x00cb, 0x4a3: 0x00cb, + 0x4a4: 0x00cb, 0x4a5: 0x00cb, 0x4a6: 0x00cb, 0x4a7: 0x00cb, 0x4a8: 0x00cb, 0x4a9: 0x00cb, + 0x4aa: 0x00cb, 0x4ab: 0x00cb, 0x4ac: 0x00cb, 0x4ad: 0x00cb, 0x4ae: 0x00cb, 0x4af: 0x00cb, + 0x4b0: 0x00cb, 0x4b1: 0x00cb, 0x4b2: 0x00cb, 0x4b3: 0x00cb, 0x4b4: 0x00cb, 0x4b5: 0x00cb, + 0x4b6: 0x00cb, 0x4b7: 0x00cb, 0x4b8: 0x00cb, 0x4b9: 0x00cb, 0x4ba: 0x00cb, 0x4bb: 0x00cb, + 0x4bc: 0x00cb, 0x4bd: 0x00cb, 0x4be: 0x008a, 0x4bf: 0x00cb, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x008a, 0x4c1: 0x00cb, 0x4c2: 0x00cb, 0x4c3: 0x008a, 0x4c4: 0x00cb, 0x4c5: 0x00cb, + 0x4c6: 0x008a, 0x4c7: 0x00cb, + 0x4d0: 0x00ca, 0x4d1: 0x00ca, + 0x4d2: 0x00ca, 0x4d3: 0x00ca, 0x4d4: 0x00ca, 0x4d5: 0x00ca, 0x4d6: 0x00ca, 0x4d7: 0x00ca, + 0x4d8: 0x00ca, 0x4d9: 0x00ca, 0x4da: 0x00ca, 0x4db: 0x00ca, 0x4dc: 0x00ca, 0x4dd: 0x00ca, + 0x4de: 0x00ca, 0x4df: 0x00ca, 0x4e0: 0x00ca, 0x4e1: 0x00ca, 0x4e2: 0x00ca, 0x4e3: 0x00ca, + 0x4e4: 0x00ca, 0x4e5: 0x00ca, 0x4e6: 0x00ca, 0x4e7: 0x00ca, 0x4e8: 0x00ca, 0x4e9: 0x00ca, + 0x4ea: 0x00ca, + 0x4f0: 0x00ca, 0x4f1: 0x00ca, 0x4f2: 0x00ca, 0x4f3: 0x0051, 0x4f4: 0x0051, + // Block 0x14, offset 0x500 + 0x500: 0x0040, 0x501: 0x0040, 0x502: 0x0040, 0x503: 0x0040, 0x504: 0x0040, 0x505: 0x0040, + 0x506: 0x0080, 0x507: 0x0080, 0x508: 0x0080, 0x509: 0x0080, 0x50a: 0x0080, 0x50b: 0x0080, + 0x50c: 0x0080, 0x50d: 0x0080, 0x50e: 0x0080, 0x50f: 0x0080, 0x510: 0x00c3, 0x511: 0x00c3, + 0x512: 0x00c3, 0x513: 0x00c3, 0x514: 0x00c3, 0x515: 0x00c3, 0x516: 0x00c3, 0x517: 0x00c3, + 0x518: 0x00c3, 0x519: 0x00c3, 0x51a: 0x00c3, 0x51b: 0x0080, 0x51c: 0x0040, + 0x51e: 0x0080, 0x51f: 0x0080, 0x520: 0x00c2, 0x521: 0x00c0, 0x522: 0x00c4, 0x523: 0x00c4, + 0x524: 0x00c4, 0x525: 0x00c4, 0x526: 0x00c2, 0x527: 0x00c4, 0x528: 0x00c2, 0x529: 0x00c4, + 0x52a: 0x00c2, 0x52b: 0x00c2, 0x52c: 0x00c2, 0x52d: 0x00c2, 0x52e: 0x00c2, 0x52f: 0x00c4, + 0x530: 0x00c4, 0x531: 0x00c4, 0x532: 0x00c4, 0x533: 0x00c2, 0x534: 0x00c2, 0x535: 0x00c2, + 0x536: 0x00c2, 0x537: 0x00c2, 0x538: 0x00c2, 0x539: 0x00c2, 0x53a: 0x00c2, 0x53b: 0x00c2, + 0x53c: 0x00c2, 0x53d: 0x00c2, 0x53e: 0x00c2, 0x53f: 0x00c2, + // Block 0x15, offset 0x540 + 0x540: 0x0040, 0x541: 0x00c2, 0x542: 0x00c2, 0x543: 0x00c2, 0x544: 0x00c2, 0x545: 0x00c2, + 0x546: 0x00c2, 0x547: 0x00c2, 0x548: 0x00c4, 0x549: 0x00c2, 0x54a: 0x00c2, 0x54b: 0x00c3, + 0x54c: 0x00c3, 0x54d: 0x00c3, 0x54e: 0x00c3, 0x54f: 0x00c3, 0x550: 0x00c3, 0x551: 0x00c3, + 0x552: 0x00c3, 0x553: 0x00c3, 0x554: 0x00c3, 0x555: 0x00c3, 0x556: 0x00c3, 0x557: 0x00c3, + 0x558: 0x00c3, 0x559: 0x00c3, 0x55a: 0x00c3, 0x55b: 0x00c3, 0x55c: 0x00c3, 0x55d: 0x00c3, + 0x55e: 0x00c3, 0x55f: 0x00c3, 0x560: 0x0053, 0x561: 0x0053, 0x562: 0x0053, 0x563: 0x0053, + 0x564: 0x0053, 0x565: 0x0053, 0x566: 0x0053, 0x567: 0x0053, 0x568: 0x0053, 0x569: 0x0053, + 0x56a: 0x0080, 0x56b: 0x0080, 0x56c: 0x0080, 0x56d: 0x0080, 0x56e: 0x00c2, 0x56f: 0x00c2, + 0x570: 0x00c3, 0x571: 0x00c4, 0x572: 0x00c4, 0x573: 0x00c4, 0x574: 0x00c0, 0x575: 0x0084, + 0x576: 0x0084, 0x577: 0x0084, 0x578: 0x0082, 0x579: 0x00c2, 0x57a: 0x00c2, 0x57b: 0x00c2, + 0x57c: 0x00c2, 0x57d: 0x00c2, 0x57e: 0x00c2, 0x57f: 0x00c2, + // Block 0x16, offset 0x580 + 0x580: 0x00c2, 0x581: 0x00c2, 0x582: 0x00c2, 0x583: 0x00c2, 0x584: 0x00c2, 0x585: 0x00c2, + 0x586: 0x00c2, 0x587: 0x00c2, 0x588: 0x00c4, 0x589: 0x00c4, 0x58a: 0x00c4, 0x58b: 0x00c4, + 0x58c: 0x00c4, 0x58d: 0x00c4, 0x58e: 0x00c4, 0x58f: 0x00c4, 0x590: 0x00c4, 0x591: 0x00c4, + 0x592: 0x00c4, 0x593: 0x00c4, 0x594: 0x00c4, 0x595: 0x00c4, 0x596: 0x00c4, 0x597: 0x00c4, + 0x598: 0x00c4, 0x599: 0x00c4, 0x59a: 0x00c2, 0x59b: 0x00c2, 0x59c: 0x00c2, 0x59d: 0x00c2, + 0x59e: 0x00c2, 0x59f: 0x00c2, 0x5a0: 0x00c2, 0x5a1: 0x00c2, 0x5a2: 0x00c2, 0x5a3: 0x00c2, + 0x5a4: 0x00c2, 0x5a5: 0x00c2, 0x5a6: 0x00c2, 0x5a7: 0x00c2, 0x5a8: 0x00c2, 0x5a9: 0x00c2, + 0x5aa: 0x00c2, 0x5ab: 0x00c2, 0x5ac: 0x00c2, 0x5ad: 0x00c2, 0x5ae: 0x00c2, 0x5af: 0x00c2, + 0x5b0: 0x00c2, 0x5b1: 0x00c2, 0x5b2: 0x00c2, 0x5b3: 0x00c2, 0x5b4: 0x00c2, 0x5b5: 0x00c2, + 0x5b6: 0x00c2, 0x5b7: 0x00c2, 0x5b8: 0x00c2, 0x5b9: 0x00c2, 0x5ba: 0x00c2, 0x5bb: 0x00c2, + 0x5bc: 0x00c2, 0x5bd: 0x00c2, 0x5be: 0x00c2, 0x5bf: 0x00c2, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x00c4, 0x5c1: 0x00c2, 0x5c2: 0x00c2, 0x5c3: 0x00c4, 0x5c4: 0x00c4, 0x5c5: 0x00c4, + 0x5c6: 0x00c4, 0x5c7: 0x00c4, 0x5c8: 0x00c4, 0x5c9: 0x00c4, 0x5ca: 0x00c4, 0x5cb: 0x00c4, + 0x5cc: 0x00c2, 0x5cd: 0x00c4, 0x5ce: 0x00c2, 0x5cf: 0x00c4, 0x5d0: 0x00c2, 0x5d1: 0x00c2, + 0x5d2: 0x00c4, 0x5d3: 0x00c4, 0x5d4: 0x0080, 0x5d5: 0x00c4, 0x5d6: 0x00c3, 0x5d7: 0x00c3, + 0x5d8: 0x00c3, 0x5d9: 0x00c3, 0x5da: 0x00c3, 0x5db: 0x00c3, 0x5dc: 0x00c3, 0x5dd: 0x0040, + 0x5de: 0x0080, 0x5df: 0x00c3, 0x5e0: 0x00c3, 0x5e1: 0x00c3, 0x5e2: 0x00c3, 0x5e3: 0x00c3, + 0x5e4: 0x00c3, 0x5e5: 0x00c0, 0x5e6: 0x00c0, 0x5e7: 0x00c3, 0x5e8: 0x00c3, 0x5e9: 0x0080, + 0x5ea: 0x00c3, 0x5eb: 0x00c3, 0x5ec: 0x00c3, 0x5ed: 0x00c3, 0x5ee: 0x00c4, 0x5ef: 0x00c4, + 0x5f0: 0x0054, 0x5f1: 0x0054, 0x5f2: 0x0054, 0x5f3: 0x0054, 0x5f4: 0x0054, 0x5f5: 0x0054, + 0x5f6: 0x0054, 0x5f7: 0x0054, 0x5f8: 0x0054, 0x5f9: 0x0054, 0x5fa: 0x00c2, 0x5fb: 0x00c2, + 0x5fc: 0x00c2, 0x5fd: 0x00c0, 0x5fe: 0x00c0, 0x5ff: 0x00c2, + // Block 0x18, offset 0x600 + 0x600: 0x0080, 0x601: 0x0080, 0x602: 0x0080, 0x603: 0x0080, 0x604: 0x0080, 0x605: 0x0080, + 0x606: 0x0080, 0x607: 0x0080, 0x608: 0x0080, 0x609: 0x0080, 0x60a: 0x0080, 0x60b: 0x0080, + 0x60c: 0x0080, 0x60d: 0x0080, 0x60f: 0x0040, 0x610: 0x00c4, 0x611: 0x00c3, + 0x612: 0x00c2, 0x613: 0x00c2, 0x614: 0x00c2, 0x615: 0x00c4, 0x616: 0x00c4, 0x617: 0x00c4, + 0x618: 0x00c4, 0x619: 0x00c4, 0x61a: 0x00c2, 0x61b: 0x00c2, 0x61c: 0x00c2, 0x61d: 0x00c2, + 0x61e: 0x00c4, 0x61f: 0x00c2, 0x620: 0x00c2, 0x621: 0x00c2, 0x622: 0x00c2, 0x623: 0x00c2, + 0x624: 0x00c2, 0x625: 0x00c2, 0x626: 0x00c2, 0x627: 0x00c2, 0x628: 0x00c4, 0x629: 0x00c2, + 0x62a: 0x00c4, 0x62b: 0x00c2, 0x62c: 0x00c4, 0x62d: 0x00c2, 0x62e: 0x00c2, 0x62f: 0x00c4, + 0x630: 0x00c3, 0x631: 0x00c3, 0x632: 0x00c3, 0x633: 0x00c3, 0x634: 0x00c3, 0x635: 0x00c3, + 0x636: 0x00c3, 0x637: 0x00c3, 0x638: 0x00c3, 0x639: 0x00c3, 0x63a: 0x00c3, 0x63b: 0x00c3, + 0x63c: 0x00c3, 0x63d: 0x00c3, 0x63e: 0x00c3, 0x63f: 0x00c3, + // Block 0x19, offset 0x640 + 0x640: 0x00c3, 0x641: 0x00c3, 0x642: 0x00c3, 0x643: 0x00c3, 0x644: 0x00c3, 0x645: 0x00c3, + 0x646: 0x00c3, 0x647: 0x00c3, 0x648: 0x00c3, 0x649: 0x00c3, 0x64a: 0x00c3, + 0x64d: 0x00c4, 0x64e: 0x00c2, 0x64f: 0x00c2, 0x650: 0x00c2, 0x651: 0x00c2, + 0x652: 0x00c2, 0x653: 0x00c2, 0x654: 0x00c2, 0x655: 0x00c2, 0x656: 0x00c2, 0x657: 0x00c2, + 0x658: 0x00c2, 0x659: 0x00c4, 0x65a: 0x00c4, 0x65b: 0x00c4, 0x65c: 0x00c2, 0x65d: 0x00c2, + 0x65e: 0x00c2, 0x65f: 0x00c2, 0x660: 0x00c2, 0x661: 0x00c2, 0x662: 0x00c2, 0x663: 0x00c2, + 0x664: 0x00c2, 0x665: 0x00c2, 0x666: 0x00c2, 0x667: 0x00c2, 0x668: 0x00c2, 0x669: 0x00c2, + 0x66a: 0x00c2, 0x66b: 0x00c4, 0x66c: 0x00c4, 0x66d: 0x00c2, 0x66e: 0x00c2, 0x66f: 0x00c2, + 0x670: 0x00c2, 0x671: 0x00c4, 0x672: 0x00c2, 0x673: 0x00c4, 0x674: 0x00c4, 0x675: 0x00c2, + 0x676: 0x00c2, 0x677: 0x00c2, 0x678: 0x00c4, 0x679: 0x00c4, 0x67a: 0x00c2, 0x67b: 0x00c2, + 0x67c: 0x00c2, 0x67d: 0x00c2, 0x67e: 0x00c2, 0x67f: 0x00c2, + // Block 0x1a, offset 0x680 + 0x680: 0x00c0, 0x681: 0x00c0, 0x682: 0x00c0, 0x683: 0x00c0, 0x684: 0x00c0, 0x685: 0x00c0, + 0x686: 0x00c0, 0x687: 0x00c0, 0x688: 0x00c0, 0x689: 0x00c0, 0x68a: 0x00c0, 0x68b: 0x00c0, + 0x68c: 0x00c0, 0x68d: 0x00c0, 0x68e: 0x00c0, 0x68f: 0x00c0, 0x690: 0x00c0, 0x691: 0x00c0, + 0x692: 0x00c0, 0x693: 0x00c0, 0x694: 0x00c0, 0x695: 0x00c0, 0x696: 0x00c0, 0x697: 0x00c0, + 0x698: 0x00c0, 0x699: 0x00c0, 0x69a: 0x00c0, 0x69b: 0x00c0, 0x69c: 0x00c0, 0x69d: 0x00c0, + 0x69e: 0x00c0, 0x69f: 0x00c0, 0x6a0: 0x00c0, 0x6a1: 0x00c0, 0x6a2: 0x00c0, 0x6a3: 0x00c0, + 0x6a4: 0x00c0, 0x6a5: 0x00c0, 0x6a6: 0x00c3, 0x6a7: 0x00c3, 0x6a8: 0x00c3, 0x6a9: 0x00c3, + 0x6aa: 0x00c3, 0x6ab: 0x00c3, 0x6ac: 0x00c3, 0x6ad: 0x00c3, 0x6ae: 0x00c3, 0x6af: 0x00c3, + 0x6b0: 0x00c3, 0x6b1: 0x00c0, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x00c0, 0x6c1: 0x00c0, 0x6c2: 0x00c0, 0x6c3: 0x00c0, 0x6c4: 0x00c0, 0x6c5: 0x00c0, + 0x6c6: 0x00c0, 0x6c7: 0x00c0, 0x6c8: 0x00c0, 0x6c9: 0x00c0, 0x6ca: 0x00c2, 0x6cb: 0x00c2, + 0x6cc: 0x00c2, 0x6cd: 0x00c2, 0x6ce: 0x00c2, 0x6cf: 0x00c2, 0x6d0: 0x00c2, 0x6d1: 0x00c2, + 0x6d2: 0x00c2, 0x6d3: 0x00c2, 0x6d4: 0x00c2, 0x6d5: 0x00c2, 0x6d6: 0x00c2, 0x6d7: 0x00c2, + 0x6d8: 0x00c2, 0x6d9: 0x00c2, 0x6da: 0x00c2, 0x6db: 0x00c2, 0x6dc: 0x00c2, 0x6dd: 0x00c2, + 0x6de: 0x00c2, 0x6df: 0x00c2, 0x6e0: 0x00c2, 0x6e1: 0x00c2, 0x6e2: 0x00c2, 0x6e3: 0x00c2, + 0x6e4: 0x00c2, 0x6e5: 0x00c2, 0x6e6: 0x00c2, 0x6e7: 0x00c2, 0x6e8: 0x00c2, 0x6e9: 0x00c2, + 0x6ea: 0x00c2, 0x6eb: 0x00c3, 0x6ec: 0x00c3, 0x6ed: 0x00c3, 0x6ee: 0x00c3, 0x6ef: 0x00c3, + 0x6f0: 0x00c3, 0x6f1: 0x00c3, 0x6f2: 0x00c3, 0x6f3: 0x00c3, 0x6f4: 0x00c0, 0x6f5: 0x00c0, + 0x6f6: 0x0080, 0x6f7: 0x0080, 0x6f8: 0x0080, 0x6f9: 0x0080, 0x6fa: 0x0040, + // Block 0x1c, offset 0x700 + 0x700: 0x00c0, 0x701: 0x00c0, 0x702: 0x00c0, 0x703: 0x00c0, 0x704: 0x00c0, 0x705: 0x00c0, + 0x706: 0x00c0, 0x707: 0x00c0, 0x708: 0x00c0, 0x709: 0x00c0, 0x70a: 0x00c0, 0x70b: 0x00c0, + 0x70c: 0x00c0, 0x70d: 0x00c0, 0x70e: 0x00c0, 0x70f: 0x00c0, 0x710: 0x00c0, 0x711: 0x00c0, + 0x712: 0x00c0, 0x713: 0x00c0, 0x714: 0x00c0, 0x715: 0x00c0, 0x716: 0x00c3, 0x717: 0x00c3, + 0x718: 0x00c3, 0x719: 0x00c3, 0x71a: 0x00c0, 0x71b: 0x00c3, 0x71c: 0x00c3, 0x71d: 0x00c3, + 0x71e: 0x00c3, 0x71f: 0x00c3, 0x720: 0x00c3, 0x721: 0x00c3, 0x722: 0x00c3, 0x723: 0x00c3, + 0x724: 0x00c0, 0x725: 0x00c3, 0x726: 0x00c3, 0x727: 0x00c3, 0x728: 0x00c0, 0x729: 0x00c3, + 0x72a: 0x00c3, 0x72b: 0x00c3, 0x72c: 0x00c3, 0x72d: 0x00c3, + 0x730: 0x0080, 0x731: 0x0080, 0x732: 0x0080, 0x733: 0x0080, 0x734: 0x0080, 0x735: 0x0080, + 0x736: 0x0080, 0x737: 0x0080, 0x738: 0x0080, 0x739: 0x0080, 0x73a: 0x0080, 0x73b: 0x0080, + 0x73c: 0x0080, 0x73d: 0x0080, 0x73e: 0x0080, + // Block 0x1d, offset 0x740 + 0x740: 0x00c4, 0x741: 0x00c2, 0x742: 0x00c2, 0x743: 0x00c2, 0x744: 0x00c2, 0x745: 0x00c2, + 0x746: 0x00c4, 0x747: 0x00c4, 0x748: 0x00c2, 0x749: 0x00c4, 0x74a: 0x00c2, 0x74b: 0x00c2, + 0x74c: 0x00c2, 0x74d: 0x00c2, 0x74e: 0x00c2, 0x74f: 0x00c2, 0x750: 0x00c2, 0x751: 0x00c2, + 0x752: 0x00c2, 0x753: 0x00c2, 0x754: 0x00c4, 0x755: 0x00c2, 0x756: 0x00c0, 0x757: 0x00c0, + 0x758: 0x00c0, 0x759: 0x00c3, 0x75a: 0x00c3, 0x75b: 0x00c3, + 0x75e: 0x0080, + // Block 0x1e, offset 0x780 + 0x7a0: 0x00c2, 0x7a1: 0x00c2, 0x7a2: 0x00c2, 0x7a3: 0x00c2, + 0x7a4: 0x00c2, 0x7a5: 0x00c2, 0x7a6: 0x00c2, 0x7a7: 0x00c2, 0x7a8: 0x00c2, 0x7a9: 0x00c2, + 0x7aa: 0x00c4, 0x7ab: 0x00c4, 0x7ac: 0x00c4, 0x7ad: 0x00c0, 0x7ae: 0x00c4, 0x7af: 0x00c2, + 0x7b0: 0x00c2, 0x7b1: 0x00c4, 0x7b2: 0x00c4, 0x7b3: 0x00c2, 0x7b4: 0x00c2, + 0x7b6: 0x00c2, 0x7b7: 0x00c2, 0x7b8: 0x00c2, 0x7b9: 0x00c4, 0x7ba: 0x00c2, 0x7bb: 0x00c2, + 0x7bc: 0x00c2, 0x7bd: 0x00c2, + // Block 0x1f, offset 0x7c0 + 0x7d4: 0x00c3, 0x7d5: 0x00c3, 0x7d6: 0x00c3, 0x7d7: 0x00c3, + 0x7d8: 0x00c3, 0x7d9: 0x00c3, 0x7da: 0x00c3, 0x7db: 0x00c3, 0x7dc: 0x00c3, 0x7dd: 0x00c3, + 0x7de: 0x00c3, 0x7df: 0x00c3, 0x7e0: 0x00c3, 0x7e1: 0x00c3, 0x7e2: 0x0040, 0x7e3: 0x00c3, + 0x7e4: 0x00c3, 0x7e5: 0x00c3, 0x7e6: 0x00c3, 0x7e7: 0x00c3, 0x7e8: 0x00c3, 0x7e9: 0x00c3, + 0x7ea: 0x00c3, 0x7eb: 0x00c3, 0x7ec: 0x00c3, 0x7ed: 0x00c3, 0x7ee: 0x00c3, 0x7ef: 0x00c3, + 0x7f0: 0x00c3, 0x7f1: 0x00c3, 0x7f2: 0x00c3, 0x7f3: 0x00c3, 0x7f4: 0x00c3, 0x7f5: 0x00c3, + 0x7f6: 0x00c3, 0x7f7: 0x00c3, 0x7f8: 0x00c3, 0x7f9: 0x00c3, 0x7fa: 0x00c3, 0x7fb: 0x00c3, + 0x7fc: 0x00c3, 0x7fd: 0x00c3, 0x7fe: 0x00c3, 0x7ff: 0x00c3, + // Block 0x20, offset 0x800 + 0x800: 0x00c3, 0x801: 0x00c3, 0x802: 0x00c3, 0x803: 0x00c0, 0x804: 0x00c0, 0x805: 0x00c0, + 0x806: 0x00c0, 0x807: 0x00c0, 0x808: 0x00c0, 0x809: 0x00c0, 0x80a: 0x00c0, 0x80b: 0x00c0, + 0x80c: 0x00c0, 0x80d: 0x00c0, 0x80e: 0x00c0, 0x80f: 0x00c0, 0x810: 0x00c0, 0x811: 0x00c0, + 0x812: 0x00c0, 0x813: 0x00c0, 0x814: 0x00c0, 0x815: 0x00c0, 0x816: 0x00c0, 0x817: 0x00c0, + 0x818: 0x00c0, 0x819: 0x00c0, 0x81a: 0x00c0, 0x81b: 0x00c0, 0x81c: 0x00c0, 0x81d: 0x00c0, + 0x81e: 0x00c0, 0x81f: 0x00c0, 0x820: 0x00c0, 0x821: 0x00c0, 0x822: 0x00c0, 0x823: 0x00c0, + 0x824: 0x00c0, 0x825: 0x00c0, 0x826: 0x00c0, 0x827: 0x00c0, 0x828: 0x00c0, 0x829: 0x00c0, + 0x82a: 0x00c0, 0x82b: 0x00c0, 0x82c: 0x00c0, 0x82d: 0x00c0, 0x82e: 0x00c0, 0x82f: 0x00c0, + 0x830: 0x00c0, 0x831: 0x00c0, 0x832: 0x00c0, 0x833: 0x00c0, 0x834: 0x00c0, 0x835: 0x00c0, + 0x836: 0x00c0, 0x837: 0x00c0, 0x838: 0x00c0, 0x839: 0x00c0, 0x83a: 0x00c3, 0x83b: 0x00c0, + 0x83c: 0x00c3, 0x83d: 0x00c0, 0x83e: 0x00c0, 0x83f: 0x00c0, + // Block 0x21, offset 0x840 + 0x840: 0x00c0, 0x841: 0x00c3, 0x842: 0x00c3, 0x843: 0x00c3, 0x844: 0x00c3, 0x845: 0x00c3, + 0x846: 0x00c3, 0x847: 0x00c3, 0x848: 0x00c3, 0x849: 0x00c0, 0x84a: 0x00c0, 0x84b: 0x00c0, + 0x84c: 0x00c0, 0x84d: 0x00c6, 0x84e: 0x00c0, 0x84f: 0x00c0, 0x850: 0x00c0, 0x851: 0x00c3, + 0x852: 0x00c3, 0x853: 0x00c3, 0x854: 0x00c3, 0x855: 0x00c3, 0x856: 0x00c3, 0x857: 0x00c3, + 0x858: 0x0080, 0x859: 0x0080, 0x85a: 0x0080, 0x85b: 0x0080, 0x85c: 0x0080, 0x85d: 0x0080, + 0x85e: 0x0080, 0x85f: 0x0080, 0x860: 0x00c0, 0x861: 0x00c0, 0x862: 0x00c3, 0x863: 0x00c3, + 0x864: 0x0080, 0x865: 0x0080, 0x866: 0x00c0, 0x867: 0x00c0, 0x868: 0x00c0, 0x869: 0x00c0, + 0x86a: 0x00c0, 0x86b: 0x00c0, 0x86c: 0x00c0, 0x86d: 0x00c0, 0x86e: 0x00c0, 0x86f: 0x00c0, + 0x870: 0x0080, 0x871: 0x00c0, 0x872: 0x00c0, 0x873: 0x00c0, 0x874: 0x00c0, 0x875: 0x00c0, + 0x876: 0x00c0, 0x877: 0x00c0, 0x878: 0x00c0, 0x879: 0x00c0, 0x87a: 0x00c0, 0x87b: 0x00c0, + 0x87c: 0x00c0, 0x87d: 0x00c0, 0x87e: 0x00c0, 0x87f: 0x00c0, + // Block 0x22, offset 0x880 + 0x880: 0x00c0, 0x881: 0x00c3, 0x882: 0x00c0, 0x883: 0x00c0, 0x885: 0x00c0, + 0x886: 0x00c0, 0x887: 0x00c0, 0x888: 0x00c0, 0x889: 0x00c0, 0x88a: 0x00c0, 0x88b: 0x00c0, + 0x88c: 0x00c0, 0x88f: 0x00c0, 0x890: 0x00c0, + 0x893: 0x00c0, 0x894: 0x00c0, 0x895: 0x00c0, 0x896: 0x00c0, 0x897: 0x00c0, + 0x898: 0x00c0, 0x899: 0x00c0, 0x89a: 0x00c0, 0x89b: 0x00c0, 0x89c: 0x00c0, 0x89d: 0x00c0, + 0x89e: 0x00c0, 0x89f: 0x00c0, 0x8a0: 0x00c0, 0x8a1: 0x00c0, 0x8a2: 0x00c0, 0x8a3: 0x00c0, + 0x8a4: 0x00c0, 0x8a5: 0x00c0, 0x8a6: 0x00c0, 0x8a7: 0x00c0, 0x8a8: 0x00c0, + 0x8aa: 0x00c0, 0x8ab: 0x00c0, 0x8ac: 0x00c0, 0x8ad: 0x00c0, 0x8ae: 0x00c0, 0x8af: 0x00c0, + 0x8b0: 0x00c0, 0x8b2: 0x00c0, + 0x8b6: 0x00c0, 0x8b7: 0x00c0, 0x8b8: 0x00c0, 0x8b9: 0x00c0, + 0x8bc: 0x00c3, 0x8bd: 0x00c0, 0x8be: 0x00c0, 0x8bf: 0x00c0, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x00c0, 0x8c1: 0x00c3, 0x8c2: 0x00c3, 0x8c3: 0x00c3, 0x8c4: 0x00c3, + 0x8c7: 0x00c0, 0x8c8: 0x00c0, 0x8cb: 0x00c0, + 0x8cc: 0x00c0, 0x8cd: 0x00c6, 0x8ce: 0x00c0, + 0x8d7: 0x00c0, + 0x8dc: 0x0080, 0x8dd: 0x0080, + 0x8df: 0x0080, 0x8e0: 0x00c0, 0x8e1: 0x00c0, 0x8e2: 0x00c3, 0x8e3: 0x00c3, + 0x8e6: 0x00c0, 0x8e7: 0x00c0, 0x8e8: 0x00c0, 0x8e9: 0x00c0, + 0x8ea: 0x00c0, 0x8eb: 0x00c0, 0x8ec: 0x00c0, 0x8ed: 0x00c0, 0x8ee: 0x00c0, 0x8ef: 0x00c0, + 0x8f0: 0x00c0, 0x8f1: 0x00c0, 0x8f2: 0x0080, 0x8f3: 0x0080, 0x8f4: 0x0080, 0x8f5: 0x0080, + 0x8f6: 0x0080, 0x8f7: 0x0080, 0x8f8: 0x0080, 0x8f9: 0x0080, 0x8fa: 0x0080, 0x8fb: 0x0080, + // Block 0x24, offset 0x900 + 0x901: 0x00c3, 0x902: 0x00c3, 0x903: 0x00c0, 0x905: 0x00c0, + 0x906: 0x00c0, 0x907: 0x00c0, 0x908: 0x00c0, 0x909: 0x00c0, 0x90a: 0x00c0, + 0x90f: 0x00c0, 0x910: 0x00c0, + 0x913: 0x00c0, 0x914: 0x00c0, 0x915: 0x00c0, 0x916: 0x00c0, 0x917: 0x00c0, + 0x918: 0x00c0, 0x919: 0x00c0, 0x91a: 0x00c0, 0x91b: 0x00c0, 0x91c: 0x00c0, 0x91d: 0x00c0, + 0x91e: 0x00c0, 0x91f: 0x00c0, 0x920: 0x00c0, 0x921: 0x00c0, 0x922: 0x00c0, 0x923: 0x00c0, + 0x924: 0x00c0, 0x925: 0x00c0, 0x926: 0x00c0, 0x927: 0x00c0, 0x928: 0x00c0, + 0x92a: 0x00c0, 0x92b: 0x00c0, 0x92c: 0x00c0, 0x92d: 0x00c0, 0x92e: 0x00c0, 0x92f: 0x00c0, + 0x930: 0x00c0, 0x932: 0x00c0, 0x933: 0x0080, 0x935: 0x00c0, + 0x936: 0x0080, 0x938: 0x00c0, 0x939: 0x00c0, + 0x93c: 0x00c3, 0x93e: 0x00c0, 0x93f: 0x00c0, + // Block 0x25, offset 0x940 + 0x940: 0x00c0, 0x941: 0x00c3, 0x942: 0x00c3, + 0x947: 0x00c3, 0x948: 0x00c3, 0x94b: 0x00c3, + 0x94c: 0x00c3, 0x94d: 0x00c6, 0x951: 0x00c3, + 0x959: 0x0080, 0x95a: 0x0080, 0x95b: 0x0080, 0x95c: 0x00c0, + 0x95e: 0x0080, + 0x966: 0x00c0, 0x967: 0x00c0, 0x968: 0x00c0, 0x969: 0x00c0, + 0x96a: 0x00c0, 0x96b: 0x00c0, 0x96c: 0x00c0, 0x96d: 0x00c0, 0x96e: 0x00c0, 0x96f: 0x00c0, + 0x970: 0x00c3, 0x971: 0x00c3, 0x972: 0x00c0, 0x973: 0x00c0, 0x974: 0x00c0, 0x975: 0x00c3, + // Block 0x26, offset 0x980 + 0x981: 0x00c3, 0x982: 0x00c3, 0x983: 0x00c0, 0x985: 0x00c0, + 0x986: 0x00c0, 0x987: 0x00c0, 0x988: 0x00c0, 0x989: 0x00c0, 0x98a: 0x00c0, 0x98b: 0x00c0, + 0x98c: 0x00c0, 0x98d: 0x00c0, 0x98f: 0x00c0, 0x990: 0x00c0, 0x991: 0x00c0, + 0x993: 0x00c0, 0x994: 0x00c0, 0x995: 0x00c0, 0x996: 0x00c0, 0x997: 0x00c0, + 0x998: 0x00c0, 0x999: 0x00c0, 0x99a: 0x00c0, 0x99b: 0x00c0, 0x99c: 0x00c0, 0x99d: 0x00c0, + 0x99e: 0x00c0, 0x99f: 0x00c0, 0x9a0: 0x00c0, 0x9a1: 0x00c0, 0x9a2: 0x00c0, 0x9a3: 0x00c0, + 0x9a4: 0x00c0, 0x9a5: 0x00c0, 0x9a6: 0x00c0, 0x9a7: 0x00c0, 0x9a8: 0x00c0, + 0x9aa: 0x00c0, 0x9ab: 0x00c0, 0x9ac: 0x00c0, 0x9ad: 0x00c0, 0x9ae: 0x00c0, 0x9af: 0x00c0, + 0x9b0: 0x00c0, 0x9b2: 0x00c0, 0x9b3: 0x00c0, 0x9b5: 0x00c0, + 0x9b6: 0x00c0, 0x9b7: 0x00c0, 0x9b8: 0x00c0, 0x9b9: 0x00c0, + 0x9bc: 0x00c3, 0x9bd: 0x00c0, 0x9be: 0x00c0, 0x9bf: 0x00c0, + // Block 0x27, offset 0x9c0 + 0x9c0: 0x00c0, 0x9c1: 0x00c3, 0x9c2: 0x00c3, 0x9c3: 0x00c3, 0x9c4: 0x00c3, 0x9c5: 0x00c3, + 0x9c7: 0x00c3, 0x9c8: 0x00c3, 0x9c9: 0x00c0, 0x9cb: 0x00c0, + 0x9cc: 0x00c0, 0x9cd: 0x00c6, 0x9d0: 0x00c0, + 0x9e0: 0x00c0, 0x9e1: 0x00c0, 0x9e2: 0x00c3, 0x9e3: 0x00c3, + 0x9e6: 0x00c0, 0x9e7: 0x00c0, 0x9e8: 0x00c0, 0x9e9: 0x00c0, + 0x9ea: 0x00c0, 0x9eb: 0x00c0, 0x9ec: 0x00c0, 0x9ed: 0x00c0, 0x9ee: 0x00c0, 0x9ef: 0x00c0, + 0x9f0: 0x0080, 0x9f1: 0x0080, + 0x9f9: 0x00c0, + // Block 0x28, offset 0xa00 + 0xa01: 0x00c3, 0xa02: 0x00c0, 0xa03: 0x00c0, 0xa05: 0x00c0, + 0xa06: 0x00c0, 0xa07: 0x00c0, 0xa08: 0x00c0, 0xa09: 0x00c0, 0xa0a: 0x00c0, 0xa0b: 0x00c0, + 0xa0c: 0x00c0, 0xa0f: 0x00c0, 0xa10: 0x00c0, + 0xa13: 0x00c0, 0xa14: 0x00c0, 0xa15: 0x00c0, 0xa16: 0x00c0, 0xa17: 0x00c0, + 0xa18: 0x00c0, 0xa19: 0x00c0, 0xa1a: 0x00c0, 0xa1b: 0x00c0, 0xa1c: 0x00c0, 0xa1d: 0x00c0, + 0xa1e: 0x00c0, 0xa1f: 0x00c0, 0xa20: 0x00c0, 0xa21: 0x00c0, 0xa22: 0x00c0, 0xa23: 0x00c0, + 0xa24: 0x00c0, 0xa25: 0x00c0, 0xa26: 0x00c0, 0xa27: 0x00c0, 0xa28: 0x00c0, + 0xa2a: 0x00c0, 0xa2b: 0x00c0, 0xa2c: 0x00c0, 0xa2d: 0x00c0, 0xa2e: 0x00c0, 0xa2f: 0x00c0, + 0xa30: 0x00c0, 0xa32: 0x00c0, 0xa33: 0x00c0, 0xa35: 0x00c0, + 0xa36: 0x00c0, 0xa37: 0x00c0, 0xa38: 0x00c0, 0xa39: 0x00c0, + 0xa3c: 0x00c3, 0xa3d: 0x00c0, 0xa3e: 0x00c0, 0xa3f: 0x00c3, + // Block 0x29, offset 0xa40 + 0xa40: 0x00c0, 0xa41: 0x00c3, 0xa42: 0x00c3, 0xa43: 0x00c3, 0xa44: 0x00c3, + 0xa47: 0x00c0, 0xa48: 0x00c0, 0xa4b: 0x00c0, + 0xa4c: 0x00c0, 0xa4d: 0x00c6, + 0xa56: 0x00c3, 0xa57: 0x00c0, + 0xa5c: 0x0080, 0xa5d: 0x0080, + 0xa5f: 0x00c0, 0xa60: 0x00c0, 0xa61: 0x00c0, 0xa62: 0x00c3, 0xa63: 0x00c3, + 0xa66: 0x00c0, 0xa67: 0x00c0, 0xa68: 0x00c0, 0xa69: 0x00c0, + 0xa6a: 0x00c0, 0xa6b: 0x00c0, 0xa6c: 0x00c0, 0xa6d: 0x00c0, 0xa6e: 0x00c0, 0xa6f: 0x00c0, + 0xa70: 0x0080, 0xa71: 0x00c0, 0xa72: 0x0080, 0xa73: 0x0080, 0xa74: 0x0080, 0xa75: 0x0080, + 0xa76: 0x0080, 0xa77: 0x0080, + // Block 0x2a, offset 0xa80 + 0xa82: 0x00c3, 0xa83: 0x00c0, 0xa85: 0x00c0, + 0xa86: 0x00c0, 0xa87: 0x00c0, 0xa88: 0x00c0, 0xa89: 0x00c0, 0xa8a: 0x00c0, + 0xa8e: 0x00c0, 0xa8f: 0x00c0, 0xa90: 0x00c0, + 0xa92: 0x00c0, 0xa93: 0x00c0, 0xa94: 0x00c0, 0xa95: 0x00c0, + 0xa99: 0x00c0, 0xa9a: 0x00c0, 0xa9c: 0x00c0, + 0xa9e: 0x00c0, 0xa9f: 0x00c0, 0xaa3: 0x00c0, + 0xaa4: 0x00c0, 0xaa8: 0x00c0, 0xaa9: 0x00c0, + 0xaaa: 0x00c0, 0xaae: 0x00c0, 0xaaf: 0x00c0, + 0xab0: 0x00c0, 0xab1: 0x00c0, 0xab2: 0x00c0, 0xab3: 0x00c0, 0xab4: 0x00c0, 0xab5: 0x00c0, + 0xab6: 0x00c0, 0xab7: 0x00c0, 0xab8: 0x00c0, 0xab9: 0x00c0, + 0xabe: 0x00c0, 0xabf: 0x00c0, + // Block 0x2b, offset 0xac0 + 0xac0: 0x00c3, 0xac1: 0x00c0, 0xac2: 0x00c0, + 0xac6: 0x00c0, 0xac7: 0x00c0, 0xac8: 0x00c0, 0xaca: 0x00c0, 0xacb: 0x00c0, + 0xacc: 0x00c0, 0xacd: 0x00c6, 0xad0: 0x00c0, + 0xad7: 0x00c0, + 0xae6: 0x00c0, 0xae7: 0x00c0, 0xae8: 0x00c0, 0xae9: 0x00c0, + 0xaea: 0x00c0, 0xaeb: 0x00c0, 0xaec: 0x00c0, 0xaed: 0x00c0, 0xaee: 0x00c0, 0xaef: 0x00c0, + 0xaf0: 0x0080, 0xaf1: 0x0080, 0xaf2: 0x0080, 0xaf3: 0x0080, 0xaf4: 0x0080, 0xaf5: 0x0080, + 0xaf6: 0x0080, 0xaf7: 0x0080, 0xaf8: 0x0080, 0xaf9: 0x0080, 0xafa: 0x0080, + // Block 0x2c, offset 0xb00 + 0xb00: 0x00c3, 0xb01: 0x00c0, 0xb02: 0x00c0, 0xb03: 0x00c0, 0xb05: 0x00c0, + 0xb06: 0x00c0, 0xb07: 0x00c0, 0xb08: 0x00c0, 0xb09: 0x00c0, 0xb0a: 0x00c0, 0xb0b: 0x00c0, + 0xb0c: 0x00c0, 0xb0e: 0x00c0, 0xb0f: 0x00c0, 0xb10: 0x00c0, + 0xb12: 0x00c0, 0xb13: 0x00c0, 0xb14: 0x00c0, 0xb15: 0x00c0, 0xb16: 0x00c0, 0xb17: 0x00c0, + 0xb18: 0x00c0, 0xb19: 0x00c0, 0xb1a: 0x00c0, 0xb1b: 0x00c0, 0xb1c: 0x00c0, 0xb1d: 0x00c0, + 0xb1e: 0x00c0, 0xb1f: 0x00c0, 0xb20: 0x00c0, 0xb21: 0x00c0, 0xb22: 0x00c0, 0xb23: 0x00c0, + 0xb24: 0x00c0, 0xb25: 0x00c0, 0xb26: 0x00c0, 0xb27: 0x00c0, 0xb28: 0x00c0, + 0xb2a: 0x00c0, 0xb2b: 0x00c0, 0xb2c: 0x00c0, 0xb2d: 0x00c0, 0xb2e: 0x00c0, 0xb2f: 0x00c0, + 0xb30: 0x00c0, 0xb31: 0x00c0, 0xb32: 0x00c0, 0xb33: 0x00c0, 0xb34: 0x00c0, 0xb35: 0x00c0, + 0xb36: 0x00c0, 0xb37: 0x00c0, 0xb38: 0x00c0, 0xb39: 0x00c0, + 0xb3d: 0x00c0, 0xb3e: 0x00c3, 0xb3f: 0x00c3, + // Block 0x2d, offset 0xb40 + 0xb40: 0x00c3, 0xb41: 0x00c0, 0xb42: 0x00c0, 0xb43: 0x00c0, 0xb44: 0x00c0, + 0xb46: 0x00c3, 0xb47: 0x00c3, 0xb48: 0x00c3, 0xb4a: 0x00c3, 0xb4b: 0x00c3, + 0xb4c: 0x00c3, 0xb4d: 0x00c6, + 0xb55: 0x00c3, 0xb56: 0x00c3, + 0xb58: 0x00c0, 0xb59: 0x00c0, 0xb5a: 0x00c0, + 0xb60: 0x00c0, 0xb61: 0x00c0, 0xb62: 0x00c3, 0xb63: 0x00c3, + 0xb66: 0x00c0, 0xb67: 0x00c0, 0xb68: 0x00c0, 0xb69: 0x00c0, + 0xb6a: 0x00c0, 0xb6b: 0x00c0, 0xb6c: 0x00c0, 0xb6d: 0x00c0, 0xb6e: 0x00c0, 0xb6f: 0x00c0, + 0xb78: 0x0080, 0xb79: 0x0080, 0xb7a: 0x0080, 0xb7b: 0x0080, + 0xb7c: 0x0080, 0xb7d: 0x0080, 0xb7e: 0x0080, 0xb7f: 0x0080, + // Block 0x2e, offset 0xb80 + 0xb80: 0x00c0, 0xb81: 0x00c3, 0xb82: 0x00c0, 0xb83: 0x00c0, 0xb85: 0x00c0, + 0xb86: 0x00c0, 0xb87: 0x00c0, 0xb88: 0x00c0, 0xb89: 0x00c0, 0xb8a: 0x00c0, 0xb8b: 0x00c0, + 0xb8c: 0x00c0, 0xb8e: 0x00c0, 0xb8f: 0x00c0, 0xb90: 0x00c0, + 0xb92: 0x00c0, 0xb93: 0x00c0, 0xb94: 0x00c0, 0xb95: 0x00c0, 0xb96: 0x00c0, 0xb97: 0x00c0, + 0xb98: 0x00c0, 0xb99: 0x00c0, 0xb9a: 0x00c0, 0xb9b: 0x00c0, 0xb9c: 0x00c0, 0xb9d: 0x00c0, + 0xb9e: 0x00c0, 0xb9f: 0x00c0, 0xba0: 0x00c0, 0xba1: 0x00c0, 0xba2: 0x00c0, 0xba3: 0x00c0, + 0xba4: 0x00c0, 0xba5: 0x00c0, 0xba6: 0x00c0, 0xba7: 0x00c0, 0xba8: 0x00c0, + 0xbaa: 0x00c0, 0xbab: 0x00c0, 0xbac: 0x00c0, 0xbad: 0x00c0, 0xbae: 0x00c0, 0xbaf: 0x00c0, + 0xbb0: 0x00c0, 0xbb1: 0x00c0, 0xbb2: 0x00c0, 0xbb3: 0x00c0, 0xbb5: 0x00c0, + 0xbb6: 0x00c0, 0xbb7: 0x00c0, 0xbb8: 0x00c0, 0xbb9: 0x00c0, + 0xbbc: 0x00c3, 0xbbd: 0x00c0, 0xbbe: 0x00c0, 0xbbf: 0x00c3, + // Block 0x2f, offset 0xbc0 + 0xbc0: 0x00c0, 0xbc1: 0x00c0, 0xbc2: 0x00c0, 0xbc3: 0x00c0, 0xbc4: 0x00c0, + 0xbc6: 0x00c3, 0xbc7: 0x00c0, 0xbc8: 0x00c0, 0xbca: 0x00c0, 0xbcb: 0x00c0, + 0xbcc: 0x00c3, 0xbcd: 0x00c6, + 0xbd5: 0x00c0, 0xbd6: 0x00c0, + 0xbde: 0x00c0, 0xbe0: 0x00c0, 0xbe1: 0x00c0, 0xbe2: 0x00c3, 0xbe3: 0x00c3, + 0xbe6: 0x00c0, 0xbe7: 0x00c0, 0xbe8: 0x00c0, 0xbe9: 0x00c0, + 0xbea: 0x00c0, 0xbeb: 0x00c0, 0xbec: 0x00c0, 0xbed: 0x00c0, 0xbee: 0x00c0, 0xbef: 0x00c0, + 0xbf1: 0x00c0, 0xbf2: 0x00c0, + // Block 0x30, offset 0xc00 + 0xc01: 0x00c3, 0xc02: 0x00c0, 0xc03: 0x00c0, 0xc05: 0x00c0, + 0xc06: 0x00c0, 0xc07: 0x00c0, 0xc08: 0x00c0, 0xc09: 0x00c0, 0xc0a: 0x00c0, 0xc0b: 0x00c0, + 0xc0c: 0x00c0, 0xc0e: 0x00c0, 0xc0f: 0x00c0, 0xc10: 0x00c0, + 0xc12: 0x00c0, 0xc13: 0x00c0, 0xc14: 0x00c0, 0xc15: 0x00c0, 0xc16: 0x00c0, 0xc17: 0x00c0, + 0xc18: 0x00c0, 0xc19: 0x00c0, 0xc1a: 0x00c0, 0xc1b: 0x00c0, 0xc1c: 0x00c0, 0xc1d: 0x00c0, + 0xc1e: 0x00c0, 0xc1f: 0x00c0, 0xc20: 0x00c0, 0xc21: 0x00c0, 0xc22: 0x00c0, 0xc23: 0x00c0, + 0xc24: 0x00c0, 0xc25: 0x00c0, 0xc26: 0x00c0, 0xc27: 0x00c0, 0xc28: 0x00c0, 0xc29: 0x00c0, + 0xc2a: 0x00c0, 0xc2b: 0x00c0, 0xc2c: 0x00c0, 0xc2d: 0x00c0, 0xc2e: 0x00c0, 0xc2f: 0x00c0, + 0xc30: 0x00c0, 0xc31: 0x00c0, 0xc32: 0x00c0, 0xc33: 0x00c0, 0xc34: 0x00c0, 0xc35: 0x00c0, + 0xc36: 0x00c0, 0xc37: 0x00c0, 0xc38: 0x00c0, 0xc39: 0x00c0, 0xc3a: 0x00c0, + 0xc3d: 0x00c0, 0xc3e: 0x00c0, 0xc3f: 0x00c0, + // Block 0x31, offset 0xc40 + 0xc40: 0x00c0, 0xc41: 0x00c3, 0xc42: 0x00c3, 0xc43: 0x00c3, 0xc44: 0x00c3, + 0xc46: 0x00c0, 0xc47: 0x00c0, 0xc48: 0x00c0, 0xc4a: 0x00c0, 0xc4b: 0x00c0, + 0xc4c: 0x00c0, 0xc4d: 0x00c6, 0xc4e: 0x00c0, 0xc4f: 0x0080, + 0xc54: 0x00c0, 0xc55: 0x00c0, 0xc56: 0x00c0, 0xc57: 0x00c0, + 0xc58: 0x0080, 0xc59: 0x0080, 0xc5a: 0x0080, 0xc5b: 0x0080, 0xc5c: 0x0080, 0xc5d: 0x0080, + 0xc5e: 0x0080, 0xc5f: 0x00c0, 0xc60: 0x00c0, 0xc61: 0x00c0, 0xc62: 0x00c3, 0xc63: 0x00c3, + 0xc66: 0x00c0, 0xc67: 0x00c0, 0xc68: 0x00c0, 0xc69: 0x00c0, + 0xc6a: 0x00c0, 0xc6b: 0x00c0, 0xc6c: 0x00c0, 0xc6d: 0x00c0, 0xc6e: 0x00c0, 0xc6f: 0x00c0, + 0xc70: 0x0080, 0xc71: 0x0080, 0xc72: 0x0080, 0xc73: 0x0080, 0xc74: 0x0080, 0xc75: 0x0080, + 0xc76: 0x0080, 0xc77: 0x0080, 0xc78: 0x0080, 0xc79: 0x0080, 0xc7a: 0x00c0, 0xc7b: 0x00c0, + 0xc7c: 0x00c0, 0xc7d: 0x00c0, 0xc7e: 0x00c0, 0xc7f: 0x00c0, + // Block 0x32, offset 0xc80 + 0xc82: 0x00c0, 0xc83: 0x00c0, 0xc85: 0x00c0, + 0xc86: 0x00c0, 0xc87: 0x00c0, 0xc88: 0x00c0, 0xc89: 0x00c0, 0xc8a: 0x00c0, 0xc8b: 0x00c0, + 0xc8c: 0x00c0, 0xc8d: 0x00c0, 0xc8e: 0x00c0, 0xc8f: 0x00c0, 0xc90: 0x00c0, 0xc91: 0x00c0, + 0xc92: 0x00c0, 0xc93: 0x00c0, 0xc94: 0x00c0, 0xc95: 0x00c0, 0xc96: 0x00c0, + 0xc9a: 0x00c0, 0xc9b: 0x00c0, 0xc9c: 0x00c0, 0xc9d: 0x00c0, + 0xc9e: 0x00c0, 0xc9f: 0x00c0, 0xca0: 0x00c0, 0xca1: 0x00c0, 0xca2: 0x00c0, 0xca3: 0x00c0, + 0xca4: 0x00c0, 0xca5: 0x00c0, 0xca6: 0x00c0, 0xca7: 0x00c0, 0xca8: 0x00c0, 0xca9: 0x00c0, + 0xcaa: 0x00c0, 0xcab: 0x00c0, 0xcac: 0x00c0, 0xcad: 0x00c0, 0xcae: 0x00c0, 0xcaf: 0x00c0, + 0xcb0: 0x00c0, 0xcb1: 0x00c0, 0xcb3: 0x00c0, 0xcb4: 0x00c0, 0xcb5: 0x00c0, + 0xcb6: 0x00c0, 0xcb7: 0x00c0, 0xcb8: 0x00c0, 0xcb9: 0x00c0, 0xcba: 0x00c0, 0xcbb: 0x00c0, + 0xcbd: 0x00c0, + // Block 0x33, offset 0xcc0 + 0xcc0: 0x00c0, 0xcc1: 0x00c0, 0xcc2: 0x00c0, 0xcc3: 0x00c0, 0xcc4: 0x00c0, 0xcc5: 0x00c0, + 0xcc6: 0x00c0, 0xcca: 0x00c6, + 0xccf: 0x00c0, 0xcd0: 0x00c0, 0xcd1: 0x00c0, + 0xcd2: 0x00c3, 0xcd3: 0x00c3, 0xcd4: 0x00c3, 0xcd6: 0x00c3, + 0xcd8: 0x00c0, 0xcd9: 0x00c0, 0xcda: 0x00c0, 0xcdb: 0x00c0, 0xcdc: 0x00c0, 0xcdd: 0x00c0, + 0xcde: 0x00c0, 0xcdf: 0x00c0, + 0xce6: 0x00c0, 0xce7: 0x00c0, 0xce8: 0x00c0, 0xce9: 0x00c0, + 0xcea: 0x00c0, 0xceb: 0x00c0, 0xcec: 0x00c0, 0xced: 0x00c0, 0xcee: 0x00c0, 0xcef: 0x00c0, + 0xcf2: 0x00c0, 0xcf3: 0x00c0, 0xcf4: 0x0080, + // Block 0x34, offset 0xd00 + 0xd01: 0x00c0, 0xd02: 0x00c0, 0xd03: 0x00c0, 0xd04: 0x00c0, 0xd05: 0x00c0, + 0xd06: 0x00c0, 0xd07: 0x00c0, 0xd08: 0x00c0, 0xd09: 0x00c0, 0xd0a: 0x00c0, 0xd0b: 0x00c0, + 0xd0c: 0x00c0, 0xd0d: 0x00c0, 0xd0e: 0x00c0, 0xd0f: 0x00c0, 0xd10: 0x00c0, 0xd11: 0x00c0, + 0xd12: 0x00c0, 0xd13: 0x00c0, 0xd14: 0x00c0, 0xd15: 0x00c0, 0xd16: 0x00c0, 0xd17: 0x00c0, + 0xd18: 0x00c0, 0xd19: 0x00c0, 0xd1a: 0x00c0, 0xd1b: 0x00c0, 0xd1c: 0x00c0, 0xd1d: 0x00c0, + 0xd1e: 0x00c0, 0xd1f: 0x00c0, 0xd20: 0x00c0, 0xd21: 0x00c0, 0xd22: 0x00c0, 0xd23: 0x00c0, + 0xd24: 0x00c0, 0xd25: 0x00c0, 0xd26: 0x00c0, 0xd27: 0x00c0, 0xd28: 0x00c0, 0xd29: 0x00c0, + 0xd2a: 0x00c0, 0xd2b: 0x00c0, 0xd2c: 0x00c0, 0xd2d: 0x00c0, 0xd2e: 0x00c0, 0xd2f: 0x00c0, + 0xd30: 0x00c0, 0xd31: 0x00c3, 0xd32: 0x00c0, 0xd33: 0x0080, 0xd34: 0x00c3, 0xd35: 0x00c3, + 0xd36: 0x00c3, 0xd37: 0x00c3, 0xd38: 0x00c3, 0xd39: 0x00c3, 0xd3a: 0x00c6, + 0xd3f: 0x0080, + // Block 0x35, offset 0xd40 + 0xd40: 0x00c0, 0xd41: 0x00c0, 0xd42: 0x00c0, 0xd43: 0x00c0, 0xd44: 0x00c0, 0xd45: 0x00c0, + 0xd46: 0x00c0, 0xd47: 0x00c3, 0xd48: 0x00c3, 0xd49: 0x00c3, 0xd4a: 0x00c3, 0xd4b: 0x00c3, + 0xd4c: 0x00c3, 0xd4d: 0x00c3, 0xd4e: 0x00c3, 0xd4f: 0x0080, 0xd50: 0x00c0, 0xd51: 0x00c0, + 0xd52: 0x00c0, 0xd53: 0x00c0, 0xd54: 0x00c0, 0xd55: 0x00c0, 0xd56: 0x00c0, 0xd57: 0x00c0, + 0xd58: 0x00c0, 0xd59: 0x00c0, 0xd5a: 0x0080, 0xd5b: 0x0080, + // Block 0x36, offset 0xd80 + 0xd81: 0x00c0, 0xd82: 0x00c0, 0xd84: 0x00c0, + 0xd87: 0x00c0, 0xd88: 0x00c0, 0xd8a: 0x00c0, + 0xd8d: 0x00c0, + 0xd94: 0x00c0, 0xd95: 0x00c0, 0xd96: 0x00c0, 0xd97: 0x00c0, + 0xd99: 0x00c0, 0xd9a: 0x00c0, 0xd9b: 0x00c0, 0xd9c: 0x00c0, 0xd9d: 0x00c0, + 0xd9e: 0x00c0, 0xd9f: 0x00c0, 0xda1: 0x00c0, 0xda2: 0x00c0, 0xda3: 0x00c0, + 0xda5: 0x00c0, 0xda7: 0x00c0, + 0xdaa: 0x00c0, 0xdab: 0x00c0, 0xdad: 0x00c0, 0xdae: 0x00c0, 0xdaf: 0x00c0, + 0xdb0: 0x00c0, 0xdb1: 0x00c3, 0xdb2: 0x00c0, 0xdb3: 0x0080, 0xdb4: 0x00c3, 0xdb5: 0x00c3, + 0xdb6: 0x00c3, 0xdb7: 0x00c3, 0xdb8: 0x00c3, 0xdb9: 0x00c3, 0xdbb: 0x00c3, + 0xdbc: 0x00c3, 0xdbd: 0x00c0, + // Block 0x37, offset 0xdc0 + 0xdc0: 0x00c0, 0xdc1: 0x00c0, 0xdc2: 0x00c0, 0xdc3: 0x00c0, 0xdc4: 0x00c0, + 0xdc6: 0x00c0, 0xdc8: 0x00c3, 0xdc9: 0x00c3, 0xdca: 0x00c3, 0xdcb: 0x00c3, + 0xdcc: 0x00c3, 0xdcd: 0x00c3, 0xdd0: 0x00c0, 0xdd1: 0x00c0, + 0xdd2: 0x00c0, 0xdd3: 0x00c0, 0xdd4: 0x00c0, 0xdd5: 0x00c0, 0xdd6: 0x00c0, 0xdd7: 0x00c0, + 0xdd8: 0x00c0, 0xdd9: 0x00c0, 0xddc: 0x0080, 0xddd: 0x0080, + 0xdde: 0x00c0, 0xddf: 0x00c0, + // Block 0x38, offset 0xe00 + 0xe00: 0x00c0, 0xe01: 0x0080, 0xe02: 0x0080, 0xe03: 0x0080, 0xe04: 0x0080, 0xe05: 0x0080, + 0xe06: 0x0080, 0xe07: 0x0080, 0xe08: 0x0080, 0xe09: 0x0080, 0xe0a: 0x0080, 0xe0b: 0x00c0, + 0xe0c: 0x0080, 0xe0d: 0x0080, 0xe0e: 0x0080, 0xe0f: 0x0080, 0xe10: 0x0080, 0xe11: 0x0080, + 0xe12: 0x0080, 0xe13: 0x0080, 0xe14: 0x0080, 0xe15: 0x0080, 0xe16: 0x0080, 0xe17: 0x0080, + 0xe18: 0x00c3, 0xe19: 0x00c3, 0xe1a: 0x0080, 0xe1b: 0x0080, 0xe1c: 0x0080, 0xe1d: 0x0080, + 0xe1e: 0x0080, 0xe1f: 0x0080, 0xe20: 0x00c0, 0xe21: 0x00c0, 0xe22: 0x00c0, 0xe23: 0x00c0, + 0xe24: 0x00c0, 0xe25: 0x00c0, 0xe26: 0x00c0, 0xe27: 0x00c0, 0xe28: 0x00c0, 0xe29: 0x00c0, + 0xe2a: 0x0080, 0xe2b: 0x0080, 0xe2c: 0x0080, 0xe2d: 0x0080, 0xe2e: 0x0080, 0xe2f: 0x0080, + 0xe30: 0x0080, 0xe31: 0x0080, 0xe32: 0x0080, 0xe33: 0x0080, 0xe34: 0x0080, 0xe35: 0x00c3, + 0xe36: 0x0080, 0xe37: 0x00c3, 0xe38: 0x0080, 0xe39: 0x00c3, 0xe3a: 0x0080, 0xe3b: 0x0080, + 0xe3c: 0x0080, 0xe3d: 0x0080, 0xe3e: 0x00c0, 0xe3f: 0x00c0, + // Block 0x39, offset 0xe40 + 0xe40: 0x00c0, 0xe41: 0x00c0, 0xe42: 0x00c0, 0xe43: 0x0080, 0xe44: 0x00c0, 0xe45: 0x00c0, + 0xe46: 0x00c0, 0xe47: 0x00c0, 0xe49: 0x00c0, 0xe4a: 0x00c0, 0xe4b: 0x00c0, + 0xe4c: 0x00c0, 0xe4d: 0x0080, 0xe4e: 0x00c0, 0xe4f: 0x00c0, 0xe50: 0x00c0, 0xe51: 0x00c0, + 0xe52: 0x0080, 0xe53: 0x00c0, 0xe54: 0x00c0, 0xe55: 0x00c0, 0xe56: 0x00c0, 0xe57: 0x0080, + 0xe58: 0x00c0, 0xe59: 0x00c0, 0xe5a: 0x00c0, 0xe5b: 0x00c0, 0xe5c: 0x0080, 0xe5d: 0x00c0, + 0xe5e: 0x00c0, 0xe5f: 0x00c0, 0xe60: 0x00c0, 0xe61: 0x00c0, 0xe62: 0x00c0, 0xe63: 0x00c0, + 0xe64: 0x00c0, 0xe65: 0x00c0, 0xe66: 0x00c0, 0xe67: 0x00c0, 0xe68: 0x00c0, 0xe69: 0x0080, + 0xe6a: 0x00c0, 0xe6b: 0x00c0, 0xe6c: 0x00c0, + 0xe71: 0x00c3, 0xe72: 0x00c3, 0xe73: 0x0083, 0xe74: 0x00c3, 0xe75: 0x0083, + 0xe76: 0x0083, 0xe77: 0x0083, 0xe78: 0x0083, 0xe79: 0x0083, 0xe7a: 0x00c3, 0xe7b: 0x00c3, + 0xe7c: 0x00c3, 0xe7d: 0x00c3, 0xe7e: 0x00c3, 0xe7f: 0x00c0, + // Block 0x3a, offset 0xe80 + 0xe80: 0x00c3, 0xe81: 0x0083, 0xe82: 0x00c3, 0xe83: 0x00c3, 0xe84: 0x00c6, 0xe85: 0x0080, + 0xe86: 0x00c3, 0xe87: 0x00c3, 0xe88: 0x00c0, 0xe89: 0x00c0, 0xe8a: 0x00c0, 0xe8b: 0x00c0, + 0xe8c: 0x00c0, 0xe8d: 0x00c3, 0xe8e: 0x00c3, 0xe8f: 0x00c3, 0xe90: 0x00c3, 0xe91: 0x00c3, + 0xe92: 0x00c3, 0xe93: 0x0083, 0xe94: 0x00c3, 0xe95: 0x00c3, 0xe96: 0x00c3, 0xe97: 0x00c3, + 0xe99: 0x00c3, 0xe9a: 0x00c3, 0xe9b: 0x00c3, 0xe9c: 0x00c3, 0xe9d: 0x0083, + 0xe9e: 0x00c3, 0xe9f: 0x00c3, 0xea0: 0x00c3, 0xea1: 0x00c3, 0xea2: 0x0083, 0xea3: 0x00c3, + 0xea4: 0x00c3, 0xea5: 0x00c3, 0xea6: 0x00c3, 0xea7: 0x0083, 0xea8: 0x00c3, 0xea9: 0x00c3, + 0xeaa: 0x00c3, 0xeab: 0x00c3, 0xeac: 0x0083, 0xead: 0x00c3, 0xeae: 0x00c3, 0xeaf: 0x00c3, + 0xeb0: 0x00c3, 0xeb1: 0x00c3, 0xeb2: 0x00c3, 0xeb3: 0x00c3, 0xeb4: 0x00c3, 0xeb5: 0x00c3, + 0xeb6: 0x00c3, 0xeb7: 0x00c3, 0xeb8: 0x00c3, 0xeb9: 0x0083, 0xeba: 0x00c3, 0xebb: 0x00c3, + 0xebc: 0x00c3, 0xebe: 0x0080, 0xebf: 0x0080, + // Block 0x3b, offset 0xec0 + 0xec0: 0x0080, 0xec1: 0x0080, 0xec2: 0x0080, 0xec3: 0x0080, 0xec4: 0x0080, 0xec5: 0x0080, + 0xec6: 0x00c3, 0xec7: 0x0080, 0xec8: 0x0080, 0xec9: 0x0080, 0xeca: 0x0080, 0xecb: 0x0080, + 0xecc: 0x0080, 0xece: 0x0080, 0xecf: 0x0080, 0xed0: 0x0080, 0xed1: 0x0080, + 0xed2: 0x0080, 0xed3: 0x0080, 0xed4: 0x0080, 0xed5: 0x0080, 0xed6: 0x0080, 0xed7: 0x0080, + 0xed8: 0x0080, 0xed9: 0x0080, 0xeda: 0x0080, + // Block 0x3c, offset 0xf00 + 0xf00: 0x00c0, 0xf01: 0x00c0, 0xf02: 0x00c0, 0xf03: 0x00c0, 0xf04: 0x00c0, 0xf05: 0x00c0, + 0xf06: 0x00c0, 0xf07: 0x00c0, 0xf08: 0x00c0, 0xf09: 0x00c0, 0xf0a: 0x00c0, 0xf0b: 0x00c0, + 0xf0c: 0x00c0, 0xf0d: 0x00c0, 0xf0e: 0x00c0, 0xf0f: 0x00c0, 0xf10: 0x00c0, 0xf11: 0x00c0, + 0xf12: 0x00c0, 0xf13: 0x00c0, 0xf14: 0x00c0, 0xf15: 0x00c0, 0xf16: 0x00c0, 0xf17: 0x00c0, + 0xf18: 0x00c0, 0xf19: 0x00c0, 0xf1a: 0x00c0, 0xf1b: 0x00c0, 0xf1c: 0x00c0, 0xf1d: 0x00c0, + 0xf1e: 0x00c0, 0xf1f: 0x00c0, 0xf20: 0x00c0, 0xf21: 0x00c0, 0xf22: 0x00c0, 0xf23: 0x00c0, + 0xf24: 0x00c0, 0xf25: 0x00c0, 0xf26: 0x00c0, 0xf27: 0x00c0, 0xf28: 0x00c0, 0xf29: 0x00c0, + 0xf2a: 0x00c0, 0xf2b: 0x00c0, 0xf2c: 0x00c0, 0xf2d: 0x00c3, 0xf2e: 0x00c3, 0xf2f: 0x00c3, + 0xf30: 0x00c3, 0xf31: 0x00c0, 0xf32: 0x00c3, 0xf33: 0x00c3, 0xf34: 0x00c3, 0xf35: 0x00c3, + 0xf36: 0x00c3, 0xf37: 0x00c3, 0xf38: 0x00c0, 0xf39: 0x00c6, 0xf3a: 0x00c6, 0xf3b: 0x00c0, + 0xf3c: 0x00c0, 0xf3d: 0x00c3, 0xf3e: 0x00c3, 0xf3f: 0x00c0, + // Block 0x3d, offset 0xf40 + 0xf40: 0x00c0, 0xf41: 0x00c0, 0xf42: 0x00c0, 0xf43: 0x00c0, 0xf44: 0x00c0, 0xf45: 0x00c0, + 0xf46: 0x00c0, 0xf47: 0x00c0, 0xf48: 0x00c0, 0xf49: 0x00c0, 0xf4a: 0x0080, 0xf4b: 0x0080, + 0xf4c: 0x0080, 0xf4d: 0x0080, 0xf4e: 0x0080, 0xf4f: 0x0080, 0xf50: 0x00c0, 0xf51: 0x00c0, + 0xf52: 0x00c0, 0xf53: 0x00c0, 0xf54: 0x00c0, 0xf55: 0x00c0, 0xf56: 0x00c0, 0xf57: 0x00c0, + 0xf58: 0x00c3, 0xf59: 0x00c3, 0xf5a: 0x00c0, 0xf5b: 0x00c0, 0xf5c: 0x00c0, 0xf5d: 0x00c0, + 0xf5e: 0x00c3, 0xf5f: 0x00c3, 0xf60: 0x00c3, 0xf61: 0x00c0, 0xf62: 0x00c0, 0xf63: 0x00c0, + 0xf64: 0x00c0, 0xf65: 0x00c0, 0xf66: 0x00c0, 0xf67: 0x00c0, 0xf68: 0x00c0, 0xf69: 0x00c0, + 0xf6a: 0x00c0, 0xf6b: 0x00c0, 0xf6c: 0x00c0, 0xf6d: 0x00c0, 0xf6e: 0x00c0, 0xf6f: 0x00c0, + 0xf70: 0x00c0, 0xf71: 0x00c3, 0xf72: 0x00c3, 0xf73: 0x00c3, 0xf74: 0x00c3, 0xf75: 0x00c0, + 0xf76: 0x00c0, 0xf77: 0x00c0, 0xf78: 0x00c0, 0xf79: 0x00c0, 0xf7a: 0x00c0, 0xf7b: 0x00c0, + 0xf7c: 0x00c0, 0xf7d: 0x00c0, 0xf7e: 0x00c0, 0xf7f: 0x00c0, + // Block 0x3e, offset 0xf80 + 0xf80: 0x00c0, 0xf81: 0x00c0, 0xf82: 0x00c3, 0xf83: 0x00c0, 0xf84: 0x00c0, 0xf85: 0x00c3, + 0xf86: 0x00c3, 0xf87: 0x00c0, 0xf88: 0x00c0, 0xf89: 0x00c0, 0xf8a: 0x00c0, 0xf8b: 0x00c0, + 0xf8c: 0x00c0, 0xf8d: 0x00c3, 0xf8e: 0x00c0, 0xf8f: 0x00c0, 0xf90: 0x00c0, 0xf91: 0x00c0, + 0xf92: 0x00c0, 0xf93: 0x00c0, 0xf94: 0x00c0, 0xf95: 0x00c0, 0xf96: 0x00c0, 0xf97: 0x00c0, + 0xf98: 0x00c0, 0xf99: 0x00c0, 0xf9a: 0x00c0, 0xf9b: 0x00c0, 0xf9c: 0x00c0, 0xf9d: 0x00c3, + 0xf9e: 0x0080, 0xf9f: 0x0080, 0xfa0: 0x00c0, 0xfa1: 0x00c0, 0xfa2: 0x00c0, 0xfa3: 0x00c0, + 0xfa4: 0x00c0, 0xfa5: 0x00c0, 0xfa6: 0x00c0, 0xfa7: 0x00c0, 0xfa8: 0x00c0, 0xfa9: 0x00c0, + 0xfaa: 0x00c0, 0xfab: 0x00c0, 0xfac: 0x00c0, 0xfad: 0x00c0, 0xfae: 0x00c0, 0xfaf: 0x00c0, + 0xfb0: 0x00c0, 0xfb1: 0x00c0, 0xfb2: 0x00c0, 0xfb3: 0x00c0, 0xfb4: 0x00c0, 0xfb5: 0x00c0, + 0xfb6: 0x00c0, 0xfb7: 0x00c0, 0xfb8: 0x00c0, 0xfb9: 0x00c0, 0xfba: 0x00c0, 0xfbb: 0x00c0, + 0xfbc: 0x00c0, 0xfbd: 0x00c0, 0xfbe: 0x00c0, 0xfbf: 0x00c0, + // Block 0x3f, offset 0xfc0 + 0xfc0: 0x00c0, 0xfc1: 0x00c0, 0xfc2: 0x00c0, 0xfc3: 0x00c0, 0xfc4: 0x00c0, 0xfc5: 0x00c0, + 0xfc7: 0x00c0, + 0xfcd: 0x00c0, 0xfd0: 0x00c0, 0xfd1: 0x00c0, + 0xfd2: 0x00c0, 0xfd3: 0x00c0, 0xfd4: 0x00c0, 0xfd5: 0x00c0, 0xfd6: 0x00c0, 0xfd7: 0x00c0, + 0xfd8: 0x00c0, 0xfd9: 0x00c0, 0xfda: 0x00c0, 0xfdb: 0x00c0, 0xfdc: 0x00c0, 0xfdd: 0x00c0, + 0xfde: 0x00c0, 0xfdf: 0x00c0, 0xfe0: 0x00c0, 0xfe1: 0x00c0, 0xfe2: 0x00c0, 0xfe3: 0x00c0, + 0xfe4: 0x00c0, 0xfe5: 0x00c0, 0xfe6: 0x00c0, 0xfe7: 0x00c0, 0xfe8: 0x00c0, 0xfe9: 0x00c0, + 0xfea: 0x00c0, 0xfeb: 0x00c0, 0xfec: 0x00c0, 0xfed: 0x00c0, 0xfee: 0x00c0, 0xfef: 0x00c0, + 0xff0: 0x00c0, 0xff1: 0x00c0, 0xff2: 0x00c0, 0xff3: 0x00c0, 0xff4: 0x00c0, 0xff5: 0x00c0, + 0xff6: 0x00c0, 0xff7: 0x00c0, 0xff8: 0x00c0, 0xff9: 0x00c0, 0xffa: 0x00c0, 0xffb: 0x0080, + 0xffc: 0x0080, 0xffd: 0x00c0, 0xffe: 0x00c0, 0xfff: 0x00c0, + // Block 0x40, offset 0x1000 + 0x1000: 0x0040, 0x1001: 0x0040, 0x1002: 0x0040, 0x1003: 0x0040, 0x1004: 0x0040, 0x1005: 0x0040, + 0x1006: 0x0040, 0x1007: 0x0040, 0x1008: 0x0040, 0x1009: 0x0040, 0x100a: 0x0040, 0x100b: 0x0040, + 0x100c: 0x0040, 0x100d: 0x0040, 0x100e: 0x0040, 0x100f: 0x0040, 0x1010: 0x0040, 0x1011: 0x0040, + 0x1012: 0x0040, 0x1013: 0x0040, 0x1014: 0x0040, 0x1015: 0x0040, 0x1016: 0x0040, 0x1017: 0x0040, + 0x1018: 0x0040, 0x1019: 0x0040, 0x101a: 0x0040, 0x101b: 0x0040, 0x101c: 0x0040, 0x101d: 0x0040, + 0x101e: 0x0040, 0x101f: 0x0040, 0x1020: 0x0040, 0x1021: 0x0040, 0x1022: 0x0040, 0x1023: 0x0040, + 0x1024: 0x0040, 0x1025: 0x0040, 0x1026: 0x0040, 0x1027: 0x0040, 0x1028: 0x0040, 0x1029: 0x0040, + 0x102a: 0x0040, 0x102b: 0x0040, 0x102c: 0x0040, 0x102d: 0x0040, 0x102e: 0x0040, 0x102f: 0x0040, + 0x1030: 0x0040, 0x1031: 0x0040, 0x1032: 0x0040, 0x1033: 0x0040, 0x1034: 0x0040, 0x1035: 0x0040, + 0x1036: 0x0040, 0x1037: 0x0040, 0x1038: 0x0040, 0x1039: 0x0040, 0x103a: 0x0040, 0x103b: 0x0040, + 0x103c: 0x0040, 0x103d: 0x0040, 0x103e: 0x0040, 0x103f: 0x0040, + // Block 0x41, offset 0x1040 + 0x1040: 0x00c0, 0x1041: 0x00c0, 0x1042: 0x00c0, 0x1043: 0x00c0, 0x1044: 0x00c0, 0x1045: 0x00c0, + 0x1046: 0x00c0, 0x1047: 0x00c0, 0x1048: 0x00c0, 0x104a: 0x00c0, 0x104b: 0x00c0, + 0x104c: 0x00c0, 0x104d: 0x00c0, 0x1050: 0x00c0, 0x1051: 0x00c0, + 0x1052: 0x00c0, 0x1053: 0x00c0, 0x1054: 0x00c0, 0x1055: 0x00c0, 0x1056: 0x00c0, + 0x1058: 0x00c0, 0x105a: 0x00c0, 0x105b: 0x00c0, 0x105c: 0x00c0, 0x105d: 0x00c0, + 0x1060: 0x00c0, 0x1061: 0x00c0, 0x1062: 0x00c0, 0x1063: 0x00c0, + 0x1064: 0x00c0, 0x1065: 0x00c0, 0x1066: 0x00c0, 0x1067: 0x00c0, 0x1068: 0x00c0, 0x1069: 0x00c0, + 0x106a: 0x00c0, 0x106b: 0x00c0, 0x106c: 0x00c0, 0x106d: 0x00c0, 0x106e: 0x00c0, 0x106f: 0x00c0, + 0x1070: 0x00c0, 0x1071: 0x00c0, 0x1072: 0x00c0, 0x1073: 0x00c0, 0x1074: 0x00c0, 0x1075: 0x00c0, + 0x1076: 0x00c0, 0x1077: 0x00c0, 0x1078: 0x00c0, 0x1079: 0x00c0, 0x107a: 0x00c0, 0x107b: 0x00c0, + 0x107c: 0x00c0, 0x107d: 0x00c0, 0x107e: 0x00c0, 0x107f: 0x00c0, + // Block 0x42, offset 0x1080 + 0x1080: 0x00c0, 0x1081: 0x00c0, 0x1082: 0x00c0, 0x1083: 0x00c0, 0x1084: 0x00c0, 0x1085: 0x00c0, + 0x1086: 0x00c0, 0x1087: 0x00c0, 0x1088: 0x00c0, 0x108a: 0x00c0, 0x108b: 0x00c0, + 0x108c: 0x00c0, 0x108d: 0x00c0, 0x1090: 0x00c0, 0x1091: 0x00c0, + 0x1092: 0x00c0, 0x1093: 0x00c0, 0x1094: 0x00c0, 0x1095: 0x00c0, 0x1096: 0x00c0, 0x1097: 0x00c0, + 0x1098: 0x00c0, 0x1099: 0x00c0, 0x109a: 0x00c0, 0x109b: 0x00c0, 0x109c: 0x00c0, 0x109d: 0x00c0, + 0x109e: 0x00c0, 0x109f: 0x00c0, 0x10a0: 0x00c0, 0x10a1: 0x00c0, 0x10a2: 0x00c0, 0x10a3: 0x00c0, + 0x10a4: 0x00c0, 0x10a5: 0x00c0, 0x10a6: 0x00c0, 0x10a7: 0x00c0, 0x10a8: 0x00c0, 0x10a9: 0x00c0, + 0x10aa: 0x00c0, 0x10ab: 0x00c0, 0x10ac: 0x00c0, 0x10ad: 0x00c0, 0x10ae: 0x00c0, 0x10af: 0x00c0, + 0x10b0: 0x00c0, 0x10b2: 0x00c0, 0x10b3: 0x00c0, 0x10b4: 0x00c0, 0x10b5: 0x00c0, + 0x10b8: 0x00c0, 0x10b9: 0x00c0, 0x10ba: 0x00c0, 0x10bb: 0x00c0, + 0x10bc: 0x00c0, 0x10bd: 0x00c0, 0x10be: 0x00c0, + // Block 0x43, offset 0x10c0 + 0x10c0: 0x00c0, 0x10c2: 0x00c0, 0x10c3: 0x00c0, 0x10c4: 0x00c0, 0x10c5: 0x00c0, + 0x10c8: 0x00c0, 0x10c9: 0x00c0, 0x10ca: 0x00c0, 0x10cb: 0x00c0, + 0x10cc: 0x00c0, 0x10cd: 0x00c0, 0x10ce: 0x00c0, 0x10cf: 0x00c0, 0x10d0: 0x00c0, 0x10d1: 0x00c0, + 0x10d2: 0x00c0, 0x10d3: 0x00c0, 0x10d4: 0x00c0, 0x10d5: 0x00c0, 0x10d6: 0x00c0, + 0x10d8: 0x00c0, 0x10d9: 0x00c0, 0x10da: 0x00c0, 0x10db: 0x00c0, 0x10dc: 0x00c0, 0x10dd: 0x00c0, + 0x10de: 0x00c0, 0x10df: 0x00c0, 0x10e0: 0x00c0, 0x10e1: 0x00c0, 0x10e2: 0x00c0, 0x10e3: 0x00c0, + 0x10e4: 0x00c0, 0x10e5: 0x00c0, 0x10e6: 0x00c0, 0x10e7: 0x00c0, 0x10e8: 0x00c0, 0x10e9: 0x00c0, + 0x10ea: 0x00c0, 0x10eb: 0x00c0, 0x10ec: 0x00c0, 0x10ed: 0x00c0, 0x10ee: 0x00c0, 0x10ef: 0x00c0, + 0x10f0: 0x00c0, 0x10f1: 0x00c0, 0x10f2: 0x00c0, 0x10f3: 0x00c0, 0x10f4: 0x00c0, 0x10f5: 0x00c0, + 0x10f6: 0x00c0, 0x10f7: 0x00c0, 0x10f8: 0x00c0, 0x10f9: 0x00c0, 0x10fa: 0x00c0, 0x10fb: 0x00c0, + 0x10fc: 0x00c0, 0x10fd: 0x00c0, 0x10fe: 0x00c0, 0x10ff: 0x00c0, + // Block 0x44, offset 0x1100 + 0x1100: 0x00c0, 0x1101: 0x00c0, 0x1102: 0x00c0, 0x1103: 0x00c0, 0x1104: 0x00c0, 0x1105: 0x00c0, + 0x1106: 0x00c0, 0x1107: 0x00c0, 0x1108: 0x00c0, 0x1109: 0x00c0, 0x110a: 0x00c0, 0x110b: 0x00c0, + 0x110c: 0x00c0, 0x110d: 0x00c0, 0x110e: 0x00c0, 0x110f: 0x00c0, 0x1110: 0x00c0, + 0x1112: 0x00c0, 0x1113: 0x00c0, 0x1114: 0x00c0, 0x1115: 0x00c0, + 0x1118: 0x00c0, 0x1119: 0x00c0, 0x111a: 0x00c0, 0x111b: 0x00c0, 0x111c: 0x00c0, 0x111d: 0x00c0, + 0x111e: 0x00c0, 0x111f: 0x00c0, 0x1120: 0x00c0, 0x1121: 0x00c0, 0x1122: 0x00c0, 0x1123: 0x00c0, + 0x1124: 0x00c0, 0x1125: 0x00c0, 0x1126: 0x00c0, 0x1127: 0x00c0, 0x1128: 0x00c0, 0x1129: 0x00c0, + 0x112a: 0x00c0, 0x112b: 0x00c0, 0x112c: 0x00c0, 0x112d: 0x00c0, 0x112e: 0x00c0, 0x112f: 0x00c0, + 0x1130: 0x00c0, 0x1131: 0x00c0, 0x1132: 0x00c0, 0x1133: 0x00c0, 0x1134: 0x00c0, 0x1135: 0x00c0, + 0x1136: 0x00c0, 0x1137: 0x00c0, 0x1138: 0x00c0, 0x1139: 0x00c0, 0x113a: 0x00c0, 0x113b: 0x00c0, + 0x113c: 0x00c0, 0x113d: 0x00c0, 0x113e: 0x00c0, 0x113f: 0x00c0, + // Block 0x45, offset 0x1140 + 0x1140: 0x00c0, 0x1141: 0x00c0, 0x1142: 0x00c0, 0x1143: 0x00c0, 0x1144: 0x00c0, 0x1145: 0x00c0, + 0x1146: 0x00c0, 0x1147: 0x00c0, 0x1148: 0x00c0, 0x1149: 0x00c0, 0x114a: 0x00c0, 0x114b: 0x00c0, + 0x114c: 0x00c0, 0x114d: 0x00c0, 0x114e: 0x00c0, 0x114f: 0x00c0, 0x1150: 0x00c0, 0x1151: 0x00c0, + 0x1152: 0x00c0, 0x1153: 0x00c0, 0x1154: 0x00c0, 0x1155: 0x00c0, 0x1156: 0x00c0, 0x1157: 0x00c0, + 0x1158: 0x00c0, 0x1159: 0x00c0, 0x115a: 0x00c0, 0x115d: 0x00c3, + 0x115e: 0x00c3, 0x115f: 0x00c3, 0x1160: 0x0080, 0x1161: 0x0080, 0x1162: 0x0080, 0x1163: 0x0080, + 0x1164: 0x0080, 0x1165: 0x0080, 0x1166: 0x0080, 0x1167: 0x0080, 0x1168: 0x0080, 0x1169: 0x0080, + 0x116a: 0x0080, 0x116b: 0x0080, 0x116c: 0x0080, 0x116d: 0x0080, 0x116e: 0x0080, 0x116f: 0x0080, + 0x1170: 0x0080, 0x1171: 0x0080, 0x1172: 0x0080, 0x1173: 0x0080, 0x1174: 0x0080, 0x1175: 0x0080, + 0x1176: 0x0080, 0x1177: 0x0080, 0x1178: 0x0080, 0x1179: 0x0080, 0x117a: 0x0080, 0x117b: 0x0080, + 0x117c: 0x0080, + // Block 0x46, offset 0x1180 + 0x1180: 0x00c0, 0x1181: 0x00c0, 0x1182: 0x00c0, 0x1183: 0x00c0, 0x1184: 0x00c0, 0x1185: 0x00c0, + 0x1186: 0x00c0, 0x1187: 0x00c0, 0x1188: 0x00c0, 0x1189: 0x00c0, 0x118a: 0x00c0, 0x118b: 0x00c0, + 0x118c: 0x00c0, 0x118d: 0x00c0, 0x118e: 0x00c0, 0x118f: 0x00c0, 0x1190: 0x0080, 0x1191: 0x0080, + 0x1192: 0x0080, 0x1193: 0x0080, 0x1194: 0x0080, 0x1195: 0x0080, 0x1196: 0x0080, 0x1197: 0x0080, + 0x1198: 0x0080, 0x1199: 0x0080, + 0x11a0: 0x00c0, 0x11a1: 0x00c0, 0x11a2: 0x00c0, 0x11a3: 0x00c0, + 0x11a4: 0x00c0, 0x11a5: 0x00c0, 0x11a6: 0x00c0, 0x11a7: 0x00c0, 0x11a8: 0x00c0, 0x11a9: 0x00c0, + 0x11aa: 0x00c0, 0x11ab: 0x00c0, 0x11ac: 0x00c0, 0x11ad: 0x00c0, 0x11ae: 0x00c0, 0x11af: 0x00c0, + 0x11b0: 0x00c0, 0x11b1: 0x00c0, 0x11b2: 0x00c0, 0x11b3: 0x00c0, 0x11b4: 0x00c0, 0x11b5: 0x00c0, + 0x11b6: 0x00c0, 0x11b7: 0x00c0, 0x11b8: 0x00c0, 0x11b9: 0x00c0, 0x11ba: 0x00c0, 0x11bb: 0x00c0, + 0x11bc: 0x00c0, 0x11bd: 0x00c0, 0x11be: 0x00c0, 0x11bf: 0x00c0, + // Block 0x47, offset 0x11c0 + 0x11c0: 0x00c0, 0x11c1: 0x00c0, 0x11c2: 0x00c0, 0x11c3: 0x00c0, 0x11c4: 0x00c0, 0x11c5: 0x00c0, + 0x11c6: 0x00c0, 0x11c7: 0x00c0, 0x11c8: 0x00c0, 0x11c9: 0x00c0, 0x11ca: 0x00c0, 0x11cb: 0x00c0, + 0x11cc: 0x00c0, 0x11cd: 0x00c0, 0x11ce: 0x00c0, 0x11cf: 0x00c0, 0x11d0: 0x00c0, 0x11d1: 0x00c0, + 0x11d2: 0x00c0, 0x11d3: 0x00c0, 0x11d4: 0x00c0, 0x11d5: 0x00c0, 0x11d6: 0x00c0, 0x11d7: 0x00c0, + 0x11d8: 0x00c0, 0x11d9: 0x00c0, 0x11da: 0x00c0, 0x11db: 0x00c0, 0x11dc: 0x00c0, 0x11dd: 0x00c0, + 0x11de: 0x00c0, 0x11df: 0x00c0, 0x11e0: 0x00c0, 0x11e1: 0x00c0, 0x11e2: 0x00c0, 0x11e3: 0x00c0, + 0x11e4: 0x00c0, 0x11e5: 0x00c0, 0x11e6: 0x00c0, 0x11e7: 0x00c0, 0x11e8: 0x00c0, 0x11e9: 0x00c0, + 0x11ea: 0x00c0, 0x11eb: 0x00c0, 0x11ec: 0x00c0, 0x11ed: 0x00c0, 0x11ee: 0x00c0, 0x11ef: 0x00c0, + 0x11f0: 0x00c0, 0x11f1: 0x00c0, 0x11f2: 0x00c0, 0x11f3: 0x00c0, 0x11f4: 0x00c0, 0x11f5: 0x00c0, + 0x11f8: 0x00c0, 0x11f9: 0x00c0, 0x11fa: 0x00c0, 0x11fb: 0x00c0, + 0x11fc: 0x00c0, 0x11fd: 0x00c0, + // Block 0x48, offset 0x1200 + 0x1200: 0x0080, 0x1201: 0x00c0, 0x1202: 0x00c0, 0x1203: 0x00c0, 0x1204: 0x00c0, 0x1205: 0x00c0, + 0x1206: 0x00c0, 0x1207: 0x00c0, 0x1208: 0x00c0, 0x1209: 0x00c0, 0x120a: 0x00c0, 0x120b: 0x00c0, + 0x120c: 0x00c0, 0x120d: 0x00c0, 0x120e: 0x00c0, 0x120f: 0x00c0, 0x1210: 0x00c0, 0x1211: 0x00c0, + 0x1212: 0x00c0, 0x1213: 0x00c0, 0x1214: 0x00c0, 0x1215: 0x00c0, 0x1216: 0x00c0, 0x1217: 0x00c0, + 0x1218: 0x00c0, 0x1219: 0x00c0, 0x121a: 0x00c0, 0x121b: 0x00c0, 0x121c: 0x00c0, 0x121d: 0x00c0, + 0x121e: 0x00c0, 0x121f: 0x00c0, 0x1220: 0x00c0, 0x1221: 0x00c0, 0x1222: 0x00c0, 0x1223: 0x00c0, + 0x1224: 0x00c0, 0x1225: 0x00c0, 0x1226: 0x00c0, 0x1227: 0x00c0, 0x1228: 0x00c0, 0x1229: 0x00c0, + 0x122a: 0x00c0, 0x122b: 0x00c0, 0x122c: 0x00c0, 0x122d: 0x00c0, 0x122e: 0x00c0, 0x122f: 0x00c0, + 0x1230: 0x00c0, 0x1231: 0x00c0, 0x1232: 0x00c0, 0x1233: 0x00c0, 0x1234: 0x00c0, 0x1235: 0x00c0, + 0x1236: 0x00c0, 0x1237: 0x00c0, 0x1238: 0x00c0, 0x1239: 0x00c0, 0x123a: 0x00c0, 0x123b: 0x00c0, + 0x123c: 0x00c0, 0x123d: 0x00c0, 0x123e: 0x00c0, 0x123f: 0x00c0, + // Block 0x49, offset 0x1240 + 0x1240: 0x00c0, 0x1241: 0x00c0, 0x1242: 0x00c0, 0x1243: 0x00c0, 0x1244: 0x00c0, 0x1245: 0x00c0, + 0x1246: 0x00c0, 0x1247: 0x00c0, 0x1248: 0x00c0, 0x1249: 0x00c0, 0x124a: 0x00c0, 0x124b: 0x00c0, + 0x124c: 0x00c0, 0x124d: 0x00c0, 0x124e: 0x00c0, 0x124f: 0x00c0, 0x1250: 0x00c0, 0x1251: 0x00c0, + 0x1252: 0x00c0, 0x1253: 0x00c0, 0x1254: 0x00c0, 0x1255: 0x00c0, 0x1256: 0x00c0, 0x1257: 0x00c0, + 0x1258: 0x00c0, 0x1259: 0x00c0, 0x125a: 0x00c0, 0x125b: 0x00c0, 0x125c: 0x00c0, 0x125d: 0x00c0, + 0x125e: 0x00c0, 0x125f: 0x00c0, 0x1260: 0x00c0, 0x1261: 0x00c0, 0x1262: 0x00c0, 0x1263: 0x00c0, + 0x1264: 0x00c0, 0x1265: 0x00c0, 0x1266: 0x00c0, 0x1267: 0x00c0, 0x1268: 0x00c0, 0x1269: 0x00c0, + 0x126a: 0x00c0, 0x126b: 0x00c0, 0x126c: 0x00c0, 0x126d: 0x0080, 0x126e: 0x0080, 0x126f: 0x00c0, + 0x1270: 0x00c0, 0x1271: 0x00c0, 0x1272: 0x00c0, 0x1273: 0x00c0, 0x1274: 0x00c0, 0x1275: 0x00c0, + 0x1276: 0x00c0, 0x1277: 0x00c0, 0x1278: 0x00c0, 0x1279: 0x00c0, 0x127a: 0x00c0, 0x127b: 0x00c0, + 0x127c: 0x00c0, 0x127d: 0x00c0, 0x127e: 0x00c0, 0x127f: 0x00c0, + // Block 0x4a, offset 0x1280 + 0x1280: 0x0080, 0x1281: 0x00c0, 0x1282: 0x00c0, 0x1283: 0x00c0, 0x1284: 0x00c0, 0x1285: 0x00c0, + 0x1286: 0x00c0, 0x1287: 0x00c0, 0x1288: 0x00c0, 0x1289: 0x00c0, 0x128a: 0x00c0, 0x128b: 0x00c0, + 0x128c: 0x00c0, 0x128d: 0x00c0, 0x128e: 0x00c0, 0x128f: 0x00c0, 0x1290: 0x00c0, 0x1291: 0x00c0, + 0x1292: 0x00c0, 0x1293: 0x00c0, 0x1294: 0x00c0, 0x1295: 0x00c0, 0x1296: 0x00c0, 0x1297: 0x00c0, + 0x1298: 0x00c0, 0x1299: 0x00c0, 0x129a: 0x00c0, 0x129b: 0x0080, 0x129c: 0x0080, + 0x12a0: 0x00c0, 0x12a1: 0x00c0, 0x12a2: 0x00c0, 0x12a3: 0x00c0, + 0x12a4: 0x00c0, 0x12a5: 0x00c0, 0x12a6: 0x00c0, 0x12a7: 0x00c0, 0x12a8: 0x00c0, 0x12a9: 0x00c0, + 0x12aa: 0x00c0, 0x12ab: 0x00c0, 0x12ac: 0x00c0, 0x12ad: 0x00c0, 0x12ae: 0x00c0, 0x12af: 0x00c0, + 0x12b0: 0x00c0, 0x12b1: 0x00c0, 0x12b2: 0x00c0, 0x12b3: 0x00c0, 0x12b4: 0x00c0, 0x12b5: 0x00c0, + 0x12b6: 0x00c0, 0x12b7: 0x00c0, 0x12b8: 0x00c0, 0x12b9: 0x00c0, 0x12ba: 0x00c0, 0x12bb: 0x00c0, + 0x12bc: 0x00c0, 0x12bd: 0x00c0, 0x12be: 0x00c0, 0x12bf: 0x00c0, + // Block 0x4b, offset 0x12c0 + 0x12c0: 0x00c0, 0x12c1: 0x00c0, 0x12c2: 0x00c0, 0x12c3: 0x00c0, 0x12c4: 0x00c0, 0x12c5: 0x00c0, + 0x12c6: 0x00c0, 0x12c7: 0x00c0, 0x12c8: 0x00c0, 0x12c9: 0x00c0, 0x12ca: 0x00c0, 0x12cb: 0x00c0, + 0x12cc: 0x00c0, 0x12cd: 0x00c0, 0x12ce: 0x00c0, 0x12cf: 0x00c0, 0x12d0: 0x00c0, 0x12d1: 0x00c0, + 0x12d2: 0x00c0, 0x12d3: 0x00c0, 0x12d4: 0x00c0, 0x12d5: 0x00c0, 0x12d6: 0x00c0, 0x12d7: 0x00c0, + 0x12d8: 0x00c0, 0x12d9: 0x00c0, 0x12da: 0x00c0, 0x12db: 0x00c0, 0x12dc: 0x00c0, 0x12dd: 0x00c0, + 0x12de: 0x00c0, 0x12df: 0x00c0, 0x12e0: 0x00c0, 0x12e1: 0x00c0, 0x12e2: 0x00c0, 0x12e3: 0x00c0, + 0x12e4: 0x00c0, 0x12e5: 0x00c0, 0x12e6: 0x00c0, 0x12e7: 0x00c0, 0x12e8: 0x00c0, 0x12e9: 0x00c0, + 0x12ea: 0x00c0, 0x12eb: 0x0080, 0x12ec: 0x0080, 0x12ed: 0x0080, 0x12ee: 0x0080, 0x12ef: 0x0080, + 0x12f0: 0x0080, 0x12f1: 0x00c0, 0x12f2: 0x00c0, 0x12f3: 0x00c0, 0x12f4: 0x00c0, 0x12f5: 0x00c0, + 0x12f6: 0x00c0, 0x12f7: 0x00c0, 0x12f8: 0x00c0, + // Block 0x4c, offset 0x1300 + 0x1300: 0x00c0, 0x1301: 0x00c0, 0x1302: 0x00c0, 0x1303: 0x00c0, 0x1304: 0x00c0, 0x1305: 0x00c0, + 0x1306: 0x00c0, 0x1307: 0x00c0, 0x1308: 0x00c0, 0x1309: 0x00c0, 0x130a: 0x00c0, 0x130b: 0x00c0, + 0x130c: 0x00c0, 0x130e: 0x00c0, 0x130f: 0x00c0, 0x1310: 0x00c0, 0x1311: 0x00c0, + 0x1312: 0x00c3, 0x1313: 0x00c3, 0x1314: 0x00c6, + 0x1320: 0x00c0, 0x1321: 0x00c0, 0x1322: 0x00c0, 0x1323: 0x00c0, + 0x1324: 0x00c0, 0x1325: 0x00c0, 0x1326: 0x00c0, 0x1327: 0x00c0, 0x1328: 0x00c0, 0x1329: 0x00c0, + 0x132a: 0x00c0, 0x132b: 0x00c0, 0x132c: 0x00c0, 0x132d: 0x00c0, 0x132e: 0x00c0, 0x132f: 0x00c0, + 0x1330: 0x00c0, 0x1331: 0x00c0, 0x1332: 0x00c3, 0x1333: 0x00c3, 0x1334: 0x00c6, 0x1335: 0x0080, + 0x1336: 0x0080, + // Block 0x4d, offset 0x1340 + 0x1340: 0x00c0, 0x1341: 0x00c0, 0x1342: 0x00c0, 0x1343: 0x00c0, 0x1344: 0x00c0, 0x1345: 0x00c0, + 0x1346: 0x00c0, 0x1347: 0x00c0, 0x1348: 0x00c0, 0x1349: 0x00c0, 0x134a: 0x00c0, 0x134b: 0x00c0, + 0x134c: 0x00c0, 0x134d: 0x00c0, 0x134e: 0x00c0, 0x134f: 0x00c0, 0x1350: 0x00c0, 0x1351: 0x00c0, + 0x1352: 0x00c3, 0x1353: 0x00c3, + 0x1360: 0x00c0, 0x1361: 0x00c0, 0x1362: 0x00c0, 0x1363: 0x00c0, + 0x1364: 0x00c0, 0x1365: 0x00c0, 0x1366: 0x00c0, 0x1367: 0x00c0, 0x1368: 0x00c0, 0x1369: 0x00c0, + 0x136a: 0x00c0, 0x136b: 0x00c0, 0x136c: 0x00c0, 0x136e: 0x00c0, 0x136f: 0x00c0, + 0x1370: 0x00c0, 0x1372: 0x00c3, 0x1373: 0x00c3, + // Block 0x4e, offset 0x1380 + 0x1380: 0x00c0, 0x1381: 0x00c0, 0x1382: 0x00c0, 0x1383: 0x00c0, 0x1384: 0x00c0, 0x1385: 0x00c0, + 0x1386: 0x00c0, 0x1387: 0x00c0, 0x1388: 0x00c0, 0x1389: 0x00c0, 0x138a: 0x00c0, 0x138b: 0x00c0, + 0x138c: 0x00c0, 0x138d: 0x00c0, 0x138e: 0x00c0, 0x138f: 0x00c0, 0x1390: 0x00c0, 0x1391: 0x00c0, + 0x1392: 0x00c0, 0x1393: 0x00c0, 0x1394: 0x00c0, 0x1395: 0x00c0, 0x1396: 0x00c0, 0x1397: 0x00c0, + 0x1398: 0x00c0, 0x1399: 0x00c0, 0x139a: 0x00c0, 0x139b: 0x00c0, 0x139c: 0x00c0, 0x139d: 0x00c0, + 0x139e: 0x00c0, 0x139f: 0x00c0, 0x13a0: 0x00c0, 0x13a1: 0x00c0, 0x13a2: 0x00c0, 0x13a3: 0x00c0, + 0x13a4: 0x00c0, 0x13a5: 0x00c0, 0x13a6: 0x00c0, 0x13a7: 0x00c0, 0x13a8: 0x00c0, 0x13a9: 0x00c0, + 0x13aa: 0x00c0, 0x13ab: 0x00c0, 0x13ac: 0x00c0, 0x13ad: 0x00c0, 0x13ae: 0x00c0, 0x13af: 0x00c0, + 0x13b0: 0x00c0, 0x13b1: 0x00c0, 0x13b2: 0x00c0, 0x13b3: 0x00c0, 0x13b4: 0x0040, 0x13b5: 0x0040, + 0x13b6: 0x00c0, 0x13b7: 0x00c3, 0x13b8: 0x00c3, 0x13b9: 0x00c3, 0x13ba: 0x00c3, 0x13bb: 0x00c3, + 0x13bc: 0x00c3, 0x13bd: 0x00c3, 0x13be: 0x00c0, 0x13bf: 0x00c0, + // Block 0x4f, offset 0x13c0 + 0x13c0: 0x00c0, 0x13c1: 0x00c0, 0x13c2: 0x00c0, 0x13c3: 0x00c0, 0x13c4: 0x00c0, 0x13c5: 0x00c0, + 0x13c6: 0x00c3, 0x13c7: 0x00c0, 0x13c8: 0x00c0, 0x13c9: 0x00c3, 0x13ca: 0x00c3, 0x13cb: 0x00c3, + 0x13cc: 0x00c3, 0x13cd: 0x00c3, 0x13ce: 0x00c3, 0x13cf: 0x00c3, 0x13d0: 0x00c3, 0x13d1: 0x00c3, + 0x13d2: 0x00c6, 0x13d3: 0x00c3, 0x13d4: 0x0080, 0x13d5: 0x0080, 0x13d6: 0x0080, 0x13d7: 0x00c0, + 0x13d8: 0x0080, 0x13d9: 0x0080, 0x13da: 0x0080, 0x13db: 0x0080, 0x13dc: 0x00c0, 0x13dd: 0x00c3, + 0x13e0: 0x00c0, 0x13e1: 0x00c0, 0x13e2: 0x00c0, 0x13e3: 0x00c0, + 0x13e4: 0x00c0, 0x13e5: 0x00c0, 0x13e6: 0x00c0, 0x13e7: 0x00c0, 0x13e8: 0x00c0, 0x13e9: 0x00c0, + 0x13f0: 0x0080, 0x13f1: 0x0080, 0x13f2: 0x0080, 0x13f3: 0x0080, 0x13f4: 0x0080, 0x13f5: 0x0080, + 0x13f6: 0x0080, 0x13f7: 0x0080, 0x13f8: 0x0080, 0x13f9: 0x0080, + // Block 0x50, offset 0x1400 + 0x1400: 0x0080, 0x1401: 0x0080, 0x1402: 0x0080, 0x1403: 0x0080, 0x1404: 0x0080, 0x1405: 0x0080, + 0x1406: 0x0080, 0x1407: 0x0082, 0x1408: 0x0080, 0x1409: 0x0080, 0x140a: 0x0080, 0x140b: 0x0040, + 0x140c: 0x0040, 0x140d: 0x0040, 0x140e: 0x0040, 0x1410: 0x00c0, 0x1411: 0x00c0, + 0x1412: 0x00c0, 0x1413: 0x00c0, 0x1414: 0x00c0, 0x1415: 0x00c0, 0x1416: 0x00c0, 0x1417: 0x00c0, + 0x1418: 0x00c0, 0x1419: 0x00c0, + 0x1420: 0x00c2, 0x1421: 0x00c2, 0x1422: 0x00c2, 0x1423: 0x00c2, + 0x1424: 0x00c2, 0x1425: 0x00c2, 0x1426: 0x00c2, 0x1427: 0x00c2, 0x1428: 0x00c2, 0x1429: 0x00c2, + 0x142a: 0x00c2, 0x142b: 0x00c2, 0x142c: 0x00c2, 0x142d: 0x00c2, 0x142e: 0x00c2, 0x142f: 0x00c2, + 0x1430: 0x00c2, 0x1431: 0x00c2, 0x1432: 0x00c2, 0x1433: 0x00c2, 0x1434: 0x00c2, 0x1435: 0x00c2, + 0x1436: 0x00c2, 0x1437: 0x00c2, 0x1438: 0x00c2, 0x1439: 0x00c2, 0x143a: 0x00c2, 0x143b: 0x00c2, + 0x143c: 0x00c2, 0x143d: 0x00c2, 0x143e: 0x00c2, 0x143f: 0x00c2, + // Block 0x51, offset 0x1440 + 0x1440: 0x00c2, 0x1441: 0x00c2, 0x1442: 0x00c2, 0x1443: 0x00c2, 0x1444: 0x00c2, 0x1445: 0x00c2, + 0x1446: 0x00c2, 0x1447: 0x00c2, 0x1448: 0x00c2, 0x1449: 0x00c2, 0x144a: 0x00c2, 0x144b: 0x00c2, + 0x144c: 0x00c2, 0x144d: 0x00c2, 0x144e: 0x00c2, 0x144f: 0x00c2, 0x1450: 0x00c2, 0x1451: 0x00c2, + 0x1452: 0x00c2, 0x1453: 0x00c2, 0x1454: 0x00c2, 0x1455: 0x00c2, 0x1456: 0x00c2, 0x1457: 0x00c2, + 0x1458: 0x00c2, 0x1459: 0x00c2, 0x145a: 0x00c2, 0x145b: 0x00c2, 0x145c: 0x00c2, 0x145d: 0x00c2, + 0x145e: 0x00c2, 0x145f: 0x00c2, 0x1460: 0x00c2, 0x1461: 0x00c2, 0x1462: 0x00c2, 0x1463: 0x00c2, + 0x1464: 0x00c2, 0x1465: 0x00c2, 0x1466: 0x00c2, 0x1467: 0x00c2, 0x1468: 0x00c2, 0x1469: 0x00c2, + 0x146a: 0x00c2, 0x146b: 0x00c2, 0x146c: 0x00c2, 0x146d: 0x00c2, 0x146e: 0x00c2, 0x146f: 0x00c2, + 0x1470: 0x00c2, 0x1471: 0x00c2, 0x1472: 0x00c2, 0x1473: 0x00c2, 0x1474: 0x00c2, 0x1475: 0x00c2, + 0x1476: 0x00c2, 0x1477: 0x00c2, + // Block 0x52, offset 0x1480 + 0x1480: 0x00c0, 0x1481: 0x00c0, 0x1482: 0x00c0, 0x1483: 0x00c0, 0x1484: 0x00c0, 0x1485: 0x00c3, + 0x1486: 0x00c3, 0x1487: 0x00c2, 0x1488: 0x00c2, 0x1489: 0x00c2, 0x148a: 0x00c2, 0x148b: 0x00c2, + 0x148c: 0x00c2, 0x148d: 0x00c2, 0x148e: 0x00c2, 0x148f: 0x00c2, 0x1490: 0x00c2, 0x1491: 0x00c2, + 0x1492: 0x00c2, 0x1493: 0x00c2, 0x1494: 0x00c2, 0x1495: 0x00c2, 0x1496: 0x00c2, 0x1497: 0x00c2, + 0x1498: 0x00c2, 0x1499: 0x00c2, 0x149a: 0x00c2, 0x149b: 0x00c2, 0x149c: 0x00c2, 0x149d: 0x00c2, + 0x149e: 0x00c2, 0x149f: 0x00c2, 0x14a0: 0x00c2, 0x14a1: 0x00c2, 0x14a2: 0x00c2, 0x14a3: 0x00c2, + 0x14a4: 0x00c2, 0x14a5: 0x00c2, 0x14a6: 0x00c2, 0x14a7: 0x00c2, 0x14a8: 0x00c2, 0x14a9: 0x00c3, + 0x14aa: 0x00c2, + 0x14b0: 0x00c0, 0x14b1: 0x00c0, 0x14b2: 0x00c0, 0x14b3: 0x00c0, 0x14b4: 0x00c0, 0x14b5: 0x00c0, + 0x14b6: 0x00c0, 0x14b7: 0x00c0, 0x14b8: 0x00c0, 0x14b9: 0x00c0, 0x14ba: 0x00c0, 0x14bb: 0x00c0, + 0x14bc: 0x00c0, 0x14bd: 0x00c0, 0x14be: 0x00c0, 0x14bf: 0x00c0, + // Block 0x53, offset 0x14c0 + 0x14c0: 0x00c0, 0x14c1: 0x00c0, 0x14c2: 0x00c0, 0x14c3: 0x00c0, 0x14c4: 0x00c0, 0x14c5: 0x00c0, + 0x14c6: 0x00c0, 0x14c7: 0x00c0, 0x14c8: 0x00c0, 0x14c9: 0x00c0, 0x14ca: 0x00c0, 0x14cb: 0x00c0, + 0x14cc: 0x00c0, 0x14cd: 0x00c0, 0x14ce: 0x00c0, 0x14cf: 0x00c0, 0x14d0: 0x00c0, 0x14d1: 0x00c0, + 0x14d2: 0x00c0, 0x14d3: 0x00c0, 0x14d4: 0x00c0, 0x14d5: 0x00c0, 0x14d6: 0x00c0, 0x14d7: 0x00c0, + 0x14d8: 0x00c0, 0x14d9: 0x00c0, 0x14da: 0x00c0, 0x14db: 0x00c0, 0x14dc: 0x00c0, 0x14dd: 0x00c0, + 0x14de: 0x00c0, 0x14df: 0x00c0, 0x14e0: 0x00c0, 0x14e1: 0x00c0, 0x14e2: 0x00c0, 0x14e3: 0x00c0, + 0x14e4: 0x00c0, 0x14e5: 0x00c0, 0x14e6: 0x00c0, 0x14e7: 0x00c0, 0x14e8: 0x00c0, 0x14e9: 0x00c0, + 0x14ea: 0x00c0, 0x14eb: 0x00c0, 0x14ec: 0x00c0, 0x14ed: 0x00c0, 0x14ee: 0x00c0, 0x14ef: 0x00c0, + 0x14f0: 0x00c0, 0x14f1: 0x00c0, 0x14f2: 0x00c0, 0x14f3: 0x00c0, 0x14f4: 0x00c0, 0x14f5: 0x00c0, + // Block 0x54, offset 0x1500 + 0x1500: 0x00c0, 0x1501: 0x00c0, 0x1502: 0x00c0, 0x1503: 0x00c0, 0x1504: 0x00c0, 0x1505: 0x00c0, + 0x1506: 0x00c0, 0x1507: 0x00c0, 0x1508: 0x00c0, 0x1509: 0x00c0, 0x150a: 0x00c0, 0x150b: 0x00c0, + 0x150c: 0x00c0, 0x150d: 0x00c0, 0x150e: 0x00c0, 0x150f: 0x00c0, 0x1510: 0x00c0, 0x1511: 0x00c0, + 0x1512: 0x00c0, 0x1513: 0x00c0, 0x1514: 0x00c0, 0x1515: 0x00c0, 0x1516: 0x00c0, 0x1517: 0x00c0, + 0x1518: 0x00c0, 0x1519: 0x00c0, 0x151a: 0x00c0, 0x151b: 0x00c0, 0x151c: 0x00c0, 0x151d: 0x00c0, + 0x151e: 0x00c0, 0x1520: 0x00c3, 0x1521: 0x00c3, 0x1522: 0x00c3, 0x1523: 0x00c0, + 0x1524: 0x00c0, 0x1525: 0x00c0, 0x1526: 0x00c0, 0x1527: 0x00c3, 0x1528: 0x00c3, 0x1529: 0x00c0, + 0x152a: 0x00c0, 0x152b: 0x00c0, + 0x1530: 0x00c0, 0x1531: 0x00c0, 0x1532: 0x00c3, 0x1533: 0x00c0, 0x1534: 0x00c0, 0x1535: 0x00c0, + 0x1536: 0x00c0, 0x1537: 0x00c0, 0x1538: 0x00c0, 0x1539: 0x00c3, 0x153a: 0x00c3, 0x153b: 0x00c3, + // Block 0x55, offset 0x1540 + 0x1540: 0x0080, 0x1544: 0x0080, 0x1545: 0x0080, + 0x1546: 0x00c0, 0x1547: 0x00c0, 0x1548: 0x00c0, 0x1549: 0x00c0, 0x154a: 0x00c0, 0x154b: 0x00c0, + 0x154c: 0x00c0, 0x154d: 0x00c0, 0x154e: 0x00c0, 0x154f: 0x00c0, 0x1550: 0x00c0, 0x1551: 0x00c0, + 0x1552: 0x00c0, 0x1553: 0x00c0, 0x1554: 0x00c0, 0x1555: 0x00c0, 0x1556: 0x00c0, 0x1557: 0x00c0, + 0x1558: 0x00c0, 0x1559: 0x00c0, 0x155a: 0x00c0, 0x155b: 0x00c0, 0x155c: 0x00c0, 0x155d: 0x00c0, + 0x155e: 0x00c0, 0x155f: 0x00c0, 0x1560: 0x00c0, 0x1561: 0x00c0, 0x1562: 0x00c0, 0x1563: 0x00c0, + 0x1564: 0x00c0, 0x1565: 0x00c0, 0x1566: 0x00c0, 0x1567: 0x00c0, 0x1568: 0x00c0, 0x1569: 0x00c0, + 0x156a: 0x00c0, 0x156b: 0x00c0, 0x156c: 0x00c0, 0x156d: 0x00c0, + 0x1570: 0x00c0, 0x1571: 0x00c0, 0x1572: 0x00c0, 0x1573: 0x00c0, 0x1574: 0x00c0, + // Block 0x56, offset 0x1580 + 0x1580: 0x00c0, 0x1581: 0x00c0, 0x1582: 0x00c0, 0x1583: 0x00c0, 0x1584: 0x00c0, 0x1585: 0x00c0, + 0x1586: 0x00c0, 0x1587: 0x00c0, 0x1588: 0x00c0, 0x1589: 0x00c0, 0x158a: 0x00c0, 0x158b: 0x00c0, + 0x158c: 0x00c0, 0x158d: 0x00c0, 0x158e: 0x00c0, 0x158f: 0x00c0, 0x1590: 0x00c0, 0x1591: 0x00c0, + 0x1592: 0x00c0, 0x1593: 0x00c0, 0x1594: 0x00c0, 0x1595: 0x00c0, 0x1596: 0x00c0, 0x1597: 0x00c0, + 0x1598: 0x00c0, 0x1599: 0x00c0, 0x159a: 0x00c0, 0x159b: 0x00c0, 0x159c: 0x00c0, 0x159d: 0x00c0, + 0x159e: 0x00c0, 0x159f: 0x00c0, 0x15a0: 0x00c0, 0x15a1: 0x00c0, 0x15a2: 0x00c0, 0x15a3: 0x00c0, + 0x15a4: 0x00c0, 0x15a5: 0x00c0, 0x15a6: 0x00c0, 0x15a7: 0x00c0, 0x15a8: 0x00c0, 0x15a9: 0x00c0, + 0x15aa: 0x00c0, 0x15ab: 0x00c0, + 0x15b0: 0x00c0, 0x15b1: 0x00c0, 0x15b2: 0x00c0, 0x15b3: 0x00c0, 0x15b4: 0x00c0, 0x15b5: 0x00c0, + 0x15b6: 0x00c0, 0x15b7: 0x00c0, 0x15b8: 0x00c0, 0x15b9: 0x00c0, 0x15ba: 0x00c0, 0x15bb: 0x00c0, + 0x15bc: 0x00c0, 0x15bd: 0x00c0, 0x15be: 0x00c0, 0x15bf: 0x00c0, + // Block 0x57, offset 0x15c0 + 0x15c0: 0x00c0, 0x15c1: 0x00c0, 0x15c2: 0x00c0, 0x15c3: 0x00c0, 0x15c4: 0x00c0, 0x15c5: 0x00c0, + 0x15c6: 0x00c0, 0x15c7: 0x00c0, 0x15c8: 0x00c0, 0x15c9: 0x00c0, + 0x15d0: 0x00c0, 0x15d1: 0x00c0, + 0x15d2: 0x00c0, 0x15d3: 0x00c0, 0x15d4: 0x00c0, 0x15d5: 0x00c0, 0x15d6: 0x00c0, 0x15d7: 0x00c0, + 0x15d8: 0x00c0, 0x15d9: 0x00c0, 0x15da: 0x0080, + 0x15de: 0x0080, 0x15df: 0x0080, 0x15e0: 0x0080, 0x15e1: 0x0080, 0x15e2: 0x0080, 0x15e3: 0x0080, + 0x15e4: 0x0080, 0x15e5: 0x0080, 0x15e6: 0x0080, 0x15e7: 0x0080, 0x15e8: 0x0080, 0x15e9: 0x0080, + 0x15ea: 0x0080, 0x15eb: 0x0080, 0x15ec: 0x0080, 0x15ed: 0x0080, 0x15ee: 0x0080, 0x15ef: 0x0080, + 0x15f0: 0x0080, 0x15f1: 0x0080, 0x15f2: 0x0080, 0x15f3: 0x0080, 0x15f4: 0x0080, 0x15f5: 0x0080, + 0x15f6: 0x0080, 0x15f7: 0x0080, 0x15f8: 0x0080, 0x15f9: 0x0080, 0x15fa: 0x0080, 0x15fb: 0x0080, + 0x15fc: 0x0080, 0x15fd: 0x0080, 0x15fe: 0x0080, 0x15ff: 0x0080, + // Block 0x58, offset 0x1600 + 0x1600: 0x00c0, 0x1601: 0x00c0, 0x1602: 0x00c0, 0x1603: 0x00c0, 0x1604: 0x00c0, 0x1605: 0x00c0, + 0x1606: 0x00c0, 0x1607: 0x00c0, 0x1608: 0x00c0, 0x1609: 0x00c0, 0x160a: 0x00c0, 0x160b: 0x00c0, + 0x160c: 0x00c0, 0x160d: 0x00c0, 0x160e: 0x00c0, 0x160f: 0x00c0, 0x1610: 0x00c0, 0x1611: 0x00c0, + 0x1612: 0x00c0, 0x1613: 0x00c0, 0x1614: 0x00c0, 0x1615: 0x00c0, 0x1616: 0x00c0, 0x1617: 0x00c3, + 0x1618: 0x00c3, 0x1619: 0x00c0, 0x161a: 0x00c0, 0x161b: 0x00c3, + 0x161e: 0x0080, 0x161f: 0x0080, 0x1620: 0x00c0, 0x1621: 0x00c0, 0x1622: 0x00c0, 0x1623: 0x00c0, + 0x1624: 0x00c0, 0x1625: 0x00c0, 0x1626: 0x00c0, 0x1627: 0x00c0, 0x1628: 0x00c0, 0x1629: 0x00c0, + 0x162a: 0x00c0, 0x162b: 0x00c0, 0x162c: 0x00c0, 0x162d: 0x00c0, 0x162e: 0x00c0, 0x162f: 0x00c0, + 0x1630: 0x00c0, 0x1631: 0x00c0, 0x1632: 0x00c0, 0x1633: 0x00c0, 0x1634: 0x00c0, 0x1635: 0x00c0, + 0x1636: 0x00c0, 0x1637: 0x00c0, 0x1638: 0x00c0, 0x1639: 0x00c0, 0x163a: 0x00c0, 0x163b: 0x00c0, + 0x163c: 0x00c0, 0x163d: 0x00c0, 0x163e: 0x00c0, 0x163f: 0x00c0, + // Block 0x59, offset 0x1640 + 0x1640: 0x00c0, 0x1641: 0x00c0, 0x1642: 0x00c0, 0x1643: 0x00c0, 0x1644: 0x00c0, 0x1645: 0x00c0, + 0x1646: 0x00c0, 0x1647: 0x00c0, 0x1648: 0x00c0, 0x1649: 0x00c0, 0x164a: 0x00c0, 0x164b: 0x00c0, + 0x164c: 0x00c0, 0x164d: 0x00c0, 0x164e: 0x00c0, 0x164f: 0x00c0, 0x1650: 0x00c0, 0x1651: 0x00c0, + 0x1652: 0x00c0, 0x1653: 0x00c0, 0x1654: 0x00c0, 0x1655: 0x00c0, 0x1656: 0x00c3, 0x1657: 0x00c0, + 0x1658: 0x00c3, 0x1659: 0x00c3, 0x165a: 0x00c3, 0x165b: 0x00c3, 0x165c: 0x00c3, 0x165d: 0x00c3, + 0x165e: 0x00c3, 0x1660: 0x00c6, 0x1661: 0x00c0, 0x1662: 0x00c3, 0x1663: 0x00c0, + 0x1664: 0x00c0, 0x1665: 0x00c3, 0x1666: 0x00c3, 0x1667: 0x00c3, 0x1668: 0x00c3, 0x1669: 0x00c3, + 0x166a: 0x00c3, 0x166b: 0x00c3, 0x166c: 0x00c3, 0x166d: 0x00c0, 0x166e: 0x00c0, 0x166f: 0x00c0, + 0x1670: 0x00c0, 0x1671: 0x00c0, 0x1672: 0x00c0, 0x1673: 0x00c3, 0x1674: 0x00c3, 0x1675: 0x00c3, + 0x1676: 0x00c3, 0x1677: 0x00c3, 0x1678: 0x00c3, 0x1679: 0x00c3, 0x167a: 0x00c3, 0x167b: 0x00c3, + 0x167c: 0x00c3, 0x167f: 0x00c3, + // Block 0x5a, offset 0x1680 + 0x1680: 0x00c0, 0x1681: 0x00c0, 0x1682: 0x00c0, 0x1683: 0x00c0, 0x1684: 0x00c0, 0x1685: 0x00c0, + 0x1686: 0x00c0, 0x1687: 0x00c0, 0x1688: 0x00c0, 0x1689: 0x00c0, + 0x1690: 0x00c0, 0x1691: 0x00c0, + 0x1692: 0x00c0, 0x1693: 0x00c0, 0x1694: 0x00c0, 0x1695: 0x00c0, 0x1696: 0x00c0, 0x1697: 0x00c0, + 0x1698: 0x00c0, 0x1699: 0x00c0, + 0x16a0: 0x0080, 0x16a1: 0x0080, 0x16a2: 0x0080, 0x16a3: 0x0080, + 0x16a4: 0x0080, 0x16a5: 0x0080, 0x16a6: 0x0080, 0x16a7: 0x00c0, 0x16a8: 0x0080, 0x16a9: 0x0080, + 0x16aa: 0x0080, 0x16ab: 0x0080, 0x16ac: 0x0080, 0x16ad: 0x0080, + 0x16b0: 0x00c3, 0x16b1: 0x00c3, 0x16b2: 0x00c3, 0x16b3: 0x00c3, 0x16b4: 0x00c3, 0x16b5: 0x00c3, + 0x16b6: 0x00c3, 0x16b7: 0x00c3, 0x16b8: 0x00c3, 0x16b9: 0x00c3, 0x16ba: 0x00c3, 0x16bb: 0x00c3, + 0x16bc: 0x00c3, 0x16bd: 0x00c3, 0x16be: 0x0083, + // Block 0x5b, offset 0x16c0 + 0x16c0: 0x00c3, 0x16c1: 0x00c3, 0x16c2: 0x00c3, 0x16c3: 0x00c3, 0x16c4: 0x00c0, 0x16c5: 0x00c0, + 0x16c6: 0x00c0, 0x16c7: 0x00c0, 0x16c8: 0x00c0, 0x16c9: 0x00c0, 0x16ca: 0x00c0, 0x16cb: 0x00c0, + 0x16cc: 0x00c0, 0x16cd: 0x00c0, 0x16ce: 0x00c0, 0x16cf: 0x00c0, 0x16d0: 0x00c0, 0x16d1: 0x00c0, + 0x16d2: 0x00c0, 0x16d3: 0x00c0, 0x16d4: 0x00c0, 0x16d5: 0x00c0, 0x16d6: 0x00c0, 0x16d7: 0x00c0, + 0x16d8: 0x00c0, 0x16d9: 0x00c0, 0x16da: 0x00c0, 0x16db: 0x00c0, 0x16dc: 0x00c0, 0x16dd: 0x00c0, + 0x16de: 0x00c0, 0x16df: 0x00c0, 0x16e0: 0x00c0, 0x16e1: 0x00c0, 0x16e2: 0x00c0, 0x16e3: 0x00c0, + 0x16e4: 0x00c0, 0x16e5: 0x00c0, 0x16e6: 0x00c0, 0x16e7: 0x00c0, 0x16e8: 0x00c0, 0x16e9: 0x00c0, + 0x16ea: 0x00c0, 0x16eb: 0x00c0, 0x16ec: 0x00c0, 0x16ed: 0x00c0, 0x16ee: 0x00c0, 0x16ef: 0x00c0, + 0x16f0: 0x00c0, 0x16f1: 0x00c0, 0x16f2: 0x00c0, 0x16f3: 0x00c0, 0x16f4: 0x00c3, 0x16f5: 0x00c0, + 0x16f6: 0x00c3, 0x16f7: 0x00c3, 0x16f8: 0x00c3, 0x16f9: 0x00c3, 0x16fa: 0x00c3, 0x16fb: 0x00c0, + 0x16fc: 0x00c3, 0x16fd: 0x00c0, 0x16fe: 0x00c0, 0x16ff: 0x00c0, + // Block 0x5c, offset 0x1700 + 0x1700: 0x00c0, 0x1701: 0x00c0, 0x1702: 0x00c3, 0x1703: 0x00c0, 0x1704: 0x00c5, 0x1705: 0x00c0, + 0x1706: 0x00c0, 0x1707: 0x00c0, 0x1708: 0x00c0, 0x1709: 0x00c0, 0x170a: 0x00c0, 0x170b: 0x00c0, + 0x1710: 0x00c0, 0x1711: 0x00c0, + 0x1712: 0x00c0, 0x1713: 0x00c0, 0x1714: 0x00c0, 0x1715: 0x00c0, 0x1716: 0x00c0, 0x1717: 0x00c0, + 0x1718: 0x00c0, 0x1719: 0x00c0, 0x171a: 0x0080, 0x171b: 0x0080, 0x171c: 0x0080, 0x171d: 0x0080, + 0x171e: 0x0080, 0x171f: 0x0080, 0x1720: 0x0080, 0x1721: 0x0080, 0x1722: 0x0080, 0x1723: 0x0080, + 0x1724: 0x0080, 0x1725: 0x0080, 0x1726: 0x0080, 0x1727: 0x0080, 0x1728: 0x0080, 0x1729: 0x0080, + 0x172a: 0x0080, 0x172b: 0x00c3, 0x172c: 0x00c3, 0x172d: 0x00c3, 0x172e: 0x00c3, 0x172f: 0x00c3, + 0x1730: 0x00c3, 0x1731: 0x00c3, 0x1732: 0x00c3, 0x1733: 0x00c3, 0x1734: 0x0080, 0x1735: 0x0080, + 0x1736: 0x0080, 0x1737: 0x0080, 0x1738: 0x0080, 0x1739: 0x0080, 0x173a: 0x0080, 0x173b: 0x0080, + 0x173c: 0x0080, + // Block 0x5d, offset 0x1740 + 0x1740: 0x00c3, 0x1741: 0x00c3, 0x1742: 0x00c0, 0x1743: 0x00c0, 0x1744: 0x00c0, 0x1745: 0x00c0, + 0x1746: 0x00c0, 0x1747: 0x00c0, 0x1748: 0x00c0, 0x1749: 0x00c0, 0x174a: 0x00c0, 0x174b: 0x00c0, + 0x174c: 0x00c0, 0x174d: 0x00c0, 0x174e: 0x00c0, 0x174f: 0x00c0, 0x1750: 0x00c0, 0x1751: 0x00c0, + 0x1752: 0x00c0, 0x1753: 0x00c0, 0x1754: 0x00c0, 0x1755: 0x00c0, 0x1756: 0x00c0, 0x1757: 0x00c0, + 0x1758: 0x00c0, 0x1759: 0x00c0, 0x175a: 0x00c0, 0x175b: 0x00c0, 0x175c: 0x00c0, 0x175d: 0x00c0, + 0x175e: 0x00c0, 0x175f: 0x00c0, 0x1760: 0x00c0, 0x1761: 0x00c0, 0x1762: 0x00c3, 0x1763: 0x00c3, + 0x1764: 0x00c3, 0x1765: 0x00c3, 0x1766: 0x00c0, 0x1767: 0x00c0, 0x1768: 0x00c3, 0x1769: 0x00c3, + 0x176a: 0x00c5, 0x176b: 0x00c6, 0x176c: 0x00c3, 0x176d: 0x00c3, 0x176e: 0x00c0, 0x176f: 0x00c0, + 0x1770: 0x00c0, 0x1771: 0x00c0, 0x1772: 0x00c0, 0x1773: 0x00c0, 0x1774: 0x00c0, 0x1775: 0x00c0, + 0x1776: 0x00c0, 0x1777: 0x00c0, 0x1778: 0x00c0, 0x1779: 0x00c0, 0x177a: 0x00c0, 0x177b: 0x00c0, + 0x177c: 0x00c0, 0x177d: 0x00c0, 0x177e: 0x00c0, 0x177f: 0x00c0, + // Block 0x5e, offset 0x1780 + 0x1780: 0x00c0, 0x1781: 0x00c0, 0x1782: 0x00c0, 0x1783: 0x00c0, 0x1784: 0x00c0, 0x1785: 0x00c0, + 0x1786: 0x00c0, 0x1787: 0x00c0, 0x1788: 0x00c0, 0x1789: 0x00c0, 0x178a: 0x00c0, 0x178b: 0x00c0, + 0x178c: 0x00c0, 0x178d: 0x00c0, 0x178e: 0x00c0, 0x178f: 0x00c0, 0x1790: 0x00c0, 0x1791: 0x00c0, + 0x1792: 0x00c0, 0x1793: 0x00c0, 0x1794: 0x00c0, 0x1795: 0x00c0, 0x1796: 0x00c0, 0x1797: 0x00c0, + 0x1798: 0x00c0, 0x1799: 0x00c0, 0x179a: 0x00c0, 0x179b: 0x00c0, 0x179c: 0x00c0, 0x179d: 0x00c0, + 0x179e: 0x00c0, 0x179f: 0x00c0, 0x17a0: 0x00c0, 0x17a1: 0x00c0, 0x17a2: 0x00c0, 0x17a3: 0x00c0, + 0x17a4: 0x00c0, 0x17a5: 0x00c0, 0x17a6: 0x00c3, 0x17a7: 0x00c0, 0x17a8: 0x00c3, 0x17a9: 0x00c3, + 0x17aa: 0x00c0, 0x17ab: 0x00c0, 0x17ac: 0x00c0, 0x17ad: 0x00c3, 0x17ae: 0x00c0, 0x17af: 0x00c3, + 0x17b0: 0x00c3, 0x17b1: 0x00c3, 0x17b2: 0x00c5, 0x17b3: 0x00c5, + 0x17bc: 0x0080, 0x17bd: 0x0080, 0x17be: 0x0080, 0x17bf: 0x0080, + // Block 0x5f, offset 0x17c0 + 0x17c0: 0x00c0, 0x17c1: 0x00c0, 0x17c2: 0x00c0, 0x17c3: 0x00c0, 0x17c4: 0x00c0, 0x17c5: 0x00c0, + 0x17c6: 0x00c0, 0x17c7: 0x00c0, 0x17c8: 0x00c0, 0x17c9: 0x00c0, 0x17ca: 0x00c0, 0x17cb: 0x00c0, + 0x17cc: 0x00c0, 0x17cd: 0x00c0, 0x17ce: 0x00c0, 0x17cf: 0x00c0, 0x17d0: 0x00c0, 0x17d1: 0x00c0, + 0x17d2: 0x00c0, 0x17d3: 0x00c0, 0x17d4: 0x00c0, 0x17d5: 0x00c0, 0x17d6: 0x00c0, 0x17d7: 0x00c0, + 0x17d8: 0x00c0, 0x17d9: 0x00c0, 0x17da: 0x00c0, 0x17db: 0x00c0, 0x17dc: 0x00c0, 0x17dd: 0x00c0, + 0x17de: 0x00c0, 0x17df: 0x00c0, 0x17e0: 0x00c0, 0x17e1: 0x00c0, 0x17e2: 0x00c0, 0x17e3: 0x00c0, + 0x17e4: 0x00c0, 0x17e5: 0x00c0, 0x17e6: 0x00c0, 0x17e7: 0x00c0, 0x17e8: 0x00c0, 0x17e9: 0x00c0, + 0x17ea: 0x00c0, 0x17eb: 0x00c0, 0x17ec: 0x00c3, 0x17ed: 0x00c3, 0x17ee: 0x00c3, 0x17ef: 0x00c3, + 0x17f0: 0x00c3, 0x17f1: 0x00c3, 0x17f2: 0x00c3, 0x17f3: 0x00c3, 0x17f4: 0x00c0, 0x17f5: 0x00c0, + 0x17f6: 0x00c3, 0x17f7: 0x00c3, 0x17fb: 0x0080, + 0x17fc: 0x0080, 0x17fd: 0x0080, 0x17fe: 0x0080, 0x17ff: 0x0080, + // Block 0x60, offset 0x1800 + 0x1800: 0x00c0, 0x1801: 0x00c0, 0x1802: 0x00c0, 0x1803: 0x00c0, 0x1804: 0x00c0, 0x1805: 0x00c0, + 0x1806: 0x00c0, 0x1807: 0x00c0, 0x1808: 0x00c0, 0x1809: 0x00c0, + 0x180d: 0x00c0, 0x180e: 0x00c0, 0x180f: 0x00c0, 0x1810: 0x00c0, 0x1811: 0x00c0, + 0x1812: 0x00c0, 0x1813: 0x00c0, 0x1814: 0x00c0, 0x1815: 0x00c0, 0x1816: 0x00c0, 0x1817: 0x00c0, + 0x1818: 0x00c0, 0x1819: 0x00c0, 0x181a: 0x00c0, 0x181b: 0x00c0, 0x181c: 0x00c0, 0x181d: 0x00c0, + 0x181e: 0x00c0, 0x181f: 0x00c0, 0x1820: 0x00c0, 0x1821: 0x00c0, 0x1822: 0x00c0, 0x1823: 0x00c0, + 0x1824: 0x00c0, 0x1825: 0x00c0, 0x1826: 0x00c0, 0x1827: 0x00c0, 0x1828: 0x00c0, 0x1829: 0x00c0, + 0x182a: 0x00c0, 0x182b: 0x00c0, 0x182c: 0x00c0, 0x182d: 0x00c0, 0x182e: 0x00c0, 0x182f: 0x00c0, + 0x1830: 0x00c0, 0x1831: 0x00c0, 0x1832: 0x00c0, 0x1833: 0x00c0, 0x1834: 0x00c0, 0x1835: 0x00c0, + 0x1836: 0x00c0, 0x1837: 0x00c0, 0x1838: 0x00c0, 0x1839: 0x00c0, 0x183a: 0x00c0, 0x183b: 0x00c0, + 0x183c: 0x00c0, 0x183d: 0x00c0, 0x183e: 0x0080, 0x183f: 0x0080, + // Block 0x61, offset 0x1840 + 0x1840: 0x00c0, 0x1841: 0x00c0, 0x1842: 0x00c0, 0x1843: 0x00c0, 0x1844: 0x00c0, 0x1845: 0x00c0, + 0x1846: 0x00c0, 0x1847: 0x00c0, 0x1848: 0x00c0, + // Block 0x62, offset 0x1880 + 0x1880: 0x0080, 0x1881: 0x0080, 0x1882: 0x0080, 0x1883: 0x0080, 0x1884: 0x0080, 0x1885: 0x0080, + 0x1886: 0x0080, 0x1887: 0x0080, + 0x1890: 0x00c3, 0x1891: 0x00c3, + 0x1892: 0x00c3, 0x1893: 0x0080, 0x1894: 0x00c3, 0x1895: 0x00c3, 0x1896: 0x00c3, 0x1897: 0x00c3, + 0x1898: 0x00c3, 0x1899: 0x00c3, 0x189a: 0x00c3, 0x189b: 0x00c3, 0x189c: 0x00c3, 0x189d: 0x00c3, + 0x189e: 0x00c3, 0x189f: 0x00c3, 0x18a0: 0x00c3, 0x18a1: 0x00c0, 0x18a2: 0x00c3, 0x18a3: 0x00c3, + 0x18a4: 0x00c3, 0x18a5: 0x00c3, 0x18a6: 0x00c3, 0x18a7: 0x00c3, 0x18a8: 0x00c3, 0x18a9: 0x00c0, + 0x18aa: 0x00c0, 0x18ab: 0x00c0, 0x18ac: 0x00c0, 0x18ad: 0x00c3, 0x18ae: 0x00c0, 0x18af: 0x00c0, + 0x18b0: 0x00c0, 0x18b1: 0x00c0, 0x18b2: 0x00c0, 0x18b3: 0x00c0, 0x18b4: 0x00c3, 0x18b5: 0x00c0, + 0x18b6: 0x00c0, 0x18b8: 0x00c3, 0x18b9: 0x00c3, + // Block 0x63, offset 0x18c0 + 0x18c0: 0x00c0, 0x18c1: 0x00c0, 0x18c2: 0x00c0, 0x18c3: 0x00c0, 0x18c4: 0x00c0, 0x18c5: 0x00c0, + 0x18c6: 0x00c0, 0x18c7: 0x00c0, 0x18c8: 0x00c0, 0x18c9: 0x00c0, 0x18ca: 0x00c0, 0x18cb: 0x00c0, + 0x18cc: 0x00c0, 0x18cd: 0x00c0, 0x18ce: 0x00c0, 0x18cf: 0x00c0, 0x18d0: 0x00c0, 0x18d1: 0x00c0, + 0x18d2: 0x00c0, 0x18d3: 0x00c0, 0x18d4: 0x00c0, 0x18d5: 0x00c0, 0x18d6: 0x00c0, 0x18d7: 0x00c0, + 0x18d8: 0x00c0, 0x18d9: 0x00c0, 0x18da: 0x00c0, 0x18db: 0x00c0, 0x18dc: 0x00c0, 0x18dd: 0x00c0, + 0x18de: 0x00c0, 0x18df: 0x00c0, 0x18e0: 0x00c0, 0x18e1: 0x00c0, 0x18e2: 0x00c0, 0x18e3: 0x00c0, + 0x18e4: 0x00c0, 0x18e5: 0x00c0, 0x18e6: 0x00c8, 0x18e7: 0x00c8, 0x18e8: 0x00c8, 0x18e9: 0x00c8, + 0x18ea: 0x00c8, 0x18eb: 0x00c0, 0x18ec: 0x0080, 0x18ed: 0x0080, 0x18ee: 0x0080, 0x18ef: 0x00c0, + 0x18f0: 0x0080, 0x18f1: 0x0080, 0x18f2: 0x0080, 0x18f3: 0x0080, 0x18f4: 0x0080, 0x18f5: 0x0080, + 0x18f6: 0x0080, 0x18f7: 0x0080, 0x18f8: 0x0080, 0x18f9: 0x0080, 0x18fa: 0x0080, 0x18fb: 0x00c0, + 0x18fc: 0x0080, 0x18fd: 0x0080, 0x18fe: 0x0080, 0x18ff: 0x0080, + // Block 0x64, offset 0x1900 + 0x1900: 0x0080, 0x1901: 0x0080, 0x1902: 0x0080, 0x1903: 0x0080, 0x1904: 0x0080, 0x1905: 0x0080, + 0x1906: 0x0080, 0x1907: 0x0080, 0x1908: 0x0080, 0x1909: 0x0080, 0x190a: 0x0080, 0x190b: 0x0080, + 0x190c: 0x0080, 0x190d: 0x0080, 0x190e: 0x00c0, 0x190f: 0x0080, 0x1910: 0x0080, 0x1911: 0x0080, + 0x1912: 0x0080, 0x1913: 0x0080, 0x1914: 0x0080, 0x1915: 0x0080, 0x1916: 0x0080, 0x1917: 0x0080, + 0x1918: 0x0080, 0x1919: 0x0080, 0x191a: 0x0080, 0x191b: 0x0080, 0x191c: 0x0080, 0x191d: 0x0088, + 0x191e: 0x0088, 0x191f: 0x0088, 0x1920: 0x0088, 0x1921: 0x0088, 0x1922: 0x0080, 0x1923: 0x0080, + 0x1924: 0x0080, 0x1925: 0x0080, 0x1926: 0x0088, 0x1927: 0x0088, 0x1928: 0x0088, 0x1929: 0x0088, + 0x192a: 0x0088, 0x192b: 0x00c0, 0x192c: 0x00c0, 0x192d: 0x00c0, 0x192e: 0x00c0, 0x192f: 0x00c0, + 0x1930: 0x00c0, 0x1931: 0x00c0, 0x1932: 0x00c0, 0x1933: 0x00c0, 0x1934: 0x00c0, 0x1935: 0x00c0, + 0x1936: 0x00c0, 0x1937: 0x00c0, 0x1938: 0x0080, 0x1939: 0x00c0, 0x193a: 0x00c0, 0x193b: 0x00c0, + 0x193c: 0x00c0, 0x193d: 0x00c0, 0x193e: 0x00c0, 0x193f: 0x00c0, + // Block 0x65, offset 0x1940 + 0x1940: 0x00c0, 0x1941: 0x00c0, 0x1942: 0x00c0, 0x1943: 0x00c0, 0x1944: 0x00c0, 0x1945: 0x00c0, + 0x1946: 0x00c0, 0x1947: 0x00c0, 0x1948: 0x00c0, 0x1949: 0x00c0, 0x194a: 0x00c0, 0x194b: 0x00c0, + 0x194c: 0x00c0, 0x194d: 0x00c0, 0x194e: 0x00c0, 0x194f: 0x00c0, 0x1950: 0x00c0, 0x1951: 0x00c0, + 0x1952: 0x00c0, 0x1953: 0x00c0, 0x1954: 0x00c0, 0x1955: 0x00c0, 0x1956: 0x00c0, 0x1957: 0x00c0, + 0x1958: 0x00c0, 0x1959: 0x00c0, 0x195a: 0x00c0, 0x195b: 0x0080, 0x195c: 0x0080, 0x195d: 0x0080, + 0x195e: 0x0080, 0x195f: 0x0080, 0x1960: 0x0080, 0x1961: 0x0080, 0x1962: 0x0080, 0x1963: 0x0080, + 0x1964: 0x0080, 0x1965: 0x0080, 0x1966: 0x0080, 0x1967: 0x0080, 0x1968: 0x0080, 0x1969: 0x0080, + 0x196a: 0x0080, 0x196b: 0x0080, 0x196c: 0x0080, 0x196d: 0x0080, 0x196e: 0x0080, 0x196f: 0x0080, + 0x1970: 0x0080, 0x1971: 0x0080, 0x1972: 0x0080, 0x1973: 0x0080, 0x1974: 0x0080, 0x1975: 0x0080, + 0x1976: 0x0080, 0x1977: 0x0080, 0x1978: 0x0080, 0x1979: 0x0080, 0x197a: 0x0080, 0x197b: 0x0080, + 0x197c: 0x0080, 0x197d: 0x0080, 0x197e: 0x0080, 0x197f: 0x0088, + // Block 0x66, offset 0x1980 + 0x1980: 0x00c3, 0x1981: 0x00c3, 0x1982: 0x00c3, 0x1983: 0x00c3, 0x1984: 0x00c3, 0x1985: 0x00c3, + 0x1986: 0x00c3, 0x1987: 0x00c3, 0x1988: 0x00c3, 0x1989: 0x00c3, 0x198a: 0x00c3, 0x198b: 0x00c3, + 0x198c: 0x00c3, 0x198d: 0x00c3, 0x198e: 0x00c3, 0x198f: 0x00c3, 0x1990: 0x00c3, 0x1991: 0x00c3, + 0x1992: 0x00c3, 0x1993: 0x00c3, 0x1994: 0x00c3, 0x1995: 0x00c3, 0x1996: 0x00c3, 0x1997: 0x00c3, + 0x1998: 0x00c3, 0x1999: 0x00c3, 0x199a: 0x00c3, 0x199b: 0x00c3, 0x199c: 0x00c3, 0x199d: 0x00c3, + 0x199e: 0x00c3, 0x199f: 0x00c3, 0x19a0: 0x00c3, 0x19a1: 0x00c3, 0x19a2: 0x00c3, 0x19a3: 0x00c3, + 0x19a4: 0x00c3, 0x19a5: 0x00c3, 0x19a6: 0x00c3, 0x19a7: 0x00c3, 0x19a8: 0x00c3, 0x19a9: 0x00c3, + 0x19aa: 0x00c3, 0x19ab: 0x00c3, 0x19ac: 0x00c3, 0x19ad: 0x00c3, 0x19ae: 0x00c3, 0x19af: 0x00c3, + 0x19b0: 0x00c3, 0x19b1: 0x00c3, 0x19b2: 0x00c3, 0x19b3: 0x00c3, 0x19b4: 0x00c3, 0x19b5: 0x00c3, + 0x19bb: 0x00c3, + 0x19bc: 0x00c3, 0x19bd: 0x00c3, 0x19be: 0x00c3, 0x19bf: 0x00c3, + // Block 0x67, offset 0x19c0 + 0x19c0: 0x00c0, 0x19c1: 0x00c0, 0x19c2: 0x00c0, 0x19c3: 0x00c0, 0x19c4: 0x00c0, 0x19c5: 0x00c0, + 0x19c6: 0x00c0, 0x19c7: 0x00c0, 0x19c8: 0x00c0, 0x19c9: 0x00c0, 0x19ca: 0x00c0, 0x19cb: 0x00c0, + 0x19cc: 0x00c0, 0x19cd: 0x00c0, 0x19ce: 0x00c0, 0x19cf: 0x00c0, 0x19d0: 0x00c0, 0x19d1: 0x00c0, + 0x19d2: 0x00c0, 0x19d3: 0x00c0, 0x19d4: 0x00c0, 0x19d5: 0x00c0, 0x19d6: 0x00c0, 0x19d7: 0x00c0, + 0x19d8: 0x00c0, 0x19d9: 0x00c0, 0x19da: 0x0080, 0x19db: 0x0080, 0x19dc: 0x00c0, 0x19dd: 0x00c0, + 0x19de: 0x00c0, 0x19df: 0x00c0, 0x19e0: 0x00c0, 0x19e1: 0x00c0, 0x19e2: 0x00c0, 0x19e3: 0x00c0, + 0x19e4: 0x00c0, 0x19e5: 0x00c0, 0x19e6: 0x00c0, 0x19e7: 0x00c0, 0x19e8: 0x00c0, 0x19e9: 0x00c0, + 0x19ea: 0x00c0, 0x19eb: 0x00c0, 0x19ec: 0x00c0, 0x19ed: 0x00c0, 0x19ee: 0x00c0, 0x19ef: 0x00c0, + 0x19f0: 0x00c0, 0x19f1: 0x00c0, 0x19f2: 0x00c0, 0x19f3: 0x00c0, 0x19f4: 0x00c0, 0x19f5: 0x00c0, + 0x19f6: 0x00c0, 0x19f7: 0x00c0, 0x19f8: 0x00c0, 0x19f9: 0x00c0, 0x19fa: 0x00c0, 0x19fb: 0x00c0, + 0x19fc: 0x00c0, 0x19fd: 0x00c0, 0x19fe: 0x00c0, 0x19ff: 0x00c0, + // Block 0x68, offset 0x1a00 + 0x1a00: 0x00c8, 0x1a01: 0x00c8, 0x1a02: 0x00c8, 0x1a03: 0x00c8, 0x1a04: 0x00c8, 0x1a05: 0x00c8, + 0x1a06: 0x00c8, 0x1a07: 0x00c8, 0x1a08: 0x00c8, 0x1a09: 0x00c8, 0x1a0a: 0x00c8, 0x1a0b: 0x00c8, + 0x1a0c: 0x00c8, 0x1a0d: 0x00c8, 0x1a0e: 0x00c8, 0x1a0f: 0x00c8, 0x1a10: 0x00c8, 0x1a11: 0x00c8, + 0x1a12: 0x00c8, 0x1a13: 0x00c8, 0x1a14: 0x00c8, 0x1a15: 0x00c8, + 0x1a18: 0x00c8, 0x1a19: 0x00c8, 0x1a1a: 0x00c8, 0x1a1b: 0x00c8, 0x1a1c: 0x00c8, 0x1a1d: 0x00c8, + 0x1a20: 0x00c8, 0x1a21: 0x00c8, 0x1a22: 0x00c8, 0x1a23: 0x00c8, + 0x1a24: 0x00c8, 0x1a25: 0x00c8, 0x1a26: 0x00c8, 0x1a27: 0x00c8, 0x1a28: 0x00c8, 0x1a29: 0x00c8, + 0x1a2a: 0x00c8, 0x1a2b: 0x00c8, 0x1a2c: 0x00c8, 0x1a2d: 0x00c8, 0x1a2e: 0x00c8, 0x1a2f: 0x00c8, + 0x1a30: 0x00c8, 0x1a31: 0x00c8, 0x1a32: 0x00c8, 0x1a33: 0x00c8, 0x1a34: 0x00c8, 0x1a35: 0x00c8, + 0x1a36: 0x00c8, 0x1a37: 0x00c8, 0x1a38: 0x00c8, 0x1a39: 0x00c8, 0x1a3a: 0x00c8, 0x1a3b: 0x00c8, + 0x1a3c: 0x00c8, 0x1a3d: 0x00c8, 0x1a3e: 0x00c8, 0x1a3f: 0x00c8, + // Block 0x69, offset 0x1a40 + 0x1a40: 0x00c8, 0x1a41: 0x00c8, 0x1a42: 0x00c8, 0x1a43: 0x00c8, 0x1a44: 0x00c8, 0x1a45: 0x00c8, + 0x1a48: 0x00c8, 0x1a49: 0x00c8, 0x1a4a: 0x00c8, 0x1a4b: 0x00c8, + 0x1a4c: 0x00c8, 0x1a4d: 0x00c8, 0x1a50: 0x00c8, 0x1a51: 0x00c8, + 0x1a52: 0x00c8, 0x1a53: 0x00c8, 0x1a54: 0x00c8, 0x1a55: 0x00c8, 0x1a56: 0x00c8, 0x1a57: 0x00c8, + 0x1a59: 0x00c8, 0x1a5b: 0x00c8, 0x1a5d: 0x00c8, + 0x1a5f: 0x00c8, 0x1a60: 0x00c8, 0x1a61: 0x00c8, 0x1a62: 0x00c8, 0x1a63: 0x00c8, + 0x1a64: 0x00c8, 0x1a65: 0x00c8, 0x1a66: 0x00c8, 0x1a67: 0x00c8, 0x1a68: 0x00c8, 0x1a69: 0x00c8, + 0x1a6a: 0x00c8, 0x1a6b: 0x00c8, 0x1a6c: 0x00c8, 0x1a6d: 0x00c8, 0x1a6e: 0x00c8, 0x1a6f: 0x00c8, + 0x1a70: 0x00c8, 0x1a71: 0x0088, 0x1a72: 0x00c8, 0x1a73: 0x0088, 0x1a74: 0x00c8, 0x1a75: 0x0088, + 0x1a76: 0x00c8, 0x1a77: 0x0088, 0x1a78: 0x00c8, 0x1a79: 0x0088, 0x1a7a: 0x00c8, 0x1a7b: 0x0088, + 0x1a7c: 0x00c8, 0x1a7d: 0x0088, + // Block 0x6a, offset 0x1a80 + 0x1a80: 0x00c8, 0x1a81: 0x00c8, 0x1a82: 0x00c8, 0x1a83: 0x00c8, 0x1a84: 0x00c8, 0x1a85: 0x00c8, + 0x1a86: 0x00c8, 0x1a87: 0x00c8, 0x1a88: 0x0088, 0x1a89: 0x0088, 0x1a8a: 0x0088, 0x1a8b: 0x0088, + 0x1a8c: 0x0088, 0x1a8d: 0x0088, 0x1a8e: 0x0088, 0x1a8f: 0x0088, 0x1a90: 0x00c8, 0x1a91: 0x00c8, + 0x1a92: 0x00c8, 0x1a93: 0x00c8, 0x1a94: 0x00c8, 0x1a95: 0x00c8, 0x1a96: 0x00c8, 0x1a97: 0x00c8, + 0x1a98: 0x0088, 0x1a99: 0x0088, 0x1a9a: 0x0088, 0x1a9b: 0x0088, 0x1a9c: 0x0088, 0x1a9d: 0x0088, + 0x1a9e: 0x0088, 0x1a9f: 0x0088, 0x1aa0: 0x00c8, 0x1aa1: 0x00c8, 0x1aa2: 0x00c8, 0x1aa3: 0x00c8, + 0x1aa4: 0x00c8, 0x1aa5: 0x00c8, 0x1aa6: 0x00c8, 0x1aa7: 0x00c8, 0x1aa8: 0x0088, 0x1aa9: 0x0088, + 0x1aaa: 0x0088, 0x1aab: 0x0088, 0x1aac: 0x0088, 0x1aad: 0x0088, 0x1aae: 0x0088, 0x1aaf: 0x0088, + 0x1ab0: 0x00c8, 0x1ab1: 0x00c8, 0x1ab2: 0x00c8, 0x1ab3: 0x00c8, 0x1ab4: 0x00c8, + 0x1ab6: 0x00c8, 0x1ab7: 0x00c8, 0x1ab8: 0x00c8, 0x1ab9: 0x00c8, 0x1aba: 0x00c8, 0x1abb: 0x0088, + 0x1abc: 0x0088, 0x1abd: 0x0088, 0x1abe: 0x0088, 0x1abf: 0x0088, + // Block 0x6b, offset 0x1ac0 + 0x1ac0: 0x0088, 0x1ac1: 0x0088, 0x1ac2: 0x00c8, 0x1ac3: 0x00c8, 0x1ac4: 0x00c8, + 0x1ac6: 0x00c8, 0x1ac7: 0x00c8, 0x1ac8: 0x00c8, 0x1ac9: 0x0088, 0x1aca: 0x00c8, 0x1acb: 0x0088, + 0x1acc: 0x0088, 0x1acd: 0x0088, 0x1ace: 0x0088, 0x1acf: 0x0088, 0x1ad0: 0x00c8, 0x1ad1: 0x00c8, + 0x1ad2: 0x00c8, 0x1ad3: 0x0088, 0x1ad6: 0x00c8, 0x1ad7: 0x00c8, + 0x1ad8: 0x00c8, 0x1ad9: 0x00c8, 0x1ada: 0x00c8, 0x1adb: 0x0088, 0x1add: 0x0088, + 0x1ade: 0x0088, 0x1adf: 0x0088, 0x1ae0: 0x00c8, 0x1ae1: 0x00c8, 0x1ae2: 0x00c8, 0x1ae3: 0x0088, + 0x1ae4: 0x00c8, 0x1ae5: 0x00c8, 0x1ae6: 0x00c8, 0x1ae7: 0x00c8, 0x1ae8: 0x00c8, 0x1ae9: 0x00c8, + 0x1aea: 0x00c8, 0x1aeb: 0x0088, 0x1aec: 0x00c8, 0x1aed: 0x0088, 0x1aee: 0x0088, 0x1aef: 0x0088, + 0x1af2: 0x00c8, 0x1af3: 0x00c8, 0x1af4: 0x00c8, + 0x1af6: 0x00c8, 0x1af7: 0x00c8, 0x1af8: 0x00c8, 0x1af9: 0x0088, 0x1afa: 0x00c8, 0x1afb: 0x0088, + 0x1afc: 0x0088, 0x1afd: 0x0088, 0x1afe: 0x0088, + // Block 0x6c, offset 0x1b00 + 0x1b00: 0x0080, 0x1b01: 0x0080, 0x1b02: 0x0080, 0x1b03: 0x0080, 0x1b04: 0x0080, 0x1b05: 0x0080, + 0x1b06: 0x0080, 0x1b07: 0x0080, 0x1b08: 0x0080, 0x1b09: 0x0080, 0x1b0a: 0x0080, 0x1b0b: 0x0040, + 0x1b0c: 0x004d, 0x1b0d: 0x004e, 0x1b0e: 0x0040, 0x1b0f: 0x0040, 0x1b10: 0x0080, 0x1b11: 0x0080, + 0x1b12: 0x0080, 0x1b13: 0x0080, 0x1b14: 0x0080, 0x1b15: 0x0080, 0x1b16: 0x0080, 0x1b17: 0x0080, + 0x1b18: 0x0080, 0x1b19: 0x0080, 0x1b1a: 0x0080, 0x1b1b: 0x0080, 0x1b1c: 0x0080, 0x1b1d: 0x0080, + 0x1b1e: 0x0080, 0x1b1f: 0x0080, 0x1b20: 0x0080, 0x1b21: 0x0080, 0x1b22: 0x0080, 0x1b23: 0x0080, + 0x1b24: 0x0080, 0x1b25: 0x0080, 0x1b26: 0x0080, 0x1b27: 0x0080, 0x1b28: 0x0040, 0x1b29: 0x0040, + 0x1b2a: 0x0040, 0x1b2b: 0x0040, 0x1b2c: 0x0040, 0x1b2d: 0x0040, 0x1b2e: 0x0040, 0x1b2f: 0x0080, + 0x1b30: 0x0080, 0x1b31: 0x0080, 0x1b32: 0x0080, 0x1b33: 0x0080, 0x1b34: 0x0080, 0x1b35: 0x0080, + 0x1b36: 0x0080, 0x1b37: 0x0080, 0x1b38: 0x0080, 0x1b39: 0x0080, 0x1b3a: 0x0080, 0x1b3b: 0x0080, + 0x1b3c: 0x0080, 0x1b3d: 0x0080, 0x1b3e: 0x0080, 0x1b3f: 0x0080, + // Block 0x6d, offset 0x1b40 + 0x1b40: 0x0080, 0x1b41: 0x0080, 0x1b42: 0x0080, 0x1b43: 0x0080, 0x1b44: 0x0080, 0x1b45: 0x0080, + 0x1b46: 0x0080, 0x1b47: 0x0080, 0x1b48: 0x0080, 0x1b49: 0x0080, 0x1b4a: 0x0080, 0x1b4b: 0x0080, + 0x1b4c: 0x0080, 0x1b4d: 0x0080, 0x1b4e: 0x0080, 0x1b4f: 0x0080, 0x1b50: 0x0080, 0x1b51: 0x0080, + 0x1b52: 0x0080, 0x1b53: 0x0080, 0x1b54: 0x0080, 0x1b55: 0x0080, 0x1b56: 0x0080, 0x1b57: 0x0080, + 0x1b58: 0x0080, 0x1b59: 0x0080, 0x1b5a: 0x0080, 0x1b5b: 0x0080, 0x1b5c: 0x0080, 0x1b5d: 0x0080, + 0x1b5e: 0x0080, 0x1b5f: 0x0080, 0x1b60: 0x0040, 0x1b61: 0x0040, 0x1b62: 0x0040, 0x1b63: 0x0040, + 0x1b64: 0x0040, 0x1b66: 0x0040, 0x1b67: 0x0040, 0x1b68: 0x0040, 0x1b69: 0x0040, + 0x1b6a: 0x0040, 0x1b6b: 0x0040, 0x1b6c: 0x0040, 0x1b6d: 0x0040, 0x1b6e: 0x0040, 0x1b6f: 0x0040, + 0x1b70: 0x0080, 0x1b71: 0x0080, 0x1b74: 0x0080, 0x1b75: 0x0080, + 0x1b76: 0x0080, 0x1b77: 0x0080, 0x1b78: 0x0080, 0x1b79: 0x0080, 0x1b7a: 0x0080, 0x1b7b: 0x0080, + 0x1b7c: 0x0080, 0x1b7d: 0x0080, 0x1b7e: 0x0080, 0x1b7f: 0x0080, + // Block 0x6e, offset 0x1b80 + 0x1b80: 0x0080, 0x1b81: 0x0080, 0x1b82: 0x0080, 0x1b83: 0x0080, 0x1b84: 0x0080, 0x1b85: 0x0080, + 0x1b86: 0x0080, 0x1b87: 0x0080, 0x1b88: 0x0080, 0x1b89: 0x0080, 0x1b8a: 0x0080, 0x1b8b: 0x0080, + 0x1b8c: 0x0080, 0x1b8d: 0x0080, 0x1b8e: 0x0080, 0x1b90: 0x0080, 0x1b91: 0x0080, + 0x1b92: 0x0080, 0x1b93: 0x0080, 0x1b94: 0x0080, 0x1b95: 0x0080, 0x1b96: 0x0080, 0x1b97: 0x0080, + 0x1b98: 0x0080, 0x1b99: 0x0080, 0x1b9a: 0x0080, 0x1b9b: 0x0080, 0x1b9c: 0x0080, + 0x1ba0: 0x0080, 0x1ba1: 0x0080, 0x1ba2: 0x0080, 0x1ba3: 0x0080, + 0x1ba4: 0x0080, 0x1ba5: 0x0080, 0x1ba6: 0x0080, 0x1ba7: 0x0080, 0x1ba8: 0x0080, 0x1ba9: 0x0080, + 0x1baa: 0x0080, 0x1bab: 0x0080, 0x1bac: 0x0080, 0x1bad: 0x0080, 0x1bae: 0x0080, 0x1baf: 0x0080, + 0x1bb0: 0x0080, 0x1bb1: 0x0080, 0x1bb2: 0x0080, 0x1bb3: 0x0080, 0x1bb4: 0x0080, 0x1bb5: 0x0080, + 0x1bb6: 0x0080, 0x1bb7: 0x0080, 0x1bb8: 0x0080, 0x1bb9: 0x0080, 0x1bba: 0x0080, 0x1bbb: 0x0080, + 0x1bbc: 0x0080, 0x1bbd: 0x0080, 0x1bbe: 0x0080, + // Block 0x6f, offset 0x1bc0 + 0x1bd0: 0x00c3, 0x1bd1: 0x00c3, + 0x1bd2: 0x00c3, 0x1bd3: 0x00c3, 0x1bd4: 0x00c3, 0x1bd5: 0x00c3, 0x1bd6: 0x00c3, 0x1bd7: 0x00c3, + 0x1bd8: 0x00c3, 0x1bd9: 0x00c3, 0x1bda: 0x00c3, 0x1bdb: 0x00c3, 0x1bdc: 0x00c3, 0x1bdd: 0x0083, + 0x1bde: 0x0083, 0x1bdf: 0x0083, 0x1be0: 0x0083, 0x1be1: 0x00c3, 0x1be2: 0x0083, 0x1be3: 0x0083, + 0x1be4: 0x0083, 0x1be5: 0x00c3, 0x1be6: 0x00c3, 0x1be7: 0x00c3, 0x1be8: 0x00c3, 0x1be9: 0x00c3, + 0x1bea: 0x00c3, 0x1beb: 0x00c3, 0x1bec: 0x00c3, 0x1bed: 0x00c3, 0x1bee: 0x00c3, 0x1bef: 0x00c3, + 0x1bf0: 0x00c3, + // Block 0x70, offset 0x1c00 + 0x1c00: 0x0080, 0x1c01: 0x0080, 0x1c02: 0x0080, 0x1c03: 0x0080, 0x1c04: 0x0080, 0x1c05: 0x0080, + 0x1c06: 0x0080, 0x1c07: 0x0080, 0x1c08: 0x0080, 0x1c09: 0x0080, 0x1c0a: 0x0080, 0x1c0b: 0x0080, + 0x1c0c: 0x0080, 0x1c0d: 0x0080, 0x1c0e: 0x0080, 0x1c0f: 0x0080, 0x1c10: 0x0080, 0x1c11: 0x0080, + 0x1c12: 0x0080, 0x1c13: 0x0080, 0x1c14: 0x0080, 0x1c15: 0x0080, 0x1c16: 0x0080, 0x1c17: 0x0080, + 0x1c18: 0x0080, 0x1c19: 0x0080, 0x1c1a: 0x0080, 0x1c1b: 0x0080, 0x1c1c: 0x0080, 0x1c1d: 0x0080, + 0x1c1e: 0x0080, 0x1c1f: 0x0080, 0x1c20: 0x0080, 0x1c21: 0x0080, 0x1c22: 0x0080, 0x1c23: 0x0080, + 0x1c24: 0x0080, 0x1c25: 0x0080, 0x1c26: 0x0088, 0x1c27: 0x0080, 0x1c28: 0x0080, 0x1c29: 0x0080, + 0x1c2a: 0x0080, 0x1c2b: 0x0080, 0x1c2c: 0x0080, 0x1c2d: 0x0080, 0x1c2e: 0x0080, 0x1c2f: 0x0080, + 0x1c30: 0x0080, 0x1c31: 0x0080, 0x1c32: 0x00c0, 0x1c33: 0x0080, 0x1c34: 0x0080, 0x1c35: 0x0080, + 0x1c36: 0x0080, 0x1c37: 0x0080, 0x1c38: 0x0080, 0x1c39: 0x0080, 0x1c3a: 0x0080, 0x1c3b: 0x0080, + 0x1c3c: 0x0080, 0x1c3d: 0x0080, 0x1c3e: 0x0080, 0x1c3f: 0x0080, + // Block 0x71, offset 0x1c40 + 0x1c40: 0x0080, 0x1c41: 0x0080, 0x1c42: 0x0080, 0x1c43: 0x0080, 0x1c44: 0x0080, 0x1c45: 0x0080, + 0x1c46: 0x0080, 0x1c47: 0x0080, 0x1c48: 0x0080, 0x1c49: 0x0080, 0x1c4a: 0x0080, 0x1c4b: 0x0080, + 0x1c4c: 0x0080, 0x1c4d: 0x0080, 0x1c4e: 0x00c0, 0x1c4f: 0x0080, 0x1c50: 0x0080, 0x1c51: 0x0080, + 0x1c52: 0x0080, 0x1c53: 0x0080, 0x1c54: 0x0080, 0x1c55: 0x0080, 0x1c56: 0x0080, 0x1c57: 0x0080, + 0x1c58: 0x0080, 0x1c59: 0x0080, 0x1c5a: 0x0080, 0x1c5b: 0x0080, 0x1c5c: 0x0080, 0x1c5d: 0x0080, + 0x1c5e: 0x0080, 0x1c5f: 0x0080, 0x1c60: 0x0080, 0x1c61: 0x0080, 0x1c62: 0x0080, 0x1c63: 0x0080, + 0x1c64: 0x0080, 0x1c65: 0x0080, 0x1c66: 0x0080, 0x1c67: 0x0080, 0x1c68: 0x0080, 0x1c69: 0x0080, + 0x1c6a: 0x0080, 0x1c6b: 0x0080, 0x1c6c: 0x0080, 0x1c6d: 0x0080, 0x1c6e: 0x0080, 0x1c6f: 0x0080, + 0x1c70: 0x0080, 0x1c71: 0x0080, 0x1c72: 0x0080, 0x1c73: 0x0080, 0x1c74: 0x0080, 0x1c75: 0x0080, + 0x1c76: 0x0080, 0x1c77: 0x0080, 0x1c78: 0x0080, 0x1c79: 0x0080, 0x1c7a: 0x0080, 0x1c7b: 0x0080, + 0x1c7c: 0x0080, 0x1c7d: 0x0080, 0x1c7e: 0x0080, 0x1c7f: 0x0080, + // Block 0x72, offset 0x1c80 + 0x1c80: 0x0080, 0x1c81: 0x0080, 0x1c82: 0x0080, 0x1c83: 0x00c0, 0x1c84: 0x00c0, 0x1c85: 0x0080, + 0x1c86: 0x0080, 0x1c87: 0x0080, 0x1c88: 0x0080, 0x1c89: 0x0080, 0x1c8a: 0x0080, 0x1c8b: 0x0080, + 0x1c90: 0x0080, 0x1c91: 0x0080, + 0x1c92: 0x0080, 0x1c93: 0x0080, 0x1c94: 0x0080, 0x1c95: 0x0080, 0x1c96: 0x0080, 0x1c97: 0x0080, + 0x1c98: 0x0080, 0x1c99: 0x0080, 0x1c9a: 0x0080, 0x1c9b: 0x0080, 0x1c9c: 0x0080, 0x1c9d: 0x0080, + 0x1c9e: 0x0080, 0x1c9f: 0x0080, 0x1ca0: 0x0080, 0x1ca1: 0x0080, 0x1ca2: 0x0080, 0x1ca3: 0x0080, + 0x1ca4: 0x0080, 0x1ca5: 0x0080, 0x1ca6: 0x0080, 0x1ca7: 0x0080, 0x1ca8: 0x0080, 0x1ca9: 0x0080, + 0x1caa: 0x0080, 0x1cab: 0x0080, 0x1cac: 0x0080, 0x1cad: 0x0080, 0x1cae: 0x0080, 0x1caf: 0x0080, + 0x1cb0: 0x0080, 0x1cb1: 0x0080, 0x1cb2: 0x0080, 0x1cb3: 0x0080, 0x1cb4: 0x0080, 0x1cb5: 0x0080, + 0x1cb6: 0x0080, 0x1cb7: 0x0080, 0x1cb8: 0x0080, 0x1cb9: 0x0080, 0x1cba: 0x0080, 0x1cbb: 0x0080, + 0x1cbc: 0x0080, 0x1cbd: 0x0080, 0x1cbe: 0x0080, 0x1cbf: 0x0080, + // Block 0x73, offset 0x1cc0 + 0x1cc0: 0x0080, 0x1cc1: 0x0080, 0x1cc2: 0x0080, 0x1cc3: 0x0080, 0x1cc4: 0x0080, 0x1cc5: 0x0080, + 0x1cc6: 0x0080, 0x1cc7: 0x0080, 0x1cc8: 0x0080, 0x1cc9: 0x0080, 0x1cca: 0x0080, 0x1ccb: 0x0080, + 0x1ccc: 0x0080, 0x1ccd: 0x0080, 0x1cce: 0x0080, 0x1ccf: 0x0080, 0x1cd0: 0x0080, 0x1cd1: 0x0080, + 0x1cd2: 0x0080, 0x1cd3: 0x0080, 0x1cd4: 0x0080, 0x1cd5: 0x0080, 0x1cd6: 0x0080, 0x1cd7: 0x0080, + 0x1cd8: 0x0080, 0x1cd9: 0x0080, 0x1cda: 0x0080, 0x1cdb: 0x0080, 0x1cdc: 0x0080, 0x1cdd: 0x0080, + 0x1cde: 0x0080, 0x1cdf: 0x0080, 0x1ce0: 0x0080, 0x1ce1: 0x0080, 0x1ce2: 0x0080, 0x1ce3: 0x0080, + 0x1ce4: 0x0080, 0x1ce5: 0x0080, 0x1ce6: 0x0080, 0x1ce7: 0x0080, 0x1ce8: 0x0080, 0x1ce9: 0x0080, + 0x1cea: 0x0080, 0x1ceb: 0x0080, 0x1cec: 0x0080, 0x1ced: 0x0080, 0x1cee: 0x0080, 0x1cef: 0x0080, + 0x1cf0: 0x0080, 0x1cf1: 0x0080, 0x1cf2: 0x0080, 0x1cf3: 0x0080, 0x1cf4: 0x0080, 0x1cf5: 0x0080, + 0x1cf6: 0x0080, 0x1cf7: 0x0080, 0x1cf8: 0x0080, 0x1cf9: 0x0080, 0x1cfa: 0x0080, 0x1cfb: 0x0080, + 0x1cfc: 0x0080, 0x1cfd: 0x0080, 0x1cfe: 0x0080, 0x1cff: 0x0080, + // Block 0x74, offset 0x1d00 + 0x1d00: 0x0080, 0x1d01: 0x0080, 0x1d02: 0x0080, 0x1d03: 0x0080, 0x1d04: 0x0080, 0x1d05: 0x0080, + 0x1d06: 0x0080, 0x1d07: 0x0080, 0x1d08: 0x0080, 0x1d09: 0x0080, 0x1d0a: 0x0080, 0x1d0b: 0x0080, + 0x1d0c: 0x0080, 0x1d0d: 0x0080, 0x1d0e: 0x0080, 0x1d0f: 0x0080, 0x1d10: 0x0080, 0x1d11: 0x0080, + 0x1d12: 0x0080, 0x1d13: 0x0080, 0x1d14: 0x0080, 0x1d15: 0x0080, 0x1d16: 0x0080, 0x1d17: 0x0080, + 0x1d18: 0x0080, 0x1d19: 0x0080, 0x1d1a: 0x0080, 0x1d1b: 0x0080, 0x1d1c: 0x0080, 0x1d1d: 0x0080, + 0x1d1e: 0x0080, 0x1d1f: 0x0080, 0x1d20: 0x0080, 0x1d21: 0x0080, 0x1d22: 0x0080, 0x1d23: 0x0080, + 0x1d24: 0x0080, 0x1d25: 0x0080, 0x1d26: 0x0080, 0x1d27: 0x0080, 0x1d28: 0x0080, 0x1d29: 0x0080, + 0x1d2a: 0x0080, 0x1d2b: 0x0080, 0x1d2c: 0x0080, 0x1d2d: 0x0080, 0x1d2e: 0x0080, 0x1d2f: 0x0080, + 0x1d30: 0x0080, 0x1d31: 0x0080, 0x1d32: 0x0080, 0x1d33: 0x0080, 0x1d34: 0x0080, 0x1d35: 0x0080, + 0x1d36: 0x0080, 0x1d37: 0x0080, 0x1d38: 0x0080, 0x1d39: 0x0080, 0x1d3a: 0x0080, 0x1d3b: 0x0080, + 0x1d3c: 0x0080, 0x1d3d: 0x0080, 0x1d3e: 0x0080, + // Block 0x75, offset 0x1d40 + 0x1d40: 0x0080, 0x1d41: 0x0080, 0x1d42: 0x0080, 0x1d43: 0x0080, 0x1d44: 0x0080, 0x1d45: 0x0080, + 0x1d46: 0x0080, 0x1d47: 0x0080, 0x1d48: 0x0080, 0x1d49: 0x0080, 0x1d4a: 0x0080, 0x1d4b: 0x0080, + 0x1d4c: 0x0080, 0x1d4d: 0x0080, 0x1d4e: 0x0080, 0x1d4f: 0x0080, 0x1d50: 0x0080, 0x1d51: 0x0080, + 0x1d52: 0x0080, 0x1d53: 0x0080, 0x1d54: 0x0080, 0x1d55: 0x0080, 0x1d56: 0x0080, 0x1d57: 0x0080, + 0x1d58: 0x0080, 0x1d59: 0x0080, 0x1d5a: 0x0080, 0x1d5b: 0x0080, 0x1d5c: 0x0080, 0x1d5d: 0x0080, + 0x1d5e: 0x0080, 0x1d5f: 0x0080, 0x1d60: 0x0080, 0x1d61: 0x0080, 0x1d62: 0x0080, 0x1d63: 0x0080, + 0x1d64: 0x0080, 0x1d65: 0x0080, 0x1d66: 0x0080, + // Block 0x76, offset 0x1d80 + 0x1d80: 0x0080, 0x1d81: 0x0080, 0x1d82: 0x0080, 0x1d83: 0x0080, 0x1d84: 0x0080, 0x1d85: 0x0080, + 0x1d86: 0x0080, 0x1d87: 0x0080, 0x1d88: 0x0080, 0x1d89: 0x0080, 0x1d8a: 0x0080, + 0x1da0: 0x0080, 0x1da1: 0x0080, 0x1da2: 0x0080, 0x1da3: 0x0080, + 0x1da4: 0x0080, 0x1da5: 0x0080, 0x1da6: 0x0080, 0x1da7: 0x0080, 0x1da8: 0x0080, 0x1da9: 0x0080, + 0x1daa: 0x0080, 0x1dab: 0x0080, 0x1dac: 0x0080, 0x1dad: 0x0080, 0x1dae: 0x0080, 0x1daf: 0x0080, + 0x1db0: 0x0080, 0x1db1: 0x0080, 0x1db2: 0x0080, 0x1db3: 0x0080, 0x1db4: 0x0080, 0x1db5: 0x0080, + 0x1db6: 0x0080, 0x1db7: 0x0080, 0x1db8: 0x0080, 0x1db9: 0x0080, 0x1dba: 0x0080, 0x1dbb: 0x0080, + 0x1dbc: 0x0080, 0x1dbd: 0x0080, 0x1dbe: 0x0080, 0x1dbf: 0x0080, + // Block 0x77, offset 0x1dc0 + 0x1dc0: 0x0080, 0x1dc1: 0x0080, 0x1dc2: 0x0080, 0x1dc3: 0x0080, 0x1dc4: 0x0080, 0x1dc5: 0x0080, + 0x1dc6: 0x0080, 0x1dc7: 0x0080, 0x1dc8: 0x0080, 0x1dc9: 0x0080, 0x1dca: 0x0080, 0x1dcb: 0x0080, + 0x1dcc: 0x0080, 0x1dcd: 0x0080, 0x1dce: 0x0080, 0x1dcf: 0x0080, 0x1dd0: 0x0080, 0x1dd1: 0x0080, + 0x1dd2: 0x0080, 0x1dd3: 0x0080, 0x1dd4: 0x0080, 0x1dd5: 0x0080, 0x1dd6: 0x0080, 0x1dd7: 0x0080, + 0x1dd8: 0x0080, 0x1dd9: 0x0080, 0x1dda: 0x0080, 0x1ddb: 0x0080, 0x1ddc: 0x0080, 0x1ddd: 0x0080, + 0x1dde: 0x0080, 0x1ddf: 0x0080, 0x1de0: 0x0080, 0x1de1: 0x0080, 0x1de2: 0x0080, 0x1de3: 0x0080, + 0x1de4: 0x0080, 0x1de5: 0x0080, 0x1de6: 0x0080, 0x1de7: 0x0080, 0x1de8: 0x0080, 0x1de9: 0x0080, + 0x1dea: 0x0080, 0x1deb: 0x0080, 0x1dec: 0x0080, 0x1ded: 0x0080, 0x1dee: 0x0080, 0x1def: 0x0080, + 0x1df0: 0x0080, 0x1df1: 0x0080, 0x1df2: 0x0080, 0x1df3: 0x0080, + 0x1df6: 0x0080, 0x1df7: 0x0080, 0x1df8: 0x0080, 0x1df9: 0x0080, 0x1dfa: 0x0080, 0x1dfb: 0x0080, + 0x1dfc: 0x0080, 0x1dfd: 0x0080, 0x1dfe: 0x0080, 0x1dff: 0x0080, + // Block 0x78, offset 0x1e00 + 0x1e00: 0x0080, 0x1e01: 0x0080, 0x1e02: 0x0080, 0x1e03: 0x0080, 0x1e04: 0x0080, 0x1e05: 0x0080, + 0x1e06: 0x0080, 0x1e07: 0x0080, 0x1e08: 0x0080, 0x1e09: 0x0080, 0x1e0a: 0x0080, 0x1e0b: 0x0080, + 0x1e0c: 0x0080, 0x1e0d: 0x0080, 0x1e0e: 0x0080, 0x1e0f: 0x0080, 0x1e10: 0x0080, 0x1e11: 0x0080, + 0x1e12: 0x0080, 0x1e13: 0x0080, 0x1e14: 0x0080, 0x1e15: 0x0080, + 0x1e18: 0x0080, 0x1e19: 0x0080, 0x1e1a: 0x0080, 0x1e1b: 0x0080, 0x1e1c: 0x0080, 0x1e1d: 0x0080, + 0x1e1e: 0x0080, 0x1e1f: 0x0080, 0x1e20: 0x0080, 0x1e21: 0x0080, 0x1e22: 0x0080, 0x1e23: 0x0080, + 0x1e24: 0x0080, 0x1e25: 0x0080, 0x1e26: 0x0080, 0x1e27: 0x0080, 0x1e28: 0x0080, 0x1e29: 0x0080, + 0x1e2a: 0x0080, 0x1e2b: 0x0080, 0x1e2c: 0x0080, 0x1e2d: 0x0080, 0x1e2e: 0x0080, 0x1e2f: 0x0080, + 0x1e30: 0x0080, 0x1e31: 0x0080, 0x1e32: 0x0080, 0x1e33: 0x0080, 0x1e34: 0x0080, 0x1e35: 0x0080, + 0x1e36: 0x0080, 0x1e37: 0x0080, 0x1e38: 0x0080, 0x1e39: 0x0080, + 0x1e3d: 0x0080, 0x1e3e: 0x0080, 0x1e3f: 0x0080, + // Block 0x79, offset 0x1e40 + 0x1e40: 0x0080, 0x1e41: 0x0080, 0x1e42: 0x0080, 0x1e43: 0x0080, 0x1e44: 0x0080, 0x1e45: 0x0080, + 0x1e46: 0x0080, 0x1e47: 0x0080, 0x1e48: 0x0080, 0x1e4a: 0x0080, 0x1e4b: 0x0080, + 0x1e4c: 0x0080, 0x1e4d: 0x0080, 0x1e4e: 0x0080, 0x1e4f: 0x0080, 0x1e50: 0x0080, 0x1e51: 0x0080, + 0x1e6c: 0x0080, 0x1e6d: 0x0080, 0x1e6e: 0x0080, 0x1e6f: 0x0080, + // Block 0x7a, offset 0x1e80 + 0x1e80: 0x00c0, 0x1e81: 0x00c0, 0x1e82: 0x00c0, 0x1e83: 0x00c0, 0x1e84: 0x00c0, 0x1e85: 0x00c0, + 0x1e86: 0x00c0, 0x1e87: 0x00c0, 0x1e88: 0x00c0, 0x1e89: 0x00c0, 0x1e8a: 0x00c0, 0x1e8b: 0x00c0, + 0x1e8c: 0x00c0, 0x1e8d: 0x00c0, 0x1e8e: 0x00c0, 0x1e8f: 0x00c0, 0x1e90: 0x00c0, 0x1e91: 0x00c0, + 0x1e92: 0x00c0, 0x1e93: 0x00c0, 0x1e94: 0x00c0, 0x1e95: 0x00c0, 0x1e96: 0x00c0, 0x1e97: 0x00c0, + 0x1e98: 0x00c0, 0x1e99: 0x00c0, 0x1e9a: 0x00c0, 0x1e9b: 0x00c0, 0x1e9c: 0x00c0, 0x1e9d: 0x00c0, + 0x1e9e: 0x00c0, 0x1e9f: 0x00c0, 0x1ea0: 0x00c0, 0x1ea1: 0x00c0, 0x1ea2: 0x00c0, 0x1ea3: 0x00c0, + 0x1ea4: 0x00c0, 0x1ea5: 0x00c0, 0x1ea6: 0x00c0, 0x1ea7: 0x00c0, 0x1ea8: 0x00c0, 0x1ea9: 0x00c0, + 0x1eaa: 0x00c0, 0x1eab: 0x00c0, 0x1eac: 0x00c0, 0x1ead: 0x00c0, 0x1eae: 0x00c0, + 0x1eb0: 0x00c0, 0x1eb1: 0x00c0, 0x1eb2: 0x00c0, 0x1eb3: 0x00c0, 0x1eb4: 0x00c0, 0x1eb5: 0x00c0, + 0x1eb6: 0x00c0, 0x1eb7: 0x00c0, 0x1eb8: 0x00c0, 0x1eb9: 0x00c0, 0x1eba: 0x00c0, 0x1ebb: 0x00c0, + 0x1ebc: 0x00c0, 0x1ebd: 0x00c0, 0x1ebe: 0x00c0, 0x1ebf: 0x00c0, + // Block 0x7b, offset 0x1ec0 + 0x1ec0: 0x00c0, 0x1ec1: 0x00c0, 0x1ec2: 0x00c0, 0x1ec3: 0x00c0, 0x1ec4: 0x00c0, 0x1ec5: 0x00c0, + 0x1ec6: 0x00c0, 0x1ec7: 0x00c0, 0x1ec8: 0x00c0, 0x1ec9: 0x00c0, 0x1eca: 0x00c0, 0x1ecb: 0x00c0, + 0x1ecc: 0x00c0, 0x1ecd: 0x00c0, 0x1ece: 0x00c0, 0x1ecf: 0x00c0, 0x1ed0: 0x00c0, 0x1ed1: 0x00c0, + 0x1ed2: 0x00c0, 0x1ed3: 0x00c0, 0x1ed4: 0x00c0, 0x1ed5: 0x00c0, 0x1ed6: 0x00c0, 0x1ed7: 0x00c0, + 0x1ed8: 0x00c0, 0x1ed9: 0x00c0, 0x1eda: 0x00c0, 0x1edb: 0x00c0, 0x1edc: 0x00c0, 0x1edd: 0x00c0, + 0x1ede: 0x00c0, 0x1ee0: 0x00c0, 0x1ee1: 0x00c0, 0x1ee2: 0x00c0, 0x1ee3: 0x00c0, + 0x1ee4: 0x00c0, 0x1ee5: 0x00c0, 0x1ee6: 0x00c0, 0x1ee7: 0x00c0, 0x1ee8: 0x00c0, 0x1ee9: 0x00c0, + 0x1eea: 0x00c0, 0x1eeb: 0x00c0, 0x1eec: 0x00c0, 0x1eed: 0x00c0, 0x1eee: 0x00c0, 0x1eef: 0x00c0, + 0x1ef0: 0x00c0, 0x1ef1: 0x00c0, 0x1ef2: 0x00c0, 0x1ef3: 0x00c0, 0x1ef4: 0x00c0, 0x1ef5: 0x00c0, + 0x1ef6: 0x00c0, 0x1ef7: 0x00c0, 0x1ef8: 0x00c0, 0x1ef9: 0x00c0, 0x1efa: 0x00c0, 0x1efb: 0x00c0, + 0x1efc: 0x0080, 0x1efd: 0x0080, 0x1efe: 0x00c0, 0x1eff: 0x00c0, + // Block 0x7c, offset 0x1f00 + 0x1f00: 0x00c0, 0x1f01: 0x00c0, 0x1f02: 0x00c0, 0x1f03: 0x00c0, 0x1f04: 0x00c0, 0x1f05: 0x00c0, + 0x1f06: 0x00c0, 0x1f07: 0x00c0, 0x1f08: 0x00c0, 0x1f09: 0x00c0, 0x1f0a: 0x00c0, 0x1f0b: 0x00c0, + 0x1f0c: 0x00c0, 0x1f0d: 0x00c0, 0x1f0e: 0x00c0, 0x1f0f: 0x00c0, 0x1f10: 0x00c0, 0x1f11: 0x00c0, + 0x1f12: 0x00c0, 0x1f13: 0x00c0, 0x1f14: 0x00c0, 0x1f15: 0x00c0, 0x1f16: 0x00c0, 0x1f17: 0x00c0, + 0x1f18: 0x00c0, 0x1f19: 0x00c0, 0x1f1a: 0x00c0, 0x1f1b: 0x00c0, 0x1f1c: 0x00c0, 0x1f1d: 0x00c0, + 0x1f1e: 0x00c0, 0x1f1f: 0x00c0, 0x1f20: 0x00c0, 0x1f21: 0x00c0, 0x1f22: 0x00c0, 0x1f23: 0x00c0, + 0x1f24: 0x00c0, 0x1f25: 0x0080, 0x1f26: 0x0080, 0x1f27: 0x0080, 0x1f28: 0x0080, 0x1f29: 0x0080, + 0x1f2a: 0x0080, 0x1f2b: 0x00c0, 0x1f2c: 0x00c0, 0x1f2d: 0x00c0, 0x1f2e: 0x00c0, 0x1f2f: 0x00c3, + 0x1f30: 0x00c3, 0x1f31: 0x00c3, 0x1f32: 0x00c0, 0x1f33: 0x00c0, + 0x1f39: 0x0080, 0x1f3a: 0x0080, 0x1f3b: 0x0080, + 0x1f3c: 0x0080, 0x1f3d: 0x0080, 0x1f3e: 0x0080, 0x1f3f: 0x0080, + // Block 0x7d, offset 0x1f40 + 0x1f40: 0x00c0, 0x1f41: 0x00c0, 0x1f42: 0x00c0, 0x1f43: 0x00c0, 0x1f44: 0x00c0, 0x1f45: 0x00c0, + 0x1f46: 0x00c0, 0x1f47: 0x00c0, 0x1f48: 0x00c0, 0x1f49: 0x00c0, 0x1f4a: 0x00c0, 0x1f4b: 0x00c0, + 0x1f4c: 0x00c0, 0x1f4d: 0x00c0, 0x1f4e: 0x00c0, 0x1f4f: 0x00c0, 0x1f50: 0x00c0, 0x1f51: 0x00c0, + 0x1f52: 0x00c0, 0x1f53: 0x00c0, 0x1f54: 0x00c0, 0x1f55: 0x00c0, 0x1f56: 0x00c0, 0x1f57: 0x00c0, + 0x1f58: 0x00c0, 0x1f59: 0x00c0, 0x1f5a: 0x00c0, 0x1f5b: 0x00c0, 0x1f5c: 0x00c0, 0x1f5d: 0x00c0, + 0x1f5e: 0x00c0, 0x1f5f: 0x00c0, 0x1f60: 0x00c0, 0x1f61: 0x00c0, 0x1f62: 0x00c0, 0x1f63: 0x00c0, + 0x1f64: 0x00c0, 0x1f65: 0x00c0, 0x1f67: 0x00c0, + 0x1f6d: 0x00c0, + 0x1f70: 0x00c0, 0x1f71: 0x00c0, 0x1f72: 0x00c0, 0x1f73: 0x00c0, 0x1f74: 0x00c0, 0x1f75: 0x00c0, + 0x1f76: 0x00c0, 0x1f77: 0x00c0, 0x1f78: 0x00c0, 0x1f79: 0x00c0, 0x1f7a: 0x00c0, 0x1f7b: 0x00c0, + 0x1f7c: 0x00c0, 0x1f7d: 0x00c0, 0x1f7e: 0x00c0, 0x1f7f: 0x00c0, + // Block 0x7e, offset 0x1f80 + 0x1f80: 0x00c0, 0x1f81: 0x00c0, 0x1f82: 0x00c0, 0x1f83: 0x00c0, 0x1f84: 0x00c0, 0x1f85: 0x00c0, + 0x1f86: 0x00c0, 0x1f87: 0x00c0, 0x1f88: 0x00c0, 0x1f89: 0x00c0, 0x1f8a: 0x00c0, 0x1f8b: 0x00c0, + 0x1f8c: 0x00c0, 0x1f8d: 0x00c0, 0x1f8e: 0x00c0, 0x1f8f: 0x00c0, 0x1f90: 0x00c0, 0x1f91: 0x00c0, + 0x1f92: 0x00c0, 0x1f93: 0x00c0, 0x1f94: 0x00c0, 0x1f95: 0x00c0, 0x1f96: 0x00c0, 0x1f97: 0x00c0, + 0x1f98: 0x00c0, 0x1f99: 0x00c0, 0x1f9a: 0x00c0, 0x1f9b: 0x00c0, 0x1f9c: 0x00c0, 0x1f9d: 0x00c0, + 0x1f9e: 0x00c0, 0x1f9f: 0x00c0, 0x1fa0: 0x00c0, 0x1fa1: 0x00c0, 0x1fa2: 0x00c0, 0x1fa3: 0x00c0, + 0x1fa4: 0x00c0, 0x1fa5: 0x00c0, 0x1fa6: 0x00c0, 0x1fa7: 0x00c0, + 0x1faf: 0x0080, + 0x1fb0: 0x0080, + 0x1fbf: 0x00c6, + // Block 0x7f, offset 0x1fc0 + 0x1fc0: 0x00c0, 0x1fc1: 0x00c0, 0x1fc2: 0x00c0, 0x1fc3: 0x00c0, 0x1fc4: 0x00c0, 0x1fc5: 0x00c0, + 0x1fc6: 0x00c0, 0x1fc7: 0x00c0, 0x1fc8: 0x00c0, 0x1fc9: 0x00c0, 0x1fca: 0x00c0, 0x1fcb: 0x00c0, + 0x1fcc: 0x00c0, 0x1fcd: 0x00c0, 0x1fce: 0x00c0, 0x1fcf: 0x00c0, 0x1fd0: 0x00c0, 0x1fd1: 0x00c0, + 0x1fd2: 0x00c0, 0x1fd3: 0x00c0, 0x1fd4: 0x00c0, 0x1fd5: 0x00c0, 0x1fd6: 0x00c0, + 0x1fe0: 0x00c0, 0x1fe1: 0x00c0, 0x1fe2: 0x00c0, 0x1fe3: 0x00c0, + 0x1fe4: 0x00c0, 0x1fe5: 0x00c0, 0x1fe6: 0x00c0, 0x1fe8: 0x00c0, 0x1fe9: 0x00c0, + 0x1fea: 0x00c0, 0x1feb: 0x00c0, 0x1fec: 0x00c0, 0x1fed: 0x00c0, 0x1fee: 0x00c0, + 0x1ff0: 0x00c0, 0x1ff1: 0x00c0, 0x1ff2: 0x00c0, 0x1ff3: 0x00c0, 0x1ff4: 0x00c0, 0x1ff5: 0x00c0, + 0x1ff6: 0x00c0, 0x1ff8: 0x00c0, 0x1ff9: 0x00c0, 0x1ffa: 0x00c0, 0x1ffb: 0x00c0, + 0x1ffc: 0x00c0, 0x1ffd: 0x00c0, 0x1ffe: 0x00c0, + // Block 0x80, offset 0x2000 + 0x2000: 0x00c0, 0x2001: 0x00c0, 0x2002: 0x00c0, 0x2003: 0x00c0, 0x2004: 0x00c0, 0x2005: 0x00c0, + 0x2006: 0x00c0, 0x2008: 0x00c0, 0x2009: 0x00c0, 0x200a: 0x00c0, 0x200b: 0x00c0, + 0x200c: 0x00c0, 0x200d: 0x00c0, 0x200e: 0x00c0, 0x2010: 0x00c0, 0x2011: 0x00c0, + 0x2012: 0x00c0, 0x2013: 0x00c0, 0x2014: 0x00c0, 0x2015: 0x00c0, 0x2016: 0x00c0, + 0x2018: 0x00c0, 0x2019: 0x00c0, 0x201a: 0x00c0, 0x201b: 0x00c0, 0x201c: 0x00c0, 0x201d: 0x00c0, + 0x201e: 0x00c0, 0x2020: 0x00c3, 0x2021: 0x00c3, 0x2022: 0x00c3, 0x2023: 0x00c3, + 0x2024: 0x00c3, 0x2025: 0x00c3, 0x2026: 0x00c3, 0x2027: 0x00c3, 0x2028: 0x00c3, 0x2029: 0x00c3, + 0x202a: 0x00c3, 0x202b: 0x00c3, 0x202c: 0x00c3, 0x202d: 0x00c3, 0x202e: 0x00c3, 0x202f: 0x00c3, + 0x2030: 0x00c3, 0x2031: 0x00c3, 0x2032: 0x00c3, 0x2033: 0x00c3, 0x2034: 0x00c3, 0x2035: 0x00c3, + 0x2036: 0x00c3, 0x2037: 0x00c3, 0x2038: 0x00c3, 0x2039: 0x00c3, 0x203a: 0x00c3, 0x203b: 0x00c3, + 0x203c: 0x00c3, 0x203d: 0x00c3, 0x203e: 0x00c3, 0x203f: 0x00c3, + // Block 0x81, offset 0x2040 + 0x2040: 0x0080, 0x2041: 0x0080, 0x2042: 0x0080, 0x2043: 0x0080, 0x2044: 0x0080, 0x2045: 0x0080, + 0x2046: 0x0080, 0x2047: 0x0080, 0x2048: 0x0080, 0x2049: 0x0080, 0x204a: 0x0080, 0x204b: 0x0080, + 0x204c: 0x0080, 0x204d: 0x0080, 0x204e: 0x0080, 0x204f: 0x0080, 0x2050: 0x0080, 0x2051: 0x0080, + 0x2052: 0x0080, 0x2053: 0x0080, 0x2054: 0x0080, 0x2055: 0x0080, 0x2056: 0x0080, 0x2057: 0x0080, + 0x2058: 0x0080, 0x2059: 0x0080, 0x205a: 0x0080, 0x205b: 0x0080, 0x205c: 0x0080, 0x205d: 0x0080, + 0x205e: 0x0080, 0x205f: 0x0080, 0x2060: 0x0080, 0x2061: 0x0080, 0x2062: 0x0080, 0x2063: 0x0080, + 0x2064: 0x0080, 0x2065: 0x0080, 0x2066: 0x0080, 0x2067: 0x0080, 0x2068: 0x0080, 0x2069: 0x0080, + 0x206a: 0x0080, 0x206b: 0x0080, 0x206c: 0x0080, 0x206d: 0x0080, 0x206e: 0x0080, 0x206f: 0x00c0, + 0x2070: 0x0080, 0x2071: 0x0080, 0x2072: 0x0080, 0x2073: 0x0080, 0x2074: 0x0080, 0x2075: 0x0080, + 0x2076: 0x0080, 0x2077: 0x0080, 0x2078: 0x0080, 0x2079: 0x0080, 0x207a: 0x0080, 0x207b: 0x0080, + 0x207c: 0x0080, 0x207d: 0x0080, 0x207e: 0x0080, 0x207f: 0x0080, + // Block 0x82, offset 0x2080 + 0x2080: 0x0080, 0x2081: 0x0080, 0x2082: 0x0080, 0x2083: 0x0080, 0x2084: 0x0080, + // Block 0x83, offset 0x20c0 + 0x20c0: 0x008c, 0x20c1: 0x008c, 0x20c2: 0x008c, 0x20c3: 0x008c, 0x20c4: 0x008c, 0x20c5: 0x008c, + 0x20c6: 0x008c, 0x20c7: 0x008c, 0x20c8: 0x008c, 0x20c9: 0x008c, 0x20ca: 0x008c, 0x20cb: 0x008c, + 0x20cc: 0x008c, 0x20cd: 0x008c, 0x20ce: 0x008c, 0x20cf: 0x008c, 0x20d0: 0x008c, 0x20d1: 0x008c, + 0x20d2: 0x008c, 0x20d3: 0x008c, 0x20d4: 0x008c, 0x20d5: 0x008c, 0x20d6: 0x008c, 0x20d7: 0x008c, + 0x20d8: 0x008c, 0x20d9: 0x008c, 0x20db: 0x008c, 0x20dc: 0x008c, 0x20dd: 0x008c, + 0x20de: 0x008c, 0x20df: 0x008c, 0x20e0: 0x008c, 0x20e1: 0x008c, 0x20e2: 0x008c, 0x20e3: 0x008c, + 0x20e4: 0x008c, 0x20e5: 0x008c, 0x20e6: 0x008c, 0x20e7: 0x008c, 0x20e8: 0x008c, 0x20e9: 0x008c, + 0x20ea: 0x008c, 0x20eb: 0x008c, 0x20ec: 0x008c, 0x20ed: 0x008c, 0x20ee: 0x008c, 0x20ef: 0x008c, + 0x20f0: 0x008c, 0x20f1: 0x008c, 0x20f2: 0x008c, 0x20f3: 0x008c, 0x20f4: 0x008c, 0x20f5: 0x008c, + 0x20f6: 0x008c, 0x20f7: 0x008c, 0x20f8: 0x008c, 0x20f9: 0x008c, 0x20fa: 0x008c, 0x20fb: 0x008c, + 0x20fc: 0x008c, 0x20fd: 0x008c, 0x20fe: 0x008c, 0x20ff: 0x008c, + // Block 0x84, offset 0x2100 + 0x2100: 0x008c, 0x2101: 0x008c, 0x2102: 0x008c, 0x2103: 0x008c, 0x2104: 0x008c, 0x2105: 0x008c, + 0x2106: 0x008c, 0x2107: 0x008c, 0x2108: 0x008c, 0x2109: 0x008c, 0x210a: 0x008c, 0x210b: 0x008c, + 0x210c: 0x008c, 0x210d: 0x008c, 0x210e: 0x008c, 0x210f: 0x008c, 0x2110: 0x008c, 0x2111: 0x008c, + 0x2112: 0x008c, 0x2113: 0x008c, 0x2114: 0x008c, 0x2115: 0x008c, 0x2116: 0x008c, 0x2117: 0x008c, + 0x2118: 0x008c, 0x2119: 0x008c, 0x211a: 0x008c, 0x211b: 0x008c, 0x211c: 0x008c, 0x211d: 0x008c, + 0x211e: 0x008c, 0x211f: 0x008c, 0x2120: 0x008c, 0x2121: 0x008c, 0x2122: 0x008c, 0x2123: 0x008c, + 0x2124: 0x008c, 0x2125: 0x008c, 0x2126: 0x008c, 0x2127: 0x008c, 0x2128: 0x008c, 0x2129: 0x008c, + 0x212a: 0x008c, 0x212b: 0x008c, 0x212c: 0x008c, 0x212d: 0x008c, 0x212e: 0x008c, 0x212f: 0x008c, + 0x2130: 0x008c, 0x2131: 0x008c, 0x2132: 0x008c, 0x2133: 0x008c, + // Block 0x85, offset 0x2140 + 0x2140: 0x008c, 0x2141: 0x008c, 0x2142: 0x008c, 0x2143: 0x008c, 0x2144: 0x008c, 0x2145: 0x008c, + 0x2146: 0x008c, 0x2147: 0x008c, 0x2148: 0x008c, 0x2149: 0x008c, 0x214a: 0x008c, 0x214b: 0x008c, + 0x214c: 0x008c, 0x214d: 0x008c, 0x214e: 0x008c, 0x214f: 0x008c, 0x2150: 0x008c, 0x2151: 0x008c, + 0x2152: 0x008c, 0x2153: 0x008c, 0x2154: 0x008c, 0x2155: 0x008c, 0x2156: 0x008c, 0x2157: 0x008c, + 0x2158: 0x008c, 0x2159: 0x008c, 0x215a: 0x008c, 0x215b: 0x008c, 0x215c: 0x008c, 0x215d: 0x008c, + 0x215e: 0x008c, 0x215f: 0x008c, 0x2160: 0x008c, 0x2161: 0x008c, 0x2162: 0x008c, 0x2163: 0x008c, + 0x2164: 0x008c, 0x2165: 0x008c, 0x2166: 0x008c, 0x2167: 0x008c, 0x2168: 0x008c, 0x2169: 0x008c, + 0x216a: 0x008c, 0x216b: 0x008c, 0x216c: 0x008c, 0x216d: 0x008c, 0x216e: 0x008c, 0x216f: 0x008c, + 0x2170: 0x008c, 0x2171: 0x008c, 0x2172: 0x008c, 0x2173: 0x008c, 0x2174: 0x008c, 0x2175: 0x008c, + 0x2176: 0x008c, 0x2177: 0x008c, 0x2178: 0x008c, 0x2179: 0x008c, 0x217a: 0x008c, 0x217b: 0x008c, + 0x217c: 0x008c, 0x217d: 0x008c, 0x217e: 0x008c, 0x217f: 0x008c, + // Block 0x86, offset 0x2180 + 0x2180: 0x008c, 0x2181: 0x008c, 0x2182: 0x008c, 0x2183: 0x008c, 0x2184: 0x008c, 0x2185: 0x008c, + 0x2186: 0x008c, 0x2187: 0x008c, 0x2188: 0x008c, 0x2189: 0x008c, 0x218a: 0x008c, 0x218b: 0x008c, + 0x218c: 0x008c, 0x218d: 0x008c, 0x218e: 0x008c, 0x218f: 0x008c, 0x2190: 0x008c, 0x2191: 0x008c, + 0x2192: 0x008c, 0x2193: 0x008c, 0x2194: 0x008c, 0x2195: 0x008c, + 0x21b0: 0x0080, 0x21b1: 0x0080, 0x21b2: 0x0080, 0x21b3: 0x0080, 0x21b4: 0x0080, 0x21b5: 0x0080, + 0x21b6: 0x0080, 0x21b7: 0x0080, 0x21b8: 0x0080, 0x21b9: 0x0080, 0x21ba: 0x0080, 0x21bb: 0x0080, + // Block 0x87, offset 0x21c0 + 0x21c0: 0x0080, 0x21c1: 0x0080, 0x21c2: 0x0080, 0x21c3: 0x0080, 0x21c4: 0x0080, 0x21c5: 0x00cc, + 0x21c6: 0x00c0, 0x21c7: 0x00cc, 0x21c8: 0x0080, 0x21c9: 0x0080, 0x21ca: 0x0080, 0x21cb: 0x0080, + 0x21cc: 0x0080, 0x21cd: 0x0080, 0x21ce: 0x0080, 0x21cf: 0x0080, 0x21d0: 0x0080, 0x21d1: 0x0080, + 0x21d2: 0x0080, 0x21d3: 0x0080, 0x21d4: 0x0080, 0x21d5: 0x0080, 0x21d6: 0x0080, 0x21d7: 0x0080, + 0x21d8: 0x0080, 0x21d9: 0x0080, 0x21da: 0x0080, 0x21db: 0x0080, 0x21dc: 0x0080, 0x21dd: 0x0080, + 0x21de: 0x0080, 0x21df: 0x0080, 0x21e0: 0x0080, 0x21e1: 0x008c, 0x21e2: 0x008c, 0x21e3: 0x008c, + 0x21e4: 0x008c, 0x21e5: 0x008c, 0x21e6: 0x008c, 0x21e7: 0x008c, 0x21e8: 0x008c, 0x21e9: 0x008c, + 0x21ea: 0x00c3, 0x21eb: 0x00c3, 0x21ec: 0x00c3, 0x21ed: 0x00c3, 0x21ee: 0x0040, 0x21ef: 0x0040, + 0x21f0: 0x0080, 0x21f1: 0x0040, 0x21f2: 0x0040, 0x21f3: 0x0040, 0x21f4: 0x0040, 0x21f5: 0x0040, + 0x21f6: 0x0080, 0x21f7: 0x0080, 0x21f8: 0x008c, 0x21f9: 0x008c, 0x21fa: 0x008c, 0x21fb: 0x0040, + 0x21fc: 0x00c0, 0x21fd: 0x0080, 0x21fe: 0x0080, 0x21ff: 0x0080, + // Block 0x88, offset 0x2200 + 0x2201: 0x00cc, 0x2202: 0x00cc, 0x2203: 0x00cc, 0x2204: 0x00cc, 0x2205: 0x00cc, + 0x2206: 0x00cc, 0x2207: 0x00cc, 0x2208: 0x00cc, 0x2209: 0x00cc, 0x220a: 0x00cc, 0x220b: 0x00cc, + 0x220c: 0x00cc, 0x220d: 0x00cc, 0x220e: 0x00cc, 0x220f: 0x00cc, 0x2210: 0x00cc, 0x2211: 0x00cc, + 0x2212: 0x00cc, 0x2213: 0x00cc, 0x2214: 0x00cc, 0x2215: 0x00cc, 0x2216: 0x00cc, 0x2217: 0x00cc, + 0x2218: 0x00cc, 0x2219: 0x00cc, 0x221a: 0x00cc, 0x221b: 0x00cc, 0x221c: 0x00cc, 0x221d: 0x00cc, + 0x221e: 0x00cc, 0x221f: 0x00cc, 0x2220: 0x00cc, 0x2221: 0x00cc, 0x2222: 0x00cc, 0x2223: 0x00cc, + 0x2224: 0x00cc, 0x2225: 0x00cc, 0x2226: 0x00cc, 0x2227: 0x00cc, 0x2228: 0x00cc, 0x2229: 0x00cc, + 0x222a: 0x00cc, 0x222b: 0x00cc, 0x222c: 0x00cc, 0x222d: 0x00cc, 0x222e: 0x00cc, 0x222f: 0x00cc, + 0x2230: 0x00cc, 0x2231: 0x00cc, 0x2232: 0x00cc, 0x2233: 0x00cc, 0x2234: 0x00cc, 0x2235: 0x00cc, + 0x2236: 0x00cc, 0x2237: 0x00cc, 0x2238: 0x00cc, 0x2239: 0x00cc, 0x223a: 0x00cc, 0x223b: 0x00cc, + 0x223c: 0x00cc, 0x223d: 0x00cc, 0x223e: 0x00cc, 0x223f: 0x00cc, + // Block 0x89, offset 0x2240 + 0x2240: 0x00cc, 0x2241: 0x00cc, 0x2242: 0x00cc, 0x2243: 0x00cc, 0x2244: 0x00cc, 0x2245: 0x00cc, + 0x2246: 0x00cc, 0x2247: 0x00cc, 0x2248: 0x00cc, 0x2249: 0x00cc, 0x224a: 0x00cc, 0x224b: 0x00cc, + 0x224c: 0x00cc, 0x224d: 0x00cc, 0x224e: 0x00cc, 0x224f: 0x00cc, 0x2250: 0x00cc, 0x2251: 0x00cc, + 0x2252: 0x00cc, 0x2253: 0x00cc, 0x2254: 0x00cc, 0x2255: 0x00cc, 0x2256: 0x00cc, + 0x2259: 0x00c3, 0x225a: 0x00c3, 0x225b: 0x0080, 0x225c: 0x0080, 0x225d: 0x00cc, + 0x225e: 0x00cc, 0x225f: 0x008c, 0x2260: 0x0080, 0x2261: 0x00cc, 0x2262: 0x00cc, 0x2263: 0x00cc, + 0x2264: 0x00cc, 0x2265: 0x00cc, 0x2266: 0x00cc, 0x2267: 0x00cc, 0x2268: 0x00cc, 0x2269: 0x00cc, + 0x226a: 0x00cc, 0x226b: 0x00cc, 0x226c: 0x00cc, 0x226d: 0x00cc, 0x226e: 0x00cc, 0x226f: 0x00cc, + 0x2270: 0x00cc, 0x2271: 0x00cc, 0x2272: 0x00cc, 0x2273: 0x00cc, 0x2274: 0x00cc, 0x2275: 0x00cc, + 0x2276: 0x00cc, 0x2277: 0x00cc, 0x2278: 0x00cc, 0x2279: 0x00cc, 0x227a: 0x00cc, 0x227b: 0x00cc, + 0x227c: 0x00cc, 0x227d: 0x00cc, 0x227e: 0x00cc, 0x227f: 0x00cc, + // Block 0x8a, offset 0x2280 + 0x2280: 0x00cc, 0x2281: 0x00cc, 0x2282: 0x00cc, 0x2283: 0x00cc, 0x2284: 0x00cc, 0x2285: 0x00cc, + 0x2286: 0x00cc, 0x2287: 0x00cc, 0x2288: 0x00cc, 0x2289: 0x00cc, 0x228a: 0x00cc, 0x228b: 0x00cc, + 0x228c: 0x00cc, 0x228d: 0x00cc, 0x228e: 0x00cc, 0x228f: 0x00cc, 0x2290: 0x00cc, 0x2291: 0x00cc, + 0x2292: 0x00cc, 0x2293: 0x00cc, 0x2294: 0x00cc, 0x2295: 0x00cc, 0x2296: 0x00cc, 0x2297: 0x00cc, + 0x2298: 0x00cc, 0x2299: 0x00cc, 0x229a: 0x00cc, 0x229b: 0x00cc, 0x229c: 0x00cc, 0x229d: 0x00cc, + 0x229e: 0x00cc, 0x229f: 0x00cc, 0x22a0: 0x00cc, 0x22a1: 0x00cc, 0x22a2: 0x00cc, 0x22a3: 0x00cc, + 0x22a4: 0x00cc, 0x22a5: 0x00cc, 0x22a6: 0x00cc, 0x22a7: 0x00cc, 0x22a8: 0x00cc, 0x22a9: 0x00cc, + 0x22aa: 0x00cc, 0x22ab: 0x00cc, 0x22ac: 0x00cc, 0x22ad: 0x00cc, 0x22ae: 0x00cc, 0x22af: 0x00cc, + 0x22b0: 0x00cc, 0x22b1: 0x00cc, 0x22b2: 0x00cc, 0x22b3: 0x00cc, 0x22b4: 0x00cc, 0x22b5: 0x00cc, + 0x22b6: 0x00cc, 0x22b7: 0x00cc, 0x22b8: 0x00cc, 0x22b9: 0x00cc, 0x22ba: 0x00cc, 0x22bb: 0x00d2, + 0x22bc: 0x00c0, 0x22bd: 0x00cc, 0x22be: 0x00cc, 0x22bf: 0x008c, + // Block 0x8b, offset 0x22c0 + 0x22c5: 0x00c0, + 0x22c6: 0x00c0, 0x22c7: 0x00c0, 0x22c8: 0x00c0, 0x22c9: 0x00c0, 0x22ca: 0x00c0, 0x22cb: 0x00c0, + 0x22cc: 0x00c0, 0x22cd: 0x00c0, 0x22ce: 0x00c0, 0x22cf: 0x00c0, 0x22d0: 0x00c0, 0x22d1: 0x00c0, + 0x22d2: 0x00c0, 0x22d3: 0x00c0, 0x22d4: 0x00c0, 0x22d5: 0x00c0, 0x22d6: 0x00c0, 0x22d7: 0x00c0, + 0x22d8: 0x00c0, 0x22d9: 0x00c0, 0x22da: 0x00c0, 0x22db: 0x00c0, 0x22dc: 0x00c0, 0x22dd: 0x00c0, + 0x22de: 0x00c0, 0x22df: 0x00c0, 0x22e0: 0x00c0, 0x22e1: 0x00c0, 0x22e2: 0x00c0, 0x22e3: 0x00c0, + 0x22e4: 0x00c0, 0x22e5: 0x00c0, 0x22e6: 0x00c0, 0x22e7: 0x00c0, 0x22e8: 0x00c0, 0x22e9: 0x00c0, + 0x22ea: 0x00c0, 0x22eb: 0x00c0, 0x22ec: 0x00c0, 0x22ed: 0x00c0, + 0x22f1: 0x0080, 0x22f2: 0x0080, 0x22f3: 0x0080, 0x22f4: 0x0080, 0x22f5: 0x0080, + 0x22f6: 0x0080, 0x22f7: 0x0080, 0x22f8: 0x0080, 0x22f9: 0x0080, 0x22fa: 0x0080, 0x22fb: 0x0080, + 0x22fc: 0x0080, 0x22fd: 0x0080, 0x22fe: 0x0080, 0x22ff: 0x0080, + // Block 0x8c, offset 0x2300 + 0x2300: 0x0080, 0x2301: 0x0080, 0x2302: 0x0080, 0x2303: 0x0080, 0x2304: 0x0080, 0x2305: 0x0080, + 0x2306: 0x0080, 0x2307: 0x0080, 0x2308: 0x0080, 0x2309: 0x0080, 0x230a: 0x0080, 0x230b: 0x0080, + 0x230c: 0x0080, 0x230d: 0x0080, 0x230e: 0x0080, 0x230f: 0x0080, 0x2310: 0x0080, 0x2311: 0x0080, + 0x2312: 0x0080, 0x2313: 0x0080, 0x2314: 0x0080, 0x2315: 0x0080, 0x2316: 0x0080, 0x2317: 0x0080, + 0x2318: 0x0080, 0x2319: 0x0080, 0x231a: 0x0080, 0x231b: 0x0080, 0x231c: 0x0080, 0x231d: 0x0080, + 0x231e: 0x0080, 0x231f: 0x0080, 0x2320: 0x0080, 0x2321: 0x0080, 0x2322: 0x0080, 0x2323: 0x0080, + 0x2324: 0x0040, 0x2325: 0x0080, 0x2326: 0x0080, 0x2327: 0x0080, 0x2328: 0x0080, 0x2329: 0x0080, + 0x232a: 0x0080, 0x232b: 0x0080, 0x232c: 0x0080, 0x232d: 0x0080, 0x232e: 0x0080, 0x232f: 0x0080, + 0x2330: 0x0080, 0x2331: 0x0080, 0x2332: 0x0080, 0x2333: 0x0080, 0x2334: 0x0080, 0x2335: 0x0080, + 0x2336: 0x0080, 0x2337: 0x0080, 0x2338: 0x0080, 0x2339: 0x0080, 0x233a: 0x0080, 0x233b: 0x0080, + 0x233c: 0x0080, 0x233d: 0x0080, 0x233e: 0x0080, 0x233f: 0x0080, + // Block 0x8d, offset 0x2340 + 0x2340: 0x0080, 0x2341: 0x0080, 0x2342: 0x0080, 0x2343: 0x0080, 0x2344: 0x0080, 0x2345: 0x0080, + 0x2346: 0x0080, 0x2347: 0x0080, 0x2348: 0x0080, 0x2349: 0x0080, 0x234a: 0x0080, 0x234b: 0x0080, + 0x234c: 0x0080, 0x234d: 0x0080, 0x234e: 0x0080, 0x2350: 0x0080, 0x2351: 0x0080, + 0x2352: 0x0080, 0x2353: 0x0080, 0x2354: 0x0080, 0x2355: 0x0080, 0x2356: 0x0080, 0x2357: 0x0080, + 0x2358: 0x0080, 0x2359: 0x0080, 0x235a: 0x0080, 0x235b: 0x0080, 0x235c: 0x0080, 0x235d: 0x0080, + 0x235e: 0x0080, 0x235f: 0x0080, 0x2360: 0x00c0, 0x2361: 0x00c0, 0x2362: 0x00c0, 0x2363: 0x00c0, + 0x2364: 0x00c0, 0x2365: 0x00c0, 0x2366: 0x00c0, 0x2367: 0x00c0, 0x2368: 0x00c0, 0x2369: 0x00c0, + 0x236a: 0x00c0, 0x236b: 0x00c0, 0x236c: 0x00c0, 0x236d: 0x00c0, 0x236e: 0x00c0, 0x236f: 0x00c0, + 0x2370: 0x00c0, 0x2371: 0x00c0, 0x2372: 0x00c0, 0x2373: 0x00c0, 0x2374: 0x00c0, 0x2375: 0x00c0, + 0x2376: 0x00c0, 0x2377: 0x00c0, 0x2378: 0x00c0, 0x2379: 0x00c0, 0x237a: 0x00c0, + // Block 0x8e, offset 0x2380 + 0x2380: 0x0080, 0x2381: 0x0080, 0x2382: 0x0080, 0x2383: 0x0080, 0x2384: 0x0080, 0x2385: 0x0080, + 0x2386: 0x0080, 0x2387: 0x0080, 0x2388: 0x0080, 0x2389: 0x0080, 0x238a: 0x0080, 0x238b: 0x0080, + 0x238c: 0x0080, 0x238d: 0x0080, 0x238e: 0x0080, 0x238f: 0x0080, 0x2390: 0x0080, 0x2391: 0x0080, + 0x2392: 0x0080, 0x2393: 0x0080, 0x2394: 0x0080, 0x2395: 0x0080, 0x2396: 0x0080, 0x2397: 0x0080, + 0x2398: 0x0080, 0x2399: 0x0080, 0x239a: 0x0080, 0x239b: 0x0080, 0x239c: 0x0080, 0x239d: 0x0080, + 0x239e: 0x0080, 0x239f: 0x0080, 0x23a0: 0x0080, 0x23a1: 0x0080, 0x23a2: 0x0080, 0x23a3: 0x0080, + 0x23b0: 0x00cc, 0x23b1: 0x00cc, 0x23b2: 0x00cc, 0x23b3: 0x00cc, 0x23b4: 0x00cc, 0x23b5: 0x00cc, + 0x23b6: 0x00cc, 0x23b7: 0x00cc, 0x23b8: 0x00cc, 0x23b9: 0x00cc, 0x23ba: 0x00cc, 0x23bb: 0x00cc, + 0x23bc: 0x00cc, 0x23bd: 0x00cc, 0x23be: 0x00cc, 0x23bf: 0x00cc, + // Block 0x8f, offset 0x23c0 + 0x23c0: 0x0080, 0x23c1: 0x0080, 0x23c2: 0x0080, 0x23c3: 0x0080, 0x23c4: 0x0080, 0x23c5: 0x0080, + 0x23c6: 0x0080, 0x23c7: 0x0080, 0x23c8: 0x0080, 0x23c9: 0x0080, 0x23ca: 0x0080, 0x23cb: 0x0080, + 0x23cc: 0x0080, 0x23cd: 0x0080, 0x23ce: 0x0080, 0x23cf: 0x0080, 0x23d0: 0x0080, 0x23d1: 0x0080, + 0x23d2: 0x0080, 0x23d3: 0x0080, 0x23d4: 0x0080, 0x23d5: 0x0080, 0x23d6: 0x0080, 0x23d7: 0x0080, + 0x23d8: 0x0080, 0x23d9: 0x0080, 0x23da: 0x0080, 0x23db: 0x0080, 0x23dc: 0x0080, 0x23dd: 0x0080, + 0x23de: 0x0080, 0x23e0: 0x0080, 0x23e1: 0x0080, 0x23e2: 0x0080, 0x23e3: 0x0080, + 0x23e4: 0x0080, 0x23e5: 0x0080, 0x23e6: 0x0080, 0x23e7: 0x0080, 0x23e8: 0x0080, 0x23e9: 0x0080, + 0x23ea: 0x0080, 0x23eb: 0x0080, 0x23ec: 0x0080, 0x23ed: 0x0080, 0x23ee: 0x0080, 0x23ef: 0x0080, + 0x23f0: 0x0080, 0x23f1: 0x0080, 0x23f2: 0x0080, 0x23f3: 0x0080, 0x23f4: 0x0080, 0x23f5: 0x0080, + 0x23f6: 0x0080, 0x23f7: 0x0080, 0x23f8: 0x0080, 0x23f9: 0x0080, 0x23fa: 0x0080, 0x23fb: 0x0080, + 0x23fc: 0x0080, 0x23fd: 0x0080, 0x23fe: 0x0080, 0x23ff: 0x0080, + // Block 0x90, offset 0x2400 + 0x2400: 0x0080, 0x2401: 0x0080, 0x2402: 0x0080, 0x2403: 0x0080, 0x2404: 0x0080, 0x2405: 0x0080, + 0x2406: 0x0080, 0x2407: 0x0080, 0x2408: 0x0080, 0x2409: 0x0080, 0x240a: 0x0080, 0x240b: 0x0080, + 0x240c: 0x0080, 0x240d: 0x0080, 0x240e: 0x0080, 0x240f: 0x0080, 0x2410: 0x008c, 0x2411: 0x008c, + 0x2412: 0x008c, 0x2413: 0x008c, 0x2414: 0x008c, 0x2415: 0x008c, 0x2416: 0x008c, 0x2417: 0x008c, + 0x2418: 0x008c, 0x2419: 0x008c, 0x241a: 0x008c, 0x241b: 0x008c, 0x241c: 0x008c, 0x241d: 0x008c, + 0x241e: 0x008c, 0x241f: 0x008c, 0x2420: 0x008c, 0x2421: 0x008c, 0x2422: 0x008c, 0x2423: 0x008c, + 0x2424: 0x008c, 0x2425: 0x008c, 0x2426: 0x008c, 0x2427: 0x008c, 0x2428: 0x008c, 0x2429: 0x008c, + 0x242a: 0x008c, 0x242b: 0x008c, 0x242c: 0x008c, 0x242d: 0x008c, 0x242e: 0x008c, 0x242f: 0x008c, + 0x2430: 0x008c, 0x2431: 0x008c, 0x2432: 0x008c, 0x2433: 0x008c, 0x2434: 0x008c, 0x2435: 0x008c, + 0x2436: 0x008c, 0x2437: 0x008c, 0x2438: 0x008c, 0x2439: 0x008c, 0x243a: 0x008c, 0x243b: 0x008c, + 0x243c: 0x008c, 0x243d: 0x008c, 0x243e: 0x008c, + // Block 0x91, offset 0x2440 + 0x2440: 0x008c, 0x2441: 0x008c, 0x2442: 0x008c, 0x2443: 0x008c, 0x2444: 0x008c, 0x2445: 0x008c, + 0x2446: 0x008c, 0x2447: 0x008c, 0x2448: 0x008c, 0x2449: 0x008c, 0x244a: 0x008c, 0x244b: 0x008c, + 0x244c: 0x008c, 0x244d: 0x008c, 0x244e: 0x008c, 0x244f: 0x008c, 0x2450: 0x008c, 0x2451: 0x008c, + 0x2452: 0x008c, 0x2453: 0x008c, 0x2454: 0x008c, 0x2455: 0x008c, 0x2456: 0x008c, 0x2457: 0x008c, + 0x2458: 0x0080, 0x2459: 0x0080, 0x245a: 0x0080, 0x245b: 0x0080, 0x245c: 0x0080, 0x245d: 0x0080, + 0x245e: 0x0080, 0x245f: 0x0080, 0x2460: 0x0080, 0x2461: 0x0080, 0x2462: 0x0080, 0x2463: 0x0080, + 0x2464: 0x0080, 0x2465: 0x0080, 0x2466: 0x0080, 0x2467: 0x0080, 0x2468: 0x0080, 0x2469: 0x0080, + 0x246a: 0x0080, 0x246b: 0x0080, 0x246c: 0x0080, 0x246d: 0x0080, 0x246e: 0x0080, 0x246f: 0x0080, + 0x2470: 0x0080, 0x2471: 0x0080, 0x2472: 0x0080, 0x2473: 0x0080, 0x2474: 0x0080, 0x2475: 0x0080, + 0x2476: 0x0080, 0x2477: 0x0080, 0x2478: 0x0080, 0x2479: 0x0080, 0x247a: 0x0080, 0x247b: 0x0080, + 0x247c: 0x0080, 0x247d: 0x0080, 0x247e: 0x0080, 0x247f: 0x0080, + // Block 0x92, offset 0x2480 + 0x2480: 0x00cc, 0x2481: 0x00cc, 0x2482: 0x00cc, 0x2483: 0x00cc, 0x2484: 0x00cc, 0x2485: 0x00cc, + 0x2486: 0x00cc, 0x2487: 0x00cc, 0x2488: 0x00cc, 0x2489: 0x00cc, 0x248a: 0x00cc, 0x248b: 0x00cc, + 0x248c: 0x00cc, 0x248d: 0x00cc, 0x248e: 0x00cc, 0x248f: 0x00cc, 0x2490: 0x00cc, 0x2491: 0x00cc, + 0x2492: 0x00cc, 0x2493: 0x00cc, 0x2494: 0x00cc, 0x2495: 0x00cc, 0x2496: 0x00cc, 0x2497: 0x00cc, + 0x2498: 0x00cc, 0x2499: 0x00cc, 0x249a: 0x00cc, 0x249b: 0x00cc, 0x249c: 0x00cc, 0x249d: 0x00cc, + 0x249e: 0x00cc, 0x249f: 0x00cc, 0x24a0: 0x00cc, 0x24a1: 0x00cc, 0x24a2: 0x00cc, 0x24a3: 0x00cc, + 0x24a4: 0x00cc, 0x24a5: 0x00cc, 0x24a6: 0x00cc, 0x24a7: 0x00cc, 0x24a8: 0x00cc, 0x24a9: 0x00cc, + 0x24aa: 0x00cc, 0x24ab: 0x00cc, 0x24ac: 0x00cc, 0x24ad: 0x00cc, 0x24ae: 0x00cc, 0x24af: 0x00cc, + 0x24b0: 0x00cc, 0x24b1: 0x00cc, 0x24b2: 0x00cc, 0x24b3: 0x00cc, 0x24b4: 0x00cc, 0x24b5: 0x00cc, + 0x24b6: 0x00cc, 0x24b7: 0x00cc, 0x24b8: 0x00cc, 0x24b9: 0x00cc, 0x24ba: 0x00cc, 0x24bb: 0x00cc, + 0x24bc: 0x00cc, 0x24bd: 0x00cc, 0x24be: 0x00cc, 0x24bf: 0x00cc, + // Block 0x93, offset 0x24c0 + 0x24c0: 0x00cc, 0x24c1: 0x00cc, 0x24c2: 0x00cc, 0x24c3: 0x00cc, 0x24c4: 0x00cc, 0x24c5: 0x00cc, + 0x24c6: 0x00cc, 0x24c7: 0x00cc, 0x24c8: 0x00cc, 0x24c9: 0x00cc, 0x24ca: 0x00cc, 0x24cb: 0x00cc, + 0x24cc: 0x00cc, 0x24cd: 0x00cc, 0x24ce: 0x00cc, 0x24cf: 0x00cc, 0x24d0: 0x00cc, 0x24d1: 0x00cc, + 0x24d2: 0x00cc, 0x24d3: 0x00cc, 0x24d4: 0x00cc, 0x24d5: 0x00cc, 0x24d6: 0x00cc, 0x24d7: 0x00cc, + 0x24d8: 0x00cc, 0x24d9: 0x00cc, 0x24da: 0x00cc, 0x24db: 0x00cc, 0x24dc: 0x00cc, 0x24dd: 0x00cc, + 0x24de: 0x00cc, 0x24df: 0x00cc, 0x24e0: 0x00cc, 0x24e1: 0x00cc, 0x24e2: 0x00cc, 0x24e3: 0x00cc, + 0x24e4: 0x00cc, 0x24e5: 0x00cc, 0x24e6: 0x00cc, 0x24e7: 0x00cc, 0x24e8: 0x00cc, 0x24e9: 0x00cc, + 0x24ea: 0x00cc, 0x24eb: 0x00cc, 0x24ec: 0x00cc, 0x24ed: 0x00cc, 0x24ee: 0x00cc, 0x24ef: 0x00cc, + 0x24f0: 0x00cc, 0x24f1: 0x00cc, 0x24f2: 0x00cc, 0x24f3: 0x00cc, 0x24f4: 0x00cc, 0x24f5: 0x00cc, + // Block 0x94, offset 0x2500 + 0x2500: 0x00cc, 0x2501: 0x00cc, 0x2502: 0x00cc, 0x2503: 0x00cc, 0x2504: 0x00cc, 0x2505: 0x00cc, + 0x2506: 0x00cc, 0x2507: 0x00cc, 0x2508: 0x00cc, 0x2509: 0x00cc, 0x250a: 0x00cc, 0x250b: 0x00cc, + 0x250c: 0x00cc, 0x250d: 0x00cc, 0x250e: 0x00cc, 0x250f: 0x00cc, 0x2510: 0x00cc, 0x2511: 0x00cc, + 0x2512: 0x00cc, 0x2513: 0x00cc, 0x2514: 0x00cc, 0x2515: 0x00cc, + // Block 0x95, offset 0x2540 + 0x2540: 0x00c0, 0x2541: 0x00c0, 0x2542: 0x00c0, 0x2543: 0x00c0, 0x2544: 0x00c0, 0x2545: 0x00c0, + 0x2546: 0x00c0, 0x2547: 0x00c0, 0x2548: 0x00c0, 0x2549: 0x00c0, 0x254a: 0x00c0, 0x254b: 0x00c0, + 0x254c: 0x00c0, 0x2550: 0x0080, 0x2551: 0x0080, + 0x2552: 0x0080, 0x2553: 0x0080, 0x2554: 0x0080, 0x2555: 0x0080, 0x2556: 0x0080, 0x2557: 0x0080, + 0x2558: 0x0080, 0x2559: 0x0080, 0x255a: 0x0080, 0x255b: 0x0080, 0x255c: 0x0080, 0x255d: 0x0080, + 0x255e: 0x0080, 0x255f: 0x0080, 0x2560: 0x0080, 0x2561: 0x0080, 0x2562: 0x0080, 0x2563: 0x0080, + 0x2564: 0x0080, 0x2565: 0x0080, 0x2566: 0x0080, 0x2567: 0x0080, 0x2568: 0x0080, 0x2569: 0x0080, + 0x256a: 0x0080, 0x256b: 0x0080, 0x256c: 0x0080, 0x256d: 0x0080, 0x256e: 0x0080, 0x256f: 0x0080, + 0x2570: 0x0080, 0x2571: 0x0080, 0x2572: 0x0080, 0x2573: 0x0080, 0x2574: 0x0080, 0x2575: 0x0080, + 0x2576: 0x0080, 0x2577: 0x0080, 0x2578: 0x0080, 0x2579: 0x0080, 0x257a: 0x0080, 0x257b: 0x0080, + 0x257c: 0x0080, 0x257d: 0x0080, 0x257e: 0x0080, 0x257f: 0x0080, + // Block 0x96, offset 0x2580 + 0x2580: 0x0080, 0x2581: 0x0080, 0x2582: 0x0080, 0x2583: 0x0080, 0x2584: 0x0080, 0x2585: 0x0080, + 0x2586: 0x0080, + 0x2590: 0x00c0, 0x2591: 0x00c0, + 0x2592: 0x00c0, 0x2593: 0x00c0, 0x2594: 0x00c0, 0x2595: 0x00c0, 0x2596: 0x00c0, 0x2597: 0x00c0, + 0x2598: 0x00c0, 0x2599: 0x00c0, 0x259a: 0x00c0, 0x259b: 0x00c0, 0x259c: 0x00c0, 0x259d: 0x00c0, + 0x259e: 0x00c0, 0x259f: 0x00c0, 0x25a0: 0x00c0, 0x25a1: 0x00c0, 0x25a2: 0x00c0, 0x25a3: 0x00c0, + 0x25a4: 0x00c0, 0x25a5: 0x00c0, 0x25a6: 0x00c0, 0x25a7: 0x00c0, 0x25a8: 0x00c0, 0x25a9: 0x00c0, + 0x25aa: 0x00c0, 0x25ab: 0x00c0, 0x25ac: 0x00c0, 0x25ad: 0x00c0, 0x25ae: 0x00c0, 0x25af: 0x00c0, + 0x25b0: 0x00c0, 0x25b1: 0x00c0, 0x25b2: 0x00c0, 0x25b3: 0x00c0, 0x25b4: 0x00c0, 0x25b5: 0x00c0, + 0x25b6: 0x00c0, 0x25b7: 0x00c0, 0x25b8: 0x00c0, 0x25b9: 0x00c0, 0x25ba: 0x00c0, 0x25bb: 0x00c0, + 0x25bc: 0x00c0, 0x25bd: 0x00c0, 0x25be: 0x0080, 0x25bf: 0x0080, + // Block 0x97, offset 0x25c0 + 0x25c0: 0x00c0, 0x25c1: 0x00c0, 0x25c2: 0x00c0, 0x25c3: 0x00c0, 0x25c4: 0x00c0, 0x25c5: 0x00c0, + 0x25c6: 0x00c0, 0x25c7: 0x00c0, 0x25c8: 0x00c0, 0x25c9: 0x00c0, 0x25ca: 0x00c0, 0x25cb: 0x00c0, + 0x25cc: 0x00c0, 0x25cd: 0x0080, 0x25ce: 0x0080, 0x25cf: 0x0080, 0x25d0: 0x00c0, 0x25d1: 0x00c0, + 0x25d2: 0x00c0, 0x25d3: 0x00c0, 0x25d4: 0x00c0, 0x25d5: 0x00c0, 0x25d6: 0x00c0, 0x25d7: 0x00c0, + 0x25d8: 0x00c0, 0x25d9: 0x00c0, 0x25da: 0x00c0, 0x25db: 0x00c0, 0x25dc: 0x00c0, 0x25dd: 0x00c0, + 0x25de: 0x00c0, 0x25df: 0x00c0, 0x25e0: 0x00c0, 0x25e1: 0x00c0, 0x25e2: 0x00c0, 0x25e3: 0x00c0, + 0x25e4: 0x00c0, 0x25e5: 0x00c0, 0x25e6: 0x00c0, 0x25e7: 0x00c0, 0x25e8: 0x00c0, 0x25e9: 0x00c0, + 0x25ea: 0x00c0, 0x25eb: 0x00c0, + // Block 0x98, offset 0x2600 + 0x2600: 0x00c0, 0x2601: 0x00c0, 0x2602: 0x00c0, 0x2603: 0x00c0, 0x2604: 0x00c0, 0x2605: 0x00c0, + 0x2606: 0x00c0, 0x2607: 0x00c0, 0x2608: 0x00c0, 0x2609: 0x00c0, 0x260a: 0x00c0, 0x260b: 0x00c0, + 0x260c: 0x00c0, 0x260d: 0x00c0, 0x260e: 0x00c0, 0x260f: 0x00c0, 0x2610: 0x00c0, 0x2611: 0x00c0, + 0x2612: 0x00c0, 0x2613: 0x00c0, 0x2614: 0x00c0, 0x2615: 0x00c0, 0x2616: 0x00c0, 0x2617: 0x00c0, + 0x2618: 0x00c0, 0x2619: 0x00c0, 0x261a: 0x00c0, 0x261b: 0x00c0, 0x261c: 0x00c0, 0x261d: 0x00c0, + 0x261e: 0x00c0, 0x261f: 0x00c0, 0x2620: 0x00c0, 0x2621: 0x00c0, 0x2622: 0x00c0, 0x2623: 0x00c0, + 0x2624: 0x00c0, 0x2625: 0x00c0, 0x2626: 0x00c0, 0x2627: 0x00c0, 0x2628: 0x00c0, 0x2629: 0x00c0, + 0x262a: 0x00c0, 0x262b: 0x00c0, 0x262c: 0x00c0, 0x262d: 0x00c0, 0x262e: 0x00c0, 0x262f: 0x00c3, + 0x2630: 0x0083, 0x2631: 0x0083, 0x2632: 0x0083, 0x2633: 0x0080, 0x2634: 0x00c3, 0x2635: 0x00c3, + 0x2636: 0x00c3, 0x2637: 0x00c3, 0x2638: 0x00c3, 0x2639: 0x00c3, 0x263a: 0x00c3, 0x263b: 0x00c3, + 0x263c: 0x00c3, 0x263d: 0x00c3, 0x263e: 0x0080, 0x263f: 0x00c0, + // Block 0x99, offset 0x2640 + 0x2640: 0x00c0, 0x2641: 0x00c0, 0x2642: 0x00c0, 0x2643: 0x00c0, 0x2644: 0x00c0, 0x2645: 0x00c0, + 0x2646: 0x00c0, 0x2647: 0x00c0, 0x2648: 0x00c0, 0x2649: 0x00c0, 0x264a: 0x00c0, 0x264b: 0x00c0, + 0x264c: 0x00c0, 0x264d: 0x00c0, 0x264e: 0x00c0, 0x264f: 0x00c0, 0x2650: 0x00c0, 0x2651: 0x00c0, + 0x2652: 0x00c0, 0x2653: 0x00c0, 0x2654: 0x00c0, 0x2655: 0x00c0, 0x2656: 0x00c0, 0x2657: 0x00c0, + 0x2658: 0x00c0, 0x2659: 0x00c0, 0x265a: 0x00c0, 0x265b: 0x00c0, 0x265c: 0x0080, 0x265d: 0x0080, + 0x265e: 0x00c3, 0x265f: 0x00c3, 0x2660: 0x00c0, 0x2661: 0x00c0, 0x2662: 0x00c0, 0x2663: 0x00c0, + 0x2664: 0x00c0, 0x2665: 0x00c0, 0x2666: 0x00c0, 0x2667: 0x00c0, 0x2668: 0x00c0, 0x2669: 0x00c0, + 0x266a: 0x00c0, 0x266b: 0x00c0, 0x266c: 0x00c0, 0x266d: 0x00c0, 0x266e: 0x00c0, 0x266f: 0x00c0, + 0x2670: 0x00c0, 0x2671: 0x00c0, 0x2672: 0x00c0, 0x2673: 0x00c0, 0x2674: 0x00c0, 0x2675: 0x00c0, + 0x2676: 0x00c0, 0x2677: 0x00c0, 0x2678: 0x00c0, 0x2679: 0x00c0, 0x267a: 0x00c0, 0x267b: 0x00c0, + 0x267c: 0x00c0, 0x267d: 0x00c0, 0x267e: 0x00c0, 0x267f: 0x00c0, + // Block 0x9a, offset 0x2680 + 0x2680: 0x00c0, 0x2681: 0x00c0, 0x2682: 0x00c0, 0x2683: 0x00c0, 0x2684: 0x00c0, 0x2685: 0x00c0, + 0x2686: 0x00c0, 0x2687: 0x00c0, 0x2688: 0x00c0, 0x2689: 0x00c0, 0x268a: 0x00c0, 0x268b: 0x00c0, + 0x268c: 0x00c0, 0x268d: 0x00c0, 0x268e: 0x00c0, 0x268f: 0x00c0, 0x2690: 0x00c0, 0x2691: 0x00c0, + 0x2692: 0x00c0, 0x2693: 0x00c0, 0x2694: 0x00c0, 0x2695: 0x00c0, 0x2696: 0x00c0, 0x2697: 0x00c0, + 0x2698: 0x00c0, 0x2699: 0x00c0, 0x269a: 0x00c0, 0x269b: 0x00c0, 0x269c: 0x00c0, 0x269d: 0x00c0, + 0x269e: 0x00c0, 0x269f: 0x00c0, 0x26a0: 0x00c0, 0x26a1: 0x00c0, 0x26a2: 0x00c0, 0x26a3: 0x00c0, + 0x26a4: 0x00c0, 0x26a5: 0x00c0, 0x26a6: 0x0080, 0x26a7: 0x0080, 0x26a8: 0x0080, 0x26a9: 0x0080, + 0x26aa: 0x0080, 0x26ab: 0x0080, 0x26ac: 0x0080, 0x26ad: 0x0080, 0x26ae: 0x0080, 0x26af: 0x0080, + 0x26b0: 0x00c3, 0x26b1: 0x00c3, 0x26b2: 0x0080, 0x26b3: 0x0080, 0x26b4: 0x0080, 0x26b5: 0x0080, + 0x26b6: 0x0080, 0x26b7: 0x0080, + // Block 0x9b, offset 0x26c0 + 0x26c0: 0x0080, 0x26c1: 0x0080, 0x26c2: 0x0080, 0x26c3: 0x0080, 0x26c4: 0x0080, 0x26c5: 0x0080, + 0x26c6: 0x0080, 0x26c7: 0x0080, 0x26c8: 0x0080, 0x26c9: 0x0080, 0x26ca: 0x0080, 0x26cb: 0x0080, + 0x26cc: 0x0080, 0x26cd: 0x0080, 0x26ce: 0x0080, 0x26cf: 0x0080, 0x26d0: 0x0080, 0x26d1: 0x0080, + 0x26d2: 0x0080, 0x26d3: 0x0080, 0x26d4: 0x0080, 0x26d5: 0x0080, 0x26d6: 0x0080, 0x26d7: 0x00c0, + 0x26d8: 0x00c0, 0x26d9: 0x00c0, 0x26da: 0x00c0, 0x26db: 0x00c0, 0x26dc: 0x00c0, 0x26dd: 0x00c0, + 0x26de: 0x00c0, 0x26df: 0x00c0, 0x26e0: 0x0080, 0x26e1: 0x0080, 0x26e2: 0x00c0, 0x26e3: 0x00c0, + 0x26e4: 0x00c0, 0x26e5: 0x00c0, 0x26e6: 0x00c0, 0x26e7: 0x00c0, 0x26e8: 0x00c0, 0x26e9: 0x00c0, + 0x26ea: 0x00c0, 0x26eb: 0x00c0, 0x26ec: 0x00c0, 0x26ed: 0x00c0, 0x26ee: 0x00c0, 0x26ef: 0x00c0, + 0x26f0: 0x00c0, 0x26f1: 0x00c0, 0x26f2: 0x00c0, 0x26f3: 0x00c0, 0x26f4: 0x00c0, 0x26f5: 0x00c0, + 0x26f6: 0x00c0, 0x26f7: 0x00c0, 0x26f8: 0x00c0, 0x26f9: 0x00c0, 0x26fa: 0x00c0, 0x26fb: 0x00c0, + 0x26fc: 0x00c0, 0x26fd: 0x00c0, 0x26fe: 0x00c0, 0x26ff: 0x00c0, + // Block 0x9c, offset 0x2700 + 0x2700: 0x00c0, 0x2701: 0x00c0, 0x2702: 0x00c0, 0x2703: 0x00c0, 0x2704: 0x00c0, 0x2705: 0x00c0, + 0x2706: 0x00c0, 0x2707: 0x00c0, 0x2708: 0x00c0, 0x2709: 0x00c0, 0x270a: 0x00c0, 0x270b: 0x00c0, + 0x270c: 0x00c0, 0x270d: 0x00c0, 0x270e: 0x00c0, 0x270f: 0x00c0, 0x2710: 0x00c0, 0x2711: 0x00c0, + 0x2712: 0x00c0, 0x2713: 0x00c0, 0x2714: 0x00c0, 0x2715: 0x00c0, 0x2716: 0x00c0, 0x2717: 0x00c0, + 0x2718: 0x00c0, 0x2719: 0x00c0, 0x271a: 0x00c0, 0x271b: 0x00c0, 0x271c: 0x00c0, 0x271d: 0x00c0, + 0x271e: 0x00c0, 0x271f: 0x00c0, 0x2720: 0x00c0, 0x2721: 0x00c0, 0x2722: 0x00c0, 0x2723: 0x00c0, + 0x2724: 0x00c0, 0x2725: 0x00c0, 0x2726: 0x00c0, 0x2727: 0x00c0, 0x2728: 0x00c0, 0x2729: 0x00c0, + 0x272a: 0x00c0, 0x272b: 0x00c0, 0x272c: 0x00c0, 0x272d: 0x00c0, 0x272e: 0x00c0, 0x272f: 0x00c0, + 0x2730: 0x0080, 0x2731: 0x00c0, 0x2732: 0x00c0, 0x2733: 0x00c0, 0x2734: 0x00c0, 0x2735: 0x00c0, + 0x2736: 0x00c0, 0x2737: 0x00c0, 0x2738: 0x00c0, 0x2739: 0x00c0, 0x273a: 0x00c0, 0x273b: 0x00c0, + 0x273c: 0x00c0, 0x273d: 0x00c0, 0x273e: 0x00c0, 0x273f: 0x00c0, + // Block 0x9d, offset 0x2740 + 0x2740: 0x00c0, 0x2741: 0x00c0, 0x2742: 0x00c0, 0x2743: 0x00c0, 0x2744: 0x00c0, 0x2745: 0x00c0, + 0x2746: 0x00c0, 0x2747: 0x00c0, 0x2748: 0x00c0, 0x2749: 0x0080, 0x274a: 0x0080, 0x274b: 0x00c0, + 0x274c: 0x00c0, 0x274d: 0x00c0, 0x274e: 0x00c0, 0x274f: 0x00c0, 0x2750: 0x00c0, 0x2751: 0x00c0, + 0x2752: 0x00c0, 0x2753: 0x00c0, 0x2754: 0x00c0, 0x2755: 0x00c0, 0x2756: 0x00c0, 0x2757: 0x00c0, + 0x2758: 0x00c0, 0x2759: 0x00c0, 0x275a: 0x00c0, 0x275b: 0x00c0, 0x275c: 0x00c0, 0x275d: 0x00c0, + 0x275e: 0x00c0, 0x275f: 0x00c0, 0x2760: 0x00c0, 0x2761: 0x00c0, 0x2762: 0x00c0, 0x2763: 0x00c0, + 0x2764: 0x00c0, 0x2765: 0x00c0, 0x2766: 0x00c0, 0x2767: 0x00c0, 0x2768: 0x00c0, 0x2769: 0x00c0, + 0x276a: 0x00c0, 0x276b: 0x00c0, 0x276c: 0x00c0, 0x276d: 0x00c0, 0x276e: 0x00c0, + 0x2770: 0x00c0, 0x2771: 0x00c0, 0x2772: 0x00c0, 0x2773: 0x00c0, 0x2774: 0x00c0, 0x2775: 0x00c0, + 0x2776: 0x00c0, 0x2777: 0x00c0, + // Block 0x9e, offset 0x2780 + 0x27b7: 0x00c0, 0x27b8: 0x0080, 0x27b9: 0x0080, 0x27ba: 0x00c0, 0x27bb: 0x00c0, + 0x27bc: 0x00c0, 0x27bd: 0x00c0, 0x27be: 0x00c0, 0x27bf: 0x00c0, + // Block 0x9f, offset 0x27c0 + 0x27c0: 0x00c0, 0x27c1: 0x00c0, 0x27c2: 0x00c3, 0x27c3: 0x00c0, 0x27c4: 0x00c0, 0x27c5: 0x00c0, + 0x27c6: 0x00c6, 0x27c7: 0x00c0, 0x27c8: 0x00c0, 0x27c9: 0x00c0, 0x27ca: 0x00c0, 0x27cb: 0x00c3, + 0x27cc: 0x00c0, 0x27cd: 0x00c0, 0x27ce: 0x00c0, 0x27cf: 0x00c0, 0x27d0: 0x00c0, 0x27d1: 0x00c0, + 0x27d2: 0x00c0, 0x27d3: 0x00c0, 0x27d4: 0x00c0, 0x27d5: 0x00c0, 0x27d6: 0x00c0, 0x27d7: 0x00c0, + 0x27d8: 0x00c0, 0x27d9: 0x00c0, 0x27da: 0x00c0, 0x27db: 0x00c0, 0x27dc: 0x00c0, 0x27dd: 0x00c0, + 0x27de: 0x00c0, 0x27df: 0x00c0, 0x27e0: 0x00c0, 0x27e1: 0x00c0, 0x27e2: 0x00c0, 0x27e3: 0x00c0, + 0x27e4: 0x00c0, 0x27e5: 0x00c3, 0x27e6: 0x00c3, 0x27e7: 0x00c0, 0x27e8: 0x0080, 0x27e9: 0x0080, + 0x27ea: 0x0080, 0x27eb: 0x0080, + 0x27f0: 0x0080, 0x27f1: 0x0080, 0x27f2: 0x0080, 0x27f3: 0x0080, 0x27f4: 0x0080, 0x27f5: 0x0080, + 0x27f6: 0x0080, 0x27f7: 0x0080, 0x27f8: 0x0080, 0x27f9: 0x0080, + // Block 0xa0, offset 0x2800 + 0x2800: 0x00c2, 0x2801: 0x00c2, 0x2802: 0x00c2, 0x2803: 0x00c2, 0x2804: 0x00c2, 0x2805: 0x00c2, + 0x2806: 0x00c2, 0x2807: 0x00c2, 0x2808: 0x00c2, 0x2809: 0x00c2, 0x280a: 0x00c2, 0x280b: 0x00c2, + 0x280c: 0x00c2, 0x280d: 0x00c2, 0x280e: 0x00c2, 0x280f: 0x00c2, 0x2810: 0x00c2, 0x2811: 0x00c2, + 0x2812: 0x00c2, 0x2813: 0x00c2, 0x2814: 0x00c2, 0x2815: 0x00c2, 0x2816: 0x00c2, 0x2817: 0x00c2, + 0x2818: 0x00c2, 0x2819: 0x00c2, 0x281a: 0x00c2, 0x281b: 0x00c2, 0x281c: 0x00c2, 0x281d: 0x00c2, + 0x281e: 0x00c2, 0x281f: 0x00c2, 0x2820: 0x00c2, 0x2821: 0x00c2, 0x2822: 0x00c2, 0x2823: 0x00c2, + 0x2824: 0x00c2, 0x2825: 0x00c2, 0x2826: 0x00c2, 0x2827: 0x00c2, 0x2828: 0x00c2, 0x2829: 0x00c2, + 0x282a: 0x00c2, 0x282b: 0x00c2, 0x282c: 0x00c2, 0x282d: 0x00c2, 0x282e: 0x00c2, 0x282f: 0x00c2, + 0x2830: 0x00c2, 0x2831: 0x00c2, 0x2832: 0x00c1, 0x2833: 0x00c0, 0x2834: 0x0080, 0x2835: 0x0080, + 0x2836: 0x0080, 0x2837: 0x0080, + // Block 0xa1, offset 0x2840 + 0x2840: 0x00c0, 0x2841: 0x00c0, 0x2842: 0x00c0, 0x2843: 0x00c0, 0x2844: 0x00c6, 0x2845: 0x00c3, + 0x284e: 0x0080, 0x284f: 0x0080, 0x2850: 0x00c0, 0x2851: 0x00c0, + 0x2852: 0x00c0, 0x2853: 0x00c0, 0x2854: 0x00c0, 0x2855: 0x00c0, 0x2856: 0x00c0, 0x2857: 0x00c0, + 0x2858: 0x00c0, 0x2859: 0x00c0, + 0x2860: 0x00c3, 0x2861: 0x00c3, 0x2862: 0x00c3, 0x2863: 0x00c3, + 0x2864: 0x00c3, 0x2865: 0x00c3, 0x2866: 0x00c3, 0x2867: 0x00c3, 0x2868: 0x00c3, 0x2869: 0x00c3, + 0x286a: 0x00c3, 0x286b: 0x00c3, 0x286c: 0x00c3, 0x286d: 0x00c3, 0x286e: 0x00c3, 0x286f: 0x00c3, + 0x2870: 0x00c3, 0x2871: 0x00c3, 0x2872: 0x00c0, 0x2873: 0x00c0, 0x2874: 0x00c0, 0x2875: 0x00c0, + 0x2876: 0x00c0, 0x2877: 0x00c0, 0x2878: 0x0080, 0x2879: 0x0080, 0x287a: 0x0080, 0x287b: 0x00c0, + 0x287c: 0x0080, 0x287d: 0x00c0, + // Block 0xa2, offset 0x2880 + 0x2880: 0x00c0, 0x2881: 0x00c0, 0x2882: 0x00c0, 0x2883: 0x00c0, 0x2884: 0x00c0, 0x2885: 0x00c0, + 0x2886: 0x00c0, 0x2887: 0x00c0, 0x2888: 0x00c0, 0x2889: 0x00c0, 0x288a: 0x00c0, 0x288b: 0x00c0, + 0x288c: 0x00c0, 0x288d: 0x00c0, 0x288e: 0x00c0, 0x288f: 0x00c0, 0x2890: 0x00c0, 0x2891: 0x00c0, + 0x2892: 0x00c0, 0x2893: 0x00c0, 0x2894: 0x00c0, 0x2895: 0x00c0, 0x2896: 0x00c0, 0x2897: 0x00c0, + 0x2898: 0x00c0, 0x2899: 0x00c0, 0x289a: 0x00c0, 0x289b: 0x00c0, 0x289c: 0x00c0, 0x289d: 0x00c0, + 0x289e: 0x00c0, 0x289f: 0x00c0, 0x28a0: 0x00c0, 0x28a1: 0x00c0, 0x28a2: 0x00c0, 0x28a3: 0x00c0, + 0x28a4: 0x00c0, 0x28a5: 0x00c0, 0x28a6: 0x00c3, 0x28a7: 0x00c3, 0x28a8: 0x00c3, 0x28a9: 0x00c3, + 0x28aa: 0x00c3, 0x28ab: 0x00c3, 0x28ac: 0x00c3, 0x28ad: 0x00c3, 0x28ae: 0x0080, 0x28af: 0x0080, + 0x28b0: 0x00c0, 0x28b1: 0x00c0, 0x28b2: 0x00c0, 0x28b3: 0x00c0, 0x28b4: 0x00c0, 0x28b5: 0x00c0, + 0x28b6: 0x00c0, 0x28b7: 0x00c0, 0x28b8: 0x00c0, 0x28b9: 0x00c0, 0x28ba: 0x00c0, 0x28bb: 0x00c0, + 0x28bc: 0x00c0, 0x28bd: 0x00c0, 0x28be: 0x00c0, 0x28bf: 0x00c0, + // Block 0xa3, offset 0x28c0 + 0x28c0: 0x00c0, 0x28c1: 0x00c0, 0x28c2: 0x00c0, 0x28c3: 0x00c0, 0x28c4: 0x00c0, 0x28c5: 0x00c0, + 0x28c6: 0x00c0, 0x28c7: 0x00c3, 0x28c8: 0x00c3, 0x28c9: 0x00c3, 0x28ca: 0x00c3, 0x28cb: 0x00c3, + 0x28cc: 0x00c3, 0x28cd: 0x00c3, 0x28ce: 0x00c3, 0x28cf: 0x00c3, 0x28d0: 0x00c3, 0x28d1: 0x00c3, + 0x28d2: 0x00c0, 0x28d3: 0x00c5, + 0x28df: 0x0080, 0x28e0: 0x0040, 0x28e1: 0x0040, 0x28e2: 0x0040, 0x28e3: 0x0040, + 0x28e4: 0x0040, 0x28e5: 0x0040, 0x28e6: 0x0040, 0x28e7: 0x0040, 0x28e8: 0x0040, 0x28e9: 0x0040, + 0x28ea: 0x0040, 0x28eb: 0x0040, 0x28ec: 0x0040, 0x28ed: 0x0040, 0x28ee: 0x0040, 0x28ef: 0x0040, + 0x28f0: 0x0040, 0x28f1: 0x0040, 0x28f2: 0x0040, 0x28f3: 0x0040, 0x28f4: 0x0040, 0x28f5: 0x0040, + 0x28f6: 0x0040, 0x28f7: 0x0040, 0x28f8: 0x0040, 0x28f9: 0x0040, 0x28fa: 0x0040, 0x28fb: 0x0040, + 0x28fc: 0x0040, + // Block 0xa4, offset 0x2900 + 0x2900: 0x00c3, 0x2901: 0x00c3, 0x2902: 0x00c3, 0x2903: 0x00c0, 0x2904: 0x00c0, 0x2905: 0x00c0, + 0x2906: 0x00c0, 0x2907: 0x00c0, 0x2908: 0x00c0, 0x2909: 0x00c0, 0x290a: 0x00c0, 0x290b: 0x00c0, + 0x290c: 0x00c0, 0x290d: 0x00c0, 0x290e: 0x00c0, 0x290f: 0x00c0, 0x2910: 0x00c0, 0x2911: 0x00c0, + 0x2912: 0x00c0, 0x2913: 0x00c0, 0x2914: 0x00c0, 0x2915: 0x00c0, 0x2916: 0x00c0, 0x2917: 0x00c0, + 0x2918: 0x00c0, 0x2919: 0x00c0, 0x291a: 0x00c0, 0x291b: 0x00c0, 0x291c: 0x00c0, 0x291d: 0x00c0, + 0x291e: 0x00c0, 0x291f: 0x00c0, 0x2920: 0x00c0, 0x2921: 0x00c0, 0x2922: 0x00c0, 0x2923: 0x00c0, + 0x2924: 0x00c0, 0x2925: 0x00c0, 0x2926: 0x00c0, 0x2927: 0x00c0, 0x2928: 0x00c0, 0x2929: 0x00c0, + 0x292a: 0x00c0, 0x292b: 0x00c0, 0x292c: 0x00c0, 0x292d: 0x00c0, 0x292e: 0x00c0, 0x292f: 0x00c0, + 0x2930: 0x00c0, 0x2931: 0x00c0, 0x2932: 0x00c0, 0x2933: 0x00c3, 0x2934: 0x00c0, 0x2935: 0x00c0, + 0x2936: 0x00c3, 0x2937: 0x00c3, 0x2938: 0x00c3, 0x2939: 0x00c3, 0x293a: 0x00c0, 0x293b: 0x00c0, + 0x293c: 0x00c3, 0x293d: 0x00c0, 0x293e: 0x00c0, 0x293f: 0x00c0, + // Block 0xa5, offset 0x2940 + 0x2940: 0x00c5, 0x2941: 0x0080, 0x2942: 0x0080, 0x2943: 0x0080, 0x2944: 0x0080, 0x2945: 0x0080, + 0x2946: 0x0080, 0x2947: 0x0080, 0x2948: 0x0080, 0x2949: 0x0080, 0x294a: 0x0080, 0x294b: 0x0080, + 0x294c: 0x0080, 0x294d: 0x0080, 0x294f: 0x00c0, 0x2950: 0x00c0, 0x2951: 0x00c0, + 0x2952: 0x00c0, 0x2953: 0x00c0, 0x2954: 0x00c0, 0x2955: 0x00c0, 0x2956: 0x00c0, 0x2957: 0x00c0, + 0x2958: 0x00c0, 0x2959: 0x00c0, + 0x295e: 0x0080, 0x295f: 0x0080, 0x2960: 0x00c0, 0x2961: 0x00c0, 0x2962: 0x00c0, 0x2963: 0x00c0, + 0x2964: 0x00c0, 0x2965: 0x00c3, 0x2966: 0x00c0, 0x2967: 0x00c0, 0x2968: 0x00c0, 0x2969: 0x00c0, + 0x296a: 0x00c0, 0x296b: 0x00c0, 0x296c: 0x00c0, 0x296d: 0x00c0, 0x296e: 0x00c0, 0x296f: 0x00c0, + 0x2970: 0x00c0, 0x2971: 0x00c0, 0x2972: 0x00c0, 0x2973: 0x00c0, 0x2974: 0x00c0, 0x2975: 0x00c0, + 0x2976: 0x00c0, 0x2977: 0x00c0, 0x2978: 0x00c0, 0x2979: 0x00c0, 0x297a: 0x00c0, 0x297b: 0x00c0, + 0x297c: 0x00c0, 0x297d: 0x00c0, 0x297e: 0x00c0, + // Block 0xa6, offset 0x2980 + 0x2980: 0x00c0, 0x2981: 0x00c0, 0x2982: 0x00c0, 0x2983: 0x00c0, 0x2984: 0x00c0, 0x2985: 0x00c0, + 0x2986: 0x00c0, 0x2987: 0x00c0, 0x2988: 0x00c0, 0x2989: 0x00c0, 0x298a: 0x00c0, 0x298b: 0x00c0, + 0x298c: 0x00c0, 0x298d: 0x00c0, 0x298e: 0x00c0, 0x298f: 0x00c0, 0x2990: 0x00c0, 0x2991: 0x00c0, + 0x2992: 0x00c0, 0x2993: 0x00c0, 0x2994: 0x00c0, 0x2995: 0x00c0, 0x2996: 0x00c0, 0x2997: 0x00c0, + 0x2998: 0x00c0, 0x2999: 0x00c0, 0x299a: 0x00c0, 0x299b: 0x00c0, 0x299c: 0x00c0, 0x299d: 0x00c0, + 0x299e: 0x00c0, 0x299f: 0x00c0, 0x29a0: 0x00c0, 0x29a1: 0x00c0, 0x29a2: 0x00c0, 0x29a3: 0x00c0, + 0x29a4: 0x00c0, 0x29a5: 0x00c0, 0x29a6: 0x00c0, 0x29a7: 0x00c0, 0x29a8: 0x00c0, 0x29a9: 0x00c3, + 0x29aa: 0x00c3, 0x29ab: 0x00c3, 0x29ac: 0x00c3, 0x29ad: 0x00c3, 0x29ae: 0x00c3, 0x29af: 0x00c0, + 0x29b0: 0x00c0, 0x29b1: 0x00c3, 0x29b2: 0x00c3, 0x29b3: 0x00c0, 0x29b4: 0x00c0, 0x29b5: 0x00c3, + 0x29b6: 0x00c3, + // Block 0xa7, offset 0x29c0 + 0x29c0: 0x00c0, 0x29c1: 0x00c0, 0x29c2: 0x00c0, 0x29c3: 0x00c3, 0x29c4: 0x00c0, 0x29c5: 0x00c0, + 0x29c6: 0x00c0, 0x29c7: 0x00c0, 0x29c8: 0x00c0, 0x29c9: 0x00c0, 0x29ca: 0x00c0, 0x29cb: 0x00c0, + 0x29cc: 0x00c3, 0x29cd: 0x00c0, 0x29d0: 0x00c0, 0x29d1: 0x00c0, + 0x29d2: 0x00c0, 0x29d3: 0x00c0, 0x29d4: 0x00c0, 0x29d5: 0x00c0, 0x29d6: 0x00c0, 0x29d7: 0x00c0, + 0x29d8: 0x00c0, 0x29d9: 0x00c0, 0x29dc: 0x0080, 0x29dd: 0x0080, + 0x29de: 0x0080, 0x29df: 0x0080, 0x29e0: 0x00c0, 0x29e1: 0x00c0, 0x29e2: 0x00c0, 0x29e3: 0x00c0, + 0x29e4: 0x00c0, 0x29e5: 0x00c0, 0x29e6: 0x00c0, 0x29e7: 0x00c0, 0x29e8: 0x00c0, 0x29e9: 0x00c0, + 0x29ea: 0x00c0, 0x29eb: 0x00c0, 0x29ec: 0x00c0, 0x29ed: 0x00c0, 0x29ee: 0x00c0, 0x29ef: 0x00c0, + 0x29f0: 0x00c0, 0x29f1: 0x00c0, 0x29f2: 0x00c0, 0x29f3: 0x00c0, 0x29f4: 0x00c0, 0x29f5: 0x00c0, + 0x29f6: 0x00c0, 0x29f7: 0x0080, 0x29f8: 0x0080, 0x29f9: 0x0080, 0x29fa: 0x00c0, 0x29fb: 0x00c0, + 0x29fc: 0x00c3, 0x29fd: 0x00c0, 0x29fe: 0x00c0, 0x29ff: 0x00c0, + // Block 0xa8, offset 0x2a00 + 0x2a00: 0x00c0, 0x2a01: 0x00c0, 0x2a02: 0x00c0, 0x2a03: 0x00c0, 0x2a04: 0x00c0, 0x2a05: 0x00c0, + 0x2a06: 0x00c0, 0x2a07: 0x00c0, 0x2a08: 0x00c0, 0x2a09: 0x00c0, 0x2a0a: 0x00c0, 0x2a0b: 0x00c0, + 0x2a0c: 0x00c0, 0x2a0d: 0x00c0, 0x2a0e: 0x00c0, 0x2a0f: 0x00c0, 0x2a10: 0x00c0, 0x2a11: 0x00c0, + 0x2a12: 0x00c0, 0x2a13: 0x00c0, 0x2a14: 0x00c0, 0x2a15: 0x00c0, 0x2a16: 0x00c0, 0x2a17: 0x00c0, + 0x2a18: 0x00c0, 0x2a19: 0x00c0, 0x2a1a: 0x00c0, 0x2a1b: 0x00c0, 0x2a1c: 0x00c0, 0x2a1d: 0x00c0, + 0x2a1e: 0x00c0, 0x2a1f: 0x00c0, 0x2a20: 0x00c0, 0x2a21: 0x00c0, 0x2a22: 0x00c0, 0x2a23: 0x00c0, + 0x2a24: 0x00c0, 0x2a25: 0x00c0, 0x2a26: 0x00c0, 0x2a27: 0x00c0, 0x2a28: 0x00c0, 0x2a29: 0x00c0, + 0x2a2a: 0x00c0, 0x2a2b: 0x00c0, 0x2a2c: 0x00c0, 0x2a2d: 0x00c0, 0x2a2e: 0x00c0, 0x2a2f: 0x00c0, + 0x2a30: 0x00c3, 0x2a31: 0x00c0, 0x2a32: 0x00c3, 0x2a33: 0x00c3, 0x2a34: 0x00c3, 0x2a35: 0x00c0, + 0x2a36: 0x00c0, 0x2a37: 0x00c3, 0x2a38: 0x00c3, 0x2a39: 0x00c0, 0x2a3a: 0x00c0, 0x2a3b: 0x00c0, + 0x2a3c: 0x00c0, 0x2a3d: 0x00c0, 0x2a3e: 0x00c3, 0x2a3f: 0x00c3, + // Block 0xa9, offset 0x2a40 + 0x2a40: 0x00c0, 0x2a41: 0x00c3, 0x2a42: 0x00c0, + 0x2a5b: 0x00c0, 0x2a5c: 0x00c0, 0x2a5d: 0x00c0, + 0x2a5e: 0x0080, 0x2a5f: 0x0080, 0x2a60: 0x00c0, 0x2a61: 0x00c0, 0x2a62: 0x00c0, 0x2a63: 0x00c0, + 0x2a64: 0x00c0, 0x2a65: 0x00c0, 0x2a66: 0x00c0, 0x2a67: 0x00c0, 0x2a68: 0x00c0, 0x2a69: 0x00c0, + 0x2a6a: 0x00c0, 0x2a6b: 0x00c0, 0x2a6c: 0x00c3, 0x2a6d: 0x00c3, 0x2a6e: 0x00c0, 0x2a6f: 0x00c0, + 0x2a70: 0x0080, 0x2a71: 0x0080, 0x2a72: 0x00c0, 0x2a73: 0x00c0, 0x2a74: 0x00c0, 0x2a75: 0x00c0, + 0x2a76: 0x00c6, + // Block 0xaa, offset 0x2a80 + 0x2a81: 0x00c0, 0x2a82: 0x00c0, 0x2a83: 0x00c0, 0x2a84: 0x00c0, 0x2a85: 0x00c0, + 0x2a86: 0x00c0, 0x2a89: 0x00c0, 0x2a8a: 0x00c0, 0x2a8b: 0x00c0, + 0x2a8c: 0x00c0, 0x2a8d: 0x00c0, 0x2a8e: 0x00c0, 0x2a91: 0x00c0, + 0x2a92: 0x00c0, 0x2a93: 0x00c0, 0x2a94: 0x00c0, 0x2a95: 0x00c0, 0x2a96: 0x00c0, + 0x2aa0: 0x00c0, 0x2aa1: 0x00c0, 0x2aa2: 0x00c0, 0x2aa3: 0x00c0, + 0x2aa4: 0x00c0, 0x2aa5: 0x00c0, 0x2aa6: 0x00c0, 0x2aa8: 0x00c0, 0x2aa9: 0x00c0, + 0x2aaa: 0x00c0, 0x2aab: 0x00c0, 0x2aac: 0x00c0, 0x2aad: 0x00c0, 0x2aae: 0x00c0, + 0x2ab0: 0x00c0, 0x2ab1: 0x00c0, 0x2ab2: 0x00c0, 0x2ab3: 0x00c0, 0x2ab4: 0x00c0, 0x2ab5: 0x00c0, + 0x2ab6: 0x00c0, 0x2ab7: 0x00c0, 0x2ab8: 0x00c0, 0x2ab9: 0x00c0, 0x2aba: 0x00c0, 0x2abb: 0x00c0, + 0x2abc: 0x00c0, 0x2abd: 0x00c0, 0x2abe: 0x00c0, 0x2abf: 0x00c0, + // Block 0xab, offset 0x2ac0 + 0x2ac0: 0x00c0, 0x2ac1: 0x00c0, 0x2ac2: 0x00c0, 0x2ac3: 0x00c0, 0x2ac4: 0x00c0, 0x2ac5: 0x00c0, + 0x2ac6: 0x00c0, 0x2ac7: 0x00c0, 0x2ac8: 0x00c0, 0x2ac9: 0x00c0, 0x2aca: 0x00c0, 0x2acb: 0x00c0, + 0x2acc: 0x00c0, 0x2acd: 0x00c0, 0x2ace: 0x00c0, 0x2acf: 0x00c0, 0x2ad0: 0x00c0, 0x2ad1: 0x00c0, + 0x2ad2: 0x00c0, 0x2ad3: 0x00c0, 0x2ad4: 0x00c0, 0x2ad5: 0x00c0, 0x2ad6: 0x00c0, 0x2ad7: 0x00c0, + 0x2ad8: 0x00c0, 0x2ad9: 0x00c0, 0x2ada: 0x00c0, 0x2adb: 0x0080, 0x2adc: 0x0080, 0x2add: 0x0080, + 0x2ade: 0x0080, 0x2adf: 0x0080, 0x2ae0: 0x00c0, 0x2ae1: 0x00c0, 0x2ae2: 0x00c0, 0x2ae3: 0x00c0, + 0x2ae4: 0x00c0, 0x2ae5: 0x00c8, + 0x2af0: 0x00c0, 0x2af1: 0x00c0, 0x2af2: 0x00c0, 0x2af3: 0x00c0, 0x2af4: 0x00c0, 0x2af5: 0x00c0, + 0x2af6: 0x00c0, 0x2af7: 0x00c0, 0x2af8: 0x00c0, 0x2af9: 0x00c0, 0x2afa: 0x00c0, 0x2afb: 0x00c0, + 0x2afc: 0x00c0, 0x2afd: 0x00c0, 0x2afe: 0x00c0, 0x2aff: 0x00c0, + // Block 0xac, offset 0x2b00 + 0x2b00: 0x00c0, 0x2b01: 0x00c0, 0x2b02: 0x00c0, 0x2b03: 0x00c0, 0x2b04: 0x00c0, 0x2b05: 0x00c0, + 0x2b06: 0x00c0, 0x2b07: 0x00c0, 0x2b08: 0x00c0, 0x2b09: 0x00c0, 0x2b0a: 0x00c0, 0x2b0b: 0x00c0, + 0x2b0c: 0x00c0, 0x2b0d: 0x00c0, 0x2b0e: 0x00c0, 0x2b0f: 0x00c0, 0x2b10: 0x00c0, 0x2b11: 0x00c0, + 0x2b12: 0x00c0, 0x2b13: 0x00c0, 0x2b14: 0x00c0, 0x2b15: 0x00c0, 0x2b16: 0x00c0, 0x2b17: 0x00c0, + 0x2b18: 0x00c0, 0x2b19: 0x00c0, 0x2b1a: 0x00c0, 0x2b1b: 0x00c0, 0x2b1c: 0x00c0, 0x2b1d: 0x00c0, + 0x2b1e: 0x00c0, 0x2b1f: 0x00c0, 0x2b20: 0x00c0, 0x2b21: 0x00c0, 0x2b22: 0x00c0, 0x2b23: 0x00c0, + 0x2b24: 0x00c0, 0x2b25: 0x00c3, 0x2b26: 0x00c0, 0x2b27: 0x00c0, 0x2b28: 0x00c3, 0x2b29: 0x00c0, + 0x2b2a: 0x00c0, 0x2b2b: 0x0080, 0x2b2c: 0x00c0, 0x2b2d: 0x00c6, + 0x2b30: 0x00c0, 0x2b31: 0x00c0, 0x2b32: 0x00c0, 0x2b33: 0x00c0, 0x2b34: 0x00c0, 0x2b35: 0x00c0, + 0x2b36: 0x00c0, 0x2b37: 0x00c0, 0x2b38: 0x00c0, 0x2b39: 0x00c0, + // Block 0xad, offset 0x2b40 + 0x2b40: 0x00c0, 0x2b41: 0x00c0, 0x2b42: 0x00c0, 0x2b43: 0x00c0, 0x2b44: 0x00c0, 0x2b45: 0x00c0, + 0x2b46: 0x00c0, 0x2b47: 0x00c0, 0x2b48: 0x00c0, 0x2b49: 0x00c0, 0x2b4a: 0x00c0, 0x2b4b: 0x00c0, + 0x2b4c: 0x00c0, 0x2b4d: 0x00c0, 0x2b4e: 0x00c0, 0x2b4f: 0x00c0, 0x2b50: 0x00c0, 0x2b51: 0x00c0, + 0x2b52: 0x00c0, 0x2b53: 0x00c0, 0x2b54: 0x00c0, 0x2b55: 0x00c0, 0x2b56: 0x00c0, 0x2b57: 0x00c0, + 0x2b58: 0x00c0, 0x2b59: 0x00c0, 0x2b5a: 0x00c0, 0x2b5b: 0x00c0, 0x2b5c: 0x00c0, 0x2b5d: 0x00c0, + 0x2b5e: 0x00c0, 0x2b5f: 0x00c0, 0x2b60: 0x00c0, 0x2b61: 0x00c0, 0x2b62: 0x00c0, 0x2b63: 0x00c0, + 0x2b70: 0x0040, 0x2b71: 0x0040, 0x2b72: 0x0040, 0x2b73: 0x0040, 0x2b74: 0x0040, 0x2b75: 0x0040, + 0x2b76: 0x0040, 0x2b77: 0x0040, 0x2b78: 0x0040, 0x2b79: 0x0040, 0x2b7a: 0x0040, 0x2b7b: 0x0040, + 0x2b7c: 0x0040, 0x2b7d: 0x0040, 0x2b7e: 0x0040, 0x2b7f: 0x0040, + // Block 0xae, offset 0x2b80 + 0x2b80: 0x0040, 0x2b81: 0x0040, 0x2b82: 0x0040, 0x2b83: 0x0040, 0x2b84: 0x0040, 0x2b85: 0x0040, + 0x2b86: 0x0040, 0x2b8b: 0x0040, + 0x2b8c: 0x0040, 0x2b8d: 0x0040, 0x2b8e: 0x0040, 0x2b8f: 0x0040, 0x2b90: 0x0040, 0x2b91: 0x0040, + 0x2b92: 0x0040, 0x2b93: 0x0040, 0x2b94: 0x0040, 0x2b95: 0x0040, 0x2b96: 0x0040, 0x2b97: 0x0040, + 0x2b98: 0x0040, 0x2b99: 0x0040, 0x2b9a: 0x0040, 0x2b9b: 0x0040, 0x2b9c: 0x0040, 0x2b9d: 0x0040, + 0x2b9e: 0x0040, 0x2b9f: 0x0040, 0x2ba0: 0x0040, 0x2ba1: 0x0040, 0x2ba2: 0x0040, 0x2ba3: 0x0040, + 0x2ba4: 0x0040, 0x2ba5: 0x0040, 0x2ba6: 0x0040, 0x2ba7: 0x0040, 0x2ba8: 0x0040, 0x2ba9: 0x0040, + 0x2baa: 0x0040, 0x2bab: 0x0040, 0x2bac: 0x0040, 0x2bad: 0x0040, 0x2bae: 0x0040, 0x2baf: 0x0040, + 0x2bb0: 0x0040, 0x2bb1: 0x0040, 0x2bb2: 0x0040, 0x2bb3: 0x0040, 0x2bb4: 0x0040, 0x2bb5: 0x0040, + 0x2bb6: 0x0040, 0x2bb7: 0x0040, 0x2bb8: 0x0040, 0x2bb9: 0x0040, 0x2bba: 0x0040, 0x2bbb: 0x0040, + // Block 0xaf, offset 0x2bc0 + 0x2bc0: 0x008c, 0x2bc1: 0x008c, 0x2bc2: 0x008c, 0x2bc3: 0x008c, 0x2bc4: 0x008c, 0x2bc5: 0x008c, + 0x2bc6: 0x008c, 0x2bc7: 0x008c, 0x2bc8: 0x008c, 0x2bc9: 0x008c, 0x2bca: 0x008c, 0x2bcb: 0x008c, + 0x2bcc: 0x008c, 0x2bcd: 0x008c, 0x2bce: 0x00cc, 0x2bcf: 0x00cc, 0x2bd0: 0x008c, 0x2bd1: 0x00cc, + 0x2bd2: 0x008c, 0x2bd3: 0x00cc, 0x2bd4: 0x00cc, 0x2bd5: 0x008c, 0x2bd6: 0x008c, 0x2bd7: 0x008c, + 0x2bd8: 0x008c, 0x2bd9: 0x008c, 0x2bda: 0x008c, 0x2bdb: 0x008c, 0x2bdc: 0x008c, 0x2bdd: 0x008c, + 0x2bde: 0x008c, 0x2bdf: 0x00cc, 0x2be0: 0x008c, 0x2be1: 0x00cc, 0x2be2: 0x008c, 0x2be3: 0x00cc, + 0x2be4: 0x00cc, 0x2be5: 0x008c, 0x2be6: 0x008c, 0x2be7: 0x00cc, 0x2be8: 0x00cc, 0x2be9: 0x00cc, + 0x2bea: 0x008c, 0x2beb: 0x008c, 0x2bec: 0x008c, 0x2bed: 0x008c, 0x2bee: 0x008c, 0x2bef: 0x008c, + 0x2bf0: 0x008c, 0x2bf1: 0x008c, 0x2bf2: 0x008c, 0x2bf3: 0x008c, 0x2bf4: 0x008c, 0x2bf5: 0x008c, + 0x2bf6: 0x008c, 0x2bf7: 0x008c, 0x2bf8: 0x008c, 0x2bf9: 0x008c, 0x2bfa: 0x008c, 0x2bfb: 0x008c, + 0x2bfc: 0x008c, 0x2bfd: 0x008c, 0x2bfe: 0x008c, 0x2bff: 0x008c, + // Block 0xb0, offset 0x2c00 + 0x2c00: 0x008c, 0x2c01: 0x008c, 0x2c02: 0x008c, 0x2c03: 0x008c, 0x2c04: 0x008c, 0x2c05: 0x008c, + 0x2c06: 0x008c, 0x2c07: 0x008c, 0x2c08: 0x008c, 0x2c09: 0x008c, 0x2c0a: 0x008c, 0x2c0b: 0x008c, + 0x2c0c: 0x008c, 0x2c0d: 0x008c, 0x2c0e: 0x008c, 0x2c0f: 0x008c, 0x2c10: 0x008c, 0x2c11: 0x008c, + 0x2c12: 0x008c, 0x2c13: 0x008c, 0x2c14: 0x008c, 0x2c15: 0x008c, 0x2c16: 0x008c, 0x2c17: 0x008c, + 0x2c18: 0x008c, 0x2c19: 0x008c, 0x2c1a: 0x008c, 0x2c1b: 0x008c, 0x2c1c: 0x008c, 0x2c1d: 0x008c, + 0x2c1e: 0x008c, 0x2c1f: 0x008c, 0x2c20: 0x008c, 0x2c21: 0x008c, 0x2c22: 0x008c, 0x2c23: 0x008c, + 0x2c24: 0x008c, 0x2c25: 0x008c, 0x2c26: 0x008c, 0x2c27: 0x008c, 0x2c28: 0x008c, 0x2c29: 0x008c, + 0x2c2a: 0x008c, 0x2c2b: 0x008c, 0x2c2c: 0x008c, 0x2c2d: 0x008c, + 0x2c30: 0x008c, 0x2c31: 0x008c, 0x2c32: 0x008c, 0x2c33: 0x008c, 0x2c34: 0x008c, 0x2c35: 0x008c, + 0x2c36: 0x008c, 0x2c37: 0x008c, 0x2c38: 0x008c, 0x2c39: 0x008c, 0x2c3a: 0x008c, 0x2c3b: 0x008c, + 0x2c3c: 0x008c, 0x2c3d: 0x008c, 0x2c3e: 0x008c, 0x2c3f: 0x008c, + // Block 0xb1, offset 0x2c40 + 0x2c40: 0x008c, 0x2c41: 0x008c, 0x2c42: 0x008c, 0x2c43: 0x008c, 0x2c44: 0x008c, 0x2c45: 0x008c, + 0x2c46: 0x008c, 0x2c47: 0x008c, 0x2c48: 0x008c, 0x2c49: 0x008c, 0x2c4a: 0x008c, 0x2c4b: 0x008c, + 0x2c4c: 0x008c, 0x2c4d: 0x008c, 0x2c4e: 0x008c, 0x2c4f: 0x008c, 0x2c50: 0x008c, 0x2c51: 0x008c, + 0x2c52: 0x008c, 0x2c53: 0x008c, 0x2c54: 0x008c, 0x2c55: 0x008c, 0x2c56: 0x008c, 0x2c57: 0x008c, + 0x2c58: 0x008c, 0x2c59: 0x008c, + // Block 0xb2, offset 0x2c80 + 0x2c80: 0x0080, 0x2c81: 0x0080, 0x2c82: 0x0080, 0x2c83: 0x0080, 0x2c84: 0x0080, 0x2c85: 0x0080, + 0x2c86: 0x0080, + 0x2c93: 0x0080, 0x2c94: 0x0080, 0x2c95: 0x0080, 0x2c96: 0x0080, 0x2c97: 0x0080, + 0x2c9d: 0x008a, + 0x2c9e: 0x00cb, 0x2c9f: 0x008a, 0x2ca0: 0x008a, 0x2ca1: 0x008a, 0x2ca2: 0x008a, 0x2ca3: 0x008a, + 0x2ca4: 0x008a, 0x2ca5: 0x008a, 0x2ca6: 0x008a, 0x2ca7: 0x008a, 0x2ca8: 0x008a, 0x2ca9: 0x008a, + 0x2caa: 0x008a, 0x2cab: 0x008a, 0x2cac: 0x008a, 0x2cad: 0x008a, 0x2cae: 0x008a, 0x2caf: 0x008a, + 0x2cb0: 0x008a, 0x2cb1: 0x008a, 0x2cb2: 0x008a, 0x2cb3: 0x008a, 0x2cb4: 0x008a, 0x2cb5: 0x008a, + 0x2cb6: 0x008a, 0x2cb8: 0x008a, 0x2cb9: 0x008a, 0x2cba: 0x008a, 0x2cbb: 0x008a, + 0x2cbc: 0x008a, 0x2cbe: 0x008a, + // Block 0xb3, offset 0x2cc0 + 0x2cc0: 0x008a, 0x2cc1: 0x008a, 0x2cc3: 0x008a, 0x2cc4: 0x008a, + 0x2cc6: 0x008a, 0x2cc7: 0x008a, 0x2cc8: 0x008a, 0x2cc9: 0x008a, 0x2cca: 0x008a, 0x2ccb: 0x008a, + 0x2ccc: 0x008a, 0x2ccd: 0x008a, 0x2cce: 0x008a, 0x2ccf: 0x008a, 0x2cd0: 0x0080, 0x2cd1: 0x0080, + 0x2cd2: 0x0080, 0x2cd3: 0x0080, 0x2cd4: 0x0080, 0x2cd5: 0x0080, 0x2cd6: 0x0080, 0x2cd7: 0x0080, + 0x2cd8: 0x0080, 0x2cd9: 0x0080, 0x2cda: 0x0080, 0x2cdb: 0x0080, 0x2cdc: 0x0080, 0x2cdd: 0x0080, + 0x2cde: 0x0080, 0x2cdf: 0x0080, 0x2ce0: 0x0080, 0x2ce1: 0x0080, 0x2ce2: 0x0080, 0x2ce3: 0x0080, + 0x2ce4: 0x0080, 0x2ce5: 0x0080, 0x2ce6: 0x0080, 0x2ce7: 0x0080, 0x2ce8: 0x0080, 0x2ce9: 0x0080, + 0x2cea: 0x0080, 0x2ceb: 0x0080, 0x2cec: 0x0080, 0x2ced: 0x0080, 0x2cee: 0x0080, 0x2cef: 0x0080, + 0x2cf0: 0x0080, 0x2cf1: 0x0080, 0x2cf2: 0x0080, 0x2cf3: 0x0080, 0x2cf4: 0x0080, 0x2cf5: 0x0080, + 0x2cf6: 0x0080, 0x2cf7: 0x0080, 0x2cf8: 0x0080, 0x2cf9: 0x0080, 0x2cfa: 0x0080, 0x2cfb: 0x0080, + 0x2cfc: 0x0080, 0x2cfd: 0x0080, 0x2cfe: 0x0080, 0x2cff: 0x0080, + // Block 0xb4, offset 0x2d00 + 0x2d00: 0x0080, 0x2d01: 0x0080, + 0x2d13: 0x0080, 0x2d14: 0x0080, 0x2d15: 0x0080, 0x2d16: 0x0080, 0x2d17: 0x0080, + 0x2d18: 0x0080, 0x2d19: 0x0080, 0x2d1a: 0x0080, 0x2d1b: 0x0080, 0x2d1c: 0x0080, 0x2d1d: 0x0080, + 0x2d1e: 0x0080, 0x2d1f: 0x0080, 0x2d20: 0x0080, 0x2d21: 0x0080, 0x2d22: 0x0080, 0x2d23: 0x0080, + 0x2d24: 0x0080, 0x2d25: 0x0080, 0x2d26: 0x0080, 0x2d27: 0x0080, 0x2d28: 0x0080, 0x2d29: 0x0080, + 0x2d2a: 0x0080, 0x2d2b: 0x0080, 0x2d2c: 0x0080, 0x2d2d: 0x0080, 0x2d2e: 0x0080, 0x2d2f: 0x0080, + 0x2d30: 0x0080, 0x2d31: 0x0080, 0x2d32: 0x0080, 0x2d33: 0x0080, 0x2d34: 0x0080, 0x2d35: 0x0080, + 0x2d36: 0x0080, 0x2d37: 0x0080, 0x2d38: 0x0080, 0x2d39: 0x0080, 0x2d3a: 0x0080, 0x2d3b: 0x0080, + 0x2d3c: 0x0080, 0x2d3d: 0x0080, 0x2d3e: 0x0080, 0x2d3f: 0x0080, + // Block 0xb5, offset 0x2d40 + 0x2d50: 0x0080, 0x2d51: 0x0080, + 0x2d52: 0x0080, 0x2d53: 0x0080, 0x2d54: 0x0080, 0x2d55: 0x0080, 0x2d56: 0x0080, 0x2d57: 0x0080, + 0x2d58: 0x0080, 0x2d59: 0x0080, 0x2d5a: 0x0080, 0x2d5b: 0x0080, 0x2d5c: 0x0080, 0x2d5d: 0x0080, + 0x2d5e: 0x0080, 0x2d5f: 0x0080, 0x2d60: 0x0080, 0x2d61: 0x0080, 0x2d62: 0x0080, 0x2d63: 0x0080, + 0x2d64: 0x0080, 0x2d65: 0x0080, 0x2d66: 0x0080, 0x2d67: 0x0080, 0x2d68: 0x0080, 0x2d69: 0x0080, + 0x2d6a: 0x0080, 0x2d6b: 0x0080, 0x2d6c: 0x0080, 0x2d6d: 0x0080, 0x2d6e: 0x0080, 0x2d6f: 0x0080, + 0x2d70: 0x0080, 0x2d71: 0x0080, 0x2d72: 0x0080, 0x2d73: 0x0080, 0x2d74: 0x0080, 0x2d75: 0x0080, + 0x2d76: 0x0080, 0x2d77: 0x0080, 0x2d78: 0x0080, 0x2d79: 0x0080, 0x2d7a: 0x0080, 0x2d7b: 0x0080, + 0x2d7c: 0x0080, 0x2d7d: 0x0080, 0x2d7e: 0x0080, 0x2d7f: 0x0080, + // Block 0xb6, offset 0x2d80 + 0x2d80: 0x0080, 0x2d81: 0x0080, 0x2d82: 0x0080, 0x2d83: 0x0080, 0x2d84: 0x0080, 0x2d85: 0x0080, + 0x2d86: 0x0080, 0x2d87: 0x0080, 0x2d88: 0x0080, 0x2d89: 0x0080, 0x2d8a: 0x0080, 0x2d8b: 0x0080, + 0x2d8c: 0x0080, 0x2d8d: 0x0080, 0x2d8e: 0x0080, 0x2d8f: 0x0080, + 0x2d92: 0x0080, 0x2d93: 0x0080, 0x2d94: 0x0080, 0x2d95: 0x0080, 0x2d96: 0x0080, 0x2d97: 0x0080, + 0x2d98: 0x0080, 0x2d99: 0x0080, 0x2d9a: 0x0080, 0x2d9b: 0x0080, 0x2d9c: 0x0080, 0x2d9d: 0x0080, + 0x2d9e: 0x0080, 0x2d9f: 0x0080, 0x2da0: 0x0080, 0x2da1: 0x0080, 0x2da2: 0x0080, 0x2da3: 0x0080, + 0x2da4: 0x0080, 0x2da5: 0x0080, 0x2da6: 0x0080, 0x2da7: 0x0080, 0x2da8: 0x0080, 0x2da9: 0x0080, + 0x2daa: 0x0080, 0x2dab: 0x0080, 0x2dac: 0x0080, 0x2dad: 0x0080, 0x2dae: 0x0080, 0x2daf: 0x0080, + 0x2db0: 0x0080, 0x2db1: 0x0080, 0x2db2: 0x0080, 0x2db3: 0x0080, 0x2db4: 0x0080, 0x2db5: 0x0080, + 0x2db6: 0x0080, 0x2db7: 0x0080, 0x2db8: 0x0080, 0x2db9: 0x0080, 0x2dba: 0x0080, 0x2dbb: 0x0080, + 0x2dbc: 0x0080, 0x2dbd: 0x0080, 0x2dbe: 0x0080, 0x2dbf: 0x0080, + // Block 0xb7, offset 0x2dc0 + 0x2dc0: 0x0080, 0x2dc1: 0x0080, 0x2dc2: 0x0080, 0x2dc3: 0x0080, 0x2dc4: 0x0080, 0x2dc5: 0x0080, + 0x2dc6: 0x0080, 0x2dc7: 0x0080, + 0x2df0: 0x0080, 0x2df1: 0x0080, 0x2df2: 0x0080, 0x2df3: 0x0080, 0x2df4: 0x0080, 0x2df5: 0x0080, + 0x2df6: 0x0080, 0x2df7: 0x0080, 0x2df8: 0x0080, 0x2df9: 0x0080, 0x2dfa: 0x0080, 0x2dfb: 0x0080, + 0x2dfc: 0x0080, 0x2dfd: 0x0080, + // Block 0xb8, offset 0x2e00 + 0x2e00: 0x0040, 0x2e01: 0x0040, 0x2e02: 0x0040, 0x2e03: 0x0040, 0x2e04: 0x0040, 0x2e05: 0x0040, + 0x2e06: 0x0040, 0x2e07: 0x0040, 0x2e08: 0x0040, 0x2e09: 0x0040, 0x2e0a: 0x0040, 0x2e0b: 0x0040, + 0x2e0c: 0x0040, 0x2e0d: 0x0040, 0x2e0e: 0x0040, 0x2e0f: 0x0040, 0x2e10: 0x0080, 0x2e11: 0x0080, + 0x2e12: 0x0080, 0x2e13: 0x0080, 0x2e14: 0x0080, 0x2e15: 0x0080, 0x2e16: 0x0080, 0x2e17: 0x0080, + 0x2e18: 0x0080, 0x2e19: 0x0080, + 0x2e20: 0x00c3, 0x2e21: 0x00c3, 0x2e22: 0x00c3, 0x2e23: 0x00c3, + 0x2e24: 0x00c3, 0x2e25: 0x00c3, 0x2e26: 0x00c3, 0x2e27: 0x00c3, 0x2e28: 0x00c3, 0x2e29: 0x00c3, + 0x2e2a: 0x00c3, 0x2e2b: 0x00c3, 0x2e2c: 0x00c3, 0x2e2d: 0x00c3, 0x2e2e: 0x00c3, 0x2e2f: 0x00c3, + 0x2e30: 0x0080, 0x2e31: 0x0080, 0x2e32: 0x0080, 0x2e33: 0x0080, 0x2e34: 0x0080, 0x2e35: 0x0080, + 0x2e36: 0x0080, 0x2e37: 0x0080, 0x2e38: 0x0080, 0x2e39: 0x0080, 0x2e3a: 0x0080, 0x2e3b: 0x0080, + 0x2e3c: 0x0080, 0x2e3d: 0x0080, 0x2e3e: 0x0080, 0x2e3f: 0x0080, + // Block 0xb9, offset 0x2e40 + 0x2e40: 0x0080, 0x2e41: 0x0080, 0x2e42: 0x0080, 0x2e43: 0x0080, 0x2e44: 0x0080, 0x2e45: 0x0080, + 0x2e46: 0x0080, 0x2e47: 0x0080, 0x2e48: 0x0080, 0x2e49: 0x0080, 0x2e4a: 0x0080, 0x2e4b: 0x0080, + 0x2e4c: 0x0080, 0x2e4d: 0x0080, 0x2e4e: 0x0080, 0x2e4f: 0x0080, 0x2e50: 0x0080, 0x2e51: 0x0080, + 0x2e52: 0x0080, 0x2e54: 0x0080, 0x2e55: 0x0080, 0x2e56: 0x0080, 0x2e57: 0x0080, + 0x2e58: 0x0080, 0x2e59: 0x0080, 0x2e5a: 0x0080, 0x2e5b: 0x0080, 0x2e5c: 0x0080, 0x2e5d: 0x0080, + 0x2e5e: 0x0080, 0x2e5f: 0x0080, 0x2e60: 0x0080, 0x2e61: 0x0080, 0x2e62: 0x0080, 0x2e63: 0x0080, + 0x2e64: 0x0080, 0x2e65: 0x0080, 0x2e66: 0x0080, 0x2e68: 0x0080, 0x2e69: 0x0080, + 0x2e6a: 0x0080, 0x2e6b: 0x0080, + 0x2e70: 0x0080, 0x2e71: 0x0080, 0x2e72: 0x0080, 0x2e73: 0x00c0, 0x2e74: 0x0080, + 0x2e76: 0x0080, 0x2e77: 0x0080, 0x2e78: 0x0080, 0x2e79: 0x0080, 0x2e7a: 0x0080, 0x2e7b: 0x0080, + 0x2e7c: 0x0080, 0x2e7d: 0x0080, 0x2e7e: 0x0080, 0x2e7f: 0x0080, + // Block 0xba, offset 0x2e80 + 0x2e80: 0x0080, 0x2e81: 0x0080, 0x2e82: 0x0080, 0x2e83: 0x0080, 0x2e84: 0x0080, 0x2e85: 0x0080, + 0x2e86: 0x0080, 0x2e87: 0x0080, 0x2e88: 0x0080, 0x2e89: 0x0080, 0x2e8a: 0x0080, 0x2e8b: 0x0080, + 0x2e8c: 0x0080, 0x2e8d: 0x0080, 0x2e8e: 0x0080, 0x2e8f: 0x0080, 0x2e90: 0x0080, 0x2e91: 0x0080, + 0x2e92: 0x0080, 0x2e93: 0x0080, 0x2e94: 0x0080, 0x2e95: 0x0080, 0x2e96: 0x0080, 0x2e97: 0x0080, + 0x2e98: 0x0080, 0x2e99: 0x0080, 0x2e9a: 0x0080, 0x2e9b: 0x0080, 0x2e9c: 0x0080, 0x2e9d: 0x0080, + 0x2e9e: 0x0080, 0x2e9f: 0x0080, 0x2ea0: 0x0080, 0x2ea1: 0x0080, 0x2ea2: 0x0080, 0x2ea3: 0x0080, + 0x2ea4: 0x0080, 0x2ea5: 0x0080, 0x2ea6: 0x0080, 0x2ea7: 0x0080, 0x2ea8: 0x0080, 0x2ea9: 0x0080, + 0x2eaa: 0x0080, 0x2eab: 0x0080, 0x2eac: 0x0080, 0x2ead: 0x0080, 0x2eae: 0x0080, 0x2eaf: 0x0080, + 0x2eb0: 0x0080, 0x2eb1: 0x0080, 0x2eb2: 0x0080, 0x2eb3: 0x0080, 0x2eb4: 0x0080, 0x2eb5: 0x0080, + 0x2eb6: 0x0080, 0x2eb7: 0x0080, 0x2eb8: 0x0080, 0x2eb9: 0x0080, 0x2eba: 0x0080, 0x2ebb: 0x0080, + 0x2ebc: 0x0080, 0x2ebf: 0x0040, + // Block 0xbb, offset 0x2ec0 + 0x2ec1: 0x0080, 0x2ec2: 0x0080, 0x2ec3: 0x0080, 0x2ec4: 0x0080, 0x2ec5: 0x0080, + 0x2ec6: 0x0080, 0x2ec7: 0x0080, 0x2ec8: 0x0080, 0x2ec9: 0x0080, 0x2eca: 0x0080, 0x2ecb: 0x0080, + 0x2ecc: 0x0080, 0x2ecd: 0x0080, 0x2ece: 0x0080, 0x2ecf: 0x0080, 0x2ed0: 0x0080, 0x2ed1: 0x0080, + 0x2ed2: 0x0080, 0x2ed3: 0x0080, 0x2ed4: 0x0080, 0x2ed5: 0x0080, 0x2ed6: 0x0080, 0x2ed7: 0x0080, + 0x2ed8: 0x0080, 0x2ed9: 0x0080, 0x2eda: 0x0080, 0x2edb: 0x0080, 0x2edc: 0x0080, 0x2edd: 0x0080, + 0x2ede: 0x0080, 0x2edf: 0x0080, 0x2ee0: 0x0080, 0x2ee1: 0x0080, 0x2ee2: 0x0080, 0x2ee3: 0x0080, + 0x2ee4: 0x0080, 0x2ee5: 0x0080, 0x2ee6: 0x0080, 0x2ee7: 0x0080, 0x2ee8: 0x0080, 0x2ee9: 0x0080, + 0x2eea: 0x0080, 0x2eeb: 0x0080, 0x2eec: 0x0080, 0x2eed: 0x0080, 0x2eee: 0x0080, 0x2eef: 0x0080, + 0x2ef0: 0x0080, 0x2ef1: 0x0080, 0x2ef2: 0x0080, 0x2ef3: 0x0080, 0x2ef4: 0x0080, 0x2ef5: 0x0080, + 0x2ef6: 0x0080, 0x2ef7: 0x0080, 0x2ef8: 0x0080, 0x2ef9: 0x0080, 0x2efa: 0x0080, 0x2efb: 0x0080, + 0x2efc: 0x0080, 0x2efd: 0x0080, 0x2efe: 0x0080, 0x2eff: 0x0080, + // Block 0xbc, offset 0x2f00 + 0x2f00: 0x0080, 0x2f01: 0x0080, 0x2f02: 0x0080, 0x2f03: 0x0080, 0x2f04: 0x0080, 0x2f05: 0x0080, + 0x2f06: 0x0080, 0x2f07: 0x0080, 0x2f08: 0x0080, 0x2f09: 0x0080, 0x2f0a: 0x0080, 0x2f0b: 0x0080, + 0x2f0c: 0x0080, 0x2f0d: 0x0080, 0x2f0e: 0x0080, 0x2f0f: 0x0080, 0x2f10: 0x0080, 0x2f11: 0x0080, + 0x2f12: 0x0080, 0x2f13: 0x0080, 0x2f14: 0x0080, 0x2f15: 0x0080, 0x2f16: 0x0080, 0x2f17: 0x0080, + 0x2f18: 0x0080, 0x2f19: 0x0080, 0x2f1a: 0x0080, 0x2f1b: 0x0080, 0x2f1c: 0x0080, 0x2f1d: 0x0080, + 0x2f1e: 0x0080, 0x2f1f: 0x0080, 0x2f20: 0x0080, 0x2f21: 0x0080, 0x2f22: 0x0080, 0x2f23: 0x0080, + 0x2f24: 0x0080, 0x2f25: 0x0080, 0x2f26: 0x008c, 0x2f27: 0x008c, 0x2f28: 0x008c, 0x2f29: 0x008c, + 0x2f2a: 0x008c, 0x2f2b: 0x008c, 0x2f2c: 0x008c, 0x2f2d: 0x008c, 0x2f2e: 0x008c, 0x2f2f: 0x008c, + 0x2f30: 0x0080, 0x2f31: 0x008c, 0x2f32: 0x008c, 0x2f33: 0x008c, 0x2f34: 0x008c, 0x2f35: 0x008c, + 0x2f36: 0x008c, 0x2f37: 0x008c, 0x2f38: 0x008c, 0x2f39: 0x008c, 0x2f3a: 0x008c, 0x2f3b: 0x008c, + 0x2f3c: 0x008c, 0x2f3d: 0x008c, 0x2f3e: 0x008c, 0x2f3f: 0x008c, + // Block 0xbd, offset 0x2f40 + 0x2f40: 0x008c, 0x2f41: 0x008c, 0x2f42: 0x008c, 0x2f43: 0x008c, 0x2f44: 0x008c, 0x2f45: 0x008c, + 0x2f46: 0x008c, 0x2f47: 0x008c, 0x2f48: 0x008c, 0x2f49: 0x008c, 0x2f4a: 0x008c, 0x2f4b: 0x008c, + 0x2f4c: 0x008c, 0x2f4d: 0x008c, 0x2f4e: 0x008c, 0x2f4f: 0x008c, 0x2f50: 0x008c, 0x2f51: 0x008c, + 0x2f52: 0x008c, 0x2f53: 0x008c, 0x2f54: 0x008c, 0x2f55: 0x008c, 0x2f56: 0x008c, 0x2f57: 0x008c, + 0x2f58: 0x008c, 0x2f59: 0x008c, 0x2f5a: 0x008c, 0x2f5b: 0x008c, 0x2f5c: 0x008c, 0x2f5d: 0x008c, + 0x2f5e: 0x0080, 0x2f5f: 0x0080, 0x2f60: 0x0040, 0x2f61: 0x0080, 0x2f62: 0x0080, 0x2f63: 0x0080, + 0x2f64: 0x0080, 0x2f65: 0x0080, 0x2f66: 0x0080, 0x2f67: 0x0080, 0x2f68: 0x0080, 0x2f69: 0x0080, + 0x2f6a: 0x0080, 0x2f6b: 0x0080, 0x2f6c: 0x0080, 0x2f6d: 0x0080, 0x2f6e: 0x0080, 0x2f6f: 0x0080, + 0x2f70: 0x0080, 0x2f71: 0x0080, 0x2f72: 0x0080, 0x2f73: 0x0080, 0x2f74: 0x0080, 0x2f75: 0x0080, + 0x2f76: 0x0080, 0x2f77: 0x0080, 0x2f78: 0x0080, 0x2f79: 0x0080, 0x2f7a: 0x0080, 0x2f7b: 0x0080, + 0x2f7c: 0x0080, 0x2f7d: 0x0080, 0x2f7e: 0x0080, + // Block 0xbe, offset 0x2f80 + 0x2f82: 0x0080, 0x2f83: 0x0080, 0x2f84: 0x0080, 0x2f85: 0x0080, + 0x2f86: 0x0080, 0x2f87: 0x0080, 0x2f8a: 0x0080, 0x2f8b: 0x0080, + 0x2f8c: 0x0080, 0x2f8d: 0x0080, 0x2f8e: 0x0080, 0x2f8f: 0x0080, + 0x2f92: 0x0080, 0x2f93: 0x0080, 0x2f94: 0x0080, 0x2f95: 0x0080, 0x2f96: 0x0080, 0x2f97: 0x0080, + 0x2f9a: 0x0080, 0x2f9b: 0x0080, 0x2f9c: 0x0080, + 0x2fa0: 0x0080, 0x2fa1: 0x0080, 0x2fa2: 0x0080, 0x2fa3: 0x0080, + 0x2fa4: 0x0080, 0x2fa5: 0x0080, 0x2fa6: 0x0080, 0x2fa8: 0x0080, 0x2fa9: 0x0080, + 0x2faa: 0x0080, 0x2fab: 0x0080, 0x2fac: 0x0080, 0x2fad: 0x0080, 0x2fae: 0x0080, + 0x2fb9: 0x0040, 0x2fba: 0x0040, 0x2fbb: 0x0040, + 0x2fbc: 0x0080, 0x2fbd: 0x0080, + // Block 0xbf, offset 0x2fc0 + 0x2fc0: 0x00c0, 0x2fc1: 0x00c0, 0x2fc2: 0x00c0, 0x2fc3: 0x00c0, 0x2fc4: 0x00c0, 0x2fc5: 0x00c0, + 0x2fc6: 0x00c0, 0x2fc7: 0x00c0, 0x2fc8: 0x00c0, 0x2fc9: 0x00c0, 0x2fca: 0x00c0, 0x2fcb: 0x00c0, + 0x2fcd: 0x00c0, 0x2fce: 0x00c0, 0x2fcf: 0x00c0, 0x2fd0: 0x00c0, 0x2fd1: 0x00c0, + 0x2fd2: 0x00c0, 0x2fd3: 0x00c0, 0x2fd4: 0x00c0, 0x2fd5: 0x00c0, 0x2fd6: 0x00c0, 0x2fd7: 0x00c0, + 0x2fd8: 0x00c0, 0x2fd9: 0x00c0, 0x2fda: 0x00c0, 0x2fdb: 0x00c0, 0x2fdc: 0x00c0, 0x2fdd: 0x00c0, + 0x2fde: 0x00c0, 0x2fdf: 0x00c0, 0x2fe0: 0x00c0, 0x2fe1: 0x00c0, 0x2fe2: 0x00c0, 0x2fe3: 0x00c0, + 0x2fe4: 0x00c0, 0x2fe5: 0x00c0, 0x2fe6: 0x00c0, 0x2fe8: 0x00c0, 0x2fe9: 0x00c0, + 0x2fea: 0x00c0, 0x2feb: 0x00c0, 0x2fec: 0x00c0, 0x2fed: 0x00c0, 0x2fee: 0x00c0, 0x2fef: 0x00c0, + 0x2ff0: 0x00c0, 0x2ff1: 0x00c0, 0x2ff2: 0x00c0, 0x2ff3: 0x00c0, 0x2ff4: 0x00c0, 0x2ff5: 0x00c0, + 0x2ff6: 0x00c0, 0x2ff7: 0x00c0, 0x2ff8: 0x00c0, 0x2ff9: 0x00c0, 0x2ffa: 0x00c0, + 0x2ffc: 0x00c0, 0x2ffd: 0x00c0, 0x2fff: 0x00c0, + // Block 0xc0, offset 0x3000 + 0x3000: 0x00c0, 0x3001: 0x00c0, 0x3002: 0x00c0, 0x3003: 0x00c0, 0x3004: 0x00c0, 0x3005: 0x00c0, + 0x3006: 0x00c0, 0x3007: 0x00c0, 0x3008: 0x00c0, 0x3009: 0x00c0, 0x300a: 0x00c0, 0x300b: 0x00c0, + 0x300c: 0x00c0, 0x300d: 0x00c0, 0x3010: 0x00c0, 0x3011: 0x00c0, + 0x3012: 0x00c0, 0x3013: 0x00c0, 0x3014: 0x00c0, 0x3015: 0x00c0, 0x3016: 0x00c0, 0x3017: 0x00c0, + 0x3018: 0x00c0, 0x3019: 0x00c0, 0x301a: 0x00c0, 0x301b: 0x00c0, 0x301c: 0x00c0, 0x301d: 0x00c0, + // Block 0xc1, offset 0x3040 + 0x3040: 0x00c0, 0x3041: 0x00c0, 0x3042: 0x00c0, 0x3043: 0x00c0, 0x3044: 0x00c0, 0x3045: 0x00c0, + 0x3046: 0x00c0, 0x3047: 0x00c0, 0x3048: 0x00c0, 0x3049: 0x00c0, 0x304a: 0x00c0, 0x304b: 0x00c0, + 0x304c: 0x00c0, 0x304d: 0x00c0, 0x304e: 0x00c0, 0x304f: 0x00c0, 0x3050: 0x00c0, 0x3051: 0x00c0, + 0x3052: 0x00c0, 0x3053: 0x00c0, 0x3054: 0x00c0, 0x3055: 0x00c0, 0x3056: 0x00c0, 0x3057: 0x00c0, + 0x3058: 0x00c0, 0x3059: 0x00c0, 0x305a: 0x00c0, 0x305b: 0x00c0, 0x305c: 0x00c0, 0x305d: 0x00c0, + 0x305e: 0x00c0, 0x305f: 0x00c0, 0x3060: 0x00c0, 0x3061: 0x00c0, 0x3062: 0x00c0, 0x3063: 0x00c0, + 0x3064: 0x00c0, 0x3065: 0x00c0, 0x3066: 0x00c0, 0x3067: 0x00c0, 0x3068: 0x00c0, 0x3069: 0x00c0, + 0x306a: 0x00c0, 0x306b: 0x00c0, 0x306c: 0x00c0, 0x306d: 0x00c0, 0x306e: 0x00c0, 0x306f: 0x00c0, + 0x3070: 0x00c0, 0x3071: 0x00c0, 0x3072: 0x00c0, 0x3073: 0x00c0, 0x3074: 0x00c0, 0x3075: 0x00c0, + 0x3076: 0x00c0, 0x3077: 0x00c0, 0x3078: 0x00c0, 0x3079: 0x00c0, 0x307a: 0x00c0, + // Block 0xc2, offset 0x3080 + 0x3080: 0x0080, 0x3081: 0x0080, 0x3082: 0x0080, + 0x3087: 0x0080, 0x3088: 0x0080, 0x3089: 0x0080, 0x308a: 0x0080, 0x308b: 0x0080, + 0x308c: 0x0080, 0x308d: 0x0080, 0x308e: 0x0080, 0x308f: 0x0080, 0x3090: 0x0080, 0x3091: 0x0080, + 0x3092: 0x0080, 0x3093: 0x0080, 0x3094: 0x0080, 0x3095: 0x0080, 0x3096: 0x0080, 0x3097: 0x0080, + 0x3098: 0x0080, 0x3099: 0x0080, 0x309a: 0x0080, 0x309b: 0x0080, 0x309c: 0x0080, 0x309d: 0x0080, + 0x309e: 0x0080, 0x309f: 0x0080, 0x30a0: 0x0080, 0x30a1: 0x0080, 0x30a2: 0x0080, 0x30a3: 0x0080, + 0x30a4: 0x0080, 0x30a5: 0x0080, 0x30a6: 0x0080, 0x30a7: 0x0080, 0x30a8: 0x0080, 0x30a9: 0x0080, + 0x30aa: 0x0080, 0x30ab: 0x0080, 0x30ac: 0x0080, 0x30ad: 0x0080, 0x30ae: 0x0080, 0x30af: 0x0080, + 0x30b0: 0x0080, 0x30b1: 0x0080, 0x30b2: 0x0080, 0x30b3: 0x0080, + 0x30b7: 0x0080, 0x30b8: 0x0080, 0x30b9: 0x0080, 0x30ba: 0x0080, 0x30bb: 0x0080, + 0x30bc: 0x0080, 0x30bd: 0x0080, 0x30be: 0x0080, 0x30bf: 0x0080, + // Block 0xc3, offset 0x30c0 + 0x30c0: 0x0088, 0x30c1: 0x0088, 0x30c2: 0x0088, 0x30c3: 0x0088, 0x30c4: 0x0088, 0x30c5: 0x0088, + 0x30c6: 0x0088, 0x30c7: 0x0088, 0x30c8: 0x0088, 0x30c9: 0x0088, 0x30ca: 0x0088, 0x30cb: 0x0088, + 0x30cc: 0x0088, 0x30cd: 0x0088, 0x30ce: 0x0088, 0x30cf: 0x0088, 0x30d0: 0x0088, 0x30d1: 0x0088, + 0x30d2: 0x0088, 0x30d3: 0x0088, 0x30d4: 0x0088, 0x30d5: 0x0088, 0x30d6: 0x0088, 0x30d7: 0x0088, + 0x30d8: 0x0088, 0x30d9: 0x0088, 0x30da: 0x0088, 0x30db: 0x0088, 0x30dc: 0x0088, 0x30dd: 0x0088, + 0x30de: 0x0088, 0x30df: 0x0088, 0x30e0: 0x0088, 0x30e1: 0x0088, 0x30e2: 0x0088, 0x30e3: 0x0088, + 0x30e4: 0x0088, 0x30e5: 0x0088, 0x30e6: 0x0088, 0x30e7: 0x0088, 0x30e8: 0x0088, 0x30e9: 0x0088, + 0x30ea: 0x0088, 0x30eb: 0x0088, 0x30ec: 0x0088, 0x30ed: 0x0088, 0x30ee: 0x0088, 0x30ef: 0x0088, + 0x30f0: 0x0088, 0x30f1: 0x0088, 0x30f2: 0x0088, 0x30f3: 0x0088, 0x30f4: 0x0088, 0x30f5: 0x0088, + 0x30f6: 0x0088, 0x30f7: 0x0088, 0x30f8: 0x0088, 0x30f9: 0x0088, 0x30fa: 0x0088, 0x30fb: 0x0088, + 0x30fc: 0x0088, 0x30fd: 0x0088, 0x30fe: 0x0088, 0x30ff: 0x0088, + // Block 0xc4, offset 0x3100 + 0x3100: 0x0088, 0x3101: 0x0088, 0x3102: 0x0088, 0x3103: 0x0088, 0x3104: 0x0088, 0x3105: 0x0088, + 0x3106: 0x0088, 0x3107: 0x0088, 0x3108: 0x0088, 0x3109: 0x0088, 0x310a: 0x0088, 0x310b: 0x0088, + 0x310c: 0x0088, 0x310d: 0x0088, 0x310e: 0x0088, 0x3110: 0x0080, 0x3111: 0x0080, + 0x3112: 0x0080, 0x3113: 0x0080, 0x3114: 0x0080, 0x3115: 0x0080, 0x3116: 0x0080, 0x3117: 0x0080, + 0x3118: 0x0080, 0x3119: 0x0080, 0x311a: 0x0080, 0x311b: 0x0080, + 0x3120: 0x0088, + // Block 0xc5, offset 0x3140 + 0x3150: 0x0080, 0x3151: 0x0080, + 0x3152: 0x0080, 0x3153: 0x0080, 0x3154: 0x0080, 0x3155: 0x0080, 0x3156: 0x0080, 0x3157: 0x0080, + 0x3158: 0x0080, 0x3159: 0x0080, 0x315a: 0x0080, 0x315b: 0x0080, 0x315c: 0x0080, 0x315d: 0x0080, + 0x315e: 0x0080, 0x315f: 0x0080, 0x3160: 0x0080, 0x3161: 0x0080, 0x3162: 0x0080, 0x3163: 0x0080, + 0x3164: 0x0080, 0x3165: 0x0080, 0x3166: 0x0080, 0x3167: 0x0080, 0x3168: 0x0080, 0x3169: 0x0080, + 0x316a: 0x0080, 0x316b: 0x0080, 0x316c: 0x0080, 0x316d: 0x0080, 0x316e: 0x0080, 0x316f: 0x0080, + 0x3170: 0x0080, 0x3171: 0x0080, 0x3172: 0x0080, 0x3173: 0x0080, 0x3174: 0x0080, 0x3175: 0x0080, + 0x3176: 0x0080, 0x3177: 0x0080, 0x3178: 0x0080, 0x3179: 0x0080, 0x317a: 0x0080, 0x317b: 0x0080, + 0x317c: 0x0080, 0x317d: 0x00c3, + // Block 0xc6, offset 0x3180 + 0x3180: 0x00c0, 0x3181: 0x00c0, 0x3182: 0x00c0, 0x3183: 0x00c0, 0x3184: 0x00c0, 0x3185: 0x00c0, + 0x3186: 0x00c0, 0x3187: 0x00c0, 0x3188: 0x00c0, 0x3189: 0x00c0, 0x318a: 0x00c0, 0x318b: 0x00c0, + 0x318c: 0x00c0, 0x318d: 0x00c0, 0x318e: 0x00c0, 0x318f: 0x00c0, 0x3190: 0x00c0, 0x3191: 0x00c0, + 0x3192: 0x00c0, 0x3193: 0x00c0, 0x3194: 0x00c0, 0x3195: 0x00c0, 0x3196: 0x00c0, 0x3197: 0x00c0, + 0x3198: 0x00c0, 0x3199: 0x00c0, 0x319a: 0x00c0, 0x319b: 0x00c0, 0x319c: 0x00c0, + 0x31a0: 0x00c0, 0x31a1: 0x00c0, 0x31a2: 0x00c0, 0x31a3: 0x00c0, + 0x31a4: 0x00c0, 0x31a5: 0x00c0, 0x31a6: 0x00c0, 0x31a7: 0x00c0, 0x31a8: 0x00c0, 0x31a9: 0x00c0, + 0x31aa: 0x00c0, 0x31ab: 0x00c0, 0x31ac: 0x00c0, 0x31ad: 0x00c0, 0x31ae: 0x00c0, 0x31af: 0x00c0, + 0x31b0: 0x00c0, 0x31b1: 0x00c0, 0x31b2: 0x00c0, 0x31b3: 0x00c0, 0x31b4: 0x00c0, 0x31b5: 0x00c0, + 0x31b6: 0x00c0, 0x31b7: 0x00c0, 0x31b8: 0x00c0, 0x31b9: 0x00c0, 0x31ba: 0x00c0, 0x31bb: 0x00c0, + 0x31bc: 0x00c0, 0x31bd: 0x00c0, 0x31be: 0x00c0, 0x31bf: 0x00c0, + // Block 0xc7, offset 0x31c0 + 0x31c0: 0x00c0, 0x31c1: 0x00c0, 0x31c2: 0x00c0, 0x31c3: 0x00c0, 0x31c4: 0x00c0, 0x31c5: 0x00c0, + 0x31c6: 0x00c0, 0x31c7: 0x00c0, 0x31c8: 0x00c0, 0x31c9: 0x00c0, 0x31ca: 0x00c0, 0x31cb: 0x00c0, + 0x31cc: 0x00c0, 0x31cd: 0x00c0, 0x31ce: 0x00c0, 0x31cf: 0x00c0, 0x31d0: 0x00c0, + 0x31e0: 0x00c3, 0x31e1: 0x0080, 0x31e2: 0x0080, 0x31e3: 0x0080, + 0x31e4: 0x0080, 0x31e5: 0x0080, 0x31e6: 0x0080, 0x31e7: 0x0080, 0x31e8: 0x0080, 0x31e9: 0x0080, + 0x31ea: 0x0080, 0x31eb: 0x0080, 0x31ec: 0x0080, 0x31ed: 0x0080, 0x31ee: 0x0080, 0x31ef: 0x0080, + 0x31f0: 0x0080, 0x31f1: 0x0080, 0x31f2: 0x0080, 0x31f3: 0x0080, 0x31f4: 0x0080, 0x31f5: 0x0080, + 0x31f6: 0x0080, 0x31f7: 0x0080, 0x31f8: 0x0080, 0x31f9: 0x0080, 0x31fa: 0x0080, 0x31fb: 0x0080, + // Block 0xc8, offset 0x3200 + 0x3200: 0x00c0, 0x3201: 0x00c0, 0x3202: 0x00c0, 0x3203: 0x00c0, 0x3204: 0x00c0, 0x3205: 0x00c0, + 0x3206: 0x00c0, 0x3207: 0x00c0, 0x3208: 0x00c0, 0x3209: 0x00c0, 0x320a: 0x00c0, 0x320b: 0x00c0, + 0x320c: 0x00c0, 0x320d: 0x00c0, 0x320e: 0x00c0, 0x320f: 0x00c0, 0x3210: 0x00c0, 0x3211: 0x00c0, + 0x3212: 0x00c0, 0x3213: 0x00c0, 0x3214: 0x00c0, 0x3215: 0x00c0, 0x3216: 0x00c0, 0x3217: 0x00c0, + 0x3218: 0x00c0, 0x3219: 0x00c0, 0x321a: 0x00c0, 0x321b: 0x00c0, 0x321c: 0x00c0, 0x321d: 0x00c0, + 0x321e: 0x00c0, 0x321f: 0x00c0, 0x3220: 0x0080, 0x3221: 0x0080, 0x3222: 0x0080, 0x3223: 0x0080, + 0x3230: 0x00c0, 0x3231: 0x00c0, 0x3232: 0x00c0, 0x3233: 0x00c0, 0x3234: 0x00c0, 0x3235: 0x00c0, + 0x3236: 0x00c0, 0x3237: 0x00c0, 0x3238: 0x00c0, 0x3239: 0x00c0, 0x323a: 0x00c0, 0x323b: 0x00c0, + 0x323c: 0x00c0, 0x323d: 0x00c0, 0x323e: 0x00c0, 0x323f: 0x00c0, + // Block 0xc9, offset 0x3240 + 0x3240: 0x00c0, 0x3241: 0x0080, 0x3242: 0x00c0, 0x3243: 0x00c0, 0x3244: 0x00c0, 0x3245: 0x00c0, + 0x3246: 0x00c0, 0x3247: 0x00c0, 0x3248: 0x00c0, 0x3249: 0x00c0, 0x324a: 0x0080, + 0x3250: 0x00c0, 0x3251: 0x00c0, + 0x3252: 0x00c0, 0x3253: 0x00c0, 0x3254: 0x00c0, 0x3255: 0x00c0, 0x3256: 0x00c0, 0x3257: 0x00c0, + 0x3258: 0x00c0, 0x3259: 0x00c0, 0x325a: 0x00c0, 0x325b: 0x00c0, 0x325c: 0x00c0, 0x325d: 0x00c0, + 0x325e: 0x00c0, 0x325f: 0x00c0, 0x3260: 0x00c0, 0x3261: 0x00c0, 0x3262: 0x00c0, 0x3263: 0x00c0, + 0x3264: 0x00c0, 0x3265: 0x00c0, 0x3266: 0x00c0, 0x3267: 0x00c0, 0x3268: 0x00c0, 0x3269: 0x00c0, + 0x326a: 0x00c0, 0x326b: 0x00c0, 0x326c: 0x00c0, 0x326d: 0x00c0, 0x326e: 0x00c0, 0x326f: 0x00c0, + 0x3270: 0x00c0, 0x3271: 0x00c0, 0x3272: 0x00c0, 0x3273: 0x00c0, 0x3274: 0x00c0, 0x3275: 0x00c0, + 0x3276: 0x00c3, 0x3277: 0x00c3, 0x3278: 0x00c3, 0x3279: 0x00c3, 0x327a: 0x00c3, + // Block 0xca, offset 0x3280 + 0x3280: 0x00c0, 0x3281: 0x00c0, 0x3282: 0x00c0, 0x3283: 0x00c0, 0x3284: 0x00c0, 0x3285: 0x00c0, + 0x3286: 0x00c0, 0x3287: 0x00c0, 0x3288: 0x00c0, 0x3289: 0x00c0, 0x328a: 0x00c0, 0x328b: 0x00c0, + 0x328c: 0x00c0, 0x328d: 0x00c0, 0x328e: 0x00c0, 0x328f: 0x00c0, 0x3290: 0x00c0, 0x3291: 0x00c0, + 0x3292: 0x00c0, 0x3293: 0x00c0, 0x3294: 0x00c0, 0x3295: 0x00c0, 0x3296: 0x00c0, 0x3297: 0x00c0, + 0x3298: 0x00c0, 0x3299: 0x00c0, 0x329a: 0x00c0, 0x329b: 0x00c0, 0x329c: 0x00c0, 0x329d: 0x00c0, + 0x329f: 0x0080, 0x32a0: 0x00c0, 0x32a1: 0x00c0, 0x32a2: 0x00c0, 0x32a3: 0x00c0, + 0x32a4: 0x00c0, 0x32a5: 0x00c0, 0x32a6: 0x00c0, 0x32a7: 0x00c0, 0x32a8: 0x00c0, 0x32a9: 0x00c0, + 0x32aa: 0x00c0, 0x32ab: 0x00c0, 0x32ac: 0x00c0, 0x32ad: 0x00c0, 0x32ae: 0x00c0, 0x32af: 0x00c0, + 0x32b0: 0x00c0, 0x32b1: 0x00c0, 0x32b2: 0x00c0, 0x32b3: 0x00c0, 0x32b4: 0x00c0, 0x32b5: 0x00c0, + 0x32b6: 0x00c0, 0x32b7: 0x00c0, 0x32b8: 0x00c0, 0x32b9: 0x00c0, 0x32ba: 0x00c0, 0x32bb: 0x00c0, + 0x32bc: 0x00c0, 0x32bd: 0x00c0, 0x32be: 0x00c0, 0x32bf: 0x00c0, + // Block 0xcb, offset 0x32c0 + 0x32c0: 0x00c0, 0x32c1: 0x00c0, 0x32c2: 0x00c0, 0x32c3: 0x00c0, + 0x32c8: 0x00c0, 0x32c9: 0x00c0, 0x32ca: 0x00c0, 0x32cb: 0x00c0, + 0x32cc: 0x00c0, 0x32cd: 0x00c0, 0x32ce: 0x00c0, 0x32cf: 0x00c0, 0x32d0: 0x0080, 0x32d1: 0x0080, + 0x32d2: 0x0080, 0x32d3: 0x0080, 0x32d4: 0x0080, 0x32d5: 0x0080, + // Block 0xcc, offset 0x3300 + 0x3300: 0x00c0, 0x3301: 0x00c0, 0x3302: 0x00c0, 0x3303: 0x00c0, 0x3304: 0x00c0, 0x3305: 0x00c0, + 0x3306: 0x00c0, 0x3307: 0x00c0, 0x3308: 0x00c0, 0x3309: 0x00c0, 0x330a: 0x00c0, 0x330b: 0x00c0, + 0x330c: 0x00c0, 0x330d: 0x00c0, 0x330e: 0x00c0, 0x330f: 0x00c0, 0x3310: 0x00c0, 0x3311: 0x00c0, + 0x3312: 0x00c0, 0x3313: 0x00c0, 0x3314: 0x00c0, 0x3315: 0x00c0, 0x3316: 0x00c0, 0x3317: 0x00c0, + 0x3318: 0x00c0, 0x3319: 0x00c0, 0x331a: 0x00c0, 0x331b: 0x00c0, 0x331c: 0x00c0, 0x331d: 0x00c0, + 0x3320: 0x00c0, 0x3321: 0x00c0, 0x3322: 0x00c0, 0x3323: 0x00c0, + 0x3324: 0x00c0, 0x3325: 0x00c0, 0x3326: 0x00c0, 0x3327: 0x00c0, 0x3328: 0x00c0, 0x3329: 0x00c0, + 0x3330: 0x00c0, 0x3331: 0x00c0, 0x3332: 0x00c0, 0x3333: 0x00c0, 0x3334: 0x00c0, 0x3335: 0x00c0, + 0x3336: 0x00c0, 0x3337: 0x00c0, 0x3338: 0x00c0, 0x3339: 0x00c0, 0x333a: 0x00c0, 0x333b: 0x00c0, + 0x333c: 0x00c0, 0x333d: 0x00c0, 0x333e: 0x00c0, 0x333f: 0x00c0, + // Block 0xcd, offset 0x3340 + 0x3340: 0x00c0, 0x3341: 0x00c0, 0x3342: 0x00c0, 0x3343: 0x00c0, 0x3344: 0x00c0, 0x3345: 0x00c0, + 0x3346: 0x00c0, 0x3347: 0x00c0, 0x3348: 0x00c0, 0x3349: 0x00c0, 0x334a: 0x00c0, 0x334b: 0x00c0, + 0x334c: 0x00c0, 0x334d: 0x00c0, 0x334e: 0x00c0, 0x334f: 0x00c0, 0x3350: 0x00c0, 0x3351: 0x00c0, + 0x3352: 0x00c0, 0x3353: 0x00c0, + 0x3358: 0x00c0, 0x3359: 0x00c0, 0x335a: 0x00c0, 0x335b: 0x00c0, 0x335c: 0x00c0, 0x335d: 0x00c0, + 0x335e: 0x00c0, 0x335f: 0x00c0, 0x3360: 0x00c0, 0x3361: 0x00c0, 0x3362: 0x00c0, 0x3363: 0x00c0, + 0x3364: 0x00c0, 0x3365: 0x00c0, 0x3366: 0x00c0, 0x3367: 0x00c0, 0x3368: 0x00c0, 0x3369: 0x00c0, + 0x336a: 0x00c0, 0x336b: 0x00c0, 0x336c: 0x00c0, 0x336d: 0x00c0, 0x336e: 0x00c0, 0x336f: 0x00c0, + 0x3370: 0x00c0, 0x3371: 0x00c0, 0x3372: 0x00c0, 0x3373: 0x00c0, 0x3374: 0x00c0, 0x3375: 0x00c0, + 0x3376: 0x00c0, 0x3377: 0x00c0, 0x3378: 0x00c0, 0x3379: 0x00c0, 0x337a: 0x00c0, 0x337b: 0x00c0, + // Block 0xce, offset 0x3380 + 0x3380: 0x00c0, 0x3381: 0x00c0, 0x3382: 0x00c0, 0x3383: 0x00c0, 0x3384: 0x00c0, 0x3385: 0x00c0, + 0x3386: 0x00c0, 0x3387: 0x00c0, 0x3388: 0x00c0, 0x3389: 0x00c0, 0x338a: 0x00c0, 0x338b: 0x00c0, + 0x338c: 0x00c0, 0x338d: 0x00c0, 0x338e: 0x00c0, 0x338f: 0x00c0, 0x3390: 0x00c0, 0x3391: 0x00c0, + 0x3392: 0x00c0, 0x3393: 0x00c0, 0x3394: 0x00c0, 0x3395: 0x00c0, 0x3396: 0x00c0, 0x3397: 0x00c0, + 0x3398: 0x00c0, 0x3399: 0x00c0, 0x339a: 0x00c0, 0x339b: 0x00c0, 0x339c: 0x00c0, 0x339d: 0x00c0, + 0x339e: 0x00c0, 0x339f: 0x00c0, 0x33a0: 0x00c0, 0x33a1: 0x00c0, 0x33a2: 0x00c0, 0x33a3: 0x00c0, + 0x33a4: 0x00c0, 0x33a5: 0x00c0, 0x33a6: 0x00c0, 0x33a7: 0x00c0, + 0x33b0: 0x00c0, 0x33b1: 0x00c0, 0x33b2: 0x00c0, 0x33b3: 0x00c0, 0x33b4: 0x00c0, 0x33b5: 0x00c0, + 0x33b6: 0x00c0, 0x33b7: 0x00c0, 0x33b8: 0x00c0, 0x33b9: 0x00c0, 0x33ba: 0x00c0, 0x33bb: 0x00c0, + 0x33bc: 0x00c0, 0x33bd: 0x00c0, 0x33be: 0x00c0, 0x33bf: 0x00c0, + // Block 0xcf, offset 0x33c0 + 0x33c0: 0x00c0, 0x33c1: 0x00c0, 0x33c2: 0x00c0, 0x33c3: 0x00c0, 0x33c4: 0x00c0, 0x33c5: 0x00c0, + 0x33c6: 0x00c0, 0x33c7: 0x00c0, 0x33c8: 0x00c0, 0x33c9: 0x00c0, 0x33ca: 0x00c0, 0x33cb: 0x00c0, + 0x33cc: 0x00c0, 0x33cd: 0x00c0, 0x33ce: 0x00c0, 0x33cf: 0x00c0, 0x33d0: 0x00c0, 0x33d1: 0x00c0, + 0x33d2: 0x00c0, 0x33d3: 0x00c0, 0x33d4: 0x00c0, 0x33d5: 0x00c0, 0x33d6: 0x00c0, 0x33d7: 0x00c0, + 0x33d8: 0x00c0, 0x33d9: 0x00c0, 0x33da: 0x00c0, 0x33db: 0x00c0, 0x33dc: 0x00c0, 0x33dd: 0x00c0, + 0x33de: 0x00c0, 0x33df: 0x00c0, 0x33e0: 0x00c0, 0x33e1: 0x00c0, 0x33e2: 0x00c0, 0x33e3: 0x00c0, + 0x33ef: 0x0080, + // Block 0xd0, offset 0x3400 + 0x3400: 0x00c0, 0x3401: 0x00c0, 0x3402: 0x00c0, 0x3403: 0x00c0, 0x3404: 0x00c0, 0x3405: 0x00c0, + 0x3406: 0x00c0, 0x3407: 0x00c0, 0x3408: 0x00c0, 0x3409: 0x00c0, 0x340a: 0x00c0, 0x340b: 0x00c0, + 0x340c: 0x00c0, 0x340d: 0x00c0, 0x340e: 0x00c0, 0x340f: 0x00c0, 0x3410: 0x00c0, 0x3411: 0x00c0, + 0x3412: 0x00c0, 0x3413: 0x00c0, 0x3414: 0x00c0, 0x3415: 0x00c0, 0x3416: 0x00c0, 0x3417: 0x00c0, + 0x3418: 0x00c0, 0x3419: 0x00c0, 0x341a: 0x00c0, 0x341b: 0x00c0, 0x341c: 0x00c0, 0x341d: 0x00c0, + 0x341e: 0x00c0, 0x341f: 0x00c0, 0x3420: 0x00c0, 0x3421: 0x00c0, 0x3422: 0x00c0, 0x3423: 0x00c0, + 0x3424: 0x00c0, 0x3425: 0x00c0, 0x3426: 0x00c0, 0x3427: 0x00c0, 0x3428: 0x00c0, 0x3429: 0x00c0, + 0x342a: 0x00c0, 0x342b: 0x00c0, 0x342c: 0x00c0, 0x342d: 0x00c0, 0x342e: 0x00c0, 0x342f: 0x00c0, + 0x3430: 0x00c0, 0x3431: 0x00c0, 0x3432: 0x00c0, 0x3433: 0x00c0, 0x3434: 0x00c0, 0x3435: 0x00c0, + 0x3436: 0x00c0, + // Block 0xd1, offset 0x3440 + 0x3440: 0x00c0, 0x3441: 0x00c0, 0x3442: 0x00c0, 0x3443: 0x00c0, 0x3444: 0x00c0, 0x3445: 0x00c0, + 0x3446: 0x00c0, 0x3447: 0x00c0, 0x3448: 0x00c0, 0x3449: 0x00c0, 0x344a: 0x00c0, 0x344b: 0x00c0, + 0x344c: 0x00c0, 0x344d: 0x00c0, 0x344e: 0x00c0, 0x344f: 0x00c0, 0x3450: 0x00c0, 0x3451: 0x00c0, + 0x3452: 0x00c0, 0x3453: 0x00c0, 0x3454: 0x00c0, 0x3455: 0x00c0, + 0x3460: 0x00c0, 0x3461: 0x00c0, 0x3462: 0x00c0, 0x3463: 0x00c0, + 0x3464: 0x00c0, 0x3465: 0x00c0, 0x3466: 0x00c0, 0x3467: 0x00c0, + // Block 0xd2, offset 0x3480 + 0x3480: 0x00c0, 0x3481: 0x00c0, 0x3482: 0x00c0, 0x3483: 0x00c0, 0x3484: 0x00c0, 0x3485: 0x00c0, + 0x3488: 0x00c0, 0x348a: 0x00c0, 0x348b: 0x00c0, + 0x348c: 0x00c0, 0x348d: 0x00c0, 0x348e: 0x00c0, 0x348f: 0x00c0, 0x3490: 0x00c0, 0x3491: 0x00c0, + 0x3492: 0x00c0, 0x3493: 0x00c0, 0x3494: 0x00c0, 0x3495: 0x00c0, 0x3496: 0x00c0, 0x3497: 0x00c0, + 0x3498: 0x00c0, 0x3499: 0x00c0, 0x349a: 0x00c0, 0x349b: 0x00c0, 0x349c: 0x00c0, 0x349d: 0x00c0, + 0x349e: 0x00c0, 0x349f: 0x00c0, 0x34a0: 0x00c0, 0x34a1: 0x00c0, 0x34a2: 0x00c0, 0x34a3: 0x00c0, + 0x34a4: 0x00c0, 0x34a5: 0x00c0, 0x34a6: 0x00c0, 0x34a7: 0x00c0, 0x34a8: 0x00c0, 0x34a9: 0x00c0, + 0x34aa: 0x00c0, 0x34ab: 0x00c0, 0x34ac: 0x00c0, 0x34ad: 0x00c0, 0x34ae: 0x00c0, 0x34af: 0x00c0, + 0x34b0: 0x00c0, 0x34b1: 0x00c0, 0x34b2: 0x00c0, 0x34b3: 0x00c0, 0x34b4: 0x00c0, 0x34b5: 0x00c0, + 0x34b7: 0x00c0, 0x34b8: 0x00c0, + 0x34bc: 0x00c0, 0x34bf: 0x00c0, + // Block 0xd3, offset 0x34c0 + 0x34c0: 0x00c0, 0x34c1: 0x00c0, 0x34c2: 0x00c0, 0x34c3: 0x00c0, 0x34c4: 0x00c0, 0x34c5: 0x00c0, + 0x34c6: 0x00c0, 0x34c7: 0x00c0, 0x34c8: 0x00c0, 0x34c9: 0x00c0, 0x34ca: 0x00c0, 0x34cb: 0x00c0, + 0x34cc: 0x00c0, 0x34cd: 0x00c0, 0x34ce: 0x00c0, 0x34cf: 0x00c0, 0x34d0: 0x00c0, 0x34d1: 0x00c0, + 0x34d2: 0x00c0, 0x34d3: 0x00c0, 0x34d4: 0x00c0, 0x34d5: 0x00c0, 0x34d7: 0x0080, + 0x34d8: 0x0080, 0x34d9: 0x0080, 0x34da: 0x0080, 0x34db: 0x0080, 0x34dc: 0x0080, 0x34dd: 0x0080, + 0x34de: 0x0080, 0x34df: 0x0080, 0x34e0: 0x00c0, 0x34e1: 0x00c0, 0x34e2: 0x00c0, 0x34e3: 0x00c0, + 0x34e4: 0x00c0, 0x34e5: 0x00c0, 0x34e6: 0x00c0, 0x34e7: 0x00c0, 0x34e8: 0x00c0, 0x34e9: 0x00c0, + 0x34ea: 0x00c0, 0x34eb: 0x00c0, 0x34ec: 0x00c0, 0x34ed: 0x00c0, 0x34ee: 0x00c0, 0x34ef: 0x00c0, + 0x34f0: 0x00c0, 0x34f1: 0x00c0, 0x34f2: 0x00c0, 0x34f3: 0x00c0, 0x34f4: 0x00c0, 0x34f5: 0x00c0, + 0x34f6: 0x00c0, 0x34f7: 0x0080, 0x34f8: 0x0080, 0x34f9: 0x0080, 0x34fa: 0x0080, 0x34fb: 0x0080, + 0x34fc: 0x0080, 0x34fd: 0x0080, 0x34fe: 0x0080, 0x34ff: 0x0080, + // Block 0xd4, offset 0x3500 + 0x3500: 0x00c0, 0x3501: 0x00c0, 0x3502: 0x00c0, 0x3503: 0x00c0, 0x3504: 0x00c0, 0x3505: 0x00c0, + 0x3506: 0x00c0, 0x3507: 0x00c0, 0x3508: 0x00c0, 0x3509: 0x00c0, 0x350a: 0x00c0, 0x350b: 0x00c0, + 0x350c: 0x00c0, 0x350d: 0x00c0, 0x350e: 0x00c0, 0x350f: 0x00c0, 0x3510: 0x00c0, 0x3511: 0x00c0, + 0x3512: 0x00c0, 0x3513: 0x00c0, 0x3514: 0x00c0, 0x3515: 0x00c0, 0x3516: 0x00c0, 0x3517: 0x00c0, + 0x3518: 0x00c0, 0x3519: 0x00c0, 0x351a: 0x00c0, 0x351b: 0x00c0, 0x351c: 0x00c0, 0x351d: 0x00c0, + 0x351e: 0x00c0, + 0x3527: 0x0080, 0x3528: 0x0080, 0x3529: 0x0080, + 0x352a: 0x0080, 0x352b: 0x0080, 0x352c: 0x0080, 0x352d: 0x0080, 0x352e: 0x0080, 0x352f: 0x0080, + // Block 0xd5, offset 0x3540 + 0x3560: 0x00c0, 0x3561: 0x00c0, 0x3562: 0x00c0, 0x3563: 0x00c0, + 0x3564: 0x00c0, 0x3565: 0x00c0, 0x3566: 0x00c0, 0x3567: 0x00c0, 0x3568: 0x00c0, 0x3569: 0x00c0, + 0x356a: 0x00c0, 0x356b: 0x00c0, 0x356c: 0x00c0, 0x356d: 0x00c0, 0x356e: 0x00c0, 0x356f: 0x00c0, + 0x3570: 0x00c0, 0x3571: 0x00c0, 0x3572: 0x00c0, 0x3574: 0x00c0, 0x3575: 0x00c0, + 0x357b: 0x0080, + 0x357c: 0x0080, 0x357d: 0x0080, 0x357e: 0x0080, 0x357f: 0x0080, + // Block 0xd6, offset 0x3580 + 0x3580: 0x00c0, 0x3581: 0x00c0, 0x3582: 0x00c0, 0x3583: 0x00c0, 0x3584: 0x00c0, 0x3585: 0x00c0, + 0x3586: 0x00c0, 0x3587: 0x00c0, 0x3588: 0x00c0, 0x3589: 0x00c0, 0x358a: 0x00c0, 0x358b: 0x00c0, + 0x358c: 0x00c0, 0x358d: 0x00c0, 0x358e: 0x00c0, 0x358f: 0x00c0, 0x3590: 0x00c0, 0x3591: 0x00c0, + 0x3592: 0x00c0, 0x3593: 0x00c0, 0x3594: 0x00c0, 0x3595: 0x00c0, 0x3596: 0x0080, 0x3597: 0x0080, + 0x3598: 0x0080, 0x3599: 0x0080, 0x359a: 0x0080, 0x359b: 0x0080, + 0x359f: 0x0080, 0x35a0: 0x00c0, 0x35a1: 0x00c0, 0x35a2: 0x00c0, 0x35a3: 0x00c0, + 0x35a4: 0x00c0, 0x35a5: 0x00c0, 0x35a6: 0x00c0, 0x35a7: 0x00c0, 0x35a8: 0x00c0, 0x35a9: 0x00c0, + 0x35aa: 0x00c0, 0x35ab: 0x00c0, 0x35ac: 0x00c0, 0x35ad: 0x00c0, 0x35ae: 0x00c0, 0x35af: 0x00c0, + 0x35b0: 0x00c0, 0x35b1: 0x00c0, 0x35b2: 0x00c0, 0x35b3: 0x00c0, 0x35b4: 0x00c0, 0x35b5: 0x00c0, + 0x35b6: 0x00c0, 0x35b7: 0x00c0, 0x35b8: 0x00c0, 0x35b9: 0x00c0, + 0x35bf: 0x0080, + // Block 0xd7, offset 0x35c0 + 0x35c0: 0x00c0, 0x35c1: 0x00c0, 0x35c2: 0x00c0, 0x35c3: 0x00c0, 0x35c4: 0x00c0, 0x35c5: 0x00c0, + 0x35c6: 0x00c0, 0x35c7: 0x00c0, 0x35c8: 0x00c0, 0x35c9: 0x00c0, 0x35ca: 0x00c0, 0x35cb: 0x00c0, + 0x35cc: 0x00c0, 0x35cd: 0x00c0, 0x35ce: 0x00c0, 0x35cf: 0x00c0, 0x35d0: 0x00c0, 0x35d1: 0x00c0, + 0x35d2: 0x00c0, 0x35d3: 0x00c0, 0x35d4: 0x00c0, 0x35d5: 0x00c0, 0x35d6: 0x00c0, 0x35d7: 0x00c0, + 0x35d8: 0x00c0, 0x35d9: 0x00c0, 0x35da: 0x00c0, 0x35db: 0x00c0, 0x35dc: 0x00c0, 0x35dd: 0x00c0, + 0x35de: 0x00c0, 0x35df: 0x00c0, 0x35e0: 0x00c0, 0x35e1: 0x00c0, 0x35e2: 0x00c0, 0x35e3: 0x00c0, + 0x35e4: 0x00c0, 0x35e5: 0x00c0, 0x35e6: 0x00c0, 0x35e7: 0x00c0, 0x35e8: 0x00c0, 0x35e9: 0x00c0, + 0x35ea: 0x00c0, 0x35eb: 0x00c0, 0x35ec: 0x00c0, 0x35ed: 0x00c0, 0x35ee: 0x00c0, 0x35ef: 0x00c0, + 0x35f0: 0x00c0, 0x35f1: 0x00c0, 0x35f2: 0x00c0, 0x35f3: 0x00c0, 0x35f4: 0x00c0, 0x35f5: 0x00c0, + 0x35f6: 0x00c0, 0x35f7: 0x00c0, + 0x35fc: 0x0080, 0x35fd: 0x0080, 0x35fe: 0x00c0, 0x35ff: 0x00c0, + // Block 0xd8, offset 0x3600 + 0x3600: 0x00c0, 0x3601: 0x00c3, 0x3602: 0x00c3, 0x3603: 0x00c3, 0x3605: 0x00c3, + 0x3606: 0x00c3, + 0x360c: 0x00c3, 0x360d: 0x00c3, 0x360e: 0x00c3, 0x360f: 0x00c3, 0x3610: 0x00c0, 0x3611: 0x00c0, + 0x3612: 0x00c0, 0x3613: 0x00c0, 0x3615: 0x00c0, 0x3616: 0x00c0, 0x3617: 0x00c0, + 0x3619: 0x00c0, 0x361a: 0x00c0, 0x361b: 0x00c0, 0x361c: 0x00c0, 0x361d: 0x00c0, + 0x361e: 0x00c0, 0x361f: 0x00c0, 0x3620: 0x00c0, 0x3621: 0x00c0, 0x3622: 0x00c0, 0x3623: 0x00c0, + 0x3624: 0x00c0, 0x3625: 0x00c0, 0x3626: 0x00c0, 0x3627: 0x00c0, 0x3628: 0x00c0, 0x3629: 0x00c0, + 0x362a: 0x00c0, 0x362b: 0x00c0, 0x362c: 0x00c0, 0x362d: 0x00c0, 0x362e: 0x00c0, 0x362f: 0x00c0, + 0x3630: 0x00c0, 0x3631: 0x00c0, 0x3632: 0x00c0, 0x3633: 0x00c0, + 0x3638: 0x00c3, 0x3639: 0x00c3, 0x363a: 0x00c3, + 0x363f: 0x00c6, + // Block 0xd9, offset 0x3640 + 0x3640: 0x0080, 0x3641: 0x0080, 0x3642: 0x0080, 0x3643: 0x0080, 0x3644: 0x0080, 0x3645: 0x0080, + 0x3646: 0x0080, 0x3647: 0x0080, + 0x3650: 0x0080, 0x3651: 0x0080, + 0x3652: 0x0080, 0x3653: 0x0080, 0x3654: 0x0080, 0x3655: 0x0080, 0x3656: 0x0080, 0x3657: 0x0080, + 0x3658: 0x0080, + 0x3660: 0x00c0, 0x3661: 0x00c0, 0x3662: 0x00c0, 0x3663: 0x00c0, + 0x3664: 0x00c0, 0x3665: 0x00c0, 0x3666: 0x00c0, 0x3667: 0x00c0, 0x3668: 0x00c0, 0x3669: 0x00c0, + 0x366a: 0x00c0, 0x366b: 0x00c0, 0x366c: 0x00c0, 0x366d: 0x00c0, 0x366e: 0x00c0, 0x366f: 0x00c0, + 0x3670: 0x00c0, 0x3671: 0x00c0, 0x3672: 0x00c0, 0x3673: 0x00c0, 0x3674: 0x00c0, 0x3675: 0x00c0, + 0x3676: 0x00c0, 0x3677: 0x00c0, 0x3678: 0x00c0, 0x3679: 0x00c0, 0x367a: 0x00c0, 0x367b: 0x00c0, + 0x367c: 0x00c0, 0x367d: 0x0080, 0x367e: 0x0080, 0x367f: 0x0080, + // Block 0xda, offset 0x3680 + 0x3680: 0x00c0, 0x3681: 0x00c0, 0x3682: 0x00c0, 0x3683: 0x00c0, 0x3684: 0x00c0, 0x3685: 0x00c0, + 0x3686: 0x00c0, 0x3687: 0x00c0, 0x3688: 0x00c0, 0x3689: 0x00c0, 0x368a: 0x00c0, 0x368b: 0x00c0, + 0x368c: 0x00c0, 0x368d: 0x00c0, 0x368e: 0x00c0, 0x368f: 0x00c0, 0x3690: 0x00c0, 0x3691: 0x00c0, + 0x3692: 0x00c0, 0x3693: 0x00c0, 0x3694: 0x00c0, 0x3695: 0x00c0, 0x3696: 0x00c0, 0x3697: 0x00c0, + 0x3698: 0x00c0, 0x3699: 0x00c0, 0x369a: 0x00c0, 0x369b: 0x00c0, 0x369c: 0x00c0, 0x369d: 0x0080, + 0x369e: 0x0080, 0x369f: 0x0080, + // Block 0xdb, offset 0x36c0 + 0x36c0: 0x00c2, 0x36c1: 0x00c2, 0x36c2: 0x00c2, 0x36c3: 0x00c2, 0x36c4: 0x00c2, 0x36c5: 0x00c4, + 0x36c6: 0x00c0, 0x36c7: 0x00c4, 0x36c8: 0x0080, 0x36c9: 0x00c4, 0x36ca: 0x00c4, 0x36cb: 0x00c0, + 0x36cc: 0x00c0, 0x36cd: 0x00c1, 0x36ce: 0x00c4, 0x36cf: 0x00c4, 0x36d0: 0x00c4, 0x36d1: 0x00c4, + 0x36d2: 0x00c4, 0x36d3: 0x00c2, 0x36d4: 0x00c2, 0x36d5: 0x00c2, 0x36d6: 0x00c2, 0x36d7: 0x00c1, + 0x36d8: 0x00c2, 0x36d9: 0x00c2, 0x36da: 0x00c2, 0x36db: 0x00c2, 0x36dc: 0x00c2, 0x36dd: 0x00c4, + 0x36de: 0x00c2, 0x36df: 0x00c2, 0x36e0: 0x00c2, 0x36e1: 0x00c4, 0x36e2: 0x00c0, 0x36e3: 0x00c0, + 0x36e4: 0x00c4, 0x36e5: 0x00c3, 0x36e6: 0x00c3, + 0x36eb: 0x0082, 0x36ec: 0x0082, 0x36ed: 0x0082, 0x36ee: 0x0082, 0x36ef: 0x0084, + 0x36f0: 0x0080, 0x36f1: 0x0080, 0x36f2: 0x0080, 0x36f3: 0x0080, 0x36f4: 0x0080, 0x36f5: 0x0080, + 0x36f6: 0x0080, + // Block 0xdc, offset 0x3700 + 0x3700: 0x00c0, 0x3701: 0x00c0, 0x3702: 0x00c0, 0x3703: 0x00c0, 0x3704: 0x00c0, 0x3705: 0x00c0, + 0x3706: 0x00c0, 0x3707: 0x00c0, 0x3708: 0x00c0, 0x3709: 0x00c0, 0x370a: 0x00c0, 0x370b: 0x00c0, + 0x370c: 0x00c0, 0x370d: 0x00c0, 0x370e: 0x00c0, 0x370f: 0x00c0, 0x3710: 0x00c0, 0x3711: 0x00c0, + 0x3712: 0x00c0, 0x3713: 0x00c0, 0x3714: 0x00c0, 0x3715: 0x00c0, 0x3716: 0x00c0, 0x3717: 0x00c0, + 0x3718: 0x00c0, 0x3719: 0x00c0, 0x371a: 0x00c0, 0x371b: 0x00c0, 0x371c: 0x00c0, 0x371d: 0x00c0, + 0x371e: 0x00c0, 0x371f: 0x00c0, 0x3720: 0x00c0, 0x3721: 0x00c0, 0x3722: 0x00c0, 0x3723: 0x00c0, + 0x3724: 0x00c0, 0x3725: 0x00c0, 0x3726: 0x00c0, 0x3727: 0x00c0, 0x3728: 0x00c0, 0x3729: 0x00c0, + 0x372a: 0x00c0, 0x372b: 0x00c0, 0x372c: 0x00c0, 0x372d: 0x00c0, 0x372e: 0x00c0, 0x372f: 0x00c0, + 0x3730: 0x00c0, 0x3731: 0x00c0, 0x3732: 0x00c0, 0x3733: 0x00c0, 0x3734: 0x00c0, 0x3735: 0x00c0, + 0x3739: 0x0080, 0x373a: 0x0080, 0x373b: 0x0080, + 0x373c: 0x0080, 0x373d: 0x0080, 0x373e: 0x0080, 0x373f: 0x0080, + // Block 0xdd, offset 0x3740 + 0x3740: 0x00c0, 0x3741: 0x00c0, 0x3742: 0x00c0, 0x3743: 0x00c0, 0x3744: 0x00c0, 0x3745: 0x00c0, + 0x3746: 0x00c0, 0x3747: 0x00c0, 0x3748: 0x00c0, 0x3749: 0x00c0, 0x374a: 0x00c0, 0x374b: 0x00c0, + 0x374c: 0x00c0, 0x374d: 0x00c0, 0x374e: 0x00c0, 0x374f: 0x00c0, 0x3750: 0x00c0, 0x3751: 0x00c0, + 0x3752: 0x00c0, 0x3753: 0x00c0, 0x3754: 0x00c0, 0x3755: 0x00c0, + 0x3758: 0x0080, 0x3759: 0x0080, 0x375a: 0x0080, 0x375b: 0x0080, 0x375c: 0x0080, 0x375d: 0x0080, + 0x375e: 0x0080, 0x375f: 0x0080, 0x3760: 0x00c0, 0x3761: 0x00c0, 0x3762: 0x00c0, 0x3763: 0x00c0, + 0x3764: 0x00c0, 0x3765: 0x00c0, 0x3766: 0x00c0, 0x3767: 0x00c0, 0x3768: 0x00c0, 0x3769: 0x00c0, + 0x376a: 0x00c0, 0x376b: 0x00c0, 0x376c: 0x00c0, 0x376d: 0x00c0, 0x376e: 0x00c0, 0x376f: 0x00c0, + 0x3770: 0x00c0, 0x3771: 0x00c0, 0x3772: 0x00c0, + 0x3778: 0x0080, 0x3779: 0x0080, 0x377a: 0x0080, 0x377b: 0x0080, + 0x377c: 0x0080, 0x377d: 0x0080, 0x377e: 0x0080, 0x377f: 0x0080, + // Block 0xde, offset 0x3780 + 0x3780: 0x00c2, 0x3781: 0x00c4, 0x3782: 0x00c2, 0x3783: 0x00c4, 0x3784: 0x00c4, 0x3785: 0x00c4, + 0x3786: 0x00c2, 0x3787: 0x00c2, 0x3788: 0x00c2, 0x3789: 0x00c4, 0x378a: 0x00c2, 0x378b: 0x00c2, + 0x378c: 0x00c4, 0x378d: 0x00c2, 0x378e: 0x00c4, 0x378f: 0x00c4, 0x3790: 0x00c2, 0x3791: 0x00c4, + 0x3799: 0x0080, 0x379a: 0x0080, 0x379b: 0x0080, 0x379c: 0x0080, + 0x37a9: 0x0084, + 0x37aa: 0x0084, 0x37ab: 0x0084, 0x37ac: 0x0084, 0x37ad: 0x0082, 0x37ae: 0x0082, 0x37af: 0x0080, + // Block 0xdf, offset 0x37c0 + 0x37c0: 0x00c0, 0x37c1: 0x00c0, 0x37c2: 0x00c0, 0x37c3: 0x00c0, 0x37c4: 0x00c0, 0x37c5: 0x00c0, + 0x37c6: 0x00c0, 0x37c7: 0x00c0, 0x37c8: 0x00c0, 0x37c9: 0x00c0, 0x37ca: 0x00c0, 0x37cb: 0x00c0, + 0x37cc: 0x00c0, 0x37cd: 0x00c0, 0x37ce: 0x00c0, 0x37cf: 0x00c0, 0x37d0: 0x00c0, 0x37d1: 0x00c0, + 0x37d2: 0x00c0, 0x37d3: 0x00c0, 0x37d4: 0x00c0, 0x37d5: 0x00c0, 0x37d6: 0x00c0, 0x37d7: 0x00c0, + 0x37d8: 0x00c0, 0x37d9: 0x00c0, 0x37da: 0x00c0, 0x37db: 0x00c0, 0x37dc: 0x00c0, 0x37dd: 0x00c0, + 0x37de: 0x00c0, 0x37df: 0x00c0, 0x37e0: 0x00c0, 0x37e1: 0x00c0, 0x37e2: 0x00c0, 0x37e3: 0x00c0, + 0x37e4: 0x00c0, 0x37e5: 0x00c0, 0x37e6: 0x00c0, 0x37e7: 0x00c0, 0x37e8: 0x00c0, 0x37e9: 0x00c0, + 0x37ea: 0x00c0, 0x37eb: 0x00c0, 0x37ec: 0x00c0, 0x37ed: 0x00c0, 0x37ee: 0x00c0, 0x37ef: 0x00c0, + 0x37f0: 0x00c0, 0x37f1: 0x00c0, 0x37f2: 0x00c0, + // Block 0xe0, offset 0x3800 + 0x3800: 0x00c0, 0x3801: 0x00c0, 0x3802: 0x00c0, 0x3803: 0x00c0, 0x3804: 0x00c0, 0x3805: 0x00c0, + 0x3806: 0x00c0, 0x3807: 0x00c0, 0x3808: 0x00c0, 0x3809: 0x00c0, 0x380a: 0x00c0, 0x380b: 0x00c0, + 0x380c: 0x00c0, 0x380d: 0x00c0, 0x380e: 0x00c0, 0x380f: 0x00c0, 0x3810: 0x00c0, 0x3811: 0x00c0, + 0x3812: 0x00c0, 0x3813: 0x00c0, 0x3814: 0x00c0, 0x3815: 0x00c0, 0x3816: 0x00c0, 0x3817: 0x00c0, + 0x3818: 0x00c0, 0x3819: 0x00c0, 0x381a: 0x00c0, 0x381b: 0x00c0, 0x381c: 0x00c0, 0x381d: 0x00c0, + 0x381e: 0x00c0, 0x381f: 0x00c0, 0x3820: 0x00c0, 0x3821: 0x00c0, 0x3822: 0x00c0, 0x3823: 0x00c0, + 0x3824: 0x00c0, 0x3825: 0x00c0, 0x3826: 0x00c0, 0x3827: 0x00c0, 0x3828: 0x00c0, 0x3829: 0x00c0, + 0x382a: 0x00c0, 0x382b: 0x00c0, 0x382c: 0x00c0, 0x382d: 0x00c0, 0x382e: 0x00c0, 0x382f: 0x00c0, + 0x3830: 0x00c0, 0x3831: 0x00c0, 0x3832: 0x00c0, + 0x383a: 0x0080, 0x383b: 0x0080, + 0x383c: 0x0080, 0x383d: 0x0080, 0x383e: 0x0080, 0x383f: 0x0080, + // Block 0xe1, offset 0x3840 + 0x3860: 0x0080, 0x3861: 0x0080, 0x3862: 0x0080, 0x3863: 0x0080, + 0x3864: 0x0080, 0x3865: 0x0080, 0x3866: 0x0080, 0x3867: 0x0080, 0x3868: 0x0080, 0x3869: 0x0080, + 0x386a: 0x0080, 0x386b: 0x0080, 0x386c: 0x0080, 0x386d: 0x0080, 0x386e: 0x0080, 0x386f: 0x0080, + 0x3870: 0x0080, 0x3871: 0x0080, 0x3872: 0x0080, 0x3873: 0x0080, 0x3874: 0x0080, 0x3875: 0x0080, + 0x3876: 0x0080, 0x3877: 0x0080, 0x3878: 0x0080, 0x3879: 0x0080, 0x387a: 0x0080, 0x387b: 0x0080, + 0x387c: 0x0080, 0x387d: 0x0080, 0x387e: 0x0080, + // Block 0xe2, offset 0x3880 + 0x3880: 0x00c0, 0x3881: 0x00c3, 0x3882: 0x00c0, 0x3883: 0x00c0, 0x3884: 0x00c0, 0x3885: 0x00c0, + 0x3886: 0x00c0, 0x3887: 0x00c0, 0x3888: 0x00c0, 0x3889: 0x00c0, 0x388a: 0x00c0, 0x388b: 0x00c0, + 0x388c: 0x00c0, 0x388d: 0x00c0, 0x388e: 0x00c0, 0x388f: 0x00c0, 0x3890: 0x00c0, 0x3891: 0x00c0, + 0x3892: 0x00c0, 0x3893: 0x00c0, 0x3894: 0x00c0, 0x3895: 0x00c0, 0x3896: 0x00c0, 0x3897: 0x00c0, + 0x3898: 0x00c0, 0x3899: 0x00c0, 0x389a: 0x00c0, 0x389b: 0x00c0, 0x389c: 0x00c0, 0x389d: 0x00c0, + 0x389e: 0x00c0, 0x389f: 0x00c0, 0x38a0: 0x00c0, 0x38a1: 0x00c0, 0x38a2: 0x00c0, 0x38a3: 0x00c0, + 0x38a4: 0x00c0, 0x38a5: 0x00c0, 0x38a6: 0x00c0, 0x38a7: 0x00c0, 0x38a8: 0x00c0, 0x38a9: 0x00c0, + 0x38aa: 0x00c0, 0x38ab: 0x00c0, 0x38ac: 0x00c0, 0x38ad: 0x00c0, 0x38ae: 0x00c0, 0x38af: 0x00c0, + 0x38b0: 0x00c0, 0x38b1: 0x00c0, 0x38b2: 0x00c0, 0x38b3: 0x00c0, 0x38b4: 0x00c0, 0x38b5: 0x00c0, + 0x38b6: 0x00c0, 0x38b7: 0x00c0, 0x38b8: 0x00c3, 0x38b9: 0x00c3, 0x38ba: 0x00c3, 0x38bb: 0x00c3, + 0x38bc: 0x00c3, 0x38bd: 0x00c3, 0x38be: 0x00c3, 0x38bf: 0x00c3, + // Block 0xe3, offset 0x38c0 + 0x38c0: 0x00c3, 0x38c1: 0x00c3, 0x38c2: 0x00c3, 0x38c3: 0x00c3, 0x38c4: 0x00c3, 0x38c5: 0x00c3, + 0x38c6: 0x00c6, 0x38c7: 0x0080, 0x38c8: 0x0080, 0x38c9: 0x0080, 0x38ca: 0x0080, 0x38cb: 0x0080, + 0x38cc: 0x0080, 0x38cd: 0x0080, + 0x38d2: 0x0080, 0x38d3: 0x0080, 0x38d4: 0x0080, 0x38d5: 0x0080, 0x38d6: 0x0080, 0x38d7: 0x0080, + 0x38d8: 0x0080, 0x38d9: 0x0080, 0x38da: 0x0080, 0x38db: 0x0080, 0x38dc: 0x0080, 0x38dd: 0x0080, + 0x38de: 0x0080, 0x38df: 0x0080, 0x38e0: 0x0080, 0x38e1: 0x0080, 0x38e2: 0x0080, 0x38e3: 0x0080, + 0x38e4: 0x0080, 0x38e5: 0x0080, 0x38e6: 0x00c0, 0x38e7: 0x00c0, 0x38e8: 0x00c0, 0x38e9: 0x00c0, + 0x38ea: 0x00c0, 0x38eb: 0x00c0, 0x38ec: 0x00c0, 0x38ed: 0x00c0, 0x38ee: 0x00c0, 0x38ef: 0x00c0, + 0x38ff: 0x00c6, + // Block 0xe4, offset 0x3900 + 0x3900: 0x00c3, 0x3901: 0x00c3, 0x3902: 0x00c0, 0x3903: 0x00c0, 0x3904: 0x00c0, 0x3905: 0x00c0, + 0x3906: 0x00c0, 0x3907: 0x00c0, 0x3908: 0x00c0, 0x3909: 0x00c0, 0x390a: 0x00c0, 0x390b: 0x00c0, + 0x390c: 0x00c0, 0x390d: 0x00c0, 0x390e: 0x00c0, 0x390f: 0x00c0, 0x3910: 0x00c0, 0x3911: 0x00c0, + 0x3912: 0x00c0, 0x3913: 0x00c0, 0x3914: 0x00c0, 0x3915: 0x00c0, 0x3916: 0x00c0, 0x3917: 0x00c0, + 0x3918: 0x00c0, 0x3919: 0x00c0, 0x391a: 0x00c0, 0x391b: 0x00c0, 0x391c: 0x00c0, 0x391d: 0x00c0, + 0x391e: 0x00c0, 0x391f: 0x00c0, 0x3920: 0x00c0, 0x3921: 0x00c0, 0x3922: 0x00c0, 0x3923: 0x00c0, + 0x3924: 0x00c0, 0x3925: 0x00c0, 0x3926: 0x00c0, 0x3927: 0x00c0, 0x3928: 0x00c0, 0x3929: 0x00c0, + 0x392a: 0x00c0, 0x392b: 0x00c0, 0x392c: 0x00c0, 0x392d: 0x00c0, 0x392e: 0x00c0, 0x392f: 0x00c0, + 0x3930: 0x00c0, 0x3931: 0x00c0, 0x3932: 0x00c0, 0x3933: 0x00c3, 0x3934: 0x00c3, 0x3935: 0x00c3, + 0x3936: 0x00c3, 0x3937: 0x00c0, 0x3938: 0x00c0, 0x3939: 0x00c6, 0x393a: 0x00c3, 0x393b: 0x0080, + 0x393c: 0x0080, 0x393d: 0x0040, 0x393e: 0x0080, 0x393f: 0x0080, + // Block 0xe5, offset 0x3940 + 0x3940: 0x0080, 0x3941: 0x0080, + 0x3950: 0x00c0, 0x3951: 0x00c0, + 0x3952: 0x00c0, 0x3953: 0x00c0, 0x3954: 0x00c0, 0x3955: 0x00c0, 0x3956: 0x00c0, 0x3957: 0x00c0, + 0x3958: 0x00c0, 0x3959: 0x00c0, 0x395a: 0x00c0, 0x395b: 0x00c0, 0x395c: 0x00c0, 0x395d: 0x00c0, + 0x395e: 0x00c0, 0x395f: 0x00c0, 0x3960: 0x00c0, 0x3961: 0x00c0, 0x3962: 0x00c0, 0x3963: 0x00c0, + 0x3964: 0x00c0, 0x3965: 0x00c0, 0x3966: 0x00c0, 0x3967: 0x00c0, 0x3968: 0x00c0, + 0x3970: 0x00c0, 0x3971: 0x00c0, 0x3972: 0x00c0, 0x3973: 0x00c0, 0x3974: 0x00c0, 0x3975: 0x00c0, + 0x3976: 0x00c0, 0x3977: 0x00c0, 0x3978: 0x00c0, 0x3979: 0x00c0, + // Block 0xe6, offset 0x3980 + 0x3980: 0x00c3, 0x3981: 0x00c3, 0x3982: 0x00c3, 0x3983: 0x00c0, 0x3984: 0x00c0, 0x3985: 0x00c0, + 0x3986: 0x00c0, 0x3987: 0x00c0, 0x3988: 0x00c0, 0x3989: 0x00c0, 0x398a: 0x00c0, 0x398b: 0x00c0, + 0x398c: 0x00c0, 0x398d: 0x00c0, 0x398e: 0x00c0, 0x398f: 0x00c0, 0x3990: 0x00c0, 0x3991: 0x00c0, + 0x3992: 0x00c0, 0x3993: 0x00c0, 0x3994: 0x00c0, 0x3995: 0x00c0, 0x3996: 0x00c0, 0x3997: 0x00c0, + 0x3998: 0x00c0, 0x3999: 0x00c0, 0x399a: 0x00c0, 0x399b: 0x00c0, 0x399c: 0x00c0, 0x399d: 0x00c0, + 0x399e: 0x00c0, 0x399f: 0x00c0, 0x39a0: 0x00c0, 0x39a1: 0x00c0, 0x39a2: 0x00c0, 0x39a3: 0x00c0, + 0x39a4: 0x00c0, 0x39a5: 0x00c0, 0x39a6: 0x00c0, 0x39a7: 0x00c3, 0x39a8: 0x00c3, 0x39a9: 0x00c3, + 0x39aa: 0x00c3, 0x39ab: 0x00c3, 0x39ac: 0x00c0, 0x39ad: 0x00c3, 0x39ae: 0x00c3, 0x39af: 0x00c3, + 0x39b0: 0x00c3, 0x39b1: 0x00c3, 0x39b2: 0x00c3, 0x39b3: 0x00c6, 0x39b4: 0x00c6, + 0x39b6: 0x00c0, 0x39b7: 0x00c0, 0x39b8: 0x00c0, 0x39b9: 0x00c0, 0x39ba: 0x00c0, 0x39bb: 0x00c0, + 0x39bc: 0x00c0, 0x39bd: 0x00c0, 0x39be: 0x00c0, 0x39bf: 0x00c0, + // Block 0xe7, offset 0x39c0 + 0x39c0: 0x0080, 0x39c1: 0x0080, 0x39c2: 0x0080, 0x39c3: 0x0080, + 0x39d0: 0x00c0, 0x39d1: 0x00c0, + 0x39d2: 0x00c0, 0x39d3: 0x00c0, 0x39d4: 0x00c0, 0x39d5: 0x00c0, 0x39d6: 0x00c0, 0x39d7: 0x00c0, + 0x39d8: 0x00c0, 0x39d9: 0x00c0, 0x39da: 0x00c0, 0x39db: 0x00c0, 0x39dc: 0x00c0, 0x39dd: 0x00c0, + 0x39de: 0x00c0, 0x39df: 0x00c0, 0x39e0: 0x00c0, 0x39e1: 0x00c0, 0x39e2: 0x00c0, 0x39e3: 0x00c0, + 0x39e4: 0x00c0, 0x39e5: 0x00c0, 0x39e6: 0x00c0, 0x39e7: 0x00c0, 0x39e8: 0x00c0, 0x39e9: 0x00c0, + 0x39ea: 0x00c0, 0x39eb: 0x00c0, 0x39ec: 0x00c0, 0x39ed: 0x00c0, 0x39ee: 0x00c0, 0x39ef: 0x00c0, + 0x39f0: 0x00c0, 0x39f1: 0x00c0, 0x39f2: 0x00c0, 0x39f3: 0x00c3, 0x39f4: 0x0080, 0x39f5: 0x0080, + 0x39f6: 0x00c0, + // Block 0xe8, offset 0x3a00 + 0x3a00: 0x00c3, 0x3a01: 0x00c3, 0x3a02: 0x00c0, 0x3a03: 0x00c0, 0x3a04: 0x00c0, 0x3a05: 0x00c0, + 0x3a06: 0x00c0, 0x3a07: 0x00c0, 0x3a08: 0x00c0, 0x3a09: 0x00c0, 0x3a0a: 0x00c0, 0x3a0b: 0x00c0, + 0x3a0c: 0x00c0, 0x3a0d: 0x00c0, 0x3a0e: 0x00c0, 0x3a0f: 0x00c0, 0x3a10: 0x00c0, 0x3a11: 0x00c0, + 0x3a12: 0x00c0, 0x3a13: 0x00c0, 0x3a14: 0x00c0, 0x3a15: 0x00c0, 0x3a16: 0x00c0, 0x3a17: 0x00c0, + 0x3a18: 0x00c0, 0x3a19: 0x00c0, 0x3a1a: 0x00c0, 0x3a1b: 0x00c0, 0x3a1c: 0x00c0, 0x3a1d: 0x00c0, + 0x3a1e: 0x00c0, 0x3a1f: 0x00c0, 0x3a20: 0x00c0, 0x3a21: 0x00c0, 0x3a22: 0x00c0, 0x3a23: 0x00c0, + 0x3a24: 0x00c0, 0x3a25: 0x00c0, 0x3a26: 0x00c0, 0x3a27: 0x00c0, 0x3a28: 0x00c0, 0x3a29: 0x00c0, + 0x3a2a: 0x00c0, 0x3a2b: 0x00c0, 0x3a2c: 0x00c0, 0x3a2d: 0x00c0, 0x3a2e: 0x00c0, 0x3a2f: 0x00c0, + 0x3a30: 0x00c0, 0x3a31: 0x00c0, 0x3a32: 0x00c0, 0x3a33: 0x00c0, 0x3a34: 0x00c0, 0x3a35: 0x00c0, + 0x3a36: 0x00c3, 0x3a37: 0x00c3, 0x3a38: 0x00c3, 0x3a39: 0x00c3, 0x3a3a: 0x00c3, 0x3a3b: 0x00c3, + 0x3a3c: 0x00c3, 0x3a3d: 0x00c3, 0x3a3e: 0x00c3, 0x3a3f: 0x00c0, + // Block 0xe9, offset 0x3a40 + 0x3a40: 0x00c5, 0x3a41: 0x00c0, 0x3a42: 0x00c0, 0x3a43: 0x00c0, 0x3a44: 0x00c0, 0x3a45: 0x0080, + 0x3a46: 0x0080, 0x3a47: 0x0080, 0x3a48: 0x0080, 0x3a49: 0x0080, 0x3a4a: 0x00c3, 0x3a4b: 0x00c3, + 0x3a4c: 0x00c3, 0x3a4d: 0x0080, 0x3a50: 0x00c0, 0x3a51: 0x00c0, + 0x3a52: 0x00c0, 0x3a53: 0x00c0, 0x3a54: 0x00c0, 0x3a55: 0x00c0, 0x3a56: 0x00c0, 0x3a57: 0x00c0, + 0x3a58: 0x00c0, 0x3a59: 0x00c0, 0x3a5a: 0x00c0, 0x3a5b: 0x0080, 0x3a5c: 0x00c0, 0x3a5d: 0x0080, + 0x3a5e: 0x0080, 0x3a5f: 0x0080, 0x3a61: 0x0080, 0x3a62: 0x0080, 0x3a63: 0x0080, + 0x3a64: 0x0080, 0x3a65: 0x0080, 0x3a66: 0x0080, 0x3a67: 0x0080, 0x3a68: 0x0080, 0x3a69: 0x0080, + 0x3a6a: 0x0080, 0x3a6b: 0x0080, 0x3a6c: 0x0080, 0x3a6d: 0x0080, 0x3a6e: 0x0080, 0x3a6f: 0x0080, + 0x3a70: 0x0080, 0x3a71: 0x0080, 0x3a72: 0x0080, 0x3a73: 0x0080, 0x3a74: 0x0080, + // Block 0xea, offset 0x3a80 + 0x3a80: 0x00c0, 0x3a81: 0x00c0, 0x3a82: 0x00c0, 0x3a83: 0x00c0, 0x3a84: 0x00c0, 0x3a85: 0x00c0, + 0x3a86: 0x00c0, 0x3a87: 0x00c0, 0x3a88: 0x00c0, 0x3a89: 0x00c0, 0x3a8a: 0x00c0, 0x3a8b: 0x00c0, + 0x3a8c: 0x00c0, 0x3a8d: 0x00c0, 0x3a8e: 0x00c0, 0x3a8f: 0x00c0, 0x3a90: 0x00c0, 0x3a91: 0x00c0, + 0x3a93: 0x00c0, 0x3a94: 0x00c0, 0x3a95: 0x00c0, 0x3a96: 0x00c0, 0x3a97: 0x00c0, + 0x3a98: 0x00c0, 0x3a99: 0x00c0, 0x3a9a: 0x00c0, 0x3a9b: 0x00c0, 0x3a9c: 0x00c0, 0x3a9d: 0x00c0, + 0x3a9e: 0x00c0, 0x3a9f: 0x00c0, 0x3aa0: 0x00c0, 0x3aa1: 0x00c0, 0x3aa2: 0x00c0, 0x3aa3: 0x00c0, + 0x3aa4: 0x00c0, 0x3aa5: 0x00c0, 0x3aa6: 0x00c0, 0x3aa7: 0x00c0, 0x3aa8: 0x00c0, 0x3aa9: 0x00c0, + 0x3aaa: 0x00c0, 0x3aab: 0x00c0, 0x3aac: 0x00c0, 0x3aad: 0x00c0, 0x3aae: 0x00c0, 0x3aaf: 0x00c3, + 0x3ab0: 0x00c3, 0x3ab1: 0x00c3, 0x3ab2: 0x00c0, 0x3ab3: 0x00c0, 0x3ab4: 0x00c3, 0x3ab5: 0x00c5, + 0x3ab6: 0x00c3, 0x3ab7: 0x00c3, 0x3ab8: 0x0080, 0x3ab9: 0x0080, 0x3aba: 0x0080, 0x3abb: 0x0080, + 0x3abc: 0x0080, 0x3abd: 0x0080, 0x3abe: 0x00c3, + // Block 0xeb, offset 0x3ac0 + 0x3ac0: 0x00c0, 0x3ac1: 0x00c0, 0x3ac2: 0x00c0, 0x3ac3: 0x00c0, 0x3ac4: 0x00c0, 0x3ac5: 0x00c0, + 0x3ac6: 0x00c0, 0x3ac8: 0x00c0, 0x3aca: 0x00c0, 0x3acb: 0x00c0, + 0x3acc: 0x00c0, 0x3acd: 0x00c0, 0x3acf: 0x00c0, 0x3ad0: 0x00c0, 0x3ad1: 0x00c0, + 0x3ad2: 0x00c0, 0x3ad3: 0x00c0, 0x3ad4: 0x00c0, 0x3ad5: 0x00c0, 0x3ad6: 0x00c0, 0x3ad7: 0x00c0, + 0x3ad8: 0x00c0, 0x3ad9: 0x00c0, 0x3ada: 0x00c0, 0x3adb: 0x00c0, 0x3adc: 0x00c0, 0x3add: 0x00c0, + 0x3adf: 0x00c0, 0x3ae0: 0x00c0, 0x3ae1: 0x00c0, 0x3ae2: 0x00c0, 0x3ae3: 0x00c0, + 0x3ae4: 0x00c0, 0x3ae5: 0x00c0, 0x3ae6: 0x00c0, 0x3ae7: 0x00c0, 0x3ae8: 0x00c0, 0x3ae9: 0x0080, + 0x3af0: 0x00c0, 0x3af1: 0x00c0, 0x3af2: 0x00c0, 0x3af3: 0x00c0, 0x3af4: 0x00c0, 0x3af5: 0x00c0, + 0x3af6: 0x00c0, 0x3af7: 0x00c0, 0x3af8: 0x00c0, 0x3af9: 0x00c0, 0x3afa: 0x00c0, 0x3afb: 0x00c0, + 0x3afc: 0x00c0, 0x3afd: 0x00c0, 0x3afe: 0x00c0, 0x3aff: 0x00c0, + // Block 0xec, offset 0x3b00 + 0x3b00: 0x00c0, 0x3b01: 0x00c0, 0x3b02: 0x00c0, 0x3b03: 0x00c0, 0x3b04: 0x00c0, 0x3b05: 0x00c0, + 0x3b06: 0x00c0, 0x3b07: 0x00c0, 0x3b08: 0x00c0, 0x3b09: 0x00c0, 0x3b0a: 0x00c0, 0x3b0b: 0x00c0, + 0x3b0c: 0x00c0, 0x3b0d: 0x00c0, 0x3b0e: 0x00c0, 0x3b0f: 0x00c0, 0x3b10: 0x00c0, 0x3b11: 0x00c0, + 0x3b12: 0x00c0, 0x3b13: 0x00c0, 0x3b14: 0x00c0, 0x3b15: 0x00c0, 0x3b16: 0x00c0, 0x3b17: 0x00c0, + 0x3b18: 0x00c0, 0x3b19: 0x00c0, 0x3b1a: 0x00c0, 0x3b1b: 0x00c0, 0x3b1c: 0x00c0, 0x3b1d: 0x00c0, + 0x3b1e: 0x00c0, 0x3b1f: 0x00c3, 0x3b20: 0x00c0, 0x3b21: 0x00c0, 0x3b22: 0x00c0, 0x3b23: 0x00c3, + 0x3b24: 0x00c3, 0x3b25: 0x00c3, 0x3b26: 0x00c3, 0x3b27: 0x00c3, 0x3b28: 0x00c3, 0x3b29: 0x00c3, + 0x3b2a: 0x00c6, + 0x3b30: 0x00c0, 0x3b31: 0x00c0, 0x3b32: 0x00c0, 0x3b33: 0x00c0, 0x3b34: 0x00c0, 0x3b35: 0x00c0, + 0x3b36: 0x00c0, 0x3b37: 0x00c0, 0x3b38: 0x00c0, 0x3b39: 0x00c0, + // Block 0xed, offset 0x3b40 + 0x3b40: 0x00c3, 0x3b41: 0x00c3, 0x3b42: 0x00c0, 0x3b43: 0x00c0, 0x3b45: 0x00c0, + 0x3b46: 0x00c0, 0x3b47: 0x00c0, 0x3b48: 0x00c0, 0x3b49: 0x00c0, 0x3b4a: 0x00c0, 0x3b4b: 0x00c0, + 0x3b4c: 0x00c0, 0x3b4f: 0x00c0, 0x3b50: 0x00c0, + 0x3b53: 0x00c0, 0x3b54: 0x00c0, 0x3b55: 0x00c0, 0x3b56: 0x00c0, 0x3b57: 0x00c0, + 0x3b58: 0x00c0, 0x3b59: 0x00c0, 0x3b5a: 0x00c0, 0x3b5b: 0x00c0, 0x3b5c: 0x00c0, 0x3b5d: 0x00c0, + 0x3b5e: 0x00c0, 0x3b5f: 0x00c0, 0x3b60: 0x00c0, 0x3b61: 0x00c0, 0x3b62: 0x00c0, 0x3b63: 0x00c0, + 0x3b64: 0x00c0, 0x3b65: 0x00c0, 0x3b66: 0x00c0, 0x3b67: 0x00c0, 0x3b68: 0x00c0, + 0x3b6a: 0x00c0, 0x3b6b: 0x00c0, 0x3b6c: 0x00c0, 0x3b6d: 0x00c0, 0x3b6e: 0x00c0, 0x3b6f: 0x00c0, + 0x3b70: 0x00c0, 0x3b72: 0x00c0, 0x3b73: 0x00c0, 0x3b75: 0x00c0, + 0x3b76: 0x00c0, 0x3b77: 0x00c0, 0x3b78: 0x00c0, 0x3b79: 0x00c0, + 0x3b7c: 0x00c3, 0x3b7d: 0x00c0, 0x3b7e: 0x00c0, 0x3b7f: 0x00c0, + // Block 0xee, offset 0x3b80 + 0x3b80: 0x00c3, 0x3b81: 0x00c0, 0x3b82: 0x00c0, 0x3b83: 0x00c0, 0x3b84: 0x00c0, + 0x3b87: 0x00c0, 0x3b88: 0x00c0, 0x3b8b: 0x00c0, + 0x3b8c: 0x00c0, 0x3b8d: 0x00c5, 0x3b90: 0x00c0, + 0x3b97: 0x00c0, + 0x3b9d: 0x00c0, + 0x3b9e: 0x00c0, 0x3b9f: 0x00c0, 0x3ba0: 0x00c0, 0x3ba1: 0x00c0, 0x3ba2: 0x00c0, 0x3ba3: 0x00c0, + 0x3ba6: 0x00c3, 0x3ba7: 0x00c3, 0x3ba8: 0x00c3, 0x3ba9: 0x00c3, + 0x3baa: 0x00c3, 0x3bab: 0x00c3, 0x3bac: 0x00c3, + 0x3bb0: 0x00c3, 0x3bb1: 0x00c3, 0x3bb2: 0x00c3, 0x3bb3: 0x00c3, 0x3bb4: 0x00c3, + // Block 0xef, offset 0x3bc0 + 0x3bc0: 0x00c0, 0x3bc1: 0x00c0, 0x3bc2: 0x00c0, 0x3bc3: 0x00c0, 0x3bc4: 0x00c0, 0x3bc5: 0x00c0, + 0x3bc6: 0x00c0, 0x3bc7: 0x00c0, 0x3bc8: 0x00c0, 0x3bc9: 0x00c0, 0x3bca: 0x00c0, 0x3bcb: 0x00c0, + 0x3bcc: 0x00c0, 0x3bcd: 0x00c0, 0x3bce: 0x00c0, 0x3bcf: 0x00c0, 0x3bd0: 0x00c0, 0x3bd1: 0x00c0, + 0x3bd2: 0x00c0, 0x3bd3: 0x00c0, 0x3bd4: 0x00c0, 0x3bd5: 0x00c0, 0x3bd6: 0x00c0, 0x3bd7: 0x00c0, + 0x3bd8: 0x00c0, 0x3bd9: 0x00c0, 0x3bda: 0x00c0, 0x3bdb: 0x00c0, 0x3bdc: 0x00c0, 0x3bdd: 0x00c0, + 0x3bde: 0x00c0, 0x3bdf: 0x00c0, 0x3be0: 0x00c0, 0x3be1: 0x00c0, 0x3be2: 0x00c0, 0x3be3: 0x00c0, + 0x3be4: 0x00c0, 0x3be5: 0x00c0, 0x3be6: 0x00c0, 0x3be7: 0x00c0, 0x3be8: 0x00c0, 0x3be9: 0x00c0, + 0x3bea: 0x00c0, 0x3beb: 0x00c0, 0x3bec: 0x00c0, 0x3bed: 0x00c0, 0x3bee: 0x00c0, 0x3bef: 0x00c0, + 0x3bf0: 0x00c0, 0x3bf1: 0x00c0, 0x3bf2: 0x00c0, 0x3bf3: 0x00c0, 0x3bf4: 0x00c0, 0x3bf5: 0x00c0, + 0x3bf6: 0x00c0, 0x3bf7: 0x00c0, 0x3bf8: 0x00c3, 0x3bf9: 0x00c3, 0x3bfa: 0x00c3, 0x3bfb: 0x00c3, + 0x3bfc: 0x00c3, 0x3bfd: 0x00c3, 0x3bfe: 0x00c3, 0x3bff: 0x00c3, + // Block 0xf0, offset 0x3c00 + 0x3c00: 0x00c0, 0x3c01: 0x00c0, 0x3c02: 0x00c6, 0x3c03: 0x00c3, 0x3c04: 0x00c3, 0x3c05: 0x00c0, + 0x3c06: 0x00c3, 0x3c07: 0x00c0, 0x3c08: 0x00c0, 0x3c09: 0x00c0, 0x3c0a: 0x00c0, 0x3c0b: 0x0080, + 0x3c0c: 0x0080, 0x3c0d: 0x0080, 0x3c0e: 0x0080, 0x3c0f: 0x0080, 0x3c10: 0x00c0, 0x3c11: 0x00c0, + 0x3c12: 0x00c0, 0x3c13: 0x00c0, 0x3c14: 0x00c0, 0x3c15: 0x00c0, 0x3c16: 0x00c0, 0x3c17: 0x00c0, + 0x3c18: 0x00c0, 0x3c19: 0x00c0, 0x3c1b: 0x0080, 0x3c1d: 0x0080, + // Block 0xf1, offset 0x3c40 + 0x3c40: 0x00c0, 0x3c41: 0x00c0, 0x3c42: 0x00c0, 0x3c43: 0x00c0, 0x3c44: 0x00c0, 0x3c45: 0x00c0, + 0x3c46: 0x00c0, 0x3c47: 0x00c0, 0x3c48: 0x00c0, 0x3c49: 0x00c0, 0x3c4a: 0x00c0, 0x3c4b: 0x00c0, + 0x3c4c: 0x00c0, 0x3c4d: 0x00c0, 0x3c4e: 0x00c0, 0x3c4f: 0x00c0, 0x3c50: 0x00c0, 0x3c51: 0x00c0, + 0x3c52: 0x00c0, 0x3c53: 0x00c0, 0x3c54: 0x00c0, 0x3c55: 0x00c0, 0x3c56: 0x00c0, 0x3c57: 0x00c0, + 0x3c58: 0x00c0, 0x3c59: 0x00c0, 0x3c5a: 0x00c0, 0x3c5b: 0x00c0, 0x3c5c: 0x00c0, 0x3c5d: 0x00c0, + 0x3c5e: 0x00c0, 0x3c5f: 0x00c0, 0x3c60: 0x00c0, 0x3c61: 0x00c0, 0x3c62: 0x00c0, 0x3c63: 0x00c0, + 0x3c64: 0x00c0, 0x3c65: 0x00c0, 0x3c66: 0x00c0, 0x3c67: 0x00c0, 0x3c68: 0x00c0, 0x3c69: 0x00c0, + 0x3c6a: 0x00c0, 0x3c6b: 0x00c0, 0x3c6c: 0x00c0, 0x3c6d: 0x00c0, 0x3c6e: 0x00c0, 0x3c6f: 0x00c0, + 0x3c70: 0x00c0, 0x3c71: 0x00c0, 0x3c72: 0x00c0, 0x3c73: 0x00c3, 0x3c74: 0x00c3, 0x3c75: 0x00c3, + 0x3c76: 0x00c3, 0x3c77: 0x00c3, 0x3c78: 0x00c3, 0x3c79: 0x00c0, 0x3c7a: 0x00c3, 0x3c7b: 0x00c0, + 0x3c7c: 0x00c0, 0x3c7d: 0x00c0, 0x3c7e: 0x00c0, 0x3c7f: 0x00c3, + // Block 0xf2, offset 0x3c80 + 0x3c80: 0x00c3, 0x3c81: 0x00c0, 0x3c82: 0x00c6, 0x3c83: 0x00c3, 0x3c84: 0x00c0, 0x3c85: 0x00c0, + 0x3c86: 0x0080, 0x3c87: 0x00c0, + 0x3c90: 0x00c0, 0x3c91: 0x00c0, + 0x3c92: 0x00c0, 0x3c93: 0x00c0, 0x3c94: 0x00c0, 0x3c95: 0x00c0, 0x3c96: 0x00c0, 0x3c97: 0x00c0, + 0x3c98: 0x00c0, 0x3c99: 0x00c0, + // Block 0xf3, offset 0x3cc0 + 0x3cc0: 0x00c0, 0x3cc1: 0x00c0, 0x3cc2: 0x00c0, 0x3cc3: 0x00c0, 0x3cc4: 0x00c0, 0x3cc5: 0x00c0, + 0x3cc6: 0x00c0, 0x3cc7: 0x00c0, 0x3cc8: 0x00c0, 0x3cc9: 0x00c0, 0x3cca: 0x00c0, 0x3ccb: 0x00c0, + 0x3ccc: 0x00c0, 0x3ccd: 0x00c0, 0x3cce: 0x00c0, 0x3ccf: 0x00c0, 0x3cd0: 0x00c0, 0x3cd1: 0x00c0, + 0x3cd2: 0x00c0, 0x3cd3: 0x00c0, 0x3cd4: 0x00c0, 0x3cd5: 0x00c0, 0x3cd6: 0x00c0, 0x3cd7: 0x00c0, + 0x3cd8: 0x00c0, 0x3cd9: 0x00c0, 0x3cda: 0x00c0, 0x3cdb: 0x00c0, 0x3cdc: 0x00c0, 0x3cdd: 0x00c0, + 0x3cde: 0x00c0, 0x3cdf: 0x00c0, 0x3ce0: 0x00c0, 0x3ce1: 0x00c0, 0x3ce2: 0x00c0, 0x3ce3: 0x00c0, + 0x3ce4: 0x00c0, 0x3ce5: 0x00c0, 0x3ce6: 0x00c0, 0x3ce7: 0x00c0, 0x3ce8: 0x00c0, 0x3ce9: 0x00c0, + 0x3cea: 0x00c0, 0x3ceb: 0x00c0, 0x3cec: 0x00c0, 0x3ced: 0x00c0, 0x3cee: 0x00c0, 0x3cef: 0x00c0, + 0x3cf0: 0x00c0, 0x3cf1: 0x00c0, 0x3cf2: 0x00c3, 0x3cf3: 0x00c3, 0x3cf4: 0x00c3, 0x3cf5: 0x00c3, + 0x3cf8: 0x00c0, 0x3cf9: 0x00c0, 0x3cfa: 0x00c0, 0x3cfb: 0x00c0, + 0x3cfc: 0x00c3, 0x3cfd: 0x00c3, 0x3cfe: 0x00c0, 0x3cff: 0x00c6, + // Block 0xf4, offset 0x3d00 + 0x3d00: 0x00c3, 0x3d01: 0x0080, 0x3d02: 0x0080, 0x3d03: 0x0080, 0x3d04: 0x0080, 0x3d05: 0x0080, + 0x3d06: 0x0080, 0x3d07: 0x0080, 0x3d08: 0x0080, 0x3d09: 0x0080, 0x3d0a: 0x0080, 0x3d0b: 0x0080, + 0x3d0c: 0x0080, 0x3d0d: 0x0080, 0x3d0e: 0x0080, 0x3d0f: 0x0080, 0x3d10: 0x0080, 0x3d11: 0x0080, + 0x3d12: 0x0080, 0x3d13: 0x0080, 0x3d14: 0x0080, 0x3d15: 0x0080, 0x3d16: 0x0080, 0x3d17: 0x0080, + 0x3d18: 0x00c0, 0x3d19: 0x00c0, 0x3d1a: 0x00c0, 0x3d1b: 0x00c0, 0x3d1c: 0x00c3, 0x3d1d: 0x00c3, + // Block 0xf5, offset 0x3d40 + 0x3d40: 0x00c0, 0x3d41: 0x00c0, 0x3d42: 0x00c0, 0x3d43: 0x00c0, 0x3d44: 0x00c0, 0x3d45: 0x00c0, + 0x3d46: 0x00c0, 0x3d47: 0x00c0, 0x3d48: 0x00c0, 0x3d49: 0x00c0, 0x3d4a: 0x00c0, 0x3d4b: 0x00c0, + 0x3d4c: 0x00c0, 0x3d4d: 0x00c0, 0x3d4e: 0x00c0, 0x3d4f: 0x00c0, 0x3d50: 0x00c0, 0x3d51: 0x00c0, + 0x3d52: 0x00c0, 0x3d53: 0x00c0, 0x3d54: 0x00c0, 0x3d55: 0x00c0, 0x3d56: 0x00c0, 0x3d57: 0x00c0, + 0x3d58: 0x00c0, 0x3d59: 0x00c0, 0x3d5a: 0x00c0, 0x3d5b: 0x00c0, 0x3d5c: 0x00c0, 0x3d5d: 0x00c0, + 0x3d5e: 0x00c0, 0x3d5f: 0x00c0, 0x3d60: 0x00c0, 0x3d61: 0x00c0, 0x3d62: 0x00c0, 0x3d63: 0x00c0, + 0x3d64: 0x00c0, 0x3d65: 0x00c0, 0x3d66: 0x00c0, 0x3d67: 0x00c0, 0x3d68: 0x00c0, 0x3d69: 0x00c0, + 0x3d6a: 0x00c0, 0x3d6b: 0x00c0, 0x3d6c: 0x00c0, 0x3d6d: 0x00c0, 0x3d6e: 0x00c0, 0x3d6f: 0x00c0, + 0x3d70: 0x00c0, 0x3d71: 0x00c0, 0x3d72: 0x00c0, 0x3d73: 0x00c3, 0x3d74: 0x00c3, 0x3d75: 0x00c3, + 0x3d76: 0x00c3, 0x3d77: 0x00c3, 0x3d78: 0x00c3, 0x3d79: 0x00c3, 0x3d7a: 0x00c3, 0x3d7b: 0x00c0, + 0x3d7c: 0x00c0, 0x3d7d: 0x00c3, 0x3d7e: 0x00c0, 0x3d7f: 0x00c6, + // Block 0xf6, offset 0x3d80 + 0x3d80: 0x00c3, 0x3d81: 0x0080, 0x3d82: 0x0080, 0x3d83: 0x0080, 0x3d84: 0x00c0, + 0x3d90: 0x00c0, 0x3d91: 0x00c0, + 0x3d92: 0x00c0, 0x3d93: 0x00c0, 0x3d94: 0x00c0, 0x3d95: 0x00c0, 0x3d96: 0x00c0, 0x3d97: 0x00c0, + 0x3d98: 0x00c0, 0x3d99: 0x00c0, + 0x3da0: 0x0080, 0x3da1: 0x0080, 0x3da2: 0x0080, 0x3da3: 0x0080, + 0x3da4: 0x0080, 0x3da5: 0x0080, 0x3da6: 0x0080, 0x3da7: 0x0080, 0x3da8: 0x0080, 0x3da9: 0x0080, + 0x3daa: 0x0080, 0x3dab: 0x0080, 0x3dac: 0x0080, + // Block 0xf7, offset 0x3dc0 + 0x3dc0: 0x00c0, 0x3dc1: 0x00c0, 0x3dc2: 0x00c0, 0x3dc3: 0x00c0, 0x3dc4: 0x00c0, 0x3dc5: 0x00c0, + 0x3dc6: 0x00c0, 0x3dc7: 0x00c0, 0x3dc8: 0x00c0, 0x3dc9: 0x00c0, 0x3dca: 0x00c0, 0x3dcb: 0x00c0, + 0x3dcc: 0x00c0, 0x3dcd: 0x00c0, 0x3dce: 0x00c0, 0x3dcf: 0x00c0, 0x3dd0: 0x00c0, 0x3dd1: 0x00c0, + 0x3dd2: 0x00c0, 0x3dd3: 0x00c0, 0x3dd4: 0x00c0, 0x3dd5: 0x00c0, 0x3dd6: 0x00c0, 0x3dd7: 0x00c0, + 0x3dd8: 0x00c0, 0x3dd9: 0x00c0, 0x3dda: 0x00c0, 0x3ddb: 0x00c0, 0x3ddc: 0x00c0, 0x3ddd: 0x00c0, + 0x3dde: 0x00c0, 0x3ddf: 0x00c0, 0x3de0: 0x00c0, 0x3de1: 0x00c0, 0x3de2: 0x00c0, 0x3de3: 0x00c0, + 0x3de4: 0x00c0, 0x3de5: 0x00c0, 0x3de6: 0x00c0, 0x3de7: 0x00c0, 0x3de8: 0x00c0, 0x3de9: 0x00c0, + 0x3dea: 0x00c0, 0x3deb: 0x00c3, 0x3dec: 0x00c0, 0x3ded: 0x00c3, 0x3dee: 0x00c0, 0x3def: 0x00c0, + 0x3df0: 0x00c3, 0x3df1: 0x00c3, 0x3df2: 0x00c3, 0x3df3: 0x00c3, 0x3df4: 0x00c3, 0x3df5: 0x00c3, + 0x3df6: 0x00c5, 0x3df7: 0x00c3, + // Block 0xf8, offset 0x3e00 + 0x3e00: 0x00c0, 0x3e01: 0x00c0, 0x3e02: 0x00c0, 0x3e03: 0x00c0, 0x3e04: 0x00c0, 0x3e05: 0x00c0, + 0x3e06: 0x00c0, 0x3e07: 0x00c0, 0x3e08: 0x00c0, 0x3e09: 0x00c0, + // Block 0xf9, offset 0x3e40 + 0x3e40: 0x00c0, 0x3e41: 0x00c0, 0x3e42: 0x00c0, 0x3e43: 0x00c0, 0x3e44: 0x00c0, 0x3e45: 0x00c0, + 0x3e46: 0x00c0, 0x3e47: 0x00c0, 0x3e48: 0x00c0, 0x3e49: 0x00c0, 0x3e4a: 0x00c0, 0x3e4b: 0x00c0, + 0x3e4c: 0x00c0, 0x3e4d: 0x00c0, 0x3e4e: 0x00c0, 0x3e4f: 0x00c0, 0x3e50: 0x00c0, 0x3e51: 0x00c0, + 0x3e52: 0x00c0, 0x3e53: 0x00c0, 0x3e54: 0x00c0, 0x3e55: 0x00c0, 0x3e56: 0x00c0, 0x3e57: 0x00c0, + 0x3e58: 0x00c0, 0x3e59: 0x00c0, 0x3e5d: 0x00c3, + 0x3e5e: 0x00c3, 0x3e5f: 0x00c3, 0x3e60: 0x00c0, 0x3e61: 0x00c0, 0x3e62: 0x00c3, 0x3e63: 0x00c3, + 0x3e64: 0x00c3, 0x3e65: 0x00c3, 0x3e66: 0x00c0, 0x3e67: 0x00c3, 0x3e68: 0x00c3, 0x3e69: 0x00c3, + 0x3e6a: 0x00c3, 0x3e6b: 0x00c6, + 0x3e70: 0x00c0, 0x3e71: 0x00c0, 0x3e72: 0x00c0, 0x3e73: 0x00c0, 0x3e74: 0x00c0, 0x3e75: 0x00c0, + 0x3e76: 0x00c0, 0x3e77: 0x00c0, 0x3e78: 0x00c0, 0x3e79: 0x00c0, 0x3e7a: 0x0080, 0x3e7b: 0x0080, + 0x3e7c: 0x0080, 0x3e7d: 0x0080, 0x3e7e: 0x0080, 0x3e7f: 0x0080, + // Block 0xfa, offset 0x3e80 + 0x3ea0: 0x00c0, 0x3ea1: 0x00c0, 0x3ea2: 0x00c0, 0x3ea3: 0x00c0, + 0x3ea4: 0x00c0, 0x3ea5: 0x00c0, 0x3ea6: 0x00c0, 0x3ea7: 0x00c0, 0x3ea8: 0x00c0, 0x3ea9: 0x00c0, + 0x3eaa: 0x00c0, 0x3eab: 0x00c0, 0x3eac: 0x00c0, 0x3ead: 0x00c0, 0x3eae: 0x00c0, 0x3eaf: 0x00c0, + 0x3eb0: 0x00c0, 0x3eb1: 0x00c0, 0x3eb2: 0x00c0, 0x3eb3: 0x00c0, 0x3eb4: 0x00c0, 0x3eb5: 0x00c0, + 0x3eb6: 0x00c0, 0x3eb7: 0x00c0, 0x3eb8: 0x00c0, 0x3eb9: 0x00c0, 0x3eba: 0x00c0, 0x3ebb: 0x00c0, + 0x3ebc: 0x00c0, 0x3ebd: 0x00c0, 0x3ebe: 0x00c0, 0x3ebf: 0x00c0, + // Block 0xfb, offset 0x3ec0 + 0x3ec0: 0x00c0, 0x3ec1: 0x00c0, 0x3ec2: 0x00c0, 0x3ec3: 0x00c0, 0x3ec4: 0x00c0, 0x3ec5: 0x00c0, + 0x3ec6: 0x00c0, 0x3ec7: 0x00c0, 0x3ec8: 0x00c0, 0x3ec9: 0x00c0, 0x3eca: 0x00c0, 0x3ecb: 0x00c0, + 0x3ecc: 0x00c0, 0x3ecd: 0x00c0, 0x3ece: 0x00c0, 0x3ecf: 0x00c0, 0x3ed0: 0x00c0, 0x3ed1: 0x00c0, + 0x3ed2: 0x00c0, 0x3ed3: 0x00c0, 0x3ed4: 0x00c0, 0x3ed5: 0x00c0, 0x3ed6: 0x00c0, 0x3ed7: 0x00c0, + 0x3ed8: 0x00c0, 0x3ed9: 0x00c0, 0x3eda: 0x00c0, 0x3edb: 0x00c0, 0x3edc: 0x00c0, 0x3edd: 0x00c0, + 0x3ede: 0x00c0, 0x3edf: 0x00c0, 0x3ee0: 0x00c0, 0x3ee1: 0x00c0, 0x3ee2: 0x00c0, 0x3ee3: 0x00c0, + 0x3ee4: 0x00c0, 0x3ee5: 0x00c0, 0x3ee6: 0x00c0, 0x3ee7: 0x00c0, 0x3ee8: 0x00c0, 0x3ee9: 0x00c0, + 0x3eea: 0x0080, 0x3eeb: 0x0080, 0x3eec: 0x0080, 0x3eed: 0x0080, 0x3eee: 0x0080, 0x3eef: 0x0080, + 0x3ef0: 0x0080, 0x3ef1: 0x0080, 0x3ef2: 0x0080, + 0x3eff: 0x00c0, + // Block 0xfc, offset 0x3f00 + 0x3f00: 0x00c0, 0x3f01: 0x00c0, 0x3f02: 0x00c0, 0x3f03: 0x00c0, 0x3f04: 0x00c0, 0x3f05: 0x00c0, + 0x3f06: 0x00c0, 0x3f07: 0x00c0, 0x3f08: 0x00c0, 0x3f09: 0x00c0, 0x3f0a: 0x00c0, 0x3f0b: 0x00c0, + 0x3f0c: 0x00c0, 0x3f0d: 0x00c0, 0x3f0e: 0x00c0, 0x3f0f: 0x00c0, 0x3f10: 0x00c0, 0x3f11: 0x00c0, + 0x3f12: 0x00c0, 0x3f13: 0x00c0, 0x3f14: 0x00c0, 0x3f15: 0x00c0, 0x3f16: 0x00c0, 0x3f17: 0x00c0, + 0x3f18: 0x00c0, 0x3f19: 0x00c0, 0x3f1a: 0x00c0, 0x3f1b: 0x00c0, 0x3f1c: 0x00c0, 0x3f1d: 0x00c0, + 0x3f1e: 0x00c0, 0x3f1f: 0x00c0, 0x3f20: 0x00c0, 0x3f21: 0x00c0, 0x3f22: 0x00c0, 0x3f23: 0x00c0, + 0x3f24: 0x00c0, 0x3f25: 0x00c0, 0x3f26: 0x00c0, 0x3f27: 0x00c0, 0x3f28: 0x00c0, 0x3f29: 0x00c0, + 0x3f2a: 0x00c0, 0x3f2b: 0x00c0, 0x3f2c: 0x00c0, 0x3f2d: 0x00c0, 0x3f2e: 0x00c0, 0x3f2f: 0x00c0, + 0x3f30: 0x00c0, 0x3f31: 0x00c0, 0x3f32: 0x00c0, 0x3f33: 0x00c0, 0x3f34: 0x00c0, 0x3f35: 0x00c0, + 0x3f36: 0x00c0, 0x3f37: 0x00c0, 0x3f38: 0x00c0, + // Block 0xfd, offset 0x3f40 + 0x3f40: 0x00c0, 0x3f41: 0x00c0, 0x3f42: 0x00c0, 0x3f43: 0x00c0, 0x3f44: 0x00c0, 0x3f45: 0x00c0, + 0x3f46: 0x00c0, 0x3f47: 0x00c0, 0x3f48: 0x00c0, 0x3f4a: 0x00c0, 0x3f4b: 0x00c0, + 0x3f4c: 0x00c0, 0x3f4d: 0x00c0, 0x3f4e: 0x00c0, 0x3f4f: 0x00c0, 0x3f50: 0x00c0, 0x3f51: 0x00c0, + 0x3f52: 0x00c0, 0x3f53: 0x00c0, 0x3f54: 0x00c0, 0x3f55: 0x00c0, 0x3f56: 0x00c0, 0x3f57: 0x00c0, + 0x3f58: 0x00c0, 0x3f59: 0x00c0, 0x3f5a: 0x00c0, 0x3f5b: 0x00c0, 0x3f5c: 0x00c0, 0x3f5d: 0x00c0, + 0x3f5e: 0x00c0, 0x3f5f: 0x00c0, 0x3f60: 0x00c0, 0x3f61: 0x00c0, 0x3f62: 0x00c0, 0x3f63: 0x00c0, + 0x3f64: 0x00c0, 0x3f65: 0x00c0, 0x3f66: 0x00c0, 0x3f67: 0x00c0, 0x3f68: 0x00c0, 0x3f69: 0x00c0, + 0x3f6a: 0x00c0, 0x3f6b: 0x00c0, 0x3f6c: 0x00c0, 0x3f6d: 0x00c0, 0x3f6e: 0x00c0, 0x3f6f: 0x00c0, + 0x3f70: 0x00c3, 0x3f71: 0x00c3, 0x3f72: 0x00c3, 0x3f73: 0x00c3, 0x3f74: 0x00c3, 0x3f75: 0x00c3, + 0x3f76: 0x00c3, 0x3f78: 0x00c3, 0x3f79: 0x00c3, 0x3f7a: 0x00c3, 0x3f7b: 0x00c3, + 0x3f7c: 0x00c3, 0x3f7d: 0x00c3, 0x3f7e: 0x00c0, 0x3f7f: 0x00c6, + // Block 0xfe, offset 0x3f80 + 0x3f80: 0x00c0, 0x3f81: 0x0080, 0x3f82: 0x0080, 0x3f83: 0x0080, 0x3f84: 0x0080, 0x3f85: 0x0080, + 0x3f90: 0x00c0, 0x3f91: 0x00c0, + 0x3f92: 0x00c0, 0x3f93: 0x00c0, 0x3f94: 0x00c0, 0x3f95: 0x00c0, 0x3f96: 0x00c0, 0x3f97: 0x00c0, + 0x3f98: 0x00c0, 0x3f99: 0x00c0, 0x3f9a: 0x0080, 0x3f9b: 0x0080, 0x3f9c: 0x0080, 0x3f9d: 0x0080, + 0x3f9e: 0x0080, 0x3f9f: 0x0080, 0x3fa0: 0x0080, 0x3fa1: 0x0080, 0x3fa2: 0x0080, 0x3fa3: 0x0080, + 0x3fa4: 0x0080, 0x3fa5: 0x0080, 0x3fa6: 0x0080, 0x3fa7: 0x0080, 0x3fa8: 0x0080, 0x3fa9: 0x0080, + 0x3faa: 0x0080, 0x3fab: 0x0080, 0x3fac: 0x0080, + 0x3fb0: 0x0080, 0x3fb1: 0x0080, 0x3fb2: 0x00c0, 0x3fb3: 0x00c0, 0x3fb4: 0x00c0, 0x3fb5: 0x00c0, + 0x3fb6: 0x00c0, 0x3fb7: 0x00c0, 0x3fb8: 0x00c0, 0x3fb9: 0x00c0, 0x3fba: 0x00c0, 0x3fbb: 0x00c0, + 0x3fbc: 0x00c0, 0x3fbd: 0x00c0, 0x3fbe: 0x00c0, 0x3fbf: 0x00c0, + // Block 0xff, offset 0x3fc0 + 0x3fc0: 0x00c0, 0x3fc1: 0x00c0, 0x3fc2: 0x00c0, 0x3fc3: 0x00c0, 0x3fc4: 0x00c0, 0x3fc5: 0x00c0, + 0x3fc6: 0x00c0, 0x3fc7: 0x00c0, 0x3fc8: 0x00c0, 0x3fc9: 0x00c0, 0x3fca: 0x00c0, 0x3fcb: 0x00c0, + 0x3fcc: 0x00c0, 0x3fcd: 0x00c0, 0x3fce: 0x00c0, 0x3fcf: 0x00c0, + 0x3fd2: 0x00c3, 0x3fd3: 0x00c3, 0x3fd4: 0x00c3, 0x3fd5: 0x00c3, 0x3fd6: 0x00c3, 0x3fd7: 0x00c3, + 0x3fd8: 0x00c3, 0x3fd9: 0x00c3, 0x3fda: 0x00c3, 0x3fdb: 0x00c3, 0x3fdc: 0x00c3, 0x3fdd: 0x00c3, + 0x3fde: 0x00c3, 0x3fdf: 0x00c3, 0x3fe0: 0x00c3, 0x3fe1: 0x00c3, 0x3fe2: 0x00c3, 0x3fe3: 0x00c3, + 0x3fe4: 0x00c3, 0x3fe5: 0x00c3, 0x3fe6: 0x00c3, 0x3fe7: 0x00c3, 0x3fe9: 0x00c0, + 0x3fea: 0x00c3, 0x3feb: 0x00c3, 0x3fec: 0x00c3, 0x3fed: 0x00c3, 0x3fee: 0x00c3, 0x3fef: 0x00c3, + 0x3ff0: 0x00c3, 0x3ff1: 0x00c0, 0x3ff2: 0x00c3, 0x3ff3: 0x00c3, 0x3ff4: 0x00c0, 0x3ff5: 0x00c3, + 0x3ff6: 0x00c3, + // Block 0x100, offset 0x4000 + 0x4000: 0x00c0, 0x4001: 0x00c0, 0x4002: 0x00c0, 0x4003: 0x00c0, 0x4004: 0x00c0, 0x4005: 0x00c0, + 0x4006: 0x00c0, 0x4007: 0x00c0, 0x4008: 0x00c0, 0x4009: 0x00c0, 0x400a: 0x00c0, 0x400b: 0x00c0, + 0x400c: 0x00c0, 0x400d: 0x00c0, 0x400e: 0x00c0, 0x400f: 0x00c0, 0x4010: 0x00c0, 0x4011: 0x00c0, + 0x4012: 0x00c0, 0x4013: 0x00c0, 0x4014: 0x00c0, 0x4015: 0x00c0, 0x4016: 0x00c0, 0x4017: 0x00c0, + 0x4018: 0x00c0, 0x4019: 0x00c0, + // Block 0x101, offset 0x4040 + 0x4040: 0x0080, 0x4041: 0x0080, 0x4042: 0x0080, 0x4043: 0x0080, 0x4044: 0x0080, 0x4045: 0x0080, + 0x4046: 0x0080, 0x4047: 0x0080, 0x4048: 0x0080, 0x4049: 0x0080, 0x404a: 0x0080, 0x404b: 0x0080, + 0x404c: 0x0080, 0x404d: 0x0080, 0x404e: 0x0080, 0x404f: 0x0080, 0x4050: 0x0080, 0x4051: 0x0080, + 0x4052: 0x0080, 0x4053: 0x0080, 0x4054: 0x0080, 0x4055: 0x0080, 0x4056: 0x0080, 0x4057: 0x0080, + 0x4058: 0x0080, 0x4059: 0x0080, 0x405a: 0x0080, 0x405b: 0x0080, 0x405c: 0x0080, 0x405d: 0x0080, + 0x405e: 0x0080, 0x405f: 0x0080, 0x4060: 0x0080, 0x4061: 0x0080, 0x4062: 0x0080, 0x4063: 0x0080, + 0x4064: 0x0080, 0x4065: 0x0080, 0x4066: 0x0080, 0x4067: 0x0080, 0x4068: 0x0080, 0x4069: 0x0080, + 0x406a: 0x0080, 0x406b: 0x0080, 0x406c: 0x0080, 0x406d: 0x0080, 0x406e: 0x0080, + 0x4070: 0x0080, 0x4071: 0x0080, 0x4072: 0x0080, 0x4073: 0x0080, 0x4074: 0x0080, + // Block 0x102, offset 0x4080 + 0x4080: 0x00c0, 0x4081: 0x00c0, 0x4082: 0x00c0, 0x4083: 0x00c0, + // Block 0x103, offset 0x40c0 + 0x40c0: 0x00c0, 0x40c1: 0x00c0, 0x40c2: 0x00c0, 0x40c3: 0x00c0, 0x40c4: 0x00c0, 0x40c5: 0x00c0, + 0x40c6: 0x00c0, 0x40c7: 0x00c0, 0x40c8: 0x00c0, 0x40c9: 0x00c0, 0x40ca: 0x00c0, 0x40cb: 0x00c0, + 0x40cc: 0x00c0, 0x40cd: 0x00c0, 0x40ce: 0x00c0, 0x40cf: 0x00c0, 0x40d0: 0x00c0, 0x40d1: 0x00c0, + 0x40d2: 0x00c0, 0x40d3: 0x00c0, 0x40d4: 0x00c0, 0x40d5: 0x00c0, 0x40d6: 0x00c0, 0x40d7: 0x00c0, + 0x40d8: 0x00c0, 0x40d9: 0x00c0, 0x40da: 0x00c0, 0x40db: 0x00c0, 0x40dc: 0x00c0, 0x40dd: 0x00c0, + 0x40de: 0x00c0, 0x40df: 0x00c0, 0x40e0: 0x00c0, 0x40e1: 0x00c0, 0x40e2: 0x00c0, 0x40e3: 0x00c0, + 0x40e4: 0x00c0, 0x40e5: 0x00c0, 0x40e6: 0x00c0, 0x40e7: 0x00c0, 0x40e8: 0x00c0, 0x40e9: 0x00c0, + 0x40ea: 0x00c0, 0x40eb: 0x00c0, 0x40ec: 0x00c0, 0x40ed: 0x00c0, 0x40ee: 0x00c0, + // Block 0x104, offset 0x4100 + 0x4100: 0x00c0, 0x4101: 0x00c0, 0x4102: 0x00c0, 0x4103: 0x00c0, 0x4104: 0x00c0, 0x4105: 0x00c0, + 0x4106: 0x00c0, + // Block 0x105, offset 0x4140 + 0x4140: 0x00c0, 0x4141: 0x00c0, 0x4142: 0x00c0, 0x4143: 0x00c0, 0x4144: 0x00c0, 0x4145: 0x00c0, + 0x4146: 0x00c0, 0x4147: 0x00c0, 0x4148: 0x00c0, 0x4149: 0x00c0, 0x414a: 0x00c0, 0x414b: 0x00c0, + 0x414c: 0x00c0, 0x414d: 0x00c0, 0x414e: 0x00c0, 0x414f: 0x00c0, 0x4150: 0x00c0, 0x4151: 0x00c0, + 0x4152: 0x00c0, 0x4153: 0x00c0, 0x4154: 0x00c0, 0x4155: 0x00c0, 0x4156: 0x00c0, 0x4157: 0x00c0, + 0x4158: 0x00c0, 0x4159: 0x00c0, 0x415a: 0x00c0, 0x415b: 0x00c0, 0x415c: 0x00c0, 0x415d: 0x00c0, + 0x415e: 0x00c0, 0x4160: 0x00c0, 0x4161: 0x00c0, 0x4162: 0x00c0, 0x4163: 0x00c0, + 0x4164: 0x00c0, 0x4165: 0x00c0, 0x4166: 0x00c0, 0x4167: 0x00c0, 0x4168: 0x00c0, 0x4169: 0x00c0, + 0x416e: 0x0080, 0x416f: 0x0080, + // Block 0x106, offset 0x4180 + 0x4190: 0x00c0, 0x4191: 0x00c0, + 0x4192: 0x00c0, 0x4193: 0x00c0, 0x4194: 0x00c0, 0x4195: 0x00c0, 0x4196: 0x00c0, 0x4197: 0x00c0, + 0x4198: 0x00c0, 0x4199: 0x00c0, 0x419a: 0x00c0, 0x419b: 0x00c0, 0x419c: 0x00c0, 0x419d: 0x00c0, + 0x419e: 0x00c0, 0x419f: 0x00c0, 0x41a0: 0x00c0, 0x41a1: 0x00c0, 0x41a2: 0x00c0, 0x41a3: 0x00c0, + 0x41a4: 0x00c0, 0x41a5: 0x00c0, 0x41a6: 0x00c0, 0x41a7: 0x00c0, 0x41a8: 0x00c0, 0x41a9: 0x00c0, + 0x41aa: 0x00c0, 0x41ab: 0x00c0, 0x41ac: 0x00c0, 0x41ad: 0x00c0, + 0x41b0: 0x00c3, 0x41b1: 0x00c3, 0x41b2: 0x00c3, 0x41b3: 0x00c3, 0x41b4: 0x00c3, 0x41b5: 0x0080, + // Block 0x107, offset 0x41c0 + 0x41c0: 0x00c0, 0x41c1: 0x00c0, 0x41c2: 0x00c0, 0x41c3: 0x00c0, 0x41c4: 0x00c0, 0x41c5: 0x00c0, + 0x41c6: 0x00c0, 0x41c7: 0x00c0, 0x41c8: 0x00c0, 0x41c9: 0x00c0, 0x41ca: 0x00c0, 0x41cb: 0x00c0, + 0x41cc: 0x00c0, 0x41cd: 0x00c0, 0x41ce: 0x00c0, 0x41cf: 0x00c0, 0x41d0: 0x00c0, 0x41d1: 0x00c0, + 0x41d2: 0x00c0, 0x41d3: 0x00c0, 0x41d4: 0x00c0, 0x41d5: 0x00c0, 0x41d6: 0x00c0, 0x41d7: 0x00c0, + 0x41d8: 0x00c0, 0x41d9: 0x00c0, 0x41da: 0x00c0, 0x41db: 0x00c0, 0x41dc: 0x00c0, 0x41dd: 0x00c0, + 0x41de: 0x00c0, 0x41df: 0x00c0, 0x41e0: 0x00c0, 0x41e1: 0x00c0, 0x41e2: 0x00c0, 0x41e3: 0x00c0, + 0x41e4: 0x00c0, 0x41e5: 0x00c0, 0x41e6: 0x00c0, 0x41e7: 0x00c0, 0x41e8: 0x00c0, 0x41e9: 0x00c0, + 0x41ea: 0x00c0, 0x41eb: 0x00c0, 0x41ec: 0x00c0, 0x41ed: 0x00c0, 0x41ee: 0x00c0, 0x41ef: 0x00c0, + 0x41f0: 0x00c3, 0x41f1: 0x00c3, 0x41f2: 0x00c3, 0x41f3: 0x00c3, 0x41f4: 0x00c3, 0x41f5: 0x00c3, + 0x41f6: 0x00c3, 0x41f7: 0x0080, 0x41f8: 0x0080, 0x41f9: 0x0080, 0x41fa: 0x0080, 0x41fb: 0x0080, + 0x41fc: 0x0080, 0x41fd: 0x0080, 0x41fe: 0x0080, 0x41ff: 0x0080, + // Block 0x108, offset 0x4200 + 0x4200: 0x00c0, 0x4201: 0x00c0, 0x4202: 0x00c0, 0x4203: 0x00c0, 0x4204: 0x0080, 0x4205: 0x0080, + 0x4210: 0x00c0, 0x4211: 0x00c0, + 0x4212: 0x00c0, 0x4213: 0x00c0, 0x4214: 0x00c0, 0x4215: 0x00c0, 0x4216: 0x00c0, 0x4217: 0x00c0, + 0x4218: 0x00c0, 0x4219: 0x00c0, 0x421b: 0x0080, 0x421c: 0x0080, 0x421d: 0x0080, + 0x421e: 0x0080, 0x421f: 0x0080, 0x4220: 0x0080, 0x4221: 0x0080, 0x4223: 0x00c0, + 0x4224: 0x00c0, 0x4225: 0x00c0, 0x4226: 0x00c0, 0x4227: 0x00c0, 0x4228: 0x00c0, 0x4229: 0x00c0, + 0x422a: 0x00c0, 0x422b: 0x00c0, 0x422c: 0x00c0, 0x422d: 0x00c0, 0x422e: 0x00c0, 0x422f: 0x00c0, + 0x4230: 0x00c0, 0x4231: 0x00c0, 0x4232: 0x00c0, 0x4233: 0x00c0, 0x4234: 0x00c0, 0x4235: 0x00c0, + 0x4236: 0x00c0, 0x4237: 0x00c0, + 0x423d: 0x00c0, 0x423e: 0x00c0, 0x423f: 0x00c0, + // Block 0x109, offset 0x4240 + 0x4240: 0x00c0, 0x4241: 0x00c0, 0x4242: 0x00c0, 0x4243: 0x00c0, 0x4244: 0x00c0, 0x4245: 0x00c0, + 0x4246: 0x00c0, 0x4247: 0x00c0, 0x4248: 0x00c0, 0x4249: 0x00c0, 0x424a: 0x00c0, 0x424b: 0x00c0, + 0x424c: 0x00c0, 0x424d: 0x00c0, 0x424e: 0x00c0, 0x424f: 0x00c0, + // Block 0x10a, offset 0x4280 + 0x4280: 0x00c0, 0x4281: 0x00c0, 0x4282: 0x00c0, 0x4283: 0x00c0, 0x4284: 0x00c0, + 0x4290: 0x00c0, 0x4291: 0x00c0, + 0x4292: 0x00c0, 0x4293: 0x00c0, 0x4294: 0x00c0, 0x4295: 0x00c0, 0x4296: 0x00c0, 0x4297: 0x00c0, + 0x4298: 0x00c0, 0x4299: 0x00c0, 0x429a: 0x00c0, 0x429b: 0x00c0, 0x429c: 0x00c0, 0x429d: 0x00c0, + 0x429e: 0x00c0, 0x429f: 0x00c0, 0x42a0: 0x00c0, 0x42a1: 0x00c0, 0x42a2: 0x00c0, 0x42a3: 0x00c0, + 0x42a4: 0x00c0, 0x42a5: 0x00c0, 0x42a6: 0x00c0, 0x42a7: 0x00c0, 0x42a8: 0x00c0, 0x42a9: 0x00c0, + 0x42aa: 0x00c0, 0x42ab: 0x00c0, 0x42ac: 0x00c0, 0x42ad: 0x00c0, 0x42ae: 0x00c0, 0x42af: 0x00c0, + 0x42b0: 0x00c0, 0x42b1: 0x00c0, 0x42b2: 0x00c0, 0x42b3: 0x00c0, 0x42b4: 0x00c0, 0x42b5: 0x00c0, + 0x42b6: 0x00c0, 0x42b7: 0x00c0, 0x42b8: 0x00c0, 0x42b9: 0x00c0, 0x42ba: 0x00c0, 0x42bb: 0x00c0, + 0x42bc: 0x00c0, 0x42bd: 0x00c0, 0x42be: 0x00c0, + // Block 0x10b, offset 0x42c0 + 0x42cf: 0x00c3, 0x42d0: 0x00c3, 0x42d1: 0x00c3, + 0x42d2: 0x00c3, 0x42d3: 0x00c0, 0x42d4: 0x00c0, 0x42d5: 0x00c0, 0x42d6: 0x00c0, 0x42d7: 0x00c0, + 0x42d8: 0x00c0, 0x42d9: 0x00c0, 0x42da: 0x00c0, 0x42db: 0x00c0, 0x42dc: 0x00c0, 0x42dd: 0x00c0, + 0x42de: 0x00c0, 0x42df: 0x00c0, + // Block 0x10c, offset 0x4300 + 0x4320: 0x00c0, + // Block 0x10d, offset 0x4340 + 0x4340: 0x00c0, 0x4341: 0x00c0, 0x4342: 0x00c0, 0x4343: 0x00c0, 0x4344: 0x00c0, 0x4345: 0x00c0, + 0x4346: 0x00c0, 0x4347: 0x00c0, 0x4348: 0x00c0, 0x4349: 0x00c0, 0x434a: 0x00c0, 0x434b: 0x00c0, + 0x434c: 0x00c0, 0x434d: 0x00c0, 0x434e: 0x00c0, 0x434f: 0x00c0, 0x4350: 0x00c0, 0x4351: 0x00c0, + 0x4352: 0x00c0, 0x4353: 0x00c0, 0x4354: 0x00c0, 0x4355: 0x00c0, 0x4356: 0x00c0, 0x4357: 0x00c0, + 0x4358: 0x00c0, 0x4359: 0x00c0, 0x435a: 0x00c0, 0x435b: 0x00c0, 0x435c: 0x00c0, 0x435d: 0x00c0, + 0x435e: 0x00c0, 0x435f: 0x00c0, 0x4360: 0x00c0, 0x4361: 0x00c0, 0x4362: 0x00c0, 0x4363: 0x00c0, + 0x4364: 0x00c0, 0x4365: 0x00c0, 0x4366: 0x00c0, 0x4367: 0x00c0, 0x4368: 0x00c0, 0x4369: 0x00c0, + 0x436a: 0x00c0, 0x436b: 0x00c0, 0x436c: 0x00c0, + // Block 0x10e, offset 0x4380 + 0x4380: 0x00cc, 0x4381: 0x00cc, + // Block 0x10f, offset 0x43c0 + 0x43c0: 0x00c0, 0x43c1: 0x00c0, 0x43c2: 0x00c0, 0x43c3: 0x00c0, 0x43c4: 0x00c0, 0x43c5: 0x00c0, + 0x43c6: 0x00c0, 0x43c7: 0x00c0, 0x43c8: 0x00c0, 0x43c9: 0x00c0, 0x43ca: 0x00c0, 0x43cb: 0x00c0, + 0x43cc: 0x00c0, 0x43cd: 0x00c0, 0x43ce: 0x00c0, 0x43cf: 0x00c0, 0x43d0: 0x00c0, 0x43d1: 0x00c0, + 0x43d2: 0x00c0, 0x43d3: 0x00c0, 0x43d4: 0x00c0, 0x43d5: 0x00c0, 0x43d6: 0x00c0, 0x43d7: 0x00c0, + 0x43d8: 0x00c0, 0x43d9: 0x00c0, 0x43da: 0x00c0, 0x43db: 0x00c0, 0x43dc: 0x00c0, 0x43dd: 0x00c0, + 0x43de: 0x00c0, 0x43df: 0x00c0, 0x43e0: 0x00c0, 0x43e1: 0x00c0, 0x43e2: 0x00c0, 0x43e3: 0x00c0, + 0x43e4: 0x00c0, 0x43e5: 0x00c0, 0x43e6: 0x00c0, 0x43e7: 0x00c0, 0x43e8: 0x00c0, 0x43e9: 0x00c0, + 0x43ea: 0x00c0, + 0x43f0: 0x00c0, 0x43f1: 0x00c0, 0x43f2: 0x00c0, 0x43f3: 0x00c0, 0x43f4: 0x00c0, 0x43f5: 0x00c0, + 0x43f6: 0x00c0, 0x43f7: 0x00c0, 0x43f8: 0x00c0, 0x43f9: 0x00c0, 0x43fa: 0x00c0, 0x43fb: 0x00c0, + 0x43fc: 0x00c0, + // Block 0x110, offset 0x4400 + 0x4400: 0x00c0, 0x4401: 0x00c0, 0x4402: 0x00c0, 0x4403: 0x00c0, 0x4404: 0x00c0, 0x4405: 0x00c0, + 0x4406: 0x00c0, 0x4407: 0x00c0, 0x4408: 0x00c0, + 0x4410: 0x00c0, 0x4411: 0x00c0, + 0x4412: 0x00c0, 0x4413: 0x00c0, 0x4414: 0x00c0, 0x4415: 0x00c0, 0x4416: 0x00c0, 0x4417: 0x00c0, + 0x4418: 0x00c0, 0x4419: 0x00c0, 0x441c: 0x0080, 0x441d: 0x00c3, + 0x441e: 0x00c3, 0x441f: 0x0080, 0x4420: 0x0040, 0x4421: 0x0040, 0x4422: 0x0040, 0x4423: 0x0040, + // Block 0x111, offset 0x4440 + 0x4440: 0x0080, 0x4441: 0x0080, 0x4442: 0x0080, 0x4443: 0x0080, 0x4444: 0x0080, 0x4445: 0x0080, + 0x4446: 0x0080, 0x4447: 0x0080, 0x4448: 0x0080, 0x4449: 0x0080, 0x444a: 0x0080, 0x444b: 0x0080, + 0x444c: 0x0080, 0x444d: 0x0080, 0x444e: 0x0080, 0x444f: 0x0080, 0x4450: 0x0080, 0x4451: 0x0080, + 0x4452: 0x0080, 0x4453: 0x0080, 0x4454: 0x0080, 0x4455: 0x0080, 0x4456: 0x0080, 0x4457: 0x0080, + 0x4458: 0x0080, 0x4459: 0x0080, 0x445a: 0x0080, 0x445b: 0x0080, 0x445c: 0x0080, 0x445d: 0x0080, + 0x445e: 0x0080, 0x445f: 0x0080, 0x4460: 0x0080, 0x4461: 0x0080, 0x4462: 0x0080, 0x4463: 0x0080, + 0x4464: 0x0080, 0x4465: 0x0080, 0x4466: 0x0080, 0x4467: 0x0080, 0x4468: 0x0080, 0x4469: 0x0080, + 0x446a: 0x0080, 0x446b: 0x0080, 0x446c: 0x0080, 0x446d: 0x0080, 0x446e: 0x0080, 0x446f: 0x0080, + 0x4470: 0x0080, 0x4471: 0x0080, 0x4472: 0x0080, 0x4473: 0x0080, 0x4474: 0x0080, 0x4475: 0x0080, + // Block 0x112, offset 0x4480 + 0x4480: 0x0080, 0x4481: 0x0080, 0x4482: 0x0080, 0x4483: 0x0080, 0x4484: 0x0080, 0x4485: 0x0080, + 0x4486: 0x0080, 0x4487: 0x0080, 0x4488: 0x0080, 0x4489: 0x0080, 0x448a: 0x0080, 0x448b: 0x0080, + 0x448c: 0x0080, 0x448d: 0x0080, 0x448e: 0x0080, 0x448f: 0x0080, 0x4490: 0x0080, 0x4491: 0x0080, + 0x4492: 0x0080, 0x4493: 0x0080, 0x4494: 0x0080, 0x4495: 0x0080, 0x4496: 0x0080, 0x4497: 0x0080, + 0x4498: 0x0080, 0x4499: 0x0080, 0x449a: 0x0080, 0x449b: 0x0080, 0x449c: 0x0080, 0x449d: 0x0080, + 0x449e: 0x0080, 0x449f: 0x0080, 0x44a0: 0x0080, 0x44a1: 0x0080, 0x44a2: 0x0080, 0x44a3: 0x0080, + 0x44a4: 0x0080, 0x44a5: 0x0080, 0x44a6: 0x0080, 0x44a9: 0x0080, + 0x44aa: 0x0080, 0x44ab: 0x0080, 0x44ac: 0x0080, 0x44ad: 0x0080, 0x44ae: 0x0080, 0x44af: 0x0080, + 0x44b0: 0x0080, 0x44b1: 0x0080, 0x44b2: 0x0080, 0x44b3: 0x0080, 0x44b4: 0x0080, 0x44b5: 0x0080, + 0x44b6: 0x0080, 0x44b7: 0x0080, 0x44b8: 0x0080, 0x44b9: 0x0080, 0x44ba: 0x0080, 0x44bb: 0x0080, + 0x44bc: 0x0080, 0x44bd: 0x0080, 0x44be: 0x0080, 0x44bf: 0x0080, + // Block 0x113, offset 0x44c0 + 0x44c0: 0x0080, 0x44c1: 0x0080, 0x44c2: 0x0080, 0x44c3: 0x0080, 0x44c4: 0x0080, 0x44c5: 0x0080, + 0x44c6: 0x0080, 0x44c7: 0x0080, 0x44c8: 0x0080, 0x44c9: 0x0080, 0x44ca: 0x0080, 0x44cb: 0x0080, + 0x44cc: 0x0080, 0x44cd: 0x0080, 0x44ce: 0x0080, 0x44cf: 0x0080, 0x44d0: 0x0080, 0x44d1: 0x0080, + 0x44d2: 0x0080, 0x44d3: 0x0080, 0x44d4: 0x0080, 0x44d5: 0x0080, 0x44d6: 0x0080, 0x44d7: 0x0080, + 0x44d8: 0x0080, 0x44d9: 0x0080, 0x44da: 0x0080, 0x44db: 0x0080, 0x44dc: 0x0080, 0x44dd: 0x0080, + 0x44de: 0x0080, 0x44df: 0x0080, 0x44e0: 0x0080, 0x44e1: 0x0080, 0x44e2: 0x0080, 0x44e3: 0x0080, + 0x44e4: 0x0080, 0x44e5: 0x00c0, 0x44e6: 0x00c0, 0x44e7: 0x00c3, 0x44e8: 0x00c3, 0x44e9: 0x00c3, + 0x44ea: 0x0080, 0x44eb: 0x0080, 0x44ec: 0x0080, 0x44ed: 0x00c0, 0x44ee: 0x00c0, 0x44ef: 0x00c0, + 0x44f0: 0x00c0, 0x44f1: 0x00c0, 0x44f2: 0x00c0, 0x44f3: 0x0040, 0x44f4: 0x0040, 0x44f5: 0x0040, + 0x44f6: 0x0040, 0x44f7: 0x0040, 0x44f8: 0x0040, 0x44f9: 0x0040, 0x44fa: 0x0040, 0x44fb: 0x00c3, + 0x44fc: 0x00c3, 0x44fd: 0x00c3, 0x44fe: 0x00c3, 0x44ff: 0x00c3, + // Block 0x114, offset 0x4500 + 0x4500: 0x00c3, 0x4501: 0x00c3, 0x4502: 0x00c3, 0x4503: 0x0080, 0x4504: 0x0080, 0x4505: 0x00c3, + 0x4506: 0x00c3, 0x4507: 0x00c3, 0x4508: 0x00c3, 0x4509: 0x00c3, 0x450a: 0x00c3, 0x450b: 0x00c3, + 0x450c: 0x0080, 0x450d: 0x0080, 0x450e: 0x0080, 0x450f: 0x0080, 0x4510: 0x0080, 0x4511: 0x0080, + 0x4512: 0x0080, 0x4513: 0x0080, 0x4514: 0x0080, 0x4515: 0x0080, 0x4516: 0x0080, 0x4517: 0x0080, + 0x4518: 0x0080, 0x4519: 0x0080, 0x451a: 0x0080, 0x451b: 0x0080, 0x451c: 0x0080, 0x451d: 0x0080, + 0x451e: 0x0080, 0x451f: 0x0080, 0x4520: 0x0080, 0x4521: 0x0080, 0x4522: 0x0080, 0x4523: 0x0080, + 0x4524: 0x0080, 0x4525: 0x0080, 0x4526: 0x0080, 0x4527: 0x0080, 0x4528: 0x0080, 0x4529: 0x0080, + 0x452a: 0x00c3, 0x452b: 0x00c3, 0x452c: 0x00c3, 0x452d: 0x00c3, 0x452e: 0x0080, 0x452f: 0x0080, + 0x4530: 0x0080, 0x4531: 0x0080, 0x4532: 0x0080, 0x4533: 0x0080, 0x4534: 0x0080, 0x4535: 0x0080, + 0x4536: 0x0080, 0x4537: 0x0080, 0x4538: 0x0080, 0x4539: 0x0080, 0x453a: 0x0080, 0x453b: 0x0080, + 0x453c: 0x0080, 0x453d: 0x0080, 0x453e: 0x0080, 0x453f: 0x0080, + // Block 0x115, offset 0x4540 + 0x4540: 0x0080, 0x4541: 0x0080, 0x4542: 0x0080, 0x4543: 0x0080, 0x4544: 0x0080, 0x4545: 0x0080, + 0x4546: 0x0080, 0x4547: 0x0080, 0x4548: 0x0080, 0x4549: 0x0080, 0x454a: 0x0080, 0x454b: 0x0080, + 0x454c: 0x0080, 0x454d: 0x0080, 0x454e: 0x0080, 0x454f: 0x0080, 0x4550: 0x0080, 0x4551: 0x0080, + 0x4552: 0x0080, 0x4553: 0x0080, 0x4554: 0x0080, 0x4555: 0x0080, 0x4556: 0x0080, 0x4557: 0x0080, + 0x4558: 0x0080, 0x4559: 0x0080, 0x455a: 0x0080, 0x455b: 0x0080, 0x455c: 0x0080, 0x455d: 0x0080, + 0x455e: 0x0080, 0x455f: 0x0080, 0x4560: 0x0080, 0x4561: 0x0080, 0x4562: 0x0080, 0x4563: 0x0080, + 0x4564: 0x0080, 0x4565: 0x0080, 0x4566: 0x0080, 0x4567: 0x0080, 0x4568: 0x0080, + // Block 0x116, offset 0x4580 + 0x4580: 0x0088, 0x4581: 0x0088, 0x4582: 0x00c9, 0x4583: 0x00c9, 0x4584: 0x00c9, 0x4585: 0x0088, + // Block 0x117, offset 0x45c0 + 0x45c0: 0x0080, 0x45c1: 0x0080, 0x45c2: 0x0080, 0x45c3: 0x0080, 0x45c4: 0x0080, 0x45c5: 0x0080, + 0x45c6: 0x0080, 0x45c7: 0x0080, 0x45c8: 0x0080, 0x45c9: 0x0080, 0x45ca: 0x0080, 0x45cb: 0x0080, + 0x45cc: 0x0080, 0x45cd: 0x0080, 0x45ce: 0x0080, 0x45cf: 0x0080, 0x45d0: 0x0080, 0x45d1: 0x0080, + 0x45d2: 0x0080, 0x45d3: 0x0080, 0x45d4: 0x0080, 0x45d5: 0x0080, 0x45d6: 0x0080, + 0x45e0: 0x0080, 0x45e1: 0x0080, 0x45e2: 0x0080, 0x45e3: 0x0080, + 0x45e4: 0x0080, 0x45e5: 0x0080, 0x45e6: 0x0080, 0x45e7: 0x0080, 0x45e8: 0x0080, 0x45e9: 0x0080, + 0x45ea: 0x0080, 0x45eb: 0x0080, 0x45ec: 0x0080, 0x45ed: 0x0080, 0x45ee: 0x0080, 0x45ef: 0x0080, + 0x45f0: 0x0080, 0x45f1: 0x0080, + // Block 0x118, offset 0x4600 + 0x4600: 0x0080, 0x4601: 0x0080, 0x4602: 0x0080, 0x4603: 0x0080, 0x4604: 0x0080, 0x4605: 0x0080, + 0x4606: 0x0080, 0x4607: 0x0080, 0x4608: 0x0080, 0x4609: 0x0080, 0x460a: 0x0080, 0x460b: 0x0080, + 0x460c: 0x0080, 0x460d: 0x0080, 0x460e: 0x0080, 0x460f: 0x0080, 0x4610: 0x0080, 0x4611: 0x0080, + 0x4612: 0x0080, 0x4613: 0x0080, 0x4614: 0x0080, 0x4616: 0x0080, 0x4617: 0x0080, + 0x4618: 0x0080, 0x4619: 0x0080, 0x461a: 0x0080, 0x461b: 0x0080, 0x461c: 0x0080, 0x461d: 0x0080, + 0x461e: 0x0080, 0x461f: 0x0080, 0x4620: 0x0080, 0x4621: 0x0080, 0x4622: 0x0080, 0x4623: 0x0080, + 0x4624: 0x0080, 0x4625: 0x0080, 0x4626: 0x0080, 0x4627: 0x0080, 0x4628: 0x0080, 0x4629: 0x0080, + 0x462a: 0x0080, 0x462b: 0x0080, 0x462c: 0x0080, 0x462d: 0x0080, 0x462e: 0x0080, 0x462f: 0x0080, + 0x4630: 0x0080, 0x4631: 0x0080, 0x4632: 0x0080, 0x4633: 0x0080, 0x4634: 0x0080, 0x4635: 0x0080, + 0x4636: 0x0080, 0x4637: 0x0080, 0x4638: 0x0080, 0x4639: 0x0080, 0x463a: 0x0080, 0x463b: 0x0080, + 0x463c: 0x0080, 0x463d: 0x0080, 0x463e: 0x0080, 0x463f: 0x0080, + // Block 0x119, offset 0x4640 + 0x4640: 0x0080, 0x4641: 0x0080, 0x4642: 0x0080, 0x4643: 0x0080, 0x4644: 0x0080, 0x4645: 0x0080, + 0x4646: 0x0080, 0x4647: 0x0080, 0x4648: 0x0080, 0x4649: 0x0080, 0x464a: 0x0080, 0x464b: 0x0080, + 0x464c: 0x0080, 0x464d: 0x0080, 0x464e: 0x0080, 0x464f: 0x0080, 0x4650: 0x0080, 0x4651: 0x0080, + 0x4652: 0x0080, 0x4653: 0x0080, 0x4654: 0x0080, 0x4655: 0x0080, 0x4656: 0x0080, 0x4657: 0x0080, + 0x4658: 0x0080, 0x4659: 0x0080, 0x465a: 0x0080, 0x465b: 0x0080, 0x465c: 0x0080, + 0x465e: 0x0080, 0x465f: 0x0080, 0x4662: 0x0080, + 0x4665: 0x0080, 0x4666: 0x0080, 0x4669: 0x0080, + 0x466a: 0x0080, 0x466b: 0x0080, 0x466c: 0x0080, 0x466e: 0x0080, 0x466f: 0x0080, + 0x4670: 0x0080, 0x4671: 0x0080, 0x4672: 0x0080, 0x4673: 0x0080, 0x4674: 0x0080, 0x4675: 0x0080, + 0x4676: 0x0080, 0x4677: 0x0080, 0x4678: 0x0080, 0x4679: 0x0080, 0x467b: 0x0080, + 0x467d: 0x0080, 0x467e: 0x0080, 0x467f: 0x0080, + // Block 0x11a, offset 0x4680 + 0x4680: 0x0080, 0x4681: 0x0080, 0x4682: 0x0080, 0x4683: 0x0080, 0x4685: 0x0080, + 0x4686: 0x0080, 0x4687: 0x0080, 0x4688: 0x0080, 0x4689: 0x0080, 0x468a: 0x0080, 0x468b: 0x0080, + 0x468c: 0x0080, 0x468d: 0x0080, 0x468e: 0x0080, 0x468f: 0x0080, 0x4690: 0x0080, 0x4691: 0x0080, + 0x4692: 0x0080, 0x4693: 0x0080, 0x4694: 0x0080, 0x4695: 0x0080, 0x4696: 0x0080, 0x4697: 0x0080, + 0x4698: 0x0080, 0x4699: 0x0080, 0x469a: 0x0080, 0x469b: 0x0080, 0x469c: 0x0080, 0x469d: 0x0080, + 0x469e: 0x0080, 0x469f: 0x0080, 0x46a0: 0x0080, 0x46a1: 0x0080, 0x46a2: 0x0080, 0x46a3: 0x0080, + 0x46a4: 0x0080, 0x46a5: 0x0080, 0x46a6: 0x0080, 0x46a7: 0x0080, 0x46a8: 0x0080, 0x46a9: 0x0080, + 0x46aa: 0x0080, 0x46ab: 0x0080, 0x46ac: 0x0080, 0x46ad: 0x0080, 0x46ae: 0x0080, 0x46af: 0x0080, + 0x46b0: 0x0080, 0x46b1: 0x0080, 0x46b2: 0x0080, 0x46b3: 0x0080, 0x46b4: 0x0080, 0x46b5: 0x0080, + 0x46b6: 0x0080, 0x46b7: 0x0080, 0x46b8: 0x0080, 0x46b9: 0x0080, 0x46ba: 0x0080, 0x46bb: 0x0080, + 0x46bc: 0x0080, 0x46bd: 0x0080, 0x46be: 0x0080, 0x46bf: 0x0080, + // Block 0x11b, offset 0x46c0 + 0x46c0: 0x0080, 0x46c1: 0x0080, 0x46c2: 0x0080, 0x46c3: 0x0080, 0x46c4: 0x0080, 0x46c5: 0x0080, + 0x46c7: 0x0080, 0x46c8: 0x0080, 0x46c9: 0x0080, 0x46ca: 0x0080, + 0x46cd: 0x0080, 0x46ce: 0x0080, 0x46cf: 0x0080, 0x46d0: 0x0080, 0x46d1: 0x0080, + 0x46d2: 0x0080, 0x46d3: 0x0080, 0x46d4: 0x0080, 0x46d6: 0x0080, 0x46d7: 0x0080, + 0x46d8: 0x0080, 0x46d9: 0x0080, 0x46da: 0x0080, 0x46db: 0x0080, 0x46dc: 0x0080, + 0x46de: 0x0080, 0x46df: 0x0080, 0x46e0: 0x0080, 0x46e1: 0x0080, 0x46e2: 0x0080, 0x46e3: 0x0080, + 0x46e4: 0x0080, 0x46e5: 0x0080, 0x46e6: 0x0080, 0x46e7: 0x0080, 0x46e8: 0x0080, 0x46e9: 0x0080, + 0x46ea: 0x0080, 0x46eb: 0x0080, 0x46ec: 0x0080, 0x46ed: 0x0080, 0x46ee: 0x0080, 0x46ef: 0x0080, + 0x46f0: 0x0080, 0x46f1: 0x0080, 0x46f2: 0x0080, 0x46f3: 0x0080, 0x46f4: 0x0080, 0x46f5: 0x0080, + 0x46f6: 0x0080, 0x46f7: 0x0080, 0x46f8: 0x0080, 0x46f9: 0x0080, 0x46fb: 0x0080, + 0x46fc: 0x0080, 0x46fd: 0x0080, 0x46fe: 0x0080, + // Block 0x11c, offset 0x4700 + 0x4700: 0x0080, 0x4701: 0x0080, 0x4702: 0x0080, 0x4703: 0x0080, 0x4704: 0x0080, + 0x4706: 0x0080, 0x470a: 0x0080, 0x470b: 0x0080, + 0x470c: 0x0080, 0x470d: 0x0080, 0x470e: 0x0080, 0x470f: 0x0080, 0x4710: 0x0080, + 0x4712: 0x0080, 0x4713: 0x0080, 0x4714: 0x0080, 0x4715: 0x0080, 0x4716: 0x0080, 0x4717: 0x0080, + 0x4718: 0x0080, 0x4719: 0x0080, 0x471a: 0x0080, 0x471b: 0x0080, 0x471c: 0x0080, 0x471d: 0x0080, + 0x471e: 0x0080, 0x471f: 0x0080, 0x4720: 0x0080, 0x4721: 0x0080, 0x4722: 0x0080, 0x4723: 0x0080, + 0x4724: 0x0080, 0x4725: 0x0080, 0x4726: 0x0080, 0x4727: 0x0080, 0x4728: 0x0080, 0x4729: 0x0080, + 0x472a: 0x0080, 0x472b: 0x0080, 0x472c: 0x0080, 0x472d: 0x0080, 0x472e: 0x0080, 0x472f: 0x0080, + 0x4730: 0x0080, 0x4731: 0x0080, 0x4732: 0x0080, 0x4733: 0x0080, 0x4734: 0x0080, 0x4735: 0x0080, + 0x4736: 0x0080, 0x4737: 0x0080, 0x4738: 0x0080, 0x4739: 0x0080, 0x473a: 0x0080, 0x473b: 0x0080, + 0x473c: 0x0080, 0x473d: 0x0080, 0x473e: 0x0080, 0x473f: 0x0080, + // Block 0x11d, offset 0x4740 + 0x4740: 0x0080, 0x4741: 0x0080, 0x4742: 0x0080, 0x4743: 0x0080, 0x4744: 0x0080, 0x4745: 0x0080, + 0x4746: 0x0080, 0x4747: 0x0080, 0x4748: 0x0080, 0x4749: 0x0080, 0x474a: 0x0080, 0x474b: 0x0080, + 0x474c: 0x0080, 0x474d: 0x0080, 0x474e: 0x0080, 0x474f: 0x0080, 0x4750: 0x0080, 0x4751: 0x0080, + 0x4752: 0x0080, 0x4753: 0x0080, 0x4754: 0x0080, 0x4755: 0x0080, 0x4756: 0x0080, 0x4757: 0x0080, + 0x4758: 0x0080, 0x4759: 0x0080, 0x475a: 0x0080, 0x475b: 0x0080, 0x475c: 0x0080, 0x475d: 0x0080, + 0x475e: 0x0080, 0x475f: 0x0080, 0x4760: 0x0080, 0x4761: 0x0080, 0x4762: 0x0080, 0x4763: 0x0080, + 0x4764: 0x0080, 0x4765: 0x0080, 0x4768: 0x0080, 0x4769: 0x0080, + 0x476a: 0x0080, 0x476b: 0x0080, 0x476c: 0x0080, 0x476d: 0x0080, 0x476e: 0x0080, 0x476f: 0x0080, + 0x4770: 0x0080, 0x4771: 0x0080, 0x4772: 0x0080, 0x4773: 0x0080, 0x4774: 0x0080, 0x4775: 0x0080, + 0x4776: 0x0080, 0x4777: 0x0080, 0x4778: 0x0080, 0x4779: 0x0080, 0x477a: 0x0080, 0x477b: 0x0080, + 0x477c: 0x0080, 0x477d: 0x0080, 0x477e: 0x0080, 0x477f: 0x0080, + // Block 0x11e, offset 0x4780 + 0x4780: 0x0080, 0x4781: 0x0080, 0x4782: 0x0080, 0x4783: 0x0080, 0x4784: 0x0080, 0x4785: 0x0080, + 0x4786: 0x0080, 0x4787: 0x0080, 0x4788: 0x0080, 0x4789: 0x0080, 0x478a: 0x0080, 0x478b: 0x0080, + 0x478e: 0x0080, 0x478f: 0x0080, 0x4790: 0x0080, 0x4791: 0x0080, + 0x4792: 0x0080, 0x4793: 0x0080, 0x4794: 0x0080, 0x4795: 0x0080, 0x4796: 0x0080, 0x4797: 0x0080, + 0x4798: 0x0080, 0x4799: 0x0080, 0x479a: 0x0080, 0x479b: 0x0080, 0x479c: 0x0080, 0x479d: 0x0080, + 0x479e: 0x0080, 0x479f: 0x0080, 0x47a0: 0x0080, 0x47a1: 0x0080, 0x47a2: 0x0080, 0x47a3: 0x0080, + 0x47a4: 0x0080, 0x47a5: 0x0080, 0x47a6: 0x0080, 0x47a7: 0x0080, 0x47a8: 0x0080, 0x47a9: 0x0080, + 0x47aa: 0x0080, 0x47ab: 0x0080, 0x47ac: 0x0080, 0x47ad: 0x0080, 0x47ae: 0x0080, 0x47af: 0x0080, + 0x47b0: 0x0080, 0x47b1: 0x0080, 0x47b2: 0x0080, 0x47b3: 0x0080, 0x47b4: 0x0080, 0x47b5: 0x0080, + 0x47b6: 0x0080, 0x47b7: 0x0080, 0x47b8: 0x0080, 0x47b9: 0x0080, 0x47ba: 0x0080, 0x47bb: 0x0080, + 0x47bc: 0x0080, 0x47bd: 0x0080, 0x47be: 0x0080, 0x47bf: 0x0080, + // Block 0x11f, offset 0x47c0 + 0x47c0: 0x00c3, 0x47c1: 0x00c3, 0x47c2: 0x00c3, 0x47c3: 0x00c3, 0x47c4: 0x00c3, 0x47c5: 0x00c3, + 0x47c6: 0x00c3, 0x47c7: 0x00c3, 0x47c8: 0x00c3, 0x47c9: 0x00c3, 0x47ca: 0x00c3, 0x47cb: 0x00c3, + 0x47cc: 0x00c3, 0x47cd: 0x00c3, 0x47ce: 0x00c3, 0x47cf: 0x00c3, 0x47d0: 0x00c3, 0x47d1: 0x00c3, + 0x47d2: 0x00c3, 0x47d3: 0x00c3, 0x47d4: 0x00c3, 0x47d5: 0x00c3, 0x47d6: 0x00c3, 0x47d7: 0x00c3, + 0x47d8: 0x00c3, 0x47d9: 0x00c3, 0x47da: 0x00c3, 0x47db: 0x00c3, 0x47dc: 0x00c3, 0x47dd: 0x00c3, + 0x47de: 0x00c3, 0x47df: 0x00c3, 0x47e0: 0x00c3, 0x47e1: 0x00c3, 0x47e2: 0x00c3, 0x47e3: 0x00c3, + 0x47e4: 0x00c3, 0x47e5: 0x00c3, 0x47e6: 0x00c3, 0x47e7: 0x00c3, 0x47e8: 0x00c3, 0x47e9: 0x00c3, + 0x47ea: 0x00c3, 0x47eb: 0x00c3, 0x47ec: 0x00c3, 0x47ed: 0x00c3, 0x47ee: 0x00c3, 0x47ef: 0x00c3, + 0x47f0: 0x00c3, 0x47f1: 0x00c3, 0x47f2: 0x00c3, 0x47f3: 0x00c3, 0x47f4: 0x00c3, 0x47f5: 0x00c3, + 0x47f6: 0x00c3, 0x47f7: 0x0080, 0x47f8: 0x0080, 0x47f9: 0x0080, 0x47fa: 0x0080, 0x47fb: 0x00c3, + 0x47fc: 0x00c3, 0x47fd: 0x00c3, 0x47fe: 0x00c3, 0x47ff: 0x00c3, + // Block 0x120, offset 0x4800 + 0x4800: 0x00c3, 0x4801: 0x00c3, 0x4802: 0x00c3, 0x4803: 0x00c3, 0x4804: 0x00c3, 0x4805: 0x00c3, + 0x4806: 0x00c3, 0x4807: 0x00c3, 0x4808: 0x00c3, 0x4809: 0x00c3, 0x480a: 0x00c3, 0x480b: 0x00c3, + 0x480c: 0x00c3, 0x480d: 0x00c3, 0x480e: 0x00c3, 0x480f: 0x00c3, 0x4810: 0x00c3, 0x4811: 0x00c3, + 0x4812: 0x00c3, 0x4813: 0x00c3, 0x4814: 0x00c3, 0x4815: 0x00c3, 0x4816: 0x00c3, 0x4817: 0x00c3, + 0x4818: 0x00c3, 0x4819: 0x00c3, 0x481a: 0x00c3, 0x481b: 0x00c3, 0x481c: 0x00c3, 0x481d: 0x00c3, + 0x481e: 0x00c3, 0x481f: 0x00c3, 0x4820: 0x00c3, 0x4821: 0x00c3, 0x4822: 0x00c3, 0x4823: 0x00c3, + 0x4824: 0x00c3, 0x4825: 0x00c3, 0x4826: 0x00c3, 0x4827: 0x00c3, 0x4828: 0x00c3, 0x4829: 0x00c3, + 0x482a: 0x00c3, 0x482b: 0x00c3, 0x482c: 0x00c3, 0x482d: 0x0080, 0x482e: 0x0080, 0x482f: 0x0080, + 0x4830: 0x0080, 0x4831: 0x0080, 0x4832: 0x0080, 0x4833: 0x0080, 0x4834: 0x0080, 0x4835: 0x00c3, + 0x4836: 0x0080, 0x4837: 0x0080, 0x4838: 0x0080, 0x4839: 0x0080, 0x483a: 0x0080, 0x483b: 0x0080, + 0x483c: 0x0080, 0x483d: 0x0080, 0x483e: 0x0080, 0x483f: 0x0080, + // Block 0x121, offset 0x4840 + 0x4840: 0x0080, 0x4841: 0x0080, 0x4842: 0x0080, 0x4843: 0x0080, 0x4844: 0x00c3, 0x4845: 0x0080, + 0x4846: 0x0080, 0x4847: 0x0080, 0x4848: 0x0080, 0x4849: 0x0080, 0x484a: 0x0080, 0x484b: 0x0080, + 0x485b: 0x00c3, 0x485c: 0x00c3, 0x485d: 0x00c3, + 0x485e: 0x00c3, 0x485f: 0x00c3, 0x4861: 0x00c3, 0x4862: 0x00c3, 0x4863: 0x00c3, + 0x4864: 0x00c3, 0x4865: 0x00c3, 0x4866: 0x00c3, 0x4867: 0x00c3, 0x4868: 0x00c3, 0x4869: 0x00c3, + 0x486a: 0x00c3, 0x486b: 0x00c3, 0x486c: 0x00c3, 0x486d: 0x00c3, 0x486e: 0x00c3, 0x486f: 0x00c3, + // Block 0x122, offset 0x4880 + 0x4880: 0x00c3, 0x4881: 0x00c3, 0x4882: 0x00c3, 0x4883: 0x00c3, 0x4884: 0x00c3, 0x4885: 0x00c3, + 0x4886: 0x00c3, 0x4888: 0x00c3, 0x4889: 0x00c3, 0x488a: 0x00c3, 0x488b: 0x00c3, + 0x488c: 0x00c3, 0x488d: 0x00c3, 0x488e: 0x00c3, 0x488f: 0x00c3, 0x4890: 0x00c3, 0x4891: 0x00c3, + 0x4892: 0x00c3, 0x4893: 0x00c3, 0x4894: 0x00c3, 0x4895: 0x00c3, 0x4896: 0x00c3, 0x4897: 0x00c3, + 0x4898: 0x00c3, 0x489b: 0x00c3, 0x489c: 0x00c3, 0x489d: 0x00c3, + 0x489e: 0x00c3, 0x489f: 0x00c3, 0x48a0: 0x00c3, 0x48a1: 0x00c3, 0x48a3: 0x00c3, + 0x48a4: 0x00c3, 0x48a6: 0x00c3, 0x48a7: 0x00c3, 0x48a8: 0x00c3, 0x48a9: 0x00c3, + 0x48aa: 0x00c3, + // Block 0x123, offset 0x48c0 + 0x48c0: 0x00c0, 0x48c1: 0x00c0, 0x48c2: 0x00c0, 0x48c3: 0x00c0, 0x48c4: 0x00c0, + 0x48c7: 0x0080, 0x48c8: 0x0080, 0x48c9: 0x0080, 0x48ca: 0x0080, 0x48cb: 0x0080, + 0x48cc: 0x0080, 0x48cd: 0x0080, 0x48ce: 0x0080, 0x48cf: 0x0080, 0x48d0: 0x00c3, 0x48d1: 0x00c3, + 0x48d2: 0x00c3, 0x48d3: 0x00c3, 0x48d4: 0x00c3, 0x48d5: 0x00c3, 0x48d6: 0x00c3, + // Block 0x124, offset 0x4900 + 0x4900: 0x00c2, 0x4901: 0x00c2, 0x4902: 0x00c2, 0x4903: 0x00c2, 0x4904: 0x00c2, 0x4905: 0x00c2, + 0x4906: 0x00c2, 0x4907: 0x00c2, 0x4908: 0x00c2, 0x4909: 0x00c2, 0x490a: 0x00c2, 0x490b: 0x00c2, + 0x490c: 0x00c2, 0x490d: 0x00c2, 0x490e: 0x00c2, 0x490f: 0x00c2, 0x4910: 0x00c2, 0x4911: 0x00c2, + 0x4912: 0x00c2, 0x4913: 0x00c2, 0x4914: 0x00c2, 0x4915: 0x00c2, 0x4916: 0x00c2, 0x4917: 0x00c2, + 0x4918: 0x00c2, 0x4919: 0x00c2, 0x491a: 0x00c2, 0x491b: 0x00c2, 0x491c: 0x00c2, 0x491d: 0x00c2, + 0x491e: 0x00c2, 0x491f: 0x00c2, 0x4920: 0x00c2, 0x4921: 0x00c2, 0x4922: 0x00c2, 0x4923: 0x00c2, + 0x4924: 0x00c2, 0x4925: 0x00c2, 0x4926: 0x00c2, 0x4927: 0x00c2, 0x4928: 0x00c2, 0x4929: 0x00c2, + 0x492a: 0x00c2, 0x492b: 0x00c2, 0x492c: 0x00c2, 0x492d: 0x00c2, 0x492e: 0x00c2, 0x492f: 0x00c2, + 0x4930: 0x00c2, 0x4931: 0x00c2, 0x4932: 0x00c2, 0x4933: 0x00c2, 0x4934: 0x00c2, 0x4935: 0x00c2, + 0x4936: 0x00c2, 0x4937: 0x00c2, 0x4938: 0x00c2, 0x4939: 0x00c2, 0x493a: 0x00c2, 0x493b: 0x00c2, + 0x493c: 0x00c2, 0x493d: 0x00c2, 0x493e: 0x00c2, 0x493f: 0x00c2, + // Block 0x125, offset 0x4940 + 0x4940: 0x00c2, 0x4941: 0x00c2, 0x4942: 0x00c2, 0x4943: 0x00c2, 0x4944: 0x00c3, 0x4945: 0x00c3, + 0x4946: 0x00c3, 0x4947: 0x00c3, 0x4948: 0x00c3, 0x4949: 0x00c3, 0x494a: 0x00c3, + 0x4950: 0x00c0, 0x4951: 0x00c0, + 0x4952: 0x00c0, 0x4953: 0x00c0, 0x4954: 0x00c0, 0x4955: 0x00c0, 0x4956: 0x00c0, 0x4957: 0x00c0, + 0x4958: 0x00c0, 0x4959: 0x00c0, + 0x495e: 0x0080, 0x495f: 0x0080, + // Block 0x126, offset 0x4980 + 0x4980: 0x0080, 0x4981: 0x0080, 0x4982: 0x0080, 0x4983: 0x0080, 0x4985: 0x0080, + 0x4986: 0x0080, 0x4987: 0x0080, 0x4988: 0x0080, 0x4989: 0x0080, 0x498a: 0x0080, 0x498b: 0x0080, + 0x498c: 0x0080, 0x498d: 0x0080, 0x498e: 0x0080, 0x498f: 0x0080, 0x4990: 0x0080, 0x4991: 0x0080, + 0x4992: 0x0080, 0x4993: 0x0080, 0x4994: 0x0080, 0x4995: 0x0080, 0x4996: 0x0080, 0x4997: 0x0080, + 0x4998: 0x0080, 0x4999: 0x0080, 0x499a: 0x0080, 0x499b: 0x0080, 0x499c: 0x0080, 0x499d: 0x0080, + 0x499e: 0x0080, 0x499f: 0x0080, 0x49a1: 0x0080, 0x49a2: 0x0080, + 0x49a4: 0x0080, 0x49a7: 0x0080, 0x49a9: 0x0080, + 0x49aa: 0x0080, 0x49ab: 0x0080, 0x49ac: 0x0080, 0x49ad: 0x0080, 0x49ae: 0x0080, 0x49af: 0x0080, + 0x49b0: 0x0080, 0x49b1: 0x0080, 0x49b2: 0x0080, 0x49b4: 0x0080, 0x49b5: 0x0080, + 0x49b6: 0x0080, 0x49b7: 0x0080, 0x49b9: 0x0080, 0x49bb: 0x0080, + // Block 0x127, offset 0x49c0 + 0x49c2: 0x0080, + 0x49c7: 0x0080, 0x49c9: 0x0080, 0x49cb: 0x0080, + 0x49cd: 0x0080, 0x49ce: 0x0080, 0x49cf: 0x0080, 0x49d1: 0x0080, + 0x49d2: 0x0080, 0x49d4: 0x0080, 0x49d7: 0x0080, + 0x49d9: 0x0080, 0x49db: 0x0080, 0x49dd: 0x0080, + 0x49df: 0x0080, 0x49e1: 0x0080, 0x49e2: 0x0080, + 0x49e4: 0x0080, 0x49e7: 0x0080, 0x49e8: 0x0080, 0x49e9: 0x0080, + 0x49ea: 0x0080, 0x49ec: 0x0080, 0x49ed: 0x0080, 0x49ee: 0x0080, 0x49ef: 0x0080, + 0x49f0: 0x0080, 0x49f1: 0x0080, 0x49f2: 0x0080, 0x49f4: 0x0080, 0x49f5: 0x0080, + 0x49f6: 0x0080, 0x49f7: 0x0080, 0x49f9: 0x0080, 0x49fa: 0x0080, 0x49fb: 0x0080, + 0x49fc: 0x0080, 0x49fe: 0x0080, + // Block 0x128, offset 0x4a00 + 0x4a00: 0x0080, 0x4a01: 0x0080, 0x4a02: 0x0080, 0x4a03: 0x0080, 0x4a04: 0x0080, 0x4a05: 0x0080, + 0x4a06: 0x0080, 0x4a07: 0x0080, 0x4a08: 0x0080, 0x4a09: 0x0080, 0x4a0b: 0x0080, + 0x4a0c: 0x0080, 0x4a0d: 0x0080, 0x4a0e: 0x0080, 0x4a0f: 0x0080, 0x4a10: 0x0080, 0x4a11: 0x0080, + 0x4a12: 0x0080, 0x4a13: 0x0080, 0x4a14: 0x0080, 0x4a15: 0x0080, 0x4a16: 0x0080, 0x4a17: 0x0080, + 0x4a18: 0x0080, 0x4a19: 0x0080, 0x4a1a: 0x0080, 0x4a1b: 0x0080, + 0x4a21: 0x0080, 0x4a22: 0x0080, 0x4a23: 0x0080, + 0x4a25: 0x0080, 0x4a26: 0x0080, 0x4a27: 0x0080, 0x4a28: 0x0080, 0x4a29: 0x0080, + 0x4a2b: 0x0080, 0x4a2c: 0x0080, 0x4a2d: 0x0080, 0x4a2e: 0x0080, 0x4a2f: 0x0080, + 0x4a30: 0x0080, 0x4a31: 0x0080, 0x4a32: 0x0080, 0x4a33: 0x0080, 0x4a34: 0x0080, 0x4a35: 0x0080, + 0x4a36: 0x0080, 0x4a37: 0x0080, 0x4a38: 0x0080, 0x4a39: 0x0080, 0x4a3a: 0x0080, 0x4a3b: 0x0080, + // Block 0x129, offset 0x4a40 + 0x4a70: 0x0080, 0x4a71: 0x0080, + // Block 0x12a, offset 0x4a80 + 0x4a80: 0x0080, 0x4a81: 0x0080, 0x4a82: 0x0080, 0x4a83: 0x0080, 0x4a84: 0x0080, 0x4a85: 0x0080, + 0x4a86: 0x0080, 0x4a87: 0x0080, 0x4a88: 0x0080, 0x4a89: 0x0080, 0x4a8a: 0x0080, 0x4a8b: 0x0080, + 0x4a8c: 0x0080, 0x4a8d: 0x0080, 0x4a8e: 0x0080, 0x4a8f: 0x0080, 0x4a90: 0x0080, 0x4a91: 0x0080, + 0x4a92: 0x0080, 0x4a93: 0x0080, 0x4a94: 0x0080, 0x4a95: 0x0080, 0x4a96: 0x0080, 0x4a97: 0x0080, + 0x4a98: 0x0080, 0x4a99: 0x0080, 0x4a9a: 0x0080, 0x4a9b: 0x0080, 0x4a9c: 0x0080, 0x4a9d: 0x0080, + 0x4a9e: 0x0080, 0x4a9f: 0x0080, 0x4aa0: 0x0080, 0x4aa1: 0x0080, 0x4aa2: 0x0080, 0x4aa3: 0x0080, + 0x4aa4: 0x0080, 0x4aa5: 0x0080, 0x4aa6: 0x0080, 0x4aa7: 0x0080, 0x4aa8: 0x0080, 0x4aa9: 0x0080, + 0x4aaa: 0x0080, 0x4aab: 0x0080, + 0x4ab0: 0x0080, 0x4ab1: 0x0080, 0x4ab2: 0x0080, 0x4ab3: 0x0080, 0x4ab4: 0x0080, 0x4ab5: 0x0080, + 0x4ab6: 0x0080, 0x4ab7: 0x0080, 0x4ab8: 0x0080, 0x4ab9: 0x0080, 0x4aba: 0x0080, 0x4abb: 0x0080, + 0x4abc: 0x0080, 0x4abd: 0x0080, 0x4abe: 0x0080, 0x4abf: 0x0080, + // Block 0x12b, offset 0x4ac0 + 0x4ac0: 0x0080, 0x4ac1: 0x0080, 0x4ac2: 0x0080, 0x4ac3: 0x0080, 0x4ac4: 0x0080, 0x4ac5: 0x0080, + 0x4ac6: 0x0080, 0x4ac7: 0x0080, 0x4ac8: 0x0080, 0x4ac9: 0x0080, 0x4aca: 0x0080, 0x4acb: 0x0080, + 0x4acc: 0x0080, 0x4acd: 0x0080, 0x4ace: 0x0080, 0x4acf: 0x0080, 0x4ad0: 0x0080, 0x4ad1: 0x0080, + 0x4ad2: 0x0080, 0x4ad3: 0x0080, + 0x4ae0: 0x0080, 0x4ae1: 0x0080, 0x4ae2: 0x0080, 0x4ae3: 0x0080, + 0x4ae4: 0x0080, 0x4ae5: 0x0080, 0x4ae6: 0x0080, 0x4ae7: 0x0080, 0x4ae8: 0x0080, 0x4ae9: 0x0080, + 0x4aea: 0x0080, 0x4aeb: 0x0080, 0x4aec: 0x0080, 0x4aed: 0x0080, 0x4aee: 0x0080, + 0x4af1: 0x0080, 0x4af2: 0x0080, 0x4af3: 0x0080, 0x4af4: 0x0080, 0x4af5: 0x0080, + 0x4af6: 0x0080, 0x4af7: 0x0080, 0x4af8: 0x0080, 0x4af9: 0x0080, 0x4afa: 0x0080, 0x4afb: 0x0080, + 0x4afc: 0x0080, 0x4afd: 0x0080, 0x4afe: 0x0080, 0x4aff: 0x0080, + // Block 0x12c, offset 0x4b00 + 0x4b01: 0x0080, 0x4b02: 0x0080, 0x4b03: 0x0080, 0x4b04: 0x0080, 0x4b05: 0x0080, + 0x4b06: 0x0080, 0x4b07: 0x0080, 0x4b08: 0x0080, 0x4b09: 0x0080, 0x4b0a: 0x0080, 0x4b0b: 0x0080, + 0x4b0c: 0x0080, 0x4b0d: 0x0080, 0x4b0e: 0x0080, 0x4b0f: 0x0080, 0x4b11: 0x0080, + 0x4b12: 0x0080, 0x4b13: 0x0080, 0x4b14: 0x0080, 0x4b15: 0x0080, 0x4b16: 0x0080, 0x4b17: 0x0080, + 0x4b18: 0x0080, 0x4b19: 0x0080, 0x4b1a: 0x0080, 0x4b1b: 0x0080, 0x4b1c: 0x0080, 0x4b1d: 0x0080, + 0x4b1e: 0x0080, 0x4b1f: 0x0080, 0x4b20: 0x0080, 0x4b21: 0x0080, 0x4b22: 0x0080, 0x4b23: 0x0080, + 0x4b24: 0x0080, 0x4b25: 0x0080, 0x4b26: 0x0080, 0x4b27: 0x0080, 0x4b28: 0x0080, 0x4b29: 0x0080, + 0x4b2a: 0x0080, 0x4b2b: 0x0080, 0x4b2c: 0x0080, 0x4b2d: 0x0080, 0x4b2e: 0x0080, 0x4b2f: 0x0080, + 0x4b30: 0x0080, 0x4b31: 0x0080, 0x4b32: 0x0080, 0x4b33: 0x0080, 0x4b34: 0x0080, 0x4b35: 0x0080, + // Block 0x12d, offset 0x4b40 + 0x4b40: 0x0080, 0x4b41: 0x0080, 0x4b42: 0x0080, 0x4b43: 0x0080, 0x4b44: 0x0080, 0x4b45: 0x0080, + 0x4b46: 0x0080, 0x4b47: 0x0080, 0x4b48: 0x0080, 0x4b49: 0x0080, 0x4b4a: 0x0080, 0x4b4b: 0x0080, + 0x4b4c: 0x0080, 0x4b50: 0x0080, 0x4b51: 0x0080, + 0x4b52: 0x0080, 0x4b53: 0x0080, 0x4b54: 0x0080, 0x4b55: 0x0080, 0x4b56: 0x0080, 0x4b57: 0x0080, + 0x4b58: 0x0080, 0x4b59: 0x0080, 0x4b5a: 0x0080, 0x4b5b: 0x0080, 0x4b5c: 0x0080, 0x4b5d: 0x0080, + 0x4b5e: 0x0080, 0x4b5f: 0x0080, 0x4b60: 0x0080, 0x4b61: 0x0080, 0x4b62: 0x0080, 0x4b63: 0x0080, + 0x4b64: 0x0080, 0x4b65: 0x0080, 0x4b66: 0x0080, 0x4b67: 0x0080, 0x4b68: 0x0080, 0x4b69: 0x0080, + 0x4b6a: 0x0080, 0x4b6b: 0x0080, 0x4b6c: 0x0080, 0x4b6d: 0x0080, 0x4b6e: 0x0080, + 0x4b70: 0x0080, 0x4b71: 0x0080, 0x4b72: 0x0080, 0x4b73: 0x0080, 0x4b74: 0x0080, 0x4b75: 0x0080, + 0x4b76: 0x0080, 0x4b77: 0x0080, 0x4b78: 0x0080, 0x4b79: 0x0080, 0x4b7a: 0x0080, 0x4b7b: 0x0080, + 0x4b7c: 0x0080, 0x4b7d: 0x0080, 0x4b7e: 0x0080, 0x4b7f: 0x0080, + // Block 0x12e, offset 0x4b80 + 0x4b80: 0x0080, 0x4b81: 0x0080, 0x4b82: 0x0080, 0x4b83: 0x0080, 0x4b84: 0x0080, 0x4b85: 0x0080, + 0x4b86: 0x0080, 0x4b87: 0x0080, 0x4b88: 0x0080, 0x4b89: 0x0080, 0x4b8a: 0x0080, 0x4b8b: 0x0080, + 0x4b8c: 0x0080, 0x4b8d: 0x0080, 0x4b8e: 0x0080, 0x4b8f: 0x0080, 0x4b90: 0x0080, 0x4b91: 0x0080, + 0x4b92: 0x0080, 0x4b93: 0x0080, 0x4b94: 0x0080, 0x4b95: 0x0080, 0x4b96: 0x0080, 0x4b97: 0x0080, + 0x4b98: 0x0080, 0x4b99: 0x0080, 0x4b9a: 0x0080, 0x4b9b: 0x0080, 0x4b9c: 0x0080, 0x4b9d: 0x0080, + 0x4b9e: 0x0080, 0x4b9f: 0x0080, 0x4ba0: 0x0080, 0x4ba1: 0x0080, 0x4ba2: 0x0080, 0x4ba3: 0x0080, + 0x4ba4: 0x0080, 0x4ba5: 0x0080, 0x4ba6: 0x0080, 0x4ba7: 0x0080, 0x4ba8: 0x0080, 0x4ba9: 0x0080, + 0x4baa: 0x0080, 0x4bab: 0x0080, 0x4bac: 0x0080, + // Block 0x12f, offset 0x4bc0 + 0x4be6: 0x0080, 0x4be7: 0x0080, 0x4be8: 0x0080, 0x4be9: 0x0080, + 0x4bea: 0x0080, 0x4beb: 0x0080, 0x4bec: 0x0080, 0x4bed: 0x0080, 0x4bee: 0x0080, 0x4bef: 0x0080, + 0x4bf0: 0x0080, 0x4bf1: 0x0080, 0x4bf2: 0x0080, 0x4bf3: 0x0080, 0x4bf4: 0x0080, 0x4bf5: 0x0080, + 0x4bf6: 0x0080, 0x4bf7: 0x0080, 0x4bf8: 0x0080, 0x4bf9: 0x0080, 0x4bfa: 0x0080, 0x4bfb: 0x0080, + 0x4bfc: 0x0080, 0x4bfd: 0x0080, 0x4bfe: 0x0080, 0x4bff: 0x0080, + // Block 0x130, offset 0x4c00 + 0x4c00: 0x008c, 0x4c01: 0x0080, 0x4c02: 0x0080, + 0x4c10: 0x0080, 0x4c11: 0x0080, + 0x4c12: 0x0080, 0x4c13: 0x0080, 0x4c14: 0x0080, 0x4c15: 0x0080, 0x4c16: 0x0080, 0x4c17: 0x0080, + 0x4c18: 0x0080, 0x4c19: 0x0080, 0x4c1a: 0x0080, 0x4c1b: 0x0080, 0x4c1c: 0x0080, 0x4c1d: 0x0080, + 0x4c1e: 0x0080, 0x4c1f: 0x0080, 0x4c20: 0x0080, 0x4c21: 0x0080, 0x4c22: 0x0080, 0x4c23: 0x0080, + 0x4c24: 0x0080, 0x4c25: 0x0080, 0x4c26: 0x0080, 0x4c27: 0x0080, 0x4c28: 0x0080, 0x4c29: 0x0080, + 0x4c2a: 0x0080, 0x4c2b: 0x0080, 0x4c2c: 0x0080, 0x4c2d: 0x0080, 0x4c2e: 0x0080, 0x4c2f: 0x0080, + 0x4c30: 0x0080, 0x4c31: 0x0080, 0x4c32: 0x0080, 0x4c33: 0x0080, 0x4c34: 0x0080, 0x4c35: 0x0080, + 0x4c36: 0x0080, 0x4c37: 0x0080, 0x4c38: 0x0080, 0x4c39: 0x0080, 0x4c3a: 0x0080, 0x4c3b: 0x0080, + // Block 0x131, offset 0x4c40 + 0x4c40: 0x0080, 0x4c41: 0x0080, 0x4c42: 0x0080, 0x4c43: 0x0080, 0x4c44: 0x0080, 0x4c45: 0x0080, + 0x4c46: 0x0080, 0x4c47: 0x0080, 0x4c48: 0x0080, + 0x4c50: 0x0080, 0x4c51: 0x0080, + // Block 0x132, offset 0x4c80 + 0x4c80: 0x0080, 0x4c81: 0x0080, 0x4c82: 0x0080, 0x4c83: 0x0080, 0x4c84: 0x0080, 0x4c85: 0x0080, + 0x4c86: 0x0080, 0x4c87: 0x0080, 0x4c88: 0x0080, 0x4c89: 0x0080, 0x4c8a: 0x0080, 0x4c8b: 0x0080, + 0x4c8c: 0x0080, 0x4c8d: 0x0080, 0x4c8e: 0x0080, 0x4c8f: 0x0080, 0x4c90: 0x0080, 0x4c91: 0x0080, + 0x4c92: 0x0080, + 0x4ca0: 0x0080, 0x4ca1: 0x0080, 0x4ca2: 0x0080, 0x4ca3: 0x0080, + 0x4ca4: 0x0080, 0x4ca5: 0x0080, 0x4ca6: 0x0080, 0x4ca7: 0x0080, 0x4ca8: 0x0080, 0x4ca9: 0x0080, + 0x4caa: 0x0080, 0x4cab: 0x0080, 0x4cac: 0x0080, + 0x4cb0: 0x0080, 0x4cb1: 0x0080, 0x4cb2: 0x0080, 0x4cb3: 0x0080, 0x4cb4: 0x0080, 0x4cb5: 0x0080, + 0x4cb6: 0x0080, + // Block 0x133, offset 0x4cc0 + 0x4cc0: 0x0080, 0x4cc1: 0x0080, 0x4cc2: 0x0080, 0x4cc3: 0x0080, 0x4cc4: 0x0080, 0x4cc5: 0x0080, + 0x4cc6: 0x0080, 0x4cc7: 0x0080, 0x4cc8: 0x0080, 0x4cc9: 0x0080, 0x4cca: 0x0080, 0x4ccb: 0x0080, + 0x4ccc: 0x0080, 0x4ccd: 0x0080, 0x4cce: 0x0080, 0x4ccf: 0x0080, 0x4cd0: 0x0080, 0x4cd1: 0x0080, + 0x4cd2: 0x0080, 0x4cd3: 0x0080, 0x4cd4: 0x0080, 0x4cd5: 0x0080, 0x4cd6: 0x0080, 0x4cd7: 0x0080, + 0x4cd8: 0x0080, 0x4cd9: 0x0080, 0x4cda: 0x0080, 0x4cdb: 0x0080, 0x4cdc: 0x0080, 0x4cdd: 0x0080, + 0x4cde: 0x0080, 0x4cdf: 0x0080, 0x4ce0: 0x0080, 0x4ce1: 0x0080, 0x4ce2: 0x0080, 0x4ce3: 0x0080, + 0x4ce4: 0x0080, 0x4ce5: 0x0080, 0x4ce6: 0x0080, 0x4ce7: 0x0080, 0x4ce8: 0x0080, 0x4ce9: 0x0080, + 0x4cea: 0x0080, 0x4ceb: 0x0080, 0x4cec: 0x0080, 0x4ced: 0x0080, 0x4cee: 0x0080, 0x4cef: 0x0080, + 0x4cf0: 0x0080, 0x4cf1: 0x0080, 0x4cf2: 0x0080, 0x4cf3: 0x0080, + // Block 0x134, offset 0x4d00 + 0x4d00: 0x0080, 0x4d01: 0x0080, 0x4d02: 0x0080, 0x4d03: 0x0080, 0x4d04: 0x0080, 0x4d05: 0x0080, + 0x4d06: 0x0080, 0x4d07: 0x0080, 0x4d08: 0x0080, 0x4d09: 0x0080, 0x4d0a: 0x0080, 0x4d0b: 0x0080, + 0x4d0c: 0x0080, 0x4d0d: 0x0080, 0x4d0e: 0x0080, 0x4d0f: 0x0080, 0x4d10: 0x0080, 0x4d11: 0x0080, + 0x4d12: 0x0080, 0x4d13: 0x0080, 0x4d14: 0x0080, + // Block 0x135, offset 0x4d40 + 0x4d40: 0x0080, 0x4d41: 0x0080, 0x4d42: 0x0080, 0x4d43: 0x0080, 0x4d44: 0x0080, 0x4d45: 0x0080, + 0x4d46: 0x0080, 0x4d47: 0x0080, 0x4d48: 0x0080, 0x4d49: 0x0080, 0x4d4a: 0x0080, 0x4d4b: 0x0080, + 0x4d50: 0x0080, 0x4d51: 0x0080, + 0x4d52: 0x0080, 0x4d53: 0x0080, 0x4d54: 0x0080, 0x4d55: 0x0080, 0x4d56: 0x0080, 0x4d57: 0x0080, + 0x4d58: 0x0080, 0x4d59: 0x0080, 0x4d5a: 0x0080, 0x4d5b: 0x0080, 0x4d5c: 0x0080, 0x4d5d: 0x0080, + 0x4d5e: 0x0080, 0x4d5f: 0x0080, 0x4d60: 0x0080, 0x4d61: 0x0080, 0x4d62: 0x0080, 0x4d63: 0x0080, + 0x4d64: 0x0080, 0x4d65: 0x0080, 0x4d66: 0x0080, 0x4d67: 0x0080, 0x4d68: 0x0080, 0x4d69: 0x0080, + 0x4d6a: 0x0080, 0x4d6b: 0x0080, 0x4d6c: 0x0080, 0x4d6d: 0x0080, 0x4d6e: 0x0080, 0x4d6f: 0x0080, + 0x4d70: 0x0080, 0x4d71: 0x0080, 0x4d72: 0x0080, 0x4d73: 0x0080, 0x4d74: 0x0080, 0x4d75: 0x0080, + 0x4d76: 0x0080, 0x4d77: 0x0080, 0x4d78: 0x0080, 0x4d79: 0x0080, 0x4d7a: 0x0080, 0x4d7b: 0x0080, + 0x4d7c: 0x0080, 0x4d7d: 0x0080, 0x4d7e: 0x0080, 0x4d7f: 0x0080, + // Block 0x136, offset 0x4d80 + 0x4d80: 0x0080, 0x4d81: 0x0080, 0x4d82: 0x0080, 0x4d83: 0x0080, 0x4d84: 0x0080, 0x4d85: 0x0080, + 0x4d86: 0x0080, 0x4d87: 0x0080, + 0x4d90: 0x0080, 0x4d91: 0x0080, + 0x4d92: 0x0080, 0x4d93: 0x0080, 0x4d94: 0x0080, 0x4d95: 0x0080, 0x4d96: 0x0080, 0x4d97: 0x0080, + 0x4d98: 0x0080, 0x4d99: 0x0080, + 0x4da0: 0x0080, 0x4da1: 0x0080, 0x4da2: 0x0080, 0x4da3: 0x0080, + 0x4da4: 0x0080, 0x4da5: 0x0080, 0x4da6: 0x0080, 0x4da7: 0x0080, 0x4da8: 0x0080, 0x4da9: 0x0080, + 0x4daa: 0x0080, 0x4dab: 0x0080, 0x4dac: 0x0080, 0x4dad: 0x0080, 0x4dae: 0x0080, 0x4daf: 0x0080, + 0x4db0: 0x0080, 0x4db1: 0x0080, 0x4db2: 0x0080, 0x4db3: 0x0080, 0x4db4: 0x0080, 0x4db5: 0x0080, + 0x4db6: 0x0080, 0x4db7: 0x0080, 0x4db8: 0x0080, 0x4db9: 0x0080, 0x4dba: 0x0080, 0x4dbb: 0x0080, + 0x4dbc: 0x0080, 0x4dbd: 0x0080, 0x4dbe: 0x0080, 0x4dbf: 0x0080, + // Block 0x137, offset 0x4dc0 + 0x4dc0: 0x0080, 0x4dc1: 0x0080, 0x4dc2: 0x0080, 0x4dc3: 0x0080, 0x4dc4: 0x0080, 0x4dc5: 0x0080, + 0x4dc6: 0x0080, 0x4dc7: 0x0080, + 0x4dd0: 0x0080, 0x4dd1: 0x0080, + 0x4dd2: 0x0080, 0x4dd3: 0x0080, 0x4dd4: 0x0080, 0x4dd5: 0x0080, 0x4dd6: 0x0080, 0x4dd7: 0x0080, + 0x4dd8: 0x0080, 0x4dd9: 0x0080, 0x4dda: 0x0080, 0x4ddb: 0x0080, 0x4ddc: 0x0080, 0x4ddd: 0x0080, + 0x4dde: 0x0080, 0x4ddf: 0x0080, 0x4de0: 0x0080, 0x4de1: 0x0080, 0x4de2: 0x0080, 0x4de3: 0x0080, + 0x4de4: 0x0080, 0x4de5: 0x0080, 0x4de6: 0x0080, 0x4de7: 0x0080, 0x4de8: 0x0080, 0x4de9: 0x0080, + 0x4dea: 0x0080, 0x4deb: 0x0080, 0x4dec: 0x0080, 0x4ded: 0x0080, + // Block 0x138, offset 0x4e00 + 0x4e10: 0x0080, 0x4e11: 0x0080, + 0x4e12: 0x0080, 0x4e13: 0x0080, 0x4e14: 0x0080, 0x4e15: 0x0080, 0x4e16: 0x0080, 0x4e17: 0x0080, + 0x4e18: 0x0080, 0x4e19: 0x0080, 0x4e1a: 0x0080, 0x4e1b: 0x0080, 0x4e1c: 0x0080, 0x4e1d: 0x0080, + 0x4e1e: 0x0080, 0x4e20: 0x0080, 0x4e21: 0x0080, 0x4e22: 0x0080, 0x4e23: 0x0080, + 0x4e24: 0x0080, 0x4e25: 0x0080, 0x4e26: 0x0080, 0x4e27: 0x0080, + 0x4e30: 0x0080, 0x4e33: 0x0080, 0x4e34: 0x0080, 0x4e35: 0x0080, + 0x4e36: 0x0080, 0x4e37: 0x0080, 0x4e38: 0x0080, 0x4e39: 0x0080, 0x4e3a: 0x0080, 0x4e3b: 0x0080, + 0x4e3c: 0x0080, 0x4e3d: 0x0080, 0x4e3e: 0x0080, + // Block 0x139, offset 0x4e40 + 0x4e40: 0x0080, 0x4e41: 0x0080, 0x4e42: 0x0080, 0x4e43: 0x0080, 0x4e44: 0x0080, 0x4e45: 0x0080, + 0x4e46: 0x0080, 0x4e47: 0x0080, 0x4e48: 0x0080, 0x4e49: 0x0080, 0x4e4a: 0x0080, 0x4e4b: 0x0080, + 0x4e50: 0x0080, 0x4e51: 0x0080, + 0x4e52: 0x0080, 0x4e53: 0x0080, 0x4e54: 0x0080, 0x4e55: 0x0080, 0x4e56: 0x0080, 0x4e57: 0x0080, + 0x4e58: 0x0080, 0x4e59: 0x0080, 0x4e5a: 0x0080, 0x4e5b: 0x0080, 0x4e5c: 0x0080, 0x4e5d: 0x0080, + 0x4e5e: 0x0080, + // Block 0x13a, offset 0x4e80 + 0x4e80: 0x0080, 0x4e81: 0x0080, 0x4e82: 0x0080, 0x4e83: 0x0080, 0x4e84: 0x0080, 0x4e85: 0x0080, + 0x4e86: 0x0080, 0x4e87: 0x0080, 0x4e88: 0x0080, 0x4e89: 0x0080, 0x4e8a: 0x0080, 0x4e8b: 0x0080, + 0x4e8c: 0x0080, 0x4e8d: 0x0080, 0x4e8e: 0x0080, 0x4e8f: 0x0080, 0x4e90: 0x0080, 0x4e91: 0x0080, + // Block 0x13b, offset 0x4ec0 + 0x4ec0: 0x0080, + // Block 0x13c, offset 0x4f00 + 0x4f00: 0x00cc, 0x4f01: 0x00cc, 0x4f02: 0x00cc, 0x4f03: 0x00cc, 0x4f04: 0x00cc, 0x4f05: 0x00cc, + 0x4f06: 0x00cc, 0x4f07: 0x00cc, 0x4f08: 0x00cc, 0x4f09: 0x00cc, 0x4f0a: 0x00cc, 0x4f0b: 0x00cc, + 0x4f0c: 0x00cc, 0x4f0d: 0x00cc, 0x4f0e: 0x00cc, 0x4f0f: 0x00cc, 0x4f10: 0x00cc, 0x4f11: 0x00cc, + 0x4f12: 0x00cc, 0x4f13: 0x00cc, 0x4f14: 0x00cc, 0x4f15: 0x00cc, 0x4f16: 0x00cc, + // Block 0x13d, offset 0x4f40 + 0x4f40: 0x00cc, 0x4f41: 0x00cc, 0x4f42: 0x00cc, 0x4f43: 0x00cc, 0x4f44: 0x00cc, 0x4f45: 0x00cc, + 0x4f46: 0x00cc, 0x4f47: 0x00cc, 0x4f48: 0x00cc, 0x4f49: 0x00cc, 0x4f4a: 0x00cc, 0x4f4b: 0x00cc, + 0x4f4c: 0x00cc, 0x4f4d: 0x00cc, 0x4f4e: 0x00cc, 0x4f4f: 0x00cc, 0x4f50: 0x00cc, 0x4f51: 0x00cc, + 0x4f52: 0x00cc, 0x4f53: 0x00cc, 0x4f54: 0x00cc, 0x4f55: 0x00cc, 0x4f56: 0x00cc, 0x4f57: 0x00cc, + 0x4f58: 0x00cc, 0x4f59: 0x00cc, 0x4f5a: 0x00cc, 0x4f5b: 0x00cc, 0x4f5c: 0x00cc, 0x4f5d: 0x00cc, + 0x4f5e: 0x00cc, 0x4f5f: 0x00cc, 0x4f60: 0x00cc, 0x4f61: 0x00cc, 0x4f62: 0x00cc, 0x4f63: 0x00cc, + 0x4f64: 0x00cc, 0x4f65: 0x00cc, 0x4f66: 0x00cc, 0x4f67: 0x00cc, 0x4f68: 0x00cc, 0x4f69: 0x00cc, + 0x4f6a: 0x00cc, 0x4f6b: 0x00cc, 0x4f6c: 0x00cc, 0x4f6d: 0x00cc, 0x4f6e: 0x00cc, 0x4f6f: 0x00cc, + 0x4f70: 0x00cc, 0x4f71: 0x00cc, 0x4f72: 0x00cc, 0x4f73: 0x00cc, 0x4f74: 0x00cc, + // Block 0x13e, offset 0x4f80 + 0x4f80: 0x00cc, 0x4f81: 0x00cc, 0x4f82: 0x00cc, 0x4f83: 0x00cc, 0x4f84: 0x00cc, 0x4f85: 0x00cc, + 0x4f86: 0x00cc, 0x4f87: 0x00cc, 0x4f88: 0x00cc, 0x4f89: 0x00cc, 0x4f8a: 0x00cc, 0x4f8b: 0x00cc, + 0x4f8c: 0x00cc, 0x4f8d: 0x00cc, 0x4f8e: 0x00cc, 0x4f8f: 0x00cc, 0x4f90: 0x00cc, 0x4f91: 0x00cc, + 0x4f92: 0x00cc, 0x4f93: 0x00cc, 0x4f94: 0x00cc, 0x4f95: 0x00cc, 0x4f96: 0x00cc, 0x4f97: 0x00cc, + 0x4f98: 0x00cc, 0x4f99: 0x00cc, 0x4f9a: 0x00cc, 0x4f9b: 0x00cc, 0x4f9c: 0x00cc, 0x4f9d: 0x00cc, + 0x4fa0: 0x00cc, 0x4fa1: 0x00cc, 0x4fa2: 0x00cc, 0x4fa3: 0x00cc, + 0x4fa4: 0x00cc, 0x4fa5: 0x00cc, 0x4fa6: 0x00cc, 0x4fa7: 0x00cc, 0x4fa8: 0x00cc, 0x4fa9: 0x00cc, + 0x4faa: 0x00cc, 0x4fab: 0x00cc, 0x4fac: 0x00cc, 0x4fad: 0x00cc, 0x4fae: 0x00cc, 0x4faf: 0x00cc, + 0x4fb0: 0x00cc, 0x4fb1: 0x00cc, 0x4fb2: 0x00cc, 0x4fb3: 0x00cc, 0x4fb4: 0x00cc, 0x4fb5: 0x00cc, + 0x4fb6: 0x00cc, 0x4fb7: 0x00cc, 0x4fb8: 0x00cc, 0x4fb9: 0x00cc, 0x4fba: 0x00cc, 0x4fbb: 0x00cc, + 0x4fbc: 0x00cc, 0x4fbd: 0x00cc, 0x4fbe: 0x00cc, 0x4fbf: 0x00cc, + // Block 0x13f, offset 0x4fc0 + 0x4fc0: 0x00cc, 0x4fc1: 0x00cc, 0x4fc2: 0x00cc, 0x4fc3: 0x00cc, 0x4fc4: 0x00cc, 0x4fc5: 0x00cc, + 0x4fc6: 0x00cc, 0x4fc7: 0x00cc, 0x4fc8: 0x00cc, 0x4fc9: 0x00cc, 0x4fca: 0x00cc, 0x4fcb: 0x00cc, + 0x4fcc: 0x00cc, 0x4fcd: 0x00cc, 0x4fce: 0x00cc, 0x4fcf: 0x00cc, 0x4fd0: 0x00cc, 0x4fd1: 0x00cc, + 0x4fd2: 0x00cc, 0x4fd3: 0x00cc, 0x4fd4: 0x00cc, 0x4fd5: 0x00cc, 0x4fd6: 0x00cc, 0x4fd7: 0x00cc, + 0x4fd8: 0x00cc, 0x4fd9: 0x00cc, 0x4fda: 0x00cc, 0x4fdb: 0x00cc, 0x4fdc: 0x00cc, 0x4fdd: 0x00cc, + 0x4fde: 0x00cc, 0x4fdf: 0x00cc, 0x4fe0: 0x00cc, 0x4fe1: 0x00cc, + // Block 0x140, offset 0x5000 + 0x5000: 0x008c, 0x5001: 0x008c, 0x5002: 0x008c, 0x5003: 0x008c, 0x5004: 0x008c, 0x5005: 0x008c, + 0x5006: 0x008c, 0x5007: 0x008c, 0x5008: 0x008c, 0x5009: 0x008c, 0x500a: 0x008c, 0x500b: 0x008c, + 0x500c: 0x008c, 0x500d: 0x008c, 0x500e: 0x008c, 0x500f: 0x008c, 0x5010: 0x008c, 0x5011: 0x008c, + 0x5012: 0x008c, 0x5013: 0x008c, 0x5014: 0x008c, 0x5015: 0x008c, 0x5016: 0x008c, 0x5017: 0x008c, + 0x5018: 0x008c, 0x5019: 0x008c, 0x501a: 0x008c, 0x501b: 0x008c, 0x501c: 0x008c, 0x501d: 0x008c, + // Block 0x141, offset 0x5040 + 0x5041: 0x0040, + 0x5060: 0x0040, 0x5061: 0x0040, 0x5062: 0x0040, 0x5063: 0x0040, + 0x5064: 0x0040, 0x5065: 0x0040, 0x5066: 0x0040, 0x5067: 0x0040, 0x5068: 0x0040, 0x5069: 0x0040, + 0x506a: 0x0040, 0x506b: 0x0040, 0x506c: 0x0040, 0x506d: 0x0040, 0x506e: 0x0040, 0x506f: 0x0040, + 0x5070: 0x0040, 0x5071: 0x0040, 0x5072: 0x0040, 0x5073: 0x0040, 0x5074: 0x0040, 0x5075: 0x0040, + 0x5076: 0x0040, 0x5077: 0x0040, 0x5078: 0x0040, 0x5079: 0x0040, 0x507a: 0x0040, 0x507b: 0x0040, + 0x507c: 0x0040, 0x507d: 0x0040, 0x507e: 0x0040, 0x507f: 0x0040, + // Block 0x142, offset 0x5080 + 0x5080: 0x0040, 0x5081: 0x0040, 0x5082: 0x0040, 0x5083: 0x0040, 0x5084: 0x0040, 0x5085: 0x0040, + 0x5086: 0x0040, 0x5087: 0x0040, 0x5088: 0x0040, 0x5089: 0x0040, 0x508a: 0x0040, 0x508b: 0x0040, + 0x508c: 0x0040, 0x508d: 0x0040, 0x508e: 0x0040, 0x508f: 0x0040, 0x5090: 0x0040, 0x5091: 0x0040, + 0x5092: 0x0040, 0x5093: 0x0040, 0x5094: 0x0040, 0x5095: 0x0040, 0x5096: 0x0040, 0x5097: 0x0040, + 0x5098: 0x0040, 0x5099: 0x0040, 0x509a: 0x0040, 0x509b: 0x0040, 0x509c: 0x0040, 0x509d: 0x0040, + 0x509e: 0x0040, 0x509f: 0x0040, 0x50a0: 0x0040, 0x50a1: 0x0040, 0x50a2: 0x0040, 0x50a3: 0x0040, + 0x50a4: 0x0040, 0x50a5: 0x0040, 0x50a6: 0x0040, 0x50a7: 0x0040, 0x50a8: 0x0040, 0x50a9: 0x0040, + 0x50aa: 0x0040, 0x50ab: 0x0040, 0x50ac: 0x0040, 0x50ad: 0x0040, 0x50ae: 0x0040, 0x50af: 0x0040, + // Block 0x143, offset 0x50c0 + 0x50c0: 0x0040, 0x50c1: 0x0040, 0x50c2: 0x0040, 0x50c3: 0x0040, 0x50c4: 0x0040, 0x50c5: 0x0040, + 0x50c6: 0x0040, 0x50c7: 0x0040, 0x50c8: 0x0040, 0x50c9: 0x0040, 0x50ca: 0x0040, 0x50cb: 0x0040, + 0x50cc: 0x0040, 0x50cd: 0x0040, 0x50ce: 0x0040, 0x50cf: 0x0040, 0x50d0: 0x0040, 0x50d1: 0x0040, + 0x50d2: 0x0040, 0x50d3: 0x0040, 0x50d4: 0x0040, 0x50d5: 0x0040, 0x50d6: 0x0040, 0x50d7: 0x0040, + 0x50d8: 0x0040, 0x50d9: 0x0040, 0x50da: 0x0040, 0x50db: 0x0040, 0x50dc: 0x0040, 0x50dd: 0x0040, + 0x50de: 0x0040, 0x50df: 0x0040, 0x50e0: 0x0040, 0x50e1: 0x0040, 0x50e2: 0x0040, 0x50e3: 0x0040, + 0x50e4: 0x0040, 0x50e5: 0x0040, 0x50e6: 0x0040, 0x50e7: 0x0040, 0x50e8: 0x0040, 0x50e9: 0x0040, + 0x50ea: 0x0040, 0x50eb: 0x0040, 0x50ec: 0x0040, 0x50ed: 0x0040, 0x50ee: 0x0040, 0x50ef: 0x0040, + 0x50f0: 0x0040, 0x50f1: 0x0040, 0x50f2: 0x0040, 0x50f3: 0x0040, 0x50f4: 0x0040, 0x50f5: 0x0040, + 0x50f6: 0x0040, 0x50f7: 0x0040, 0x50f8: 0x0040, 0x50f9: 0x0040, 0x50fa: 0x0040, 0x50fb: 0x0040, + 0x50fc: 0x0040, 0x50fd: 0x0040, +} + +// derivedPropertiesIndex: 36 blocks, 2304 entries, 4608 bytes +// Block 0 is the zero block. +var derivedPropertiesIndex = [2304]uint16{ + // Block 0x0, offset 0x0 + // Block 0x1, offset 0x40 + // Block 0x2, offset 0x80 + // Block 0x3, offset 0xc0 + 0xc2: 0x01, 0xc3: 0x02, 0xc4: 0x03, 0xc5: 0x04, 0xc6: 0x05, 0xc7: 0x06, + 0xc8: 0x05, 0xc9: 0x05, 0xca: 0x07, 0xcb: 0x08, 0xcc: 0x09, 0xcd: 0x0a, 0xce: 0x0b, 0xcf: 0x0c, + 0xd0: 0x05, 0xd1: 0x05, 0xd2: 0x0d, 0xd3: 0x05, 0xd4: 0x0e, 0xd5: 0x0f, 0xd6: 0x10, 0xd7: 0x11, + 0xd8: 0x12, 0xd9: 0x13, 0xda: 0x14, 0xdb: 0x15, 0xdc: 0x16, 0xdd: 0x17, 0xde: 0x18, 0xdf: 0x19, + 0xe0: 0x02, 0xe1: 0x03, 0xe2: 0x04, 0xe3: 0x05, 0xe4: 0x06, 0xe5: 0x07, 0xe6: 0x07, 0xe7: 0x07, + 0xe8: 0x07, 0xe9: 0x08, 0xea: 0x09, 0xeb: 0x0a, 0xec: 0x0a, 0xed: 0x0b, 0xee: 0x0c, 0xef: 0x0d, + 0xf0: 0x1d, 0xf3: 0x20, 0xf4: 0x21, + // Block 0x4, offset 0x100 + 0x120: 0x1a, 0x121: 0x1b, 0x122: 0x1c, 0x123: 0x1d, 0x124: 0x1e, 0x125: 0x1f, 0x126: 0x20, 0x127: 0x21, + 0x128: 0x22, 0x129: 0x23, 0x12a: 0x24, 0x12b: 0x25, 0x12c: 0x26, 0x12d: 0x27, 0x12e: 0x28, 0x12f: 0x29, + 0x130: 0x2a, 0x131: 0x2b, 0x132: 0x2c, 0x133: 0x2d, 0x134: 0x2e, 0x135: 0x2f, 0x136: 0x30, 0x137: 0x31, + 0x138: 0x32, 0x139: 0x33, 0x13a: 0x34, 0x13b: 0x35, 0x13c: 0x36, 0x13d: 0x37, 0x13e: 0x38, 0x13f: 0x39, + // Block 0x5, offset 0x140 + 0x140: 0x3a, 0x141: 0x3b, 0x142: 0x3c, 0x143: 0x3d, 0x144: 0x3e, 0x145: 0x3e, 0x146: 0x3e, 0x147: 0x3e, + 0x148: 0x05, 0x149: 0x3f, 0x14a: 0x40, 0x14b: 0x41, 0x14c: 0x42, 0x14d: 0x43, 0x14e: 0x44, 0x14f: 0x45, + 0x150: 0x46, 0x151: 0x05, 0x152: 0x05, 0x153: 0x05, 0x154: 0x05, 0x155: 0x05, 0x156: 0x05, 0x157: 0x05, + 0x158: 0x05, 0x159: 0x47, 0x15a: 0x48, 0x15b: 0x49, 0x15c: 0x4a, 0x15d: 0x4b, 0x15e: 0x4c, 0x15f: 0x4d, + 0x160: 0x4e, 0x161: 0x4f, 0x162: 0x50, 0x163: 0x51, 0x164: 0x52, 0x165: 0x53, 0x166: 0x54, 0x167: 0x55, + 0x168: 0x56, 0x169: 0x57, 0x16a: 0x58, 0x16c: 0x59, 0x16d: 0x5a, 0x16e: 0x5b, 0x16f: 0x5c, + 0x170: 0x5d, 0x171: 0x5e, 0x172: 0x5f, 0x173: 0x60, 0x174: 0x61, 0x175: 0x62, 0x176: 0x63, 0x177: 0x64, + 0x178: 0x05, 0x179: 0x05, 0x17a: 0x65, 0x17b: 0x05, 0x17c: 0x66, 0x17d: 0x67, 0x17e: 0x68, 0x17f: 0x69, + // Block 0x6, offset 0x180 + 0x180: 0x6a, 0x181: 0x6b, 0x182: 0x6c, 0x183: 0x6d, 0x184: 0x6e, 0x185: 0x6f, 0x186: 0x70, 0x187: 0x71, + 0x188: 0x71, 0x189: 0x71, 0x18a: 0x71, 0x18b: 0x71, 0x18c: 0x71, 0x18d: 0x71, 0x18e: 0x71, 0x18f: 0x72, + 0x190: 0x73, 0x191: 0x74, 0x192: 0x71, 0x193: 0x71, 0x194: 0x71, 0x195: 0x71, 0x196: 0x71, 0x197: 0x71, + 0x198: 0x71, 0x199: 0x71, 0x19a: 0x71, 0x19b: 0x71, 0x19c: 0x71, 0x19d: 0x71, 0x19e: 0x71, 0x19f: 0x71, + 0x1a0: 0x71, 0x1a1: 0x71, 0x1a2: 0x71, 0x1a3: 0x71, 0x1a4: 0x71, 0x1a5: 0x71, 0x1a6: 0x71, 0x1a7: 0x71, + 0x1a8: 0x71, 0x1a9: 0x71, 0x1aa: 0x71, 0x1ab: 0x71, 0x1ac: 0x71, 0x1ad: 0x75, 0x1ae: 0x76, 0x1af: 0x77, + 0x1b0: 0x78, 0x1b1: 0x79, 0x1b2: 0x05, 0x1b3: 0x7a, 0x1b4: 0x7b, 0x1b5: 0x7c, 0x1b6: 0x7d, 0x1b7: 0x7e, + 0x1b8: 0x7f, 0x1b9: 0x80, 0x1ba: 0x81, 0x1bb: 0x82, 0x1bc: 0x83, 0x1bd: 0x83, 0x1be: 0x83, 0x1bf: 0x84, + // Block 0x7, offset 0x1c0 + 0x1c0: 0x85, 0x1c1: 0x86, 0x1c2: 0x87, 0x1c3: 0x88, 0x1c4: 0x89, 0x1c5: 0x8a, 0x1c6: 0x8b, 0x1c7: 0x8c, + 0x1c8: 0x8d, 0x1c9: 0x71, 0x1ca: 0x71, 0x1cb: 0x8e, 0x1cc: 0x83, 0x1cd: 0x8f, 0x1ce: 0x71, 0x1cf: 0x71, + 0x1d0: 0x90, 0x1d1: 0x90, 0x1d2: 0x90, 0x1d3: 0x90, 0x1d4: 0x90, 0x1d5: 0x90, 0x1d6: 0x90, 0x1d7: 0x90, + 0x1d8: 0x90, 0x1d9: 0x90, 0x1da: 0x90, 0x1db: 0x90, 0x1dc: 0x90, 0x1dd: 0x90, 0x1de: 0x90, 0x1df: 0x90, + 0x1e0: 0x90, 0x1e1: 0x90, 0x1e2: 0x90, 0x1e3: 0x90, 0x1e4: 0x90, 0x1e5: 0x90, 0x1e6: 0x90, 0x1e7: 0x90, + 0x1e8: 0x90, 0x1e9: 0x90, 0x1ea: 0x90, 0x1eb: 0x90, 0x1ec: 0x90, 0x1ed: 0x90, 0x1ee: 0x90, 0x1ef: 0x90, + 0x1f0: 0x90, 0x1f1: 0x90, 0x1f2: 0x90, 0x1f3: 0x90, 0x1f4: 0x90, 0x1f5: 0x90, 0x1f6: 0x90, 0x1f7: 0x90, + 0x1f8: 0x90, 0x1f9: 0x90, 0x1fa: 0x90, 0x1fb: 0x90, 0x1fc: 0x90, 0x1fd: 0x90, 0x1fe: 0x90, 0x1ff: 0x90, + // Block 0x8, offset 0x200 + 0x200: 0x90, 0x201: 0x90, 0x202: 0x90, 0x203: 0x90, 0x204: 0x90, 0x205: 0x90, 0x206: 0x90, 0x207: 0x90, + 0x208: 0x90, 0x209: 0x90, 0x20a: 0x90, 0x20b: 0x90, 0x20c: 0x90, 0x20d: 0x90, 0x20e: 0x90, 0x20f: 0x90, + 0x210: 0x90, 0x211: 0x90, 0x212: 0x90, 0x213: 0x90, 0x214: 0x90, 0x215: 0x90, 0x216: 0x90, 0x217: 0x90, + 0x218: 0x90, 0x219: 0x90, 0x21a: 0x90, 0x21b: 0x90, 0x21c: 0x90, 0x21d: 0x90, 0x21e: 0x90, 0x21f: 0x90, + 0x220: 0x90, 0x221: 0x90, 0x222: 0x90, 0x223: 0x90, 0x224: 0x90, 0x225: 0x90, 0x226: 0x90, 0x227: 0x90, + 0x228: 0x90, 0x229: 0x90, 0x22a: 0x90, 0x22b: 0x90, 0x22c: 0x90, 0x22d: 0x90, 0x22e: 0x90, 0x22f: 0x90, + 0x230: 0x90, 0x231: 0x90, 0x232: 0x90, 0x233: 0x90, 0x234: 0x90, 0x235: 0x90, 0x236: 0x91, 0x237: 0x71, + 0x238: 0x90, 0x239: 0x90, 0x23a: 0x90, 0x23b: 0x90, 0x23c: 0x90, 0x23d: 0x90, 0x23e: 0x90, 0x23f: 0x90, + // Block 0x9, offset 0x240 + 0x240: 0x90, 0x241: 0x90, 0x242: 0x90, 0x243: 0x90, 0x244: 0x90, 0x245: 0x90, 0x246: 0x90, 0x247: 0x90, + 0x248: 0x90, 0x249: 0x90, 0x24a: 0x90, 0x24b: 0x90, 0x24c: 0x90, 0x24d: 0x90, 0x24e: 0x90, 0x24f: 0x90, + 0x250: 0x90, 0x251: 0x90, 0x252: 0x90, 0x253: 0x90, 0x254: 0x90, 0x255: 0x90, 0x256: 0x90, 0x257: 0x90, + 0x258: 0x90, 0x259: 0x90, 0x25a: 0x90, 0x25b: 0x90, 0x25c: 0x90, 0x25d: 0x90, 0x25e: 0x90, 0x25f: 0x90, + 0x260: 0x90, 0x261: 0x90, 0x262: 0x90, 0x263: 0x90, 0x264: 0x90, 0x265: 0x90, 0x266: 0x90, 0x267: 0x90, + 0x268: 0x90, 0x269: 0x90, 0x26a: 0x90, 0x26b: 0x90, 0x26c: 0x90, 0x26d: 0x90, 0x26e: 0x90, 0x26f: 0x90, + 0x270: 0x90, 0x271: 0x90, 0x272: 0x90, 0x273: 0x90, 0x274: 0x90, 0x275: 0x90, 0x276: 0x90, 0x277: 0x90, + 0x278: 0x90, 0x279: 0x90, 0x27a: 0x90, 0x27b: 0x90, 0x27c: 0x90, 0x27d: 0x90, 0x27e: 0x90, 0x27f: 0x90, + // Block 0xa, offset 0x280 + 0x280: 0x90, 0x281: 0x90, 0x282: 0x90, 0x283: 0x90, 0x284: 0x90, 0x285: 0x90, 0x286: 0x90, 0x287: 0x90, + 0x288: 0x90, 0x289: 0x90, 0x28a: 0x90, 0x28b: 0x90, 0x28c: 0x90, 0x28d: 0x90, 0x28e: 0x90, 0x28f: 0x90, + 0x290: 0x90, 0x291: 0x90, 0x292: 0x90, 0x293: 0x90, 0x294: 0x90, 0x295: 0x90, 0x296: 0x90, 0x297: 0x90, + 0x298: 0x90, 0x299: 0x90, 0x29a: 0x90, 0x29b: 0x90, 0x29c: 0x90, 0x29d: 0x90, 0x29e: 0x90, 0x29f: 0x90, + 0x2a0: 0x90, 0x2a1: 0x90, 0x2a2: 0x90, 0x2a3: 0x90, 0x2a4: 0x90, 0x2a5: 0x90, 0x2a6: 0x90, 0x2a7: 0x90, + 0x2a8: 0x90, 0x2a9: 0x90, 0x2aa: 0x90, 0x2ab: 0x90, 0x2ac: 0x90, 0x2ad: 0x90, 0x2ae: 0x90, 0x2af: 0x90, + 0x2b0: 0x90, 0x2b1: 0x90, 0x2b2: 0x90, 0x2b3: 0x90, 0x2b4: 0x90, 0x2b5: 0x90, 0x2b6: 0x90, 0x2b7: 0x90, + 0x2b8: 0x90, 0x2b9: 0x90, 0x2ba: 0x90, 0x2bb: 0x90, 0x2bc: 0x90, 0x2bd: 0x90, 0x2be: 0x90, 0x2bf: 0x92, + // Block 0xb, offset 0x2c0 + 0x2c0: 0x05, 0x2c1: 0x05, 0x2c2: 0x05, 0x2c3: 0x05, 0x2c4: 0x05, 0x2c5: 0x05, 0x2c6: 0x05, 0x2c7: 0x05, + 0x2c8: 0x05, 0x2c9: 0x05, 0x2ca: 0x05, 0x2cb: 0x05, 0x2cc: 0x05, 0x2cd: 0x05, 0x2ce: 0x05, 0x2cf: 0x05, + 0x2d0: 0x05, 0x2d1: 0x05, 0x2d2: 0x93, 0x2d3: 0x94, 0x2d4: 0x05, 0x2d5: 0x05, 0x2d6: 0x05, 0x2d7: 0x05, + 0x2d8: 0x95, 0x2d9: 0x96, 0x2da: 0x97, 0x2db: 0x98, 0x2dc: 0x99, 0x2dd: 0x9a, 0x2de: 0x9b, 0x2df: 0x9c, + 0x2e0: 0x9d, 0x2e1: 0x9e, 0x2e2: 0x05, 0x2e3: 0x9f, 0x2e4: 0xa0, 0x2e5: 0xa1, 0x2e6: 0xa2, 0x2e7: 0xa3, + 0x2e8: 0xa4, 0x2e9: 0xa5, 0x2ea: 0xa6, 0x2eb: 0xa7, 0x2ec: 0xa8, 0x2ed: 0xa9, 0x2ee: 0x05, 0x2ef: 0xaa, + 0x2f0: 0x05, 0x2f1: 0x05, 0x2f2: 0x05, 0x2f3: 0x05, 0x2f4: 0x05, 0x2f5: 0x05, 0x2f6: 0x05, 0x2f7: 0x05, + 0x2f8: 0x05, 0x2f9: 0x05, 0x2fa: 0x05, 0x2fb: 0x05, 0x2fc: 0x05, 0x2fd: 0x05, 0x2fe: 0x05, 0x2ff: 0x05, + // Block 0xc, offset 0x300 + 0x300: 0x05, 0x301: 0x05, 0x302: 0x05, 0x303: 0x05, 0x304: 0x05, 0x305: 0x05, 0x306: 0x05, 0x307: 0x05, + 0x308: 0x05, 0x309: 0x05, 0x30a: 0x05, 0x30b: 0x05, 0x30c: 0x05, 0x30d: 0x05, 0x30e: 0x05, 0x30f: 0x05, + 0x310: 0x05, 0x311: 0x05, 0x312: 0x05, 0x313: 0x05, 0x314: 0x05, 0x315: 0x05, 0x316: 0x05, 0x317: 0x05, + 0x318: 0x05, 0x319: 0x05, 0x31a: 0x05, 0x31b: 0x05, 0x31c: 0x05, 0x31d: 0x05, 0x31e: 0x05, 0x31f: 0x05, + 0x320: 0x05, 0x321: 0x05, 0x322: 0x05, 0x323: 0x05, 0x324: 0x05, 0x325: 0x05, 0x326: 0x05, 0x327: 0x05, + 0x328: 0x05, 0x329: 0x05, 0x32a: 0x05, 0x32b: 0x05, 0x32c: 0x05, 0x32d: 0x05, 0x32e: 0x05, 0x32f: 0x05, + 0x330: 0x05, 0x331: 0x05, 0x332: 0x05, 0x333: 0x05, 0x334: 0x05, 0x335: 0x05, 0x336: 0x05, 0x337: 0x05, + 0x338: 0x05, 0x339: 0x05, 0x33a: 0x05, 0x33b: 0x05, 0x33c: 0x05, 0x33d: 0x05, 0x33e: 0x05, 0x33f: 0x05, + // Block 0xd, offset 0x340 + 0x340: 0x05, 0x341: 0x05, 0x342: 0x05, 0x343: 0x05, 0x344: 0x05, 0x345: 0x05, 0x346: 0x05, 0x347: 0x05, + 0x348: 0x05, 0x349: 0x05, 0x34a: 0x05, 0x34b: 0x05, 0x34c: 0x05, 0x34d: 0x05, 0x34e: 0x05, 0x34f: 0x05, + 0x350: 0x05, 0x351: 0x05, 0x352: 0x05, 0x353: 0x05, 0x354: 0x05, 0x355: 0x05, 0x356: 0x05, 0x357: 0x05, + 0x358: 0x05, 0x359: 0x05, 0x35a: 0x05, 0x35b: 0x05, 0x35c: 0x05, 0x35d: 0x05, 0x35e: 0xab, 0x35f: 0xac, + // Block 0xe, offset 0x380 + 0x380: 0x3e, 0x381: 0x3e, 0x382: 0x3e, 0x383: 0x3e, 0x384: 0x3e, 0x385: 0x3e, 0x386: 0x3e, 0x387: 0x3e, + 0x388: 0x3e, 0x389: 0x3e, 0x38a: 0x3e, 0x38b: 0x3e, 0x38c: 0x3e, 0x38d: 0x3e, 0x38e: 0x3e, 0x38f: 0x3e, + 0x390: 0x3e, 0x391: 0x3e, 0x392: 0x3e, 0x393: 0x3e, 0x394: 0x3e, 0x395: 0x3e, 0x396: 0x3e, 0x397: 0x3e, + 0x398: 0x3e, 0x399: 0x3e, 0x39a: 0x3e, 0x39b: 0x3e, 0x39c: 0x3e, 0x39d: 0x3e, 0x39e: 0x3e, 0x39f: 0x3e, + 0x3a0: 0x3e, 0x3a1: 0x3e, 0x3a2: 0x3e, 0x3a3: 0x3e, 0x3a4: 0x3e, 0x3a5: 0x3e, 0x3a6: 0x3e, 0x3a7: 0x3e, + 0x3a8: 0x3e, 0x3a9: 0x3e, 0x3aa: 0x3e, 0x3ab: 0x3e, 0x3ac: 0x3e, 0x3ad: 0x3e, 0x3ae: 0x3e, 0x3af: 0x3e, + 0x3b0: 0x3e, 0x3b1: 0x3e, 0x3b2: 0x3e, 0x3b3: 0x3e, 0x3b4: 0x3e, 0x3b5: 0x3e, 0x3b6: 0x3e, 0x3b7: 0x3e, + 0x3b8: 0x3e, 0x3b9: 0x3e, 0x3ba: 0x3e, 0x3bb: 0x3e, 0x3bc: 0x3e, 0x3bd: 0x3e, 0x3be: 0x3e, 0x3bf: 0x3e, + // Block 0xf, offset 0x3c0 + 0x3c0: 0x3e, 0x3c1: 0x3e, 0x3c2: 0x3e, 0x3c3: 0x3e, 0x3c4: 0x3e, 0x3c5: 0x3e, 0x3c6: 0x3e, 0x3c7: 0x3e, + 0x3c8: 0x3e, 0x3c9: 0x3e, 0x3ca: 0x3e, 0x3cb: 0x3e, 0x3cc: 0x3e, 0x3cd: 0x3e, 0x3ce: 0x3e, 0x3cf: 0x3e, + 0x3d0: 0x3e, 0x3d1: 0x3e, 0x3d2: 0x3e, 0x3d3: 0x3e, 0x3d4: 0x3e, 0x3d5: 0x3e, 0x3d6: 0x3e, 0x3d7: 0x3e, + 0x3d8: 0x3e, 0x3d9: 0x3e, 0x3da: 0x3e, 0x3db: 0x3e, 0x3dc: 0x3e, 0x3dd: 0x3e, 0x3de: 0x3e, 0x3df: 0x3e, + 0x3e0: 0x3e, 0x3e1: 0x3e, 0x3e2: 0x3e, 0x3e3: 0x3e, 0x3e4: 0x83, 0x3e5: 0x83, 0x3e6: 0x83, 0x3e7: 0x83, + 0x3e8: 0xad, 0x3e9: 0xae, 0x3ea: 0x83, 0x3eb: 0xaf, 0x3ec: 0xb0, 0x3ed: 0xb1, 0x3ee: 0x71, 0x3ef: 0xb2, + 0x3f0: 0x71, 0x3f1: 0x71, 0x3f2: 0x71, 0x3f3: 0x71, 0x3f4: 0x71, 0x3f5: 0xb3, 0x3f6: 0xb4, 0x3f7: 0xb5, + 0x3f8: 0xb6, 0x3f9: 0xb7, 0x3fa: 0x71, 0x3fb: 0xb8, 0x3fc: 0xb9, 0x3fd: 0xba, 0x3fe: 0xbb, 0x3ff: 0xbc, + // Block 0x10, offset 0x400 + 0x400: 0xbd, 0x401: 0xbe, 0x402: 0x05, 0x403: 0xbf, 0x404: 0xc0, 0x405: 0xc1, 0x406: 0xc2, 0x407: 0xc3, + 0x40a: 0xc4, 0x40b: 0xc5, 0x40c: 0xc6, 0x40d: 0xc7, 0x40e: 0xc8, 0x40f: 0xc9, + 0x410: 0x05, 0x411: 0x05, 0x412: 0xca, 0x413: 0xcb, 0x414: 0xcc, 0x415: 0xcd, + 0x418: 0x05, 0x419: 0x05, 0x41a: 0x05, 0x41b: 0x05, 0x41c: 0xce, 0x41d: 0xcf, + 0x420: 0xd0, 0x421: 0xd1, 0x422: 0xd2, 0x423: 0xd3, 0x424: 0xd4, 0x426: 0xd5, 0x427: 0xb4, + 0x428: 0xd6, 0x429: 0xd7, 0x42a: 0xd8, 0x42b: 0xd9, 0x42c: 0xda, 0x42d: 0xdb, 0x42e: 0xdc, + 0x430: 0x05, 0x431: 0x5f, 0x432: 0xdd, 0x433: 0xde, + 0x439: 0xdf, + // Block 0x11, offset 0x440 + 0x440: 0xe0, 0x441: 0xe1, 0x442: 0xe2, 0x443: 0xe3, 0x444: 0xe4, 0x445: 0xe5, 0x446: 0xe6, 0x447: 0xe7, + 0x448: 0xe8, 0x44a: 0xe9, 0x44b: 0xea, 0x44c: 0xeb, 0x44d: 0xec, + 0x450: 0xed, 0x451: 0xee, 0x452: 0xef, 0x453: 0xf0, 0x456: 0xf1, 0x457: 0xf2, + 0x458: 0xf3, 0x459: 0xf4, 0x45a: 0xf5, 0x45b: 0xf6, 0x45c: 0xf7, + 0x462: 0xf8, 0x463: 0xf9, + 0x46b: 0xfa, + 0x470: 0xfb, 0x471: 0xfc, 0x472: 0xfd, + // Block 0x12, offset 0x480 + 0x480: 0x05, 0x481: 0x05, 0x482: 0x05, 0x483: 0x05, 0x484: 0x05, 0x485: 0x05, 0x486: 0x05, 0x487: 0x05, + 0x488: 0x05, 0x489: 0x05, 0x48a: 0x05, 0x48b: 0x05, 0x48c: 0x05, 0x48d: 0x05, 0x48e: 0xfe, + 0x490: 0x71, 0x491: 0xff, 0x492: 0x05, 0x493: 0x05, 0x494: 0x05, 0x495: 0x100, + // Block 0x13, offset 0x4c0 + 0x4c0: 0x05, 0x4c1: 0x05, 0x4c2: 0x05, 0x4c3: 0x05, 0x4c4: 0x05, 0x4c5: 0x05, 0x4c6: 0x05, 0x4c7: 0x05, + 0x4c8: 0x05, 0x4c9: 0x05, 0x4ca: 0x05, 0x4cb: 0x05, 0x4cc: 0x05, 0x4cd: 0x05, 0x4ce: 0x05, 0x4cf: 0x05, + 0x4d0: 0x101, + // Block 0x14, offset 0x500 + 0x510: 0x05, 0x511: 0x05, 0x512: 0x05, 0x513: 0x05, 0x514: 0x05, 0x515: 0x05, 0x516: 0x05, 0x517: 0x05, + 0x518: 0x05, 0x519: 0x102, + // Block 0x15, offset 0x540 + 0x560: 0x05, 0x561: 0x05, 0x562: 0x05, 0x563: 0x05, 0x564: 0x05, 0x565: 0x05, 0x566: 0x05, 0x567: 0x05, + 0x568: 0xfa, 0x569: 0x103, 0x56b: 0x104, 0x56c: 0x105, 0x56d: 0x106, 0x56e: 0x107, + 0x57c: 0x05, 0x57d: 0x108, 0x57e: 0x109, 0x57f: 0x10a, + // Block 0x16, offset 0x580 + 0x580: 0x05, 0x581: 0x05, 0x582: 0x05, 0x583: 0x05, 0x584: 0x05, 0x585: 0x05, 0x586: 0x05, 0x587: 0x05, + 0x588: 0x05, 0x589: 0x05, 0x58a: 0x05, 0x58b: 0x05, 0x58c: 0x05, 0x58d: 0x05, 0x58e: 0x05, 0x58f: 0x05, + 0x590: 0x05, 0x591: 0x05, 0x592: 0x05, 0x593: 0x05, 0x594: 0x05, 0x595: 0x05, 0x596: 0x05, 0x597: 0x05, + 0x598: 0x05, 0x599: 0x05, 0x59a: 0x05, 0x59b: 0x05, 0x59c: 0x05, 0x59d: 0x05, 0x59e: 0x05, 0x59f: 0x10b, + 0x5a0: 0x05, 0x5a1: 0x05, 0x5a2: 0x05, 0x5a3: 0x05, 0x5a4: 0x05, 0x5a5: 0x05, 0x5a6: 0x05, 0x5a7: 0x05, + 0x5a8: 0x05, 0x5a9: 0x05, 0x5aa: 0x05, 0x5ab: 0xdd, + // Block 0x17, offset 0x5c0 + 0x5c0: 0x10c, + 0x5f0: 0x05, 0x5f1: 0x10d, 0x5f2: 0x10e, + // Block 0x18, offset 0x600 + 0x600: 0x71, 0x601: 0x71, 0x602: 0x71, 0x603: 0x10f, 0x604: 0x110, 0x605: 0x111, 0x606: 0x112, 0x607: 0x113, + 0x608: 0xc1, 0x609: 0x114, 0x60c: 0x71, 0x60d: 0x115, + 0x610: 0x71, 0x611: 0x116, 0x612: 0x117, 0x613: 0x118, 0x614: 0x119, 0x615: 0x11a, 0x616: 0x71, 0x617: 0x71, + 0x618: 0x71, 0x619: 0x71, 0x61a: 0x11b, 0x61b: 0x71, 0x61c: 0x71, 0x61d: 0x71, 0x61e: 0x71, 0x61f: 0x11c, + 0x620: 0x71, 0x621: 0x71, 0x622: 0x71, 0x623: 0x71, 0x624: 0x71, 0x625: 0x71, 0x626: 0x71, 0x627: 0x71, + 0x628: 0x11d, 0x629: 0x11e, 0x62a: 0x11f, + // Block 0x19, offset 0x640 + 0x640: 0x120, + 0x660: 0x05, 0x661: 0x05, 0x662: 0x05, 0x663: 0x121, 0x664: 0x122, 0x665: 0x123, + 0x678: 0x124, 0x679: 0x125, 0x67a: 0x126, 0x67b: 0x127, + // Block 0x1a, offset 0x680 + 0x680: 0x128, 0x681: 0x71, 0x682: 0x129, 0x683: 0x12a, 0x684: 0x12b, 0x685: 0x128, 0x686: 0x12c, 0x687: 0x12d, + 0x688: 0x12e, 0x689: 0x12f, 0x68c: 0x71, 0x68d: 0x71, 0x68e: 0x71, 0x68f: 0x71, + 0x690: 0x71, 0x691: 0x71, 0x692: 0x71, 0x693: 0x71, 0x694: 0x71, 0x695: 0x71, 0x696: 0x71, 0x697: 0x71, + 0x698: 0x71, 0x699: 0x71, 0x69a: 0x71, 0x69b: 0x130, 0x69c: 0x71, 0x69d: 0x131, 0x69e: 0x71, 0x69f: 0x132, + 0x6a0: 0x133, 0x6a1: 0x134, 0x6a2: 0x135, 0x6a4: 0x136, 0x6a5: 0x137, 0x6a6: 0x138, 0x6a7: 0x139, + // Block 0x1b, offset 0x6c0 + 0x6c0: 0x90, 0x6c1: 0x90, 0x6c2: 0x90, 0x6c3: 0x90, 0x6c4: 0x90, 0x6c5: 0x90, 0x6c6: 0x90, 0x6c7: 0x90, + 0x6c8: 0x90, 0x6c9: 0x90, 0x6ca: 0x90, 0x6cb: 0x90, 0x6cc: 0x90, 0x6cd: 0x90, 0x6ce: 0x90, 0x6cf: 0x90, + 0x6d0: 0x90, 0x6d1: 0x90, 0x6d2: 0x90, 0x6d3: 0x90, 0x6d4: 0x90, 0x6d5: 0x90, 0x6d6: 0x90, 0x6d7: 0x90, + 0x6d8: 0x90, 0x6d9: 0x90, 0x6da: 0x90, 0x6db: 0x13a, 0x6dc: 0x90, 0x6dd: 0x90, 0x6de: 0x90, 0x6df: 0x90, + 0x6e0: 0x90, 0x6e1: 0x90, 0x6e2: 0x90, 0x6e3: 0x90, 0x6e4: 0x90, 0x6e5: 0x90, 0x6e6: 0x90, 0x6e7: 0x90, + 0x6e8: 0x90, 0x6e9: 0x90, 0x6ea: 0x90, 0x6eb: 0x90, 0x6ec: 0x90, 0x6ed: 0x90, 0x6ee: 0x90, 0x6ef: 0x90, + 0x6f0: 0x90, 0x6f1: 0x90, 0x6f2: 0x90, 0x6f3: 0x90, 0x6f4: 0x90, 0x6f5: 0x90, 0x6f6: 0x90, 0x6f7: 0x90, + 0x6f8: 0x90, 0x6f9: 0x90, 0x6fa: 0x90, 0x6fb: 0x90, 0x6fc: 0x90, 0x6fd: 0x90, 0x6fe: 0x90, 0x6ff: 0x90, + // Block 0x1c, offset 0x700 + 0x700: 0x90, 0x701: 0x90, 0x702: 0x90, 0x703: 0x90, 0x704: 0x90, 0x705: 0x90, 0x706: 0x90, 0x707: 0x90, + 0x708: 0x90, 0x709: 0x90, 0x70a: 0x90, 0x70b: 0x90, 0x70c: 0x90, 0x70d: 0x90, 0x70e: 0x90, 0x70f: 0x90, + 0x710: 0x90, 0x711: 0x90, 0x712: 0x90, 0x713: 0x90, 0x714: 0x90, 0x715: 0x90, 0x716: 0x90, 0x717: 0x90, + 0x718: 0x90, 0x719: 0x90, 0x71a: 0x90, 0x71b: 0x90, 0x71c: 0x13b, 0x71d: 0x90, 0x71e: 0x90, 0x71f: 0x90, + 0x720: 0x13c, 0x721: 0x90, 0x722: 0x90, 0x723: 0x90, 0x724: 0x90, 0x725: 0x90, 0x726: 0x90, 0x727: 0x90, + 0x728: 0x90, 0x729: 0x90, 0x72a: 0x90, 0x72b: 0x90, 0x72c: 0x90, 0x72d: 0x90, 0x72e: 0x90, 0x72f: 0x90, + 0x730: 0x90, 0x731: 0x90, 0x732: 0x90, 0x733: 0x90, 0x734: 0x90, 0x735: 0x90, 0x736: 0x90, 0x737: 0x90, + 0x738: 0x90, 0x739: 0x90, 0x73a: 0x90, 0x73b: 0x90, 0x73c: 0x90, 0x73d: 0x90, 0x73e: 0x90, 0x73f: 0x90, + // Block 0x1d, offset 0x740 + 0x740: 0x90, 0x741: 0x90, 0x742: 0x90, 0x743: 0x90, 0x744: 0x90, 0x745: 0x90, 0x746: 0x90, 0x747: 0x90, + 0x748: 0x90, 0x749: 0x90, 0x74a: 0x90, 0x74b: 0x90, 0x74c: 0x90, 0x74d: 0x90, 0x74e: 0x90, 0x74f: 0x90, + 0x750: 0x90, 0x751: 0x90, 0x752: 0x90, 0x753: 0x90, 0x754: 0x90, 0x755: 0x90, 0x756: 0x90, 0x757: 0x90, + 0x758: 0x90, 0x759: 0x90, 0x75a: 0x90, 0x75b: 0x90, 0x75c: 0x90, 0x75d: 0x90, 0x75e: 0x90, 0x75f: 0x90, + 0x760: 0x90, 0x761: 0x90, 0x762: 0x90, 0x763: 0x90, 0x764: 0x90, 0x765: 0x90, 0x766: 0x90, 0x767: 0x90, + 0x768: 0x90, 0x769: 0x90, 0x76a: 0x90, 0x76b: 0x90, 0x76c: 0x90, 0x76d: 0x90, 0x76e: 0x90, 0x76f: 0x90, + 0x770: 0x90, 0x771: 0x90, 0x772: 0x90, 0x773: 0x90, 0x774: 0x90, 0x775: 0x90, 0x776: 0x90, 0x777: 0x90, + 0x778: 0x90, 0x779: 0x90, 0x77a: 0x13d, + // Block 0x1e, offset 0x780 + 0x7a0: 0x83, 0x7a1: 0x83, 0x7a2: 0x83, 0x7a3: 0x83, 0x7a4: 0x83, 0x7a5: 0x83, 0x7a6: 0x83, 0x7a7: 0x83, + 0x7a8: 0x13e, + // Block 0x1f, offset 0x7c0 + 0x7d0: 0x0e, 0x7d1: 0x0f, 0x7d2: 0x10, 0x7d3: 0x11, 0x7d4: 0x12, 0x7d6: 0x13, 0x7d7: 0x0a, + 0x7d8: 0x14, 0x7db: 0x15, 0x7dd: 0x16, 0x7de: 0x17, 0x7df: 0x18, + 0x7e0: 0x07, 0x7e1: 0x07, 0x7e2: 0x07, 0x7e3: 0x07, 0x7e4: 0x07, 0x7e5: 0x07, 0x7e6: 0x07, 0x7e7: 0x07, + 0x7e8: 0x07, 0x7e9: 0x07, 0x7ea: 0x19, 0x7eb: 0x1a, 0x7ec: 0x1b, 0x7ef: 0x1c, + // Block 0x20, offset 0x800 + 0x800: 0x13f, 0x801: 0x3e, 0x804: 0x3e, 0x805: 0x3e, 0x806: 0x3e, 0x807: 0x140, + // Block 0x21, offset 0x840 + 0x840: 0x3e, 0x841: 0x3e, 0x842: 0x3e, 0x843: 0x3e, 0x844: 0x3e, 0x845: 0x3e, 0x846: 0x3e, 0x847: 0x3e, + 0x848: 0x3e, 0x849: 0x3e, 0x84a: 0x3e, 0x84b: 0x3e, 0x84c: 0x3e, 0x84d: 0x3e, 0x84e: 0x3e, 0x84f: 0x3e, + 0x850: 0x3e, 0x851: 0x3e, 0x852: 0x3e, 0x853: 0x3e, 0x854: 0x3e, 0x855: 0x3e, 0x856: 0x3e, 0x857: 0x3e, + 0x858: 0x3e, 0x859: 0x3e, 0x85a: 0x3e, 0x85b: 0x3e, 0x85c: 0x3e, 0x85d: 0x3e, 0x85e: 0x3e, 0x85f: 0x3e, + 0x860: 0x3e, 0x861: 0x3e, 0x862: 0x3e, 0x863: 0x3e, 0x864: 0x3e, 0x865: 0x3e, 0x866: 0x3e, 0x867: 0x3e, + 0x868: 0x3e, 0x869: 0x3e, 0x86a: 0x3e, 0x86b: 0x3e, 0x86c: 0x3e, 0x86d: 0x3e, 0x86e: 0x3e, 0x86f: 0x3e, + 0x870: 0x3e, 0x871: 0x3e, 0x872: 0x3e, 0x873: 0x3e, 0x874: 0x3e, 0x875: 0x3e, 0x876: 0x3e, 0x877: 0x3e, + 0x878: 0x3e, 0x879: 0x3e, 0x87a: 0x3e, 0x87b: 0x3e, 0x87c: 0x3e, 0x87d: 0x3e, 0x87e: 0x3e, 0x87f: 0x141, + // Block 0x22, offset 0x880 + 0x8a0: 0x1e, + 0x8b0: 0x0c, 0x8b1: 0x0c, 0x8b2: 0x0c, 0x8b3: 0x0c, 0x8b4: 0x0c, 0x8b5: 0x0c, 0x8b6: 0x0c, 0x8b7: 0x0c, + 0x8b8: 0x0c, 0x8b9: 0x0c, 0x8ba: 0x0c, 0x8bb: 0x0c, 0x8bc: 0x0c, 0x8bd: 0x0c, 0x8be: 0x0c, 0x8bf: 0x1f, + // Block 0x23, offset 0x8c0 + 0x8c0: 0x0c, 0x8c1: 0x0c, 0x8c2: 0x0c, 0x8c3: 0x0c, 0x8c4: 0x0c, 0x8c5: 0x0c, 0x8c6: 0x0c, 0x8c7: 0x0c, + 0x8c8: 0x0c, 0x8c9: 0x0c, 0x8ca: 0x0c, 0x8cb: 0x0c, 0x8cc: 0x0c, 0x8cd: 0x0c, 0x8ce: 0x0c, 0x8cf: 0x1f, +} + +// Total table size 25344 bytes (24KiB); checksum: 811C9DC5 diff --git a/vendor/golang.org/x/text/secure/precis/transformer.go b/vendor/golang.org/x/text/secure/precis/transformer.go new file mode 100644 index 00000000000..97ce5e757d0 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/transformer.go @@ -0,0 +1,32 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package precis + +import "golang.org/x/text/transform" + +// Transformer implements the transform.Transformer interface. +type Transformer struct { + t transform.Transformer +} + +// Reset implements the transform.Transformer interface. +func (t Transformer) Reset() { t.t.Reset() } + +// Transform implements the transform.Transformer interface. +func (t Transformer) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) { + return t.t.Transform(dst, src, atEOF) +} + +// Bytes returns a new byte slice with the result of applying t to b. +func (t Transformer) Bytes(b []byte) []byte { + b, _, _ = transform.Bytes(t, b) + return b +} + +// String returns a string with the result of applying t to s. +func (t Transformer) String(s string) string { + s, _, _ = transform.String(t, s) + return s +} diff --git a/vendor/golang.org/x/text/secure/precis/trieval.go b/vendor/golang.org/x/text/secure/precis/trieval.go new file mode 100644 index 00000000000..4833f9622a9 --- /dev/null +++ b/vendor/golang.org/x/text/secure/precis/trieval.go @@ -0,0 +1,64 @@ +// Code generated by running "go generate" in golang.org/x/text. DO NOT EDIT. + +package precis + +// entry is the entry of a trie table +// 7..6 property (unassigned, disallowed, maybe, valid) +// 5..0 category +type entry uint8 + +const ( + propShift = 6 + propMask = 0xc0 + catMask = 0x3f +) + +func (e entry) property() property { return property(e & propMask) } +func (e entry) category() category { return category(e & catMask) } + +type property uint8 + +// The order of these constants matter. A Profile may consider runes to be +// allowed either from pValid or idDisOrFreePVal. +const ( + unassigned property = iota << propShift + disallowed + idDisOrFreePVal // disallowed for Identifier, pValid for FreeForm + pValid +) + +// compute permutations of all properties and specialCategories. +type category uint8 + +const ( + other category = iota + + // Special rune types + joiningL + joiningD + joiningT + joiningR + viramaModifier + viramaJoinT // Virama + JoiningT + latinSmallL // U+006c + greek + greekJoinT // Greek + JoiningT + hebrew + hebrewJoinT // Hebrew + JoiningT + japanese // hirigana, katakana, han + + // Special rune types associated with contextual rules defined in + // https://tools.ietf.org/html/rfc5892#appendix-A. + // ContextO + zeroWidthNonJoiner // rule 1 + zeroWidthJoiner // rule 2 + // ContextJ + middleDot // rule 3 + greekLowerNumeralSign // rule 4 + hebrewPreceding // rule 5 and 6 + katakanaMiddleDot // rule 7 + arabicIndicDigit // rule 8 + extendedArabicIndicDigit // rule 9 + + numCategories +) diff --git a/vendor/modules.txt b/vendor/modules.txt index 9d60a72bb77..f6c22255e9c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -720,6 +720,26 @@ github.com/influxdata/influxdb-client-go/v2/log # github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf ## explicit; go 1.13 github.com/influxdata/line-protocol +# github.com/jackc/pgpassfile v1.0.0 +## explicit; go 1.12 +github.com/jackc/pgpassfile +# github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a +## explicit; go 1.14 +github.com/jackc/pgservicefile +# github.com/jackc/pgx/v5 v5.4.0 +## explicit; go 1.19 +github.com/jackc/pgx/v5 +github.com/jackc/pgx/v5/internal/anynil +github.com/jackc/pgx/v5/internal/iobufpool +github.com/jackc/pgx/v5/internal/pgio +github.com/jackc/pgx/v5/internal/sanitize +github.com/jackc/pgx/v5/internal/stmtcache +github.com/jackc/pgx/v5/pgconn +github.com/jackc/pgx/v5/pgconn/internal/bgreader +github.com/jackc/pgx/v5/pgconn/internal/ctxwatch +github.com/jackc/pgx/v5/pgproto3 +github.com/jackc/pgx/v5/pgtype +github.com/jackc/pgx/v5/stdlib # github.com/jcmturner/aescts/v2 v2.0.0 ## explicit; go 1.13 github.com/jcmturner/aescts/v2 @@ -800,11 +820,6 @@ github.com/kylelemons/godebug/pretty # github.com/leodido/go-urn v1.2.4 => github.com/leodido/go-urn v1.2.4 ## explicit; go 1.16 github.com/leodido/go-urn -# github.com/lib/pq v1.10.9 -## explicit; go 1.13 -github.com/lib/pq -github.com/lib/pq/oid -github.com/lib/pq/scram # github.com/mailru/easyjson v0.7.7 ## explicit; go 1.12 github.com/mailru/easyjson/buffer @@ -1360,6 +1375,7 @@ golang.org/x/text/internal/utf8internal golang.org/x/text/language golang.org/x/text/runes golang.org/x/text/secure/bidirule +golang.org/x/text/secure/precis golang.org/x/text/transform golang.org/x/text/unicode/bidi golang.org/x/text/unicode/norm