From 7d947a45d4509c9a221359d9d5411383dd392cd7 Mon Sep 17 00:00:00 2001 From: Owen Carey <37121709+owenthcarey@users.noreply.github.com> Date: Sun, 12 Jul 2026 13:46:11 -0700 Subject: [PATCH 1/2] feat: add CPython-parity Unicode codecs and locale --- Cargo.lock | 9 - crates/weavepy-cli/src/main.rs | 50 +- crates/weavepy-compiler/src/cpython_code.rs | 53 +- crates/weavepy-compiler/src/lib.rs | 8 + crates/weavepy-parser/src/lib.rs | 1 + crates/weavepy-parser/src/parser.rs | 56 +- crates/weavepy-vm/Cargo.toml | 3 - crates/weavepy-vm/src/builtin_types.rs | 47 + crates/weavepy-vm/src/builtins.rs | 554 +- crates/weavepy-vm/src/lib.rs | 434 +- crates/weavepy-vm/src/linejump.rs | 525 + crates/weavepy-vm/src/object.rs | 43 +- crates/weavepy-vm/src/stdlib/codecs_engine.rs | 1558 ++ crates/weavepy-vm/src/stdlib/codecs_mod.rs | 1344 +- crates/weavepy-vm/src/stdlib/io.rs | 30 +- crates/weavepy-vm/src/stdlib/io_full.rs | 22 +- crates/weavepy-vm/src/stdlib/locale_mod.rs | 392 +- crates/weavepy-vm/src/stdlib/marshal_mod.rs | 9 +- crates/weavepy-vm/src/stdlib/mod.rs | 432 +- .../src/stdlib/python/_cjk_common.py | 256 + .../src/stdlib/python/_cjk_tables.py | 8023 ++++++++ .../src/stdlib/python/_codec_cjk_dbcs.py | 611 + .../src/stdlib/python/_codec_cjk_ext.py | 1615 ++ .../src/stdlib/python/_codec_euc_jis_2004.py | 237 +- .../src/stdlib/python/_multibytecodec.py | 54 + crates/weavepy-vm/src/stdlib/python/codecs.py | 1647 +- .../src/stdlib/python/encodings/__init__.py | 7 + .../src/stdlib/python/encodings/ascii.py | 50 + .../stdlib/python/encodings/base64_codec.py | 55 + .../src/stdlib/python/encodings/charmap.py | 69 + .../src/stdlib/python/encodings/cp1006.py | 307 + .../src/stdlib/python/encodings/cp1026.py | 307 + .../src/stdlib/python/encodings/cp1125.py | 698 + .../src/stdlib/python/encodings/cp1140.py | 307 + .../src/stdlib/python/encodings/cp1250.py | 307 + .../src/stdlib/python/encodings/cp1251.py | 307 + .../src/stdlib/python/encodings/cp1252.py | 307 + .../src/stdlib/python/encodings/cp1253.py | 307 + .../src/stdlib/python/encodings/cp1254.py | 307 + .../src/stdlib/python/encodings/cp1255.py | 307 + .../src/stdlib/python/encodings/cp1256.py | 307 + .../src/stdlib/python/encodings/cp1257.py | 307 + .../src/stdlib/python/encodings/cp1258.py | 307 + .../src/stdlib/python/encodings/cp273.py | 307 + .../src/stdlib/python/encodings/cp424.py | 307 + .../src/stdlib/python/encodings/cp437.py | 698 + .../src/stdlib/python/encodings/cp500.py | 307 + .../src/stdlib/python/encodings/cp720.py | 309 + .../src/stdlib/python/encodings/cp775.py | 697 + .../src/stdlib/python/encodings/cp850.py | 698 + .../src/stdlib/python/encodings/cp852.py | 698 + .../src/stdlib/python/encodings/cp855.py | 698 + .../src/stdlib/python/encodings/cp856.py | 307 + .../src/stdlib/python/encodings/cp857.py | 694 + .../src/stdlib/python/encodings/cp858.py | 698 + .../src/stdlib/python/encodings/cp860.py | 698 + .../src/stdlib/python/encodings/cp861.py | 698 + .../src/stdlib/python/encodings/cp862.py | 698 + .../src/stdlib/python/encodings/cp863.py | 698 + .../src/stdlib/python/encodings/cp864.py | 690 + .../src/stdlib/python/encodings/cp865.py | 698 + .../src/stdlib/python/encodings/cp866.py | 698 + .../src/stdlib/python/encodings/cp869.py | 689 + .../src/stdlib/python/encodings/cp874.py | 307 + .../src/stdlib/python/encodings/cp875.py | 307 + .../src/stdlib/python/encodings/hp_roman8.py | 314 + .../src/stdlib/python/encodings/iso8859_1.py | 307 + .../src/stdlib/python/encodings/iso8859_10.py | 307 + .../src/stdlib/python/encodings/iso8859_11.py | 307 + .../src/stdlib/python/encodings/iso8859_13.py | 307 + .../src/stdlib/python/encodings/iso8859_14.py | 307 + .../src/stdlib/python/encodings/iso8859_15.py | 307 + .../src/stdlib/python/encodings/iso8859_16.py | 307 + .../src/stdlib/python/encodings/iso8859_2.py | 307 + .../src/stdlib/python/encodings/iso8859_3.py | 307 + .../src/stdlib/python/encodings/iso8859_4.py | 307 + .../src/stdlib/python/encodings/iso8859_5.py | 307 + .../src/stdlib/python/encodings/iso8859_6.py | 307 + .../src/stdlib/python/encodings/iso8859_7.py | 307 + .../src/stdlib/python/encodings/iso8859_8.py | 307 + .../src/stdlib/python/encodings/iso8859_9.py | 307 + .../src/stdlib/python/encodings/koi8_r.py | 307 + .../src/stdlib/python/encodings/koi8_t.py | 308 + .../src/stdlib/python/encodings/koi8_u.py | 307 + .../src/stdlib/python/encodings/kz1048.py | 307 + .../src/stdlib/python/encodings/latin_1.py | 50 + .../src/stdlib/python/encodings/mac_arabic.py | 698 + .../stdlib/python/encodings/mac_croatian.py | 307 + .../stdlib/python/encodings/mac_cyrillic.py | 307 + .../src/stdlib/python/encodings/mac_farsi.py | 307 + .../src/stdlib/python/encodings/mac_greek.py | 307 + .../stdlib/python/encodings/mac_iceland.py | 307 + .../src/stdlib/python/encodings/mac_latin2.py | 312 + .../src/stdlib/python/encodings/mac_roman.py | 307 + .../stdlib/python/encodings/mac_romanian.py | 307 + .../stdlib/python/encodings/mac_turkish.py | 307 + .../src/stdlib/python/encodings/palmos.py | 308 + .../src/stdlib/python/encodings/ptcp154.py | 312 + .../src/stdlib/python/encodings/rot_13.py | 113 + .../src/stdlib/python/encodings/tis_620.py | 307 + .../src/stdlib/python/encodings/undefined.py | 49 + .../src/stdlib/python/encodings/utf_8.py | 42 + .../weavepy-vm/src/stdlib/python/linecache.py | 68 +- crates/weavepy-vm/src/stdlib/python/locale.py | 1842 +- .../src/stdlib/testinternalcapi_mod.rs | 118 + crates/weavepy-vm/src/stdlib/ucd/aliases.bin | Bin 0 -> 5791 bytes .../weavepy-vm/src/stdlib/ucd/case_index1.bin | Bin 0 -> 17408 bytes .../weavepy-vm/src/stdlib/ucd/case_index2.bin | Bin 0 -> 74240 bytes .../weavepy-vm/src/stdlib/ucd/case_pool.bin | Bin 0 -> 1268 bytes .../src/stdlib/ucd/case_records.bin | Bin 0 -> 41244 bytes crates/weavepy-vm/src/stdlib/ucd/comp.bin | Bin 0 -> 12060 bytes crates/weavepy-vm/src/stdlib/ucd/decomp.bin | Bin 0 -> 153618 bytes crates/weavepy-vm/src/stdlib/ucd/index1.bin | Bin 0 -> 17408 bytes .../weavepy-vm/src/stdlib/ucd/index1_32.bin | Bin 0 -> 17408 bytes crates/weavepy-vm/src/stdlib/ucd/index2.bin | Bin 0 -> 107008 bytes .../weavepy-vm/src/stdlib/ucd/index2_32.bin | Bin 0 -> 66816 bytes crates/weavepy-vm/src/stdlib/ucd/meta.rs | 51 + crates/weavepy-vm/src/stdlib/ucd/mod.rs | 677 + crates/weavepy-vm/src/stdlib/ucd/names.bin | Bin 0 -> 974590 bytes crates/weavepy-vm/src/stdlib/ucd/names32.bin | Bin 0 -> 139264 bytes crates/weavepy-vm/src/stdlib/ucd/numeric.bin | Bin 0 -> 1160 bytes crates/weavepy-vm/src/stdlib/ucd/records.bin | Bin 0 -> 199908 bytes crates/weavepy-vm/src/stdlib/ucd/seqs.bin | Bin 0 -> 15174 bytes .../src/stdlib/unicode_decomp_data.rs | 17039 ---------------- .../weavepy-vm/src/stdlib/unicodedata_mod.rs | 1543 +- crates/weavepy-vm/src/unicode_case.rs | 213 + crates/weavepy/src/lib.rs | 3 + .../0050-faithful-unicode-codecs-cjk-ucd.md | 427 + tests/regrtest/expectations.toml | 81 +- tests/regrtest/test_rfc0050_cjk_corpus.py | 52 + tests/regrtest/test_rfc0050_stdio_wtf8.py | 100 + tests/regrtest/test_rfc0050_unicode_codecs.py | 133 + tools/data/NameAliases-15.1.0.txt | 570 + tools/data/NamedSequences-15.1.0.txt | 612 + tools/gen_cjk_dbcs_tables.py | 334 + tools/gen_ucd_tables.py | 553 + 136 files changed, 50034 insertions(+), 20352 deletions(-) create mode 100644 crates/weavepy-vm/src/linejump.rs create mode 100644 crates/weavepy-vm/src/stdlib/codecs_engine.rs create mode 100644 crates/weavepy-vm/src/stdlib/python/_cjk_common.py create mode 100644 crates/weavepy-vm/src/stdlib/python/_cjk_tables.py create mode 100644 crates/weavepy-vm/src/stdlib/python/_codec_cjk_dbcs.py create mode 100644 crates/weavepy-vm/src/stdlib/python/_codec_cjk_ext.py create mode 100644 crates/weavepy-vm/src/stdlib/python/_multibytecodec.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/ascii.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/base64_codec.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/charmap.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1006.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1026.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1125.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1140.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1250.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1251.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1252.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1253.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1254.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1255.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1256.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1257.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp1258.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp273.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp424.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp437.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp500.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp720.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp775.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp850.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp852.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp855.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp856.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp857.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp858.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp860.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp861.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp862.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp863.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp864.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp865.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp866.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp869.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp874.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/cp875.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/hp_roman8.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_1.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_10.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_11.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_13.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_14.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_15.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_16.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_2.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_3.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_4.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_5.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_6.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_7.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_8.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/iso8859_9.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/koi8_r.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/koi8_t.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/koi8_u.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/kz1048.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/latin_1.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_arabic.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_croatian.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_cyrillic.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_farsi.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_greek.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_iceland.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_latin2.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_roman.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_romanian.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/mac_turkish.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/palmos.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/ptcp154.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/rot_13.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/tis_620.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/undefined.py create mode 100644 crates/weavepy-vm/src/stdlib/python/encodings/utf_8.py create mode 100644 crates/weavepy-vm/src/stdlib/ucd/aliases.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/case_index1.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/case_index2.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/case_pool.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/case_records.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/comp.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/decomp.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/index1.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/index1_32.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/index2.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/index2_32.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/meta.rs create mode 100644 crates/weavepy-vm/src/stdlib/ucd/mod.rs create mode 100644 crates/weavepy-vm/src/stdlib/ucd/names.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/names32.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/numeric.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/records.bin create mode 100644 crates/weavepy-vm/src/stdlib/ucd/seqs.bin delete mode 100644 crates/weavepy-vm/src/stdlib/unicode_decomp_data.rs create mode 100644 crates/weavepy-vm/src/unicode_case.rs create mode 100644 docs/rfcs/0050-faithful-unicode-codecs-cjk-ucd.md create mode 100644 tests/regrtest/test_rfc0050_cjk_corpus.py create mode 100644 tests/regrtest/test_rfc0050_stdio_wtf8.py create mode 100644 tests/regrtest/test_rfc0050_unicode_codecs.py create mode 100644 tools/data/NameAliases-15.1.0.txt create mode 100644 tools/data/NamedSequences-15.1.0.txt create mode 100644 tools/gen_cjk_dbcs_tables.py create mode 100644 tools/gen_ucd_tables.py diff --git a/Cargo.lock b/Cargo.lock index d300646..ee8c41f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2153,12 +2153,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-properties" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" - [[package]] name = "unicode-segmentation" version = "1.13.2" @@ -2532,9 +2526,6 @@ dependencies = [ "stacker", "thiserror 2.0.18", "tracing", - "unicode-normalization", - "unicode-properties", - "unicode_names2", "weavepy-compiler", "weavepy-jit", "weavepy-lexer", diff --git a/crates/weavepy-cli/src/main.rs b/crates/weavepy-cli/src/main.rs index fd37013..9c354b8 100644 --- a/crates/weavepy-cli/src/main.rs +++ b/crates/weavepy-cli/src/main.rs @@ -527,7 +527,11 @@ fn run_on_large_stack(entry: fn() -> ExitCode) -> ExitCode { fn main_dispatch() -> ExitCode { init_tracing(); - let raw: Vec = env::args().collect(); + // `env::args()` panics on non-UTF-8 argv (bpo-35883's exact repro); + // decode PEP 383-style instead, carrying undecodable bytes in the + // PUA bridge window that `Interpreter::set_argv` maps back to + // lone surrogates (RFC 0050). + let raw: Vec = weavepy::vm::os_args_bridged(); // Multiprocessing spawn-child entry point. The parent passes // `--multiprocessing-fork` and an optional payload fd via @@ -676,7 +680,7 @@ fn split_argv(raw: Vec) -> (Vec, Option<(&'static str, String)>, } fn real_main() -> Result { - let raw: Vec = env::args().collect(); + let raw: Vec = weavepy::vm::os_args_bridged(); let (wp_argv, mode, child_argv) = split_argv(raw); // Re-parse the WeavePy-only slice with clap. let mut cli = Cli::parse_from(wp_argv); @@ -685,7 +689,10 @@ fn real_main() -> Result { match &mode { Some(("c", cmd)) => cli.command = Some(cmd.clone()), Some(("m", m)) => cli.module = Some(m.clone()), - Some(("s", path)) => cli.script = Some(PathBuf::from(path)), + // A script path may carry PEP 383-escaped bytes (PUA-bridged by + // `os_args_bridged`); recover the OS-level bytes so the file + // actually opens (RFC 0050). + Some(("s", path)) => cli.script = Some(bridged_arg_to_pathbuf(path)), Some(("-", _)) => cli.script = Some(PathBuf::from("-")), _ => {} } @@ -821,6 +828,7 @@ fn build_flags(cli: &Cli, env: &EnvOverrides) -> InterpreterFlags { hash_seed: env.hash_seed, io_encoding: env.io_encoding.clone(), io_errors: env.io_errors.clone(), + utf8_mode: env.utf8_mode, }; if cli.optimize == 0 && env.optimize > 0 { flags.optimize = env.optimize; @@ -848,6 +856,9 @@ struct EnvOverrides { /// part may be empty (`:errors` sets only the handler). io_encoding: Option, io_errors: Option, + /// `PYTHONUTF8=0|1` (PEP 540). `None` when unset/empty; an invalid + /// value is a startup fatal error (CPython `config_init_utf8_mode`). + utf8_mode: Option, } impl EnvOverrides { @@ -912,6 +923,23 @@ impl EnvOverrides { } } } + // `PYTHONUTF8` (PEP 540): "1" enables UTF-8 mode, "0" disables it, + // empty means unset; anything else is a startup fatal error + // (CPython's `config_init_utf8_mode`). + if let Ok(v) = env::var("PYTHONUTF8") { + match v.as_str() { + "" => {} + "1" => o.utf8_mode = Some(1), + "0" => o.utf8_mode = Some(0), + other => { + eprintln!( + "Fatal Python error: init_utf8_mode: invalid PYTHONUTF8 environment \ + variable value '{other}'" + ); + std::process::exit(1); + } + } + } o } @@ -920,6 +948,22 @@ impl EnvOverrides { } } +/// Rebuild a filesystem path from a (possibly PUA-bridged) argv string, +/// recovering the original OS bytes for PEP 383-escaped names. +fn bridged_arg_to_pathbuf(arg: &str) -> PathBuf { + #[cfg(unix)] + { + use std::os::unix::ffi::OsStringExt; + PathBuf::from(std::ffi::OsString::from_vec( + weavepy::vm::bridged_arg_bytes(arg), + )) + } + #[cfg(not(unix))] + { + PathBuf::from(arg) + } +} + /// Escape a string into a Python single-quoted string literal. fn quote_py_string(s: &str) -> String { let mut out = String::with_capacity(s.len() + 2); diff --git a/crates/weavepy-compiler/src/cpython_code.rs b/crates/weavepy-compiler/src/cpython_code.rs index 4f5131c..7c4c4a1 100644 --- a/crates/weavepy-compiler/src/cpython_code.rs +++ b/crates/weavepy-compiler/src/cpython_code.rs @@ -399,6 +399,53 @@ pub struct CpythonCode { pub inst_offsets: Vec, } +/// Memoised [`CodeObject::to_cpython`] output. The encoding is pure — +/// it depends only on the (immutable-after-compile) code object — but +/// hot paths (`f_lasti`, `co_lines()` in trace functions) call it per +/// event, and a full re-encode of a large code object costs +/// milliseconds. Interior-mutable under the same GIL invariant as +/// [`crate::bytecode::CacheSlot`] so the fill can happen through a +/// shared `&CodeObject` (`Arc` crosses thread boundaries). +#[derive(Default)] +pub struct CpCache { + inner: std::cell::UnsafeCell>>, +} + +// SAFETY: all reads/writes happen under the VM's GIL invariant — see +// `CacheSlot` in bytecode.rs for the full justification. +unsafe impl Send for CpCache {} +unsafe impl Sync for CpCache {} + +impl CpCache { + fn get_or_init(&self, init: impl FnOnce() -> CpythonCode) -> std::sync::Arc { + // SAFETY: the GIL invariant guarantees no concurrent access. + let slot = unsafe { &mut *self.inner.get() }; + slot.get_or_insert_with(|| std::sync::Arc::new(init())) + .clone() + } +} + +impl std::fmt::Debug for CpCache { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("CpCache") + } +} + +/// A clone starts cold: the copy may be mutated (e.g. `code.replace`) +/// before it is next encoded. +impl Clone for CpCache { + fn clone(&self) -> Self { + Self::default() + } +} + +/// The cache never affects code-object identity. +impl PartialEq for CpCache { + fn eq(&self, _: &Self) -> bool { + true + } +} + const CO_FAST_LOCAL: u8 = 0x20; const CO_FAST_CELL: u8 = 0x40; const CO_FAST_FREE: u8 = 0x80; @@ -1127,9 +1174,11 @@ fn map_from_cpython(cp_op: u8, arg: u32, nlocals: u32) -> Option<(OpCode, u32)> impl CodeObject { /// The CPython-3.13 wire view of this code object (RFC 0033). + /// Encoded once per code object and memoised (the encoding is hot: + /// trace functions hit `f_lasti` / `co_lines()` per event). #[must_use] - pub fn to_cpython(&self) -> CpythonCode { - encode(self) + pub fn to_cpython(&self) -> std::sync::Arc { + self.cp_cache.get_or_init(|| encode(self)) } /// Translate a WeavePy instruction index into the `co_code` byte offset diff --git a/crates/weavepy-compiler/src/lib.rs b/crates/weavepy-compiler/src/lib.rs index b2b4ec5..4e2b01a 100644 --- a/crates/weavepy-compiler/src/lib.rs +++ b/crates/weavepy-compiler/src/lib.rs @@ -175,6 +175,9 @@ pub struct CodeObject { /// coroutine. Never set by the compiler — only by the runtime /// marking helper and marshal round-trips. pub is_iterable_coroutine: bool, + /// Memoised [`Self::to_cpython`] encoding (never compared, resets + /// on clone). + pub cp_cache: cpython_code::CpCache, } /// A per-instruction source-column span (PEP-657). `col`/`end_col` are @@ -2956,6 +2959,11 @@ impl Compiler { } return Ok(()); } + // PEP 626: the `try:` line is "executed" and must fire a line + // event even though it compiles to nothing (CPython emits a NOP + // carrying the statement's location; trace consumers — and + // test_sys_settrace's relative-line bookkeeping — count on it). + self.emit(OpCode::Nop, 0); // PEP 654 static check, before anything else compiles so the // `except*` jump error wins over e.g. a `return` in a module- // level `finally` (matching CPython's reporting order). diff --git a/crates/weavepy-parser/src/lib.rs b/crates/weavepy-parser/src/lib.rs index 4482f77..78af9c2 100644 --- a/crates/weavepy-parser/src/lib.rs +++ b/crates/weavepy-parser/src/lib.rs @@ -19,6 +19,7 @@ mod parser; pub use ast::{dump_module, Module}; pub use error::ParseError; +pub use parser::{set_unicode_name_resolver, UnicodeNameResolution}; pub use weavepy_lexer::EscapeWarning; /// Parse a Python source buffer into a [`Module`]. diff --git a/crates/weavepy-parser/src/parser.rs b/crates/weavepy-parser/src/parser.rs index 8ea1991..bdf34ca 100644 --- a/crates/weavepy-parser/src/parser.rs +++ b/crates/weavepy-parser/src/parser.rs @@ -4915,6 +4915,40 @@ fn cps_to_constant(cps: Vec) -> Constant { } } +/// `\N{NAME}` resolution outcome supplied by the embedding VM (RFC 0050 +/// WS4): the runtime resolves names against its generated UCD tables and +/// honours a poisoned `sys.modules['unicodedata']` the way CPython's +/// tokenizer does. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum UnicodeNameResolution { + /// Resolved to this code point. + Code(u32), + /// No character has this name. + Unknown, + /// The unicodedata machinery can't be loaded (CPython: the import of + /// `unicodedata` failed, e.g. `sys.modules['unicodedata'] = None`). + Unavailable, +} + +static UNICODE_NAME_RESOLVER: std::sync::OnceLock UnicodeNameResolution> = + std::sync::OnceLock::new(); + +/// Install the VM-side `\N{NAME}` resolver. First installation wins; +/// standalone parser users fall back to the `unicode_names2` table. +pub fn set_unicode_name_resolver(f: fn(&str) -> UnicodeNameResolution) { + let _ = UNICODE_NAME_RESOLVER.set(f); +} + +fn resolve_unicode_name(name: &str) -> UnicodeNameResolution { + match UNICODE_NAME_RESOLVER.get() { + Some(f) => f(name), + None => match unicode_names2::character(name) { + Some(ch) => UnicodeNameResolution::Code(ch as u32), + None => UnicodeNameResolution::Unknown, + }, + } +} + fn decode_str_body(s: &str, raw: bool) -> Result { if raw { return Ok(Constant::Str(s.to_owned())); @@ -5032,10 +5066,24 @@ fn decode_str_body(s: &str, raw: bool) -> Result { loop { match chars.next() { Some((i, '}')) => { - let ch = unicode_names2::character(&name).ok_or_else(|| { - unicode_err(bs, i + 1, "unknown Unicode character name") - })?; - out.push(ch as u32); + match resolve_unicode_name(&name) { + UnicodeNameResolution::Code(cp) => out.push(cp), + UnicodeNameResolution::Unknown => { + return Err(unicode_err( + bs, + i + 1, + "unknown Unicode character name", + )) + } + // CPython's tokenizer message when importing + // `unicodedata` fails — *not* wrapped in the + // unicodeescape-codec position text. + UnicodeNameResolution::Unavailable => { + return Err("(unicode error) \\N escapes not supported \ + (can't load unicodedata module)" + .to_owned()) + } + } break; } Some((_, c)) => name.push(c), diff --git a/crates/weavepy-vm/Cargo.toml b/crates/weavepy-vm/Cargo.toml index 2cc15cf..bea2e2b 100644 --- a/crates/weavepy-vm/Cargo.toml +++ b/crates/weavepy-vm/Cargo.toml @@ -53,9 +53,6 @@ rust_decimal = { workspace = true } quick-xml = { workspace = true } # RFC 0023 — drop-in stdlib parity + HTTPS. -unicode-normalization = { workspace = true } -unicode-properties = { workspace = true } -unicode_names2 = { workspace = true } memmap2 = { workspace = true } memchr = { workspace = true } libc = { workspace = true } diff --git a/crates/weavepy-vm/src/builtin_types.rs b/crates/weavepy-vm/src/builtin_types.rs index 8375091..015a268 100644 --- a/crates/weavepy-vm/src/builtin_types.rs +++ b/crates/weavepy-vm/src/builtin_types.rs @@ -2535,6 +2535,53 @@ fn install_unicode_error_dunders(ty: &Rc, kind: UnicodeErrorKind) { rest.len() ))); } + // CPython parses with `PyArg_ParseTuple("UUnnU" / "UOnnU" / "UnnU")`: + // wrong-typed arguments raise TypeError at construction. + let is_str = |o: &Object| { + matches!(o, Object::Str(_) | Object::WStr(_)) + || matches!(o, Object::Instance(i) + if i.cls().mro.borrow().iter().any(|t| t.name == "str")) + }; + let is_index = |o: &Object| matches!(o, Object::Int(_) | Object::Bool(_)); + let is_buffer = |o: &Object| { + matches!( + o, + Object::Bytes(_) | Object::ByteArray(_) | Object::MemoryView(_) + ) + }; + let check = |ok: bool, pos: usize, expect: &str, got: &Object| { + if ok { + Ok(()) + } else { + Err(crate::error::type_error(format!( + "argument {} must be {expect}, not {}", + pos + 1, + got.type_name_owned() + ))) + } + }; + match kind { + UnicodeErrorKind::Encode => { + check(is_str(&rest[0]), 0, "str", &rest[0])?; + check(is_str(&rest[1]), 1, "str", &rest[1])?; + check(is_index(&rest[2]), 2, "int", &rest[2])?; + check(is_index(&rest[3]), 3, "int", &rest[3])?; + check(is_str(&rest[4]), 4, "str", &rest[4])?; + } + UnicodeErrorKind::Decode => { + check(is_str(&rest[0]), 0, "str", &rest[0])?; + check(is_buffer(&rest[1]), 1, "a bytes-like object", &rest[1])?; + check(is_index(&rest[2]), 2, "int", &rest[2])?; + check(is_index(&rest[3]), 3, "int", &rest[3])?; + check(is_str(&rest[4]), 4, "str", &rest[4])?; + } + UnicodeErrorKind::Translate => { + check(is_str(&rest[0]), 0, "str", &rest[0])?; + check(is_index(&rest[1]), 1, "int", &rest[1])?; + check(is_index(&rest[2]), 2, "int", &rest[2])?; + check(is_str(&rest[3]), 3, "str", &rest[3])?; + } + } let mut dict = inst_rc.dict.borrow_mut(); set(&mut dict, "args", Object::new_tuple(rest.to_vec())); let mut i = 0; diff --git a/crates/weavepy-vm/src/builtins.rs b/crates/weavepy-vm/src/builtins.rs index ff3cd24..f74550b 100644 --- a/crates/weavepy-vm/src/builtins.rs +++ b/crates/weavepy-vm/src/builtins.rs @@ -2465,8 +2465,7 @@ fn b_str(args: &[Object]) -> Result { ))) } }; - let s = crate::stdlib::codecs_mod::decode_bytes(&data, &encoding, &errors)?; - return Ok(Object::from_str(s)); + return crate::stdlib::codecs_mod::decode_bytes_obj(&data, &encoding, &errors); } // Identity for strings — a `WStr` in particular must keep its lone // surrogates rather than flatten to U+FFFD through `to_str()`. @@ -3147,9 +3146,11 @@ pub(crate) fn code_synthetic_attr( .collect(), )), // CPython-3.13 wire view (RFC 0033). Computed on demand. - "co_code" => Some(Object::Bytes(Rc::from(c.to_cpython().co_code))), - "co_linetable" => Some(Object::Bytes(Rc::from(c.to_cpython().co_linetable))), - "co_exceptiontable" => Some(Object::Bytes(Rc::from(c.to_cpython().co_exceptiontable))), + "co_code" => Some(Object::Bytes(Rc::from(c.to_cpython().co_code.clone()))), + "co_linetable" => Some(Object::Bytes(Rc::from(c.to_cpython().co_linetable.clone()))), + "co_exceptiontable" => Some(Object::Bytes(Rc::from( + c.to_cpython().co_exceptiontable.clone(), + ))), "co_localsplusnames" => Some(Object::new_tuple( c.to_cpython() .localsplusnames @@ -3157,7 +3158,9 @@ pub(crate) fn code_synthetic_attr( .map(Object::from_str) .collect(), )), - "co_localspluskinds" => Some(Object::Bytes(Rc::from(c.to_cpython().localspluskinds))), + "co_localspluskinds" => Some(Object::Bytes(Rc::from( + c.to_cpython().localspluskinds.clone(), + ))), "co_lines" => Some(code_method(c, "co_lines", code_co_lines)), "co_positions" => Some(code_method(c, "co_positions", code_co_positions)), "_varname_from_oparg" => Some(code_method( @@ -4797,26 +4800,14 @@ fn transform_decimal_and_space(raw: &str) -> String { } /// Decimal value (0–9) of a Unicode `Nd` (Decimal_Number) character, or -/// `None`. Each `Nd` block is exactly ten consecutive code points `0..=9`, -/// so the block's zero is found by walking down while still in category -/// `Nd` (bounded to nine steps). +/// `None` — straight from the generated UCD 15.1.0 record. fn unicode_decimal_value(c: char) -> Option { - use unicode_properties::{GeneralCategory, UnicodeGeneralCategory}; if let Some(d) = c.to_digit(10) { return Some(d); } - if c.general_category() != GeneralCategory::DecimalNumber { - return None; - } - let cp = c as u32; - let mut zero = cp; - while cp - zero < 9 { - match char::from_u32(zero - 1) { - Some(p) if p.general_category() == GeneralCategory::DecimalNumber => zero -= 1, - _ => break, - } - } - Some(cp - zero) + crate::stdlib::ucd::record(c as u32, false) + .decimal() + .map(u32::from) } /// PEP 515 underscore rule for decimal float literals: every `_` must sit @@ -7834,349 +7825,30 @@ fn str_arity(name: &str, args: &[Object], min: usize, max: usize) -> Result<(), fn str_upper(args: &[Object]) -> Result { str_arity("upper", args, 0, 0)?; - let up = str_self(args)?.to_uppercase(); + let up = crate::unicode_case::upper(&str_self(args)?); Ok(str_result(args, up)) } fn str_lower(args: &[Object]) -> Result { str_arity("lower", args, 0, 0)?; - let lo = str_self(args)?.to_lowercase(); + let lo = crate::unicode_case::lower(&str_self(args)?); Ok(str_result(args, lo)) } /// `str.casefold()` — aggressive, caseless-matching fold. Distinct from -/// `.lower()`: e.g. `"ß".casefold() == "ss"` and `"ς".casefold() == "σ"`. -/// Applies the per-character full case-folding mapping (`casefold_char`) -/// where it diverges from the simple lowercase mapping, and falls back -/// to `char::to_lowercase()` otherwise. Case folding is context-free -/// (no Greek final-sigma special-casing), so a per-`char` pass is exact. +/// `.lower()`: e.g. `"ß".casefold() == "ss"` and `"ς".casefold() == "σ"`, +/// and folding is context-free (no Greek final-sigma special-casing). fn str_casefold(args: &[Object]) -> Result { str_arity("casefold", args, 0, 0)?; - let s = str_self(args)?; - let mut out = String::with_capacity(s.len()); - for c in s.chars() { - match casefold_char(c) { - Some(folded) => out.push_str(folded), - None => out.extend(c.to_lowercase()), - } - } + let out = crate::unicode_case::casefold(&str_self(args)?); Ok(str_result(args, out)) } -/// Full Unicode case-folding overlay (`CaseFolding.txt` C+F status), -/// covering only the code points whose fold differs from their simple -/// `char::to_lowercase()` mapping; all others fold to their lowercase -/// form (applied by the caller). Generated from CPython's own -/// `str.casefold()` over the entire code-point space, so it tracks the -/// same Unicode version CPython ships. -fn casefold_char(c: char) -> Option<&'static str> { - match c { - '\u{b5}' => Some("\u{3bc}"), - '\u{df}' => Some("\u{73}\u{73}"), - '\u{149}' => Some("\u{2bc}\u{6e}"), - '\u{17f}' => Some("\u{73}"), - '\u{1f0}' => Some("\u{6a}\u{30c}"), - '\u{345}' => Some("\u{3b9}"), - '\u{390}' => Some("\u{3b9}\u{308}\u{301}"), - '\u{3b0}' => Some("\u{3c5}\u{308}\u{301}"), - '\u{3c2}' => Some("\u{3c3}"), - '\u{3d0}' => Some("\u{3b2}"), - '\u{3d1}' => Some("\u{3b8}"), - '\u{3d5}' => Some("\u{3c6}"), - '\u{3d6}' => Some("\u{3c0}"), - '\u{3f0}' => Some("\u{3ba}"), - '\u{3f1}' => Some("\u{3c1}"), - '\u{3f5}' => Some("\u{3b5}"), - '\u{587}' => Some("\u{565}\u{582}"), - '\u{13a0}' => Some("\u{13a0}"), - '\u{13a1}' => Some("\u{13a1}"), - '\u{13a2}' => Some("\u{13a2}"), - '\u{13a3}' => Some("\u{13a3}"), - '\u{13a4}' => Some("\u{13a4}"), - '\u{13a5}' => Some("\u{13a5}"), - '\u{13a6}' => Some("\u{13a6}"), - '\u{13a7}' => Some("\u{13a7}"), - '\u{13a8}' => Some("\u{13a8}"), - '\u{13a9}' => Some("\u{13a9}"), - '\u{13aa}' => Some("\u{13aa}"), - '\u{13ab}' => Some("\u{13ab}"), - '\u{13ac}' => Some("\u{13ac}"), - '\u{13ad}' => Some("\u{13ad}"), - '\u{13ae}' => Some("\u{13ae}"), - '\u{13af}' => Some("\u{13af}"), - '\u{13b0}' => Some("\u{13b0}"), - '\u{13b1}' => Some("\u{13b1}"), - '\u{13b2}' => Some("\u{13b2}"), - '\u{13b3}' => Some("\u{13b3}"), - '\u{13b4}' => Some("\u{13b4}"), - '\u{13b5}' => Some("\u{13b5}"), - '\u{13b6}' => Some("\u{13b6}"), - '\u{13b7}' => Some("\u{13b7}"), - '\u{13b8}' => Some("\u{13b8}"), - '\u{13b9}' => Some("\u{13b9}"), - '\u{13ba}' => Some("\u{13ba}"), - '\u{13bb}' => Some("\u{13bb}"), - '\u{13bc}' => Some("\u{13bc}"), - '\u{13bd}' => Some("\u{13bd}"), - '\u{13be}' => Some("\u{13be}"), - '\u{13bf}' => Some("\u{13bf}"), - '\u{13c0}' => Some("\u{13c0}"), - '\u{13c1}' => Some("\u{13c1}"), - '\u{13c2}' => Some("\u{13c2}"), - '\u{13c3}' => Some("\u{13c3}"), - '\u{13c4}' => Some("\u{13c4}"), - '\u{13c5}' => Some("\u{13c5}"), - '\u{13c6}' => Some("\u{13c6}"), - '\u{13c7}' => Some("\u{13c7}"), - '\u{13c8}' => Some("\u{13c8}"), - '\u{13c9}' => Some("\u{13c9}"), - '\u{13ca}' => Some("\u{13ca}"), - '\u{13cb}' => Some("\u{13cb}"), - '\u{13cc}' => Some("\u{13cc}"), - '\u{13cd}' => Some("\u{13cd}"), - '\u{13ce}' => Some("\u{13ce}"), - '\u{13cf}' => Some("\u{13cf}"), - '\u{13d0}' => Some("\u{13d0}"), - '\u{13d1}' => Some("\u{13d1}"), - '\u{13d2}' => Some("\u{13d2}"), - '\u{13d3}' => Some("\u{13d3}"), - '\u{13d4}' => Some("\u{13d4}"), - '\u{13d5}' => Some("\u{13d5}"), - '\u{13d6}' => Some("\u{13d6}"), - '\u{13d7}' => Some("\u{13d7}"), - '\u{13d8}' => Some("\u{13d8}"), - '\u{13d9}' => Some("\u{13d9}"), - '\u{13da}' => Some("\u{13da}"), - '\u{13db}' => Some("\u{13db}"), - '\u{13dc}' => Some("\u{13dc}"), - '\u{13dd}' => Some("\u{13dd}"), - '\u{13de}' => Some("\u{13de}"), - '\u{13df}' => Some("\u{13df}"), - '\u{13e0}' => Some("\u{13e0}"), - '\u{13e1}' => Some("\u{13e1}"), - '\u{13e2}' => Some("\u{13e2}"), - '\u{13e3}' => Some("\u{13e3}"), - '\u{13e4}' => Some("\u{13e4}"), - '\u{13e5}' => Some("\u{13e5}"), - '\u{13e6}' => Some("\u{13e6}"), - '\u{13e7}' => Some("\u{13e7}"), - '\u{13e8}' => Some("\u{13e8}"), - '\u{13e9}' => Some("\u{13e9}"), - '\u{13ea}' => Some("\u{13ea}"), - '\u{13eb}' => Some("\u{13eb}"), - '\u{13ec}' => Some("\u{13ec}"), - '\u{13ed}' => Some("\u{13ed}"), - '\u{13ee}' => Some("\u{13ee}"), - '\u{13ef}' => Some("\u{13ef}"), - '\u{13f0}' => Some("\u{13f0}"), - '\u{13f1}' => Some("\u{13f1}"), - '\u{13f2}' => Some("\u{13f2}"), - '\u{13f3}' => Some("\u{13f3}"), - '\u{13f4}' => Some("\u{13f4}"), - '\u{13f5}' => Some("\u{13f5}"), - '\u{13f8}' => Some("\u{13f0}"), - '\u{13f9}' => Some("\u{13f1}"), - '\u{13fa}' => Some("\u{13f2}"), - '\u{13fb}' => Some("\u{13f3}"), - '\u{13fc}' => Some("\u{13f4}"), - '\u{13fd}' => Some("\u{13f5}"), - '\u{1c80}' => Some("\u{432}"), - '\u{1c81}' => Some("\u{434}"), - '\u{1c82}' => Some("\u{43e}"), - '\u{1c83}' => Some("\u{441}"), - '\u{1c84}' => Some("\u{442}"), - '\u{1c85}' => Some("\u{442}"), - '\u{1c86}' => Some("\u{44a}"), - '\u{1c87}' => Some("\u{463}"), - '\u{1c88}' => Some("\u{a64b}"), - '\u{1e96}' => Some("\u{68}\u{331}"), - '\u{1e97}' => Some("\u{74}\u{308}"), - '\u{1e98}' => Some("\u{77}\u{30a}"), - '\u{1e99}' => Some("\u{79}\u{30a}"), - '\u{1e9a}' => Some("\u{61}\u{2be}"), - '\u{1e9b}' => Some("\u{1e61}"), - '\u{1e9e}' => Some("\u{73}\u{73}"), - '\u{1f50}' => Some("\u{3c5}\u{313}"), - '\u{1f52}' => Some("\u{3c5}\u{313}\u{300}"), - '\u{1f54}' => Some("\u{3c5}\u{313}\u{301}"), - '\u{1f56}' => Some("\u{3c5}\u{313}\u{342}"), - '\u{1f80}' => Some("\u{1f00}\u{3b9}"), - '\u{1f81}' => Some("\u{1f01}\u{3b9}"), - '\u{1f82}' => Some("\u{1f02}\u{3b9}"), - '\u{1f83}' => Some("\u{1f03}\u{3b9}"), - '\u{1f84}' => Some("\u{1f04}\u{3b9}"), - '\u{1f85}' => Some("\u{1f05}\u{3b9}"), - '\u{1f86}' => Some("\u{1f06}\u{3b9}"), - '\u{1f87}' => Some("\u{1f07}\u{3b9}"), - '\u{1f88}' => Some("\u{1f00}\u{3b9}"), - '\u{1f89}' => Some("\u{1f01}\u{3b9}"), - '\u{1f8a}' => Some("\u{1f02}\u{3b9}"), - '\u{1f8b}' => Some("\u{1f03}\u{3b9}"), - '\u{1f8c}' => Some("\u{1f04}\u{3b9}"), - '\u{1f8d}' => Some("\u{1f05}\u{3b9}"), - '\u{1f8e}' => Some("\u{1f06}\u{3b9}"), - '\u{1f8f}' => Some("\u{1f07}\u{3b9}"), - '\u{1f90}' => Some("\u{1f20}\u{3b9}"), - '\u{1f91}' => Some("\u{1f21}\u{3b9}"), - '\u{1f92}' => Some("\u{1f22}\u{3b9}"), - '\u{1f93}' => Some("\u{1f23}\u{3b9}"), - '\u{1f94}' => Some("\u{1f24}\u{3b9}"), - '\u{1f95}' => Some("\u{1f25}\u{3b9}"), - '\u{1f96}' => Some("\u{1f26}\u{3b9}"), - '\u{1f97}' => Some("\u{1f27}\u{3b9}"), - '\u{1f98}' => Some("\u{1f20}\u{3b9}"), - '\u{1f99}' => Some("\u{1f21}\u{3b9}"), - '\u{1f9a}' => Some("\u{1f22}\u{3b9}"), - '\u{1f9b}' => Some("\u{1f23}\u{3b9}"), - '\u{1f9c}' => Some("\u{1f24}\u{3b9}"), - '\u{1f9d}' => Some("\u{1f25}\u{3b9}"), - '\u{1f9e}' => Some("\u{1f26}\u{3b9}"), - '\u{1f9f}' => Some("\u{1f27}\u{3b9}"), - '\u{1fa0}' => Some("\u{1f60}\u{3b9}"), - '\u{1fa1}' => Some("\u{1f61}\u{3b9}"), - '\u{1fa2}' => Some("\u{1f62}\u{3b9}"), - '\u{1fa3}' => Some("\u{1f63}\u{3b9}"), - '\u{1fa4}' => Some("\u{1f64}\u{3b9}"), - '\u{1fa5}' => Some("\u{1f65}\u{3b9}"), - '\u{1fa6}' => Some("\u{1f66}\u{3b9}"), - '\u{1fa7}' => Some("\u{1f67}\u{3b9}"), - '\u{1fa8}' => Some("\u{1f60}\u{3b9}"), - '\u{1fa9}' => Some("\u{1f61}\u{3b9}"), - '\u{1faa}' => Some("\u{1f62}\u{3b9}"), - '\u{1fab}' => Some("\u{1f63}\u{3b9}"), - '\u{1fac}' => Some("\u{1f64}\u{3b9}"), - '\u{1fad}' => Some("\u{1f65}\u{3b9}"), - '\u{1fae}' => Some("\u{1f66}\u{3b9}"), - '\u{1faf}' => Some("\u{1f67}\u{3b9}"), - '\u{1fb2}' => Some("\u{1f70}\u{3b9}"), - '\u{1fb3}' => Some("\u{3b1}\u{3b9}"), - '\u{1fb4}' => Some("\u{3ac}\u{3b9}"), - '\u{1fb6}' => Some("\u{3b1}\u{342}"), - '\u{1fb7}' => Some("\u{3b1}\u{342}\u{3b9}"), - '\u{1fbc}' => Some("\u{3b1}\u{3b9}"), - '\u{1fbe}' => Some("\u{3b9}"), - '\u{1fc2}' => Some("\u{1f74}\u{3b9}"), - '\u{1fc3}' => Some("\u{3b7}\u{3b9}"), - '\u{1fc4}' => Some("\u{3ae}\u{3b9}"), - '\u{1fc6}' => Some("\u{3b7}\u{342}"), - '\u{1fc7}' => Some("\u{3b7}\u{342}\u{3b9}"), - '\u{1fcc}' => Some("\u{3b7}\u{3b9}"), - '\u{1fd2}' => Some("\u{3b9}\u{308}\u{300}"), - '\u{1fd3}' => Some("\u{3b9}\u{308}\u{301}"), - '\u{1fd6}' => Some("\u{3b9}\u{342}"), - '\u{1fd7}' => Some("\u{3b9}\u{308}\u{342}"), - '\u{1fe2}' => Some("\u{3c5}\u{308}\u{300}"), - '\u{1fe3}' => Some("\u{3c5}\u{308}\u{301}"), - '\u{1fe4}' => Some("\u{3c1}\u{313}"), - '\u{1fe6}' => Some("\u{3c5}\u{342}"), - '\u{1fe7}' => Some("\u{3c5}\u{308}\u{342}"), - '\u{1ff2}' => Some("\u{1f7c}\u{3b9}"), - '\u{1ff3}' => Some("\u{3c9}\u{3b9}"), - '\u{1ff4}' => Some("\u{3ce}\u{3b9}"), - '\u{1ff6}' => Some("\u{3c9}\u{342}"), - '\u{1ff7}' => Some("\u{3c9}\u{342}\u{3b9}"), - '\u{1ffc}' => Some("\u{3c9}\u{3b9}"), - '\u{ab70}' => Some("\u{13a0}"), - '\u{ab71}' => Some("\u{13a1}"), - '\u{ab72}' => Some("\u{13a2}"), - '\u{ab73}' => Some("\u{13a3}"), - '\u{ab74}' => Some("\u{13a4}"), - '\u{ab75}' => Some("\u{13a5}"), - '\u{ab76}' => Some("\u{13a6}"), - '\u{ab77}' => Some("\u{13a7}"), - '\u{ab78}' => Some("\u{13a8}"), - '\u{ab79}' => Some("\u{13a9}"), - '\u{ab7a}' => Some("\u{13aa}"), - '\u{ab7b}' => Some("\u{13ab}"), - '\u{ab7c}' => Some("\u{13ac}"), - '\u{ab7d}' => Some("\u{13ad}"), - '\u{ab7e}' => Some("\u{13ae}"), - '\u{ab7f}' => Some("\u{13af}"), - '\u{ab80}' => Some("\u{13b0}"), - '\u{ab81}' => Some("\u{13b1}"), - '\u{ab82}' => Some("\u{13b2}"), - '\u{ab83}' => Some("\u{13b3}"), - '\u{ab84}' => Some("\u{13b4}"), - '\u{ab85}' => Some("\u{13b5}"), - '\u{ab86}' => Some("\u{13b6}"), - '\u{ab87}' => Some("\u{13b7}"), - '\u{ab88}' => Some("\u{13b8}"), - '\u{ab89}' => Some("\u{13b9}"), - '\u{ab8a}' => Some("\u{13ba}"), - '\u{ab8b}' => Some("\u{13bb}"), - '\u{ab8c}' => Some("\u{13bc}"), - '\u{ab8d}' => Some("\u{13bd}"), - '\u{ab8e}' => Some("\u{13be}"), - '\u{ab8f}' => Some("\u{13bf}"), - '\u{ab90}' => Some("\u{13c0}"), - '\u{ab91}' => Some("\u{13c1}"), - '\u{ab92}' => Some("\u{13c2}"), - '\u{ab93}' => Some("\u{13c3}"), - '\u{ab94}' => Some("\u{13c4}"), - '\u{ab95}' => Some("\u{13c5}"), - '\u{ab96}' => Some("\u{13c6}"), - '\u{ab97}' => Some("\u{13c7}"), - '\u{ab98}' => Some("\u{13c8}"), - '\u{ab99}' => Some("\u{13c9}"), - '\u{ab9a}' => Some("\u{13ca}"), - '\u{ab9b}' => Some("\u{13cb}"), - '\u{ab9c}' => Some("\u{13cc}"), - '\u{ab9d}' => Some("\u{13cd}"), - '\u{ab9e}' => Some("\u{13ce}"), - '\u{ab9f}' => Some("\u{13cf}"), - '\u{aba0}' => Some("\u{13d0}"), - '\u{aba1}' => Some("\u{13d1}"), - '\u{aba2}' => Some("\u{13d2}"), - '\u{aba3}' => Some("\u{13d3}"), - '\u{aba4}' => Some("\u{13d4}"), - '\u{aba5}' => Some("\u{13d5}"), - '\u{aba6}' => Some("\u{13d6}"), - '\u{aba7}' => Some("\u{13d7}"), - '\u{aba8}' => Some("\u{13d8}"), - '\u{aba9}' => Some("\u{13d9}"), - '\u{abaa}' => Some("\u{13da}"), - '\u{abab}' => Some("\u{13db}"), - '\u{abac}' => Some("\u{13dc}"), - '\u{abad}' => Some("\u{13dd}"), - '\u{abae}' => Some("\u{13de}"), - '\u{abaf}' => Some("\u{13df}"), - '\u{abb0}' => Some("\u{13e0}"), - '\u{abb1}' => Some("\u{13e1}"), - '\u{abb2}' => Some("\u{13e2}"), - '\u{abb3}' => Some("\u{13e3}"), - '\u{abb4}' => Some("\u{13e4}"), - '\u{abb5}' => Some("\u{13e5}"), - '\u{abb6}' => Some("\u{13e6}"), - '\u{abb7}' => Some("\u{13e7}"), - '\u{abb8}' => Some("\u{13e8}"), - '\u{abb9}' => Some("\u{13e9}"), - '\u{abba}' => Some("\u{13ea}"), - '\u{abbb}' => Some("\u{13eb}"), - '\u{abbc}' => Some("\u{13ec}"), - '\u{abbd}' => Some("\u{13ed}"), - '\u{abbe}' => Some("\u{13ee}"), - '\u{abbf}' => Some("\u{13ef}"), - '\u{fb00}' => Some("\u{66}\u{66}"), - '\u{fb01}' => Some("\u{66}\u{69}"), - '\u{fb02}' => Some("\u{66}\u{6c}"), - '\u{fb03}' => Some("\u{66}\u{66}\u{69}"), - '\u{fb04}' => Some("\u{66}\u{66}\u{6c}"), - '\u{fb05}' => Some("\u{73}\u{74}"), - '\u{fb06}' => Some("\u{73}\u{74}"), - '\u{fb13}' => Some("\u{574}\u{576}"), - '\u{fb14}' => Some("\u{574}\u{565}"), - '\u{fb15}' => Some("\u{574}\u{56b}"), - '\u{fb16}' => Some("\u{57e}\u{576}"), - '\u{fb17}' => Some("\u{574}\u{56d}"), - _ => None, - } -} - fn str_strip(args: &[Object]) -> Result { str_arity("strip", args, 0, 1)?; let s = str_self(args)?; let out = match args.get(1) { - None | Some(Object::None) => s.trim().to_owned(), + None | Some(Object::None) => s.trim_matches(crate::unicode_case::is_space).to_owned(), Some(arg) => { let chars = str_arg_bridged(arg).ok_or_else(|| type_error("strip() argument must be str"))?; @@ -8198,10 +7870,16 @@ fn split_maxsplit(o: Option<&Object>) -> Result { /// `str.split` on runs of whitespace (the `sep is None` case), honouring /// `maxsplit`. Leading/trailing whitespace is stripped and empty fields -/// are dropped, matching CPython. +/// are dropped, matching CPython (Py_UNICODE_ISSPACE, which covers +/// U+001C..U+001F unlike Rust's `char::is_whitespace`). fn str_split_whitespace(s: &str, maxsplit: i64) -> Vec { + use crate::unicode_case::is_space; if maxsplit < 0 { - return s.split_whitespace().map(Object::from_str).collect(); + return s + .split(is_space) + .filter(|f| !f.is_empty()) + .map(Object::from_str) + .collect(); } let chars: Vec<(usize, char)> = s.char_indices().collect(); let n = chars.len(); @@ -8209,7 +7887,7 @@ fn str_split_whitespace(s: &str, maxsplit: i64) -> Vec { let mut i = 0; let mut splits = 0; while i < n { - while i < n && chars[i].1.is_whitespace() { + while i < n && is_space(chars[i].1) { i += 1; } if i >= n { @@ -8220,7 +7898,7 @@ fn str_split_whitespace(s: &str, maxsplit: i64) -> Vec { return out; } let start = chars[i].0; - while i < n && !chars[i].1.is_whitespace() { + while i < n && !is_space(chars[i].1) { i += 1; } let end = if i < n { chars[i].0 } else { s.len() }; @@ -8562,47 +8240,19 @@ fn byte_offset_to_char(s: &str, byte: usize) -> usize { fn str_title(args: &[Object]) -> Result { str_arity("title", args, 0, 0)?; - let mut out = String::new(); - let mut prev_alpha = false; - for ch in str_self(args)?.chars() { - if ch.is_alphabetic() { - if prev_alpha { - out.extend(ch.to_lowercase()); - } else { - out.extend(ch.to_uppercase()); - } - prev_alpha = true; - } else { - out.push(ch); - prev_alpha = false; - } - } + let out = crate::unicode_case::title(&str_self(args)?); Ok(str_result(args, out)) } fn str_capitalize(args: &[Object]) -> Result { str_arity("capitalize", args, 0, 0)?; - let s = str_self(args)?; - let mut chars = s.chars(); - let out = match chars.next() { - Some(c) => c.to_uppercase().collect::() + &chars.as_str().to_lowercase(), - None => String::new(), - }; + let out = crate::unicode_case::capitalize(&str_self(args)?); Ok(str_result(args, out)) } fn str_swapcase(args: &[Object]) -> Result { str_arity("swapcase", args, 0, 0)?; - let mut out = String::new(); - for ch in str_self(args)?.chars() { - if ch.is_uppercase() { - out.extend(ch.to_lowercase()); - } else if ch.is_lowercase() { - out.extend(ch.to_uppercase()); - } else { - out.push(ch); - } - } + let out = crate::unicode_case::swapcase(&str_self(args)?); Ok(str_result(args, out)) } @@ -8610,7 +8260,9 @@ fn str_lstrip(args: &[Object]) -> Result { str_arity("lstrip", args, 0, 1)?; let s = str_self(args)?; let out = match args.get(1) { - None | Some(Object::None) => s.trim_start().to_owned(), + None | Some(Object::None) => s + .trim_start_matches(crate::unicode_case::is_space) + .to_owned(), Some(arg) => { let chars = str_arg_bridged(arg).ok_or_else(|| type_error("lstrip() argument must be str"))?; @@ -8625,7 +8277,7 @@ fn str_rstrip(args: &[Object]) -> Result { str_arity("rstrip", args, 0, 1)?; let s = str_self(args)?; let out = match args.get(1) { - None | Some(Object::None) => s.trim_end().to_owned(), + None | Some(Object::None) => s.trim_end_matches(crate::unicode_case::is_space).to_owned(), Some(arg) => { let chars = str_arg_bridged(arg).ok_or_else(|| type_error("rstrip() argument must be str"))?; @@ -8640,8 +8292,13 @@ fn str_rstrip(args: &[Object]) -> Result { /// right. Mirrors CPython: the *last* `maxsplit` whitespace runs split, /// and the left remainder keeps its internal spacing. fn str_rsplit_whitespace(s: &str, maxsplit: i64) -> Vec { + use crate::unicode_case::is_space; if maxsplit < 0 { - return s.split_whitespace().map(Object::from_str).collect(); + return s + .split(is_space) + .filter(|f| !f.is_empty()) + .map(Object::from_str) + .collect(); } let chars: Vec<(usize, char)> = s.char_indices().collect(); let n = chars.len(); @@ -8649,7 +8306,7 @@ fn str_rsplit_whitespace(s: &str, maxsplit: i64) -> Vec { let mut i = n; let mut splits = 0; while i > 0 { - while i > 0 && chars[i - 1].1.is_whitespace() { + while i > 0 && is_space(chars[i - 1].1) { i -= 1; } if i == 0 { @@ -8660,7 +8317,7 @@ fn str_rsplit_whitespace(s: &str, maxsplit: i64) -> Vec { out_rev.push(s[..end_byte].to_string()); break; } - while i > 0 && !chars[i - 1].1.is_whitespace() { + while i > 0 && !is_space(chars[i - 1].1) { i -= 1; } let start_byte = chars[i].0; @@ -8719,16 +8376,34 @@ fn str_splitlines(args: &[Object], kwargs: &[(String, Object)]) -> Result = Vec::new(); - let bytes = s.as_bytes(); let mut start = 0; - let mut i = 0; - while i < bytes.len() { - if bytes[i] == b'\n' || bytes[i] == b'\r' { + let mut iter = s.char_indices().peekable(); + while let Some((i, c)) = iter.next() { + if is_break(c) { let end_no_eol = i; - let mut end = i + 1; - if bytes[i] == b'\r' && i + 1 < bytes.len() && bytes[i + 1] == b'\n' { - end = i + 2; + let mut end = i + c.len_utf8(); + if c == '\r' { + if let Some(&(j, '\n')) = iter.peek() { + end = j + 1; + iter.next(); + } } let line = if keepends { &s[start..end] @@ -8737,12 +8412,9 @@ fn str_splitlines(args: &[Object], kwargs: &[(String, Object)]) -> Result Result { str_arity("isalpha", args, 0, 0)?; let s = str_self(args)?; Ok(Object::Bool( - !s.is_empty() && s.chars().all(char::is_alphabetic), + !s.is_empty() && s.chars().all(crate::unicode_case::is_alpha), )) } @@ -8892,7 +8564,7 @@ fn str_isalnum(args: &[Object]) -> Result { str_arity("isalnum", args, 0, 0)?; let s = str_self(args)?; Ok(Object::Bool( - !s.is_empty() && s.chars().all(char::is_alphanumeric), + !s.is_empty() && s.chars().all(crate::unicode_case::is_alnum), )) } @@ -8900,68 +8572,29 @@ fn str_isspace(args: &[Object]) -> Result { str_arity("isspace", args, 0, 0)?; let s = str_self(args)?; Ok(Object::Bool( - !s.is_empty() && s.chars().all(char::is_whitespace), + !s.is_empty() && s.chars().all(crate::unicode_case::is_space), )) } fn str_isupper(args: &[Object]) -> Result { str_arity("isupper", args, 0, 0)?; - let s = str_self(args)?; - let mut has_cased = false; - for c in s.chars() { - if c.is_alphabetic() { - has_cased = true; - if !c.is_uppercase() { - return Ok(Object::Bool(false)); - } - } - } - Ok(Object::Bool(has_cased)) + Ok(Object::Bool(crate::unicode_case::str_isupper(&str_self( + args, + )?))) } fn str_islower(args: &[Object]) -> Result { str_arity("islower", args, 0, 0)?; - let s = str_self(args)?; - let mut has_cased = false; - for c in s.chars() { - if c.is_alphabetic() { - has_cased = true; - if !c.is_lowercase() { - return Ok(Object::Bool(false)); - } - } - } - Ok(Object::Bool(has_cased)) + Ok(Object::Bool(crate::unicode_case::str_islower(&str_self( + args, + )?))) } fn str_istitle(args: &[Object]) -> Result { - // CPython `unicode_istitle_impl`: a titlecased string has each cased run - // starting with an upper/titlecase char, and there is >=1 cased char. - // (Titlecase Lt chars are treated as uppercase for the run-start test; - // Rust's std lacks a general-category API, so uppercase covers Lu — the - // ASCII and dominant Unicode case, matching our other `is*` helpers.) str_arity("istitle", args, 0, 0)?; - let s = str_self(args)?; - let mut cased = false; - let mut prev_cased = false; - for c in s.chars() { - if c.is_uppercase() { - if prev_cased { - return Ok(Object::Bool(false)); - } - prev_cased = true; - cased = true; - } else if c.is_lowercase() { - if !prev_cased { - return Ok(Object::Bool(false)); - } - prev_cased = true; - cased = true; - } else { - prev_cased = false; - } - } - Ok(Object::Bool(cased)) + Ok(Object::Bool(crate::unicode_case::str_istitle(&str_self( + args, + )?))) } fn str_isascii(args: &[Object]) -> Result { @@ -8974,7 +8607,9 @@ fn str_isidentifier(args: &[Object]) -> Result { let s = str_self(args)?; let mut chars = s.chars(); let valid = match chars.next() { - Some(c) if c == '_' || c.is_alphabetic() => chars.all(|c| c == '_' || c.is_alphanumeric()), + Some(c) if c == '_' || crate::unicode_case::is_xid_start(c) => { + chars.all(crate::unicode_case::is_xid_continue) + } _ => false, }; Ok(Object::Bool(valid)) @@ -9261,16 +8896,29 @@ fn str_translate(args: &[Object]) -> Result { }; match entry { Some(Object::None) => {} - Some(Object::Int(i)) => push_cp(&mut out, i as u32, &mut saw_surrogate), + Some(Object::Int(i)) => { + // CPython: an out-of-range target ordinal is a ValueError. + if !(0..0x11_0000).contains(&i) { + return Err(crate::error::value_error( + "character mapping must be in range(0x110000)", + )); + } + push_cp(&mut out, i as u32, &mut saw_surrogate) + } Some(Object::Str(v)) => out.push_str(&v), Some(Object::WStr(cps)) => { saw_surrogate = true; out.push_str(&bridge_encode_cps(&cps)); } - // `str` subclass value, etc.: fall back to its text view. + // `str` subclass value: fall back to its text view. Any other + // type is a TypeError (CPython `charmaptranslate_lookup`). Some(other) => match other.native_value() { Some(Object::Str(v)) => out.push_str(&v), - _ => out.push_str(&other.to_str()), + _ => { + return Err(type_error( + "character mapping must return integer, None or str", + )) + } }, None => out.push(c), } diff --git a/crates/weavepy-vm/src/lib.rs b/crates/weavepy-vm/src/lib.rs index 4f3b377..5067d1c 100644 --- a/crates/weavepy-vm/src/lib.rs +++ b/crates/weavepy-vm/src/lib.rs @@ -36,6 +36,7 @@ pub mod frozen_code_cache; pub mod gc_trace; pub mod gil; pub mod import; +pub mod linejump; pub mod object; pub mod proc_init; pub mod pycache; @@ -51,6 +52,7 @@ mod tier2; pub mod trace; pub mod type_surface; pub mod types; +pub mod unicode_case; pub mod unicode_numeric; pub mod vm_singletons; pub mod weakref_registry; @@ -183,6 +185,33 @@ impl Frame { } } +/// Scoped marker for "this frame is dispatching trace event X" (RFC +/// 0050): CPython's `frame_setlineno` only permits jumps from specific +/// events, so `fire_*_event` wraps its callback invocation in one of +/// these and the `f_lineno` setter consults `PyFrame::trace_event`. +/// Restores the previous event on drop so nested events (a trace +/// callback that itself triggers tracing) unwind correctly. +struct TraceEventGuard { + frame: Rc, + prev: crate::linejump::TraceEvent, +} + +impl TraceEventGuard { + fn new(frame: &Rc, event: crate::linejump::TraceEvent) -> Self { + let prev = frame.trace_event.replace(event); + Self { + frame: frame.clone(), + prev, + } + } +} + +impl Drop for TraceEventGuard { + fn drop(&mut self) { + self.frame.trace_event.set(self.prev); + } +} + /// Cycle-GC traversal hook for generator-family objects: walk the /// suspended frame's locals, evaluation stack, and cells so cycles /// running through a generator frame (`g.send(g)`) are detectable. @@ -300,6 +329,62 @@ pub fn jit_stats_markdown() -> Option { } } +/// RFC 0050 — the process argv, decoded the way CPython's +/// `Py_DecodeLocale` does under UTF-8 mode: each `OsString` is decoded +/// as UTF-8 with `surrogateescape`, so undecodable bytes become lone +/// surrogates (U+DC80..U+DCFF) instead of panicking (`std::env::args()` +/// unwraps and aborts on non-UTF-8 argv — bpo-35883's exact scenario). +/// +/// Because the CLI plumbs argv through plain `String`s (clap, argv +/// splitting), lone surrogates are carried in the plane-16 PUA bridge +/// window (`builtins::BRIDGE_BASE`); [`Interpreter::set_argv`] maps +/// them back to real surrogate code points when materialising +/// `sys.argv`, and byte-oriented consumers (script open, `os.fsencode`) +/// can recover the original bytes via [`bridged_arg_bytes`]. +#[must_use] +pub fn os_args_bridged() -> Vec { + std::env::args_os() + .map(|arg| match arg.into_string() { + Ok(s) => s, + Err(os) => { + #[cfg(unix)] + { + use std::os::unix::ffi::OsStrExt; + let obj = crate::stdlib::codecs_mod::decode_bytes_obj( + os.as_bytes(), + "utf-8", + "surrogateescape", + ) + .unwrap_or_else(|_| Object::from_str(os.to_string_lossy().into_owned())); + match obj { + Object::WStr(cps) => crate::builtins::bridge_encode_cps(&cps), + other => other.to_str(), + } + } + #[cfg(not(unix))] + { + os.to_string_lossy().into_owned() + } + } + }) + .collect() +} + +/// The OS-level bytes of a (possibly PUA-bridged) argv string: the +/// inverse of [`os_args_bridged`] for one element, used when an argv +/// value names a real filesystem object (the script path). +#[must_use] +pub fn bridged_arg_bytes(arg: &str) -> Vec { + let obj = crate::builtins::bridge_to_object(arg); + match &obj { + Object::WStr(_) | Object::Str(_) => { + crate::stdlib::codecs_mod::encode_obj(&obj, "utf-8", "surrogateescape") + .unwrap_or_else(|_| arg.as_bytes().to_vec()) + } + _ => arg.as_bytes().to_vec(), + } +} + // ---------- interpreter ---------- /// Output sink. Either the process's stdout or a `Vec` for @@ -340,6 +425,39 @@ pub struct InterpreterFlags { /// The `errors` half of `PYTHONIOENCODING`. `None` keeps each stream's /// default handler (`strict`). pub io_errors: Option, + /// `PYTHONUTF8=0|1` (PEP 540), already filtered for `-E`/`-I` by the + /// CLI. `-X utf8[=0|1]` has priority; when both are absent the mode + /// falls back to the locale-based default (`C`/`POSIX` → on). + pub utf8_mode: Option, +} + +/// The effective `LC_CTYPE` locale name, resolved the way `setlocale(LC_CTYPE, +/// "")` does from the environment: `LC_ALL` beats `LC_CTYPE` beats `LANG`, +/// and an unset/empty chain means the `C` locale. +fn effective_ctype_locale() -> String { + for var in ["LC_ALL", "LC_CTYPE", "LANG"] { + if let Ok(v) = std::env::var(var) { + if !v.is_empty() { + return v; + } + } + } + "C".to_owned() +} + +/// PEP 540: the `C`/`POSIX` locale turns UTF-8 mode on by default. +fn posix_ctype_locale() -> bool { + matches!(effective_ctype_locale().as_str(), "C" | "POSIX") +} + +/// PEP 538: under the C locale — or one of its UTF-8 coercion targets — +/// CPython defaults the stdin/stdout error handler to `surrogateescape` +/// (`config_init_stdio`), independent of `-X utf8`. +fn coercion_target_ctype_locale() -> bool { + matches!( + effective_ctype_locale().as_str(), + "C" | "POSIX" | "C.UTF-8" | "C.utf8" | "UTF-8" + ) } /// The top-level entry point for executing WeavePy bytecode. @@ -372,6 +490,11 @@ pub struct Interpreter { impl Default for Interpreter { fn default() -> Self { + install_parser_unicode_hook(); + // Adopt the environment's `LC_CTYPE` locale (CPython pre-init's + // `_Py_SetLocaleFromEnv`) so `_locale.getencoding()` and + // `locale.setlocale(..., None)` observe the user's locale. + crate::stdlib::locale_mod::init_from_env(); let stdout: Stdout = Rc::new(RefCell::new(std::io::stdout())); let mut builtins_dict = builtins::default_builtins(); // The `builtins` module exposes the core types/exceptions as the @@ -540,6 +663,16 @@ impl Interpreter { /// Replace `sys.argv` with the given values. The first entry is /// the script name; subsequent entries are passed-through args. + /// + /// Values are passed through [`os_args_bridged`]'s PUA-bridge + /// convention: code points in the plane-16 bridge window are mapped + /// back to the lone surrogates CPython's PEP 383 argv decoding + /// produces (so `weavepy $'\xff'` yields `sys.argv[1] == '\udcff'`, + /// byte-exact under `os.fsencode`). Plain text is unaffected; the + /// only caveat is an embedder passing a *genuine* U+10F800..U+10FFFF + /// private-use character, which the bridge cannot distinguish from + /// an escaped surrogate (the same trade-off the `str` method bridge + /// in `builtins.rs` documents). pub fn set_argv(&self, values: I) where I: IntoIterator, @@ -548,7 +681,7 @@ impl Interpreter { let mut argv = self.cache.argv.borrow_mut(); argv.clear(); for v in values { - argv.push(Object::from_str(v.into())); + argv.push(crate::builtins::bridge_to_object(&v.into())); } } @@ -587,6 +720,23 @@ impl Interpreter { .iter() .any(|x| x == "dev" || x.starts_with("dev=")); crate::vm_singletons::set_dev_mode(dev_mode); + // Resolve `PYTHONIOENCODING`'s encoding half to its canonical codec + // name up front (CPython reports `sys.stdout.encoding` normalized: + // `latin1` → `iso8859-1`). Must happen before the sys-dict borrow + // below — the registry lookup can import frozen modules. + let canonical_io_encoding = flags.io_encoding.as_ref().map(|enc| { + let guard = if crate::vm_singletons::current_interpreter_ptr().is_none() { + Some(crate::vm_singletons::publish_interpreter_ptr( + std::ptr::from_mut::(self), + )) + } else { + None + }; + let name = + crate::stdlib::codecs_mod::canonical_codec_name(enc).unwrap_or_else(|| enc.clone()); + drop(guard); + name + }); if let Some(Object::Module(m)) = self .cache .modules @@ -644,10 +794,12 @@ impl Interpreter { "hash_randomization", flags.hash_seed.map_or(1, |_| 0), ); - // UTF-8 mode: on by default (WeavePy str is UTF-8), but - // honour an explicit `-X utf8=0`/`-X utf8=1` (PEP 540) so - // `io.text_encoding(None)` reports "locale" vs "utf-8" and - // `test_io.test_text_encoding` round-trips. + // UTF-8 mode (PEP 540) precedence: `-X utf8[=0|1]` beats + // `PYTHONUTF8` (already filtered for `-E`/`-I` by the CLI), + // which beats the locale-based default (the `C`/`POSIX` + // locale enables the mode). Drives `sys.flags.utf8_mode`, + // `io.text_encoding(None)` ("locale" vs "utf-8"), and the + // stdio error-handler defaults below. let utf8_mode = flags .xoptions .iter() @@ -661,7 +813,8 @@ impl Interpreter { None } }) - .unwrap_or(1); + .or(flags.utf8_mode.map(i64::from)) + .unwrap_or_else(|| i64::from(posix_ctype_locale())); set(&mut fld, "utf8_mode", utf8_mode); crate::vm_singletons::set_utf8_mode(utf8_mode != 0); // The lone bool field on CPython's `sys.flags`. @@ -716,25 +869,38 @@ impl Interpreter { crate::object::DictKey(Object::from_static("_xoptions")), Object::Dict(crate::sync::Rc::new(crate::sync::RefCell::new(xopts))), ); - // `PYTHONIOENCODING=encoding[:errors]` — retarget the standard - // streams' text codec, matching CPython's startup - // (`config_init_stdio`). The encoding part alone is enough to - // make `sys.stdout.encoding` report e.g. `ascii`, which is what - // codec-aware helpers (`tarfile._safe_print`, - // `traceback`/`print` redirection) key off. We only mutate when - // the env var is set so the UTF-8 default — and `-E`/`-I` - // isolation — are untouched. - if flags.io_encoding.is_some() || flags.io_errors.is_some() { - for name in ["stdin", "stdout", "stderr"] { - if let Some(Object::File(f)) = - d.get(&crate::object::DictKey(Object::from_static(name))) - { - if let Some(enc) = &flags.io_encoding { - f.set_encoding(enc); - } - if let Some(errs) = &flags.io_errors { - f.set_errors(errs); - } + // Standard-stream codec + error handlers, matching CPython's + // startup (`config_init_stdio` + `init_sys_streams`): + // encoding — `PYTHONIOENCODING`'s encoding half when given + // (reported under its canonical codec name: latin1 → + // iso8859-1), else the UTF-8 default. + // stdin/stdout errors — `PYTHONIOENCODING`'s errors half; + // else `strict` when an explicit encoding was given; else + // `surrogateescape` under UTF-8 mode or a C-locale coercion + // target (PEP 538/540); else `strict`. + // stderr errors — always `backslashreplace`. + let stdio_errors: &str = match (&flags.io_errors, &flags.io_encoding) { + (Some(errs), _) => errs, + (None, Some(_)) => "strict", + (None, None) => { + if crate::vm_singletons::utf8_mode() || coercion_target_ctype_locale() { + "surrogateescape" + } else { + "strict" + } + } + }; + for name in ["stdin", "stdout", "stderr"] { + if let Some(Object::File(f)) = + d.get(&crate::object::DictKey(Object::from_static(name))) + { + if let Some(enc) = &canonical_io_encoding { + f.set_encoding(enc); + } + if name == "stderr" { + f.set_errors("backslashreplace"); + } else { + f.set_errors(stdio_errors); } } } @@ -3422,6 +3588,15 @@ impl Interpreter { // Fast path: skip the line-table read entirely when no // observer is active. The generator-creation bootstrap // (`RETURN_GENERATOR`) fires no line events either. + // + // A trace callback that *raises* must have its exception + // propagate inside the traced frame — catchable by this + // frame's own `try/except` and carrying this frame in its + // traceback exactly once (CPython `call_trace` failure; + // `test_settrace_error`). Park the error and feed it + // through the same arm as `step`'s `Err` below instead of + // `?`-escaping the whole frame. + let mut trace_err: Option = None; if crate::trace::any_observers_active() && !is_gen_bootstrap { let line = py_frame.current_lineno(); // CPython never emits a `line` event for the @@ -3443,15 +3618,30 @@ impl Interpreter { // line bookkeeping above still advances (mirrors CPython, // which keeps tracking the line for later re-enable). if py_frame.trace_lines.get() { - self.fire_line_event(&py_frame)?; + match self.fire_line_event(&py_frame) { + Ok(()) => { + // The callback may have set `f_lineno` (RFC + // 0050 — debugger "set next statement"). + // Apply the validated plan to the live frame + // and restart dispatch at the target so its + // line event fires. + if py_frame.pending_jump.get().is_some() { + self.apply_pending_jump(frame, &py_frame); + continue; + } + } + Err(e) => trace_err = Some(e), + } } } // A `'line'` callback may have just enabled opcode tracing // (bdb's `stepinstr`); CPython then fires the `'opcode'` // event for this same instruction before it runs. The // frame-entry RESUME carries no opcode event. - if !at_resume && py_frame.trace_opcodes.get() { - self.fire_opcode_event(&py_frame)?; + if trace_err.is_none() && !at_resume && py_frame.trace_opcodes.get() { + if let Err(e) = self.fire_opcode_event(&py_frame) { + trace_err = Some(e); + } } } // RFC 0039: service pending signals (`_thread.interrupt_main`, @@ -3486,7 +3676,9 @@ impl Interpreter { } else { None }; - let stepped = if let Some(exc) = async_exc { + let stepped = if let Some(e) = trace_err { + Err(e) + } else if let Some(exc) = async_exc { Err(match Self::normalize_exception(exc, None) { Ok(pe) => RuntimeError::PyException(pe), Err(e) => e, @@ -3524,6 +3716,12 @@ impl Interpreter { Ok(StepOutcome::Yield(v)) => { if crate::trace::any_observers_active() { self.fire_yield_event(&py_frame, &v)?; + // A jump set from the yield's 'return' trace event + // (CPython allows these) lands on the suspended + // frame, taking effect if/when it resumes. + if py_frame.pending_jump.get().is_some() { + self.apply_pending_jump(frame, &py_frame); + } } break Ok(FrameOutcome::Yielded(v)); } @@ -3818,6 +4016,8 @@ impl Interpreter { trace: RefCell::new(Object::None), gen_owner: RefCell::new(None), override_lineno: Cell::new(None), + trace_event: Cell::new(crate::linejump::TraceEvent::None), + pending_jump: Cell::new(None), last_line: Cell::new(None), trace_lines: Cell::new(true), trace_opcodes: Cell::new(false), @@ -3825,6 +4025,86 @@ impl Interpreter { }) } + /// Apply a pending `f_lineno` jump (validated by + /// [`Self::frame_set_lineno`]) to the live frame: pop the value + /// stack to the target depth, unwind any `except` blocks the jump + /// leaves, and move the program counter. + fn apply_pending_jump(&mut self, frame: &mut Frame, py_frame: &Rc) { + let Some(jump) = py_frame.pending_jump.take() else { + return; + }; + while frame.stack.len() > jump.target_depth as usize { + frame.stack.pop(); + } + for _ in 0..jump.exc_pops { + frame.exc_handlers.pop(); + self.exc_info_stack.borrow_mut().pop(); + } + frame.pc = jump.target_pc; + py_frame.lasti.set(jump.target_pc); + py_frame.override_lineno.set(None); + // Force a fresh 'line' event at the landing site. + py_frame.last_line.set(None); + } + + /// `frame.f_lineno = n` — CPython's `frame_setlineno` ("set next + /// statement", RFC 0050). Validates the jump against the abstract + /// stack analysis in [`crate::linejump`] and parks the plan on the + /// frame; the dispatch loop applies it after the trace callback + /// returns. + fn frame_set_lineno(&mut self, fr: &Rc, new_lineno: i64) -> Result<(), RuntimeError> { + use crate::linejump::TraceEvent; + let event = fr.trace_event.get(); + match event { + TraceEvent::Line | TraceEvent::Yield => {} + TraceEvent::None => { + return Err(value_error("f_lineno can only be set in a trace function")) + } + TraceEvent::Call => { + return Err(value_error( + "can't jump from the 'call' trace event of a new frame", + )) + } + TraceEvent::Return | TraceEvent::Exception | TraceEvent::Opcode => { + return Err(value_error("can only jump from a 'line' trace event")) + } + } + let suspended = event == TraceEvent::Yield; + let (jump, resolved_line) = + crate::linejump::compute_jump(&fr.code, fr.lasti.get(), new_lineno, suspended)?; + // CPython binds `None` to any still-unbound local at the target + // (rather than crashing on a LOAD_FAST of a name the compiler + // "proved" bound), warning first so an escalating filter can + // veto the whole jump. + // Compiler-synthesized temporaries (`.with_exit0`, `.retval0`, + // ...) live on CPython's value stack, not in `co_varnames`; + // counting them would warn where CPython doesn't. + let synthetic = |i: usize| fr.code.varnames.get(i).is_some_and(|n| n.starts_with('.')); + if let Some(mirror) = fr.locals_mirror.borrow().as_ref() { + let unbound = mirror + .borrow() + .iter() + .enumerate() + .filter(|(i, v)| matches!(v, Object::Unbound) && !synthetic(*i)) + .count(); + if unbound > 0 { + let s = if unbound == 1 { "" } else { "s" }; + self.warn_runtime_from_builtin(format!( + "assigning None to {unbound} unbound local{s}" + ))?; + for (i, slot) in mirror.borrow_mut().iter_mut().enumerate() { + if matches!(slot, Object::Unbound) && !synthetic(i) { + *slot = Object::None; + } + } + } + } + fr.pending_jump.set(Some(jump)); + // Reads of `f_lineno` report the target until the jump lands. + fr.override_lineno.set(Some(resolved_line)); + Ok(()) + } + /// `frame.clear()` — drop the references a no-longer-executing /// frame holds (CPython `frame_clear`). Clearing the frame of a /// *created* (never-started) generator finalizes the generator; @@ -4111,6 +4391,7 @@ impl Interpreter { /// Fire the `'call'` event when a frame is entered. Installs /// the returned per-frame trace function (settrace contract). fn fire_call_event(&mut self, py_frame: &Rc) -> Result<(), RuntimeError> { + let _event = TraceEventGuard::new(py_frame, crate::linejump::TraceEvent::Call); if let Some(trace) = crate::trace::trace_hook() { let result = self.invoke_observe_hook( &trace, @@ -4210,6 +4491,7 @@ impl Interpreter { /// Fire the `'line'` event when the source line changes. fn fire_line_event(&mut self, py_frame: &Rc) -> Result<(), RuntimeError> { + let _event = TraceEventGuard::new(py_frame, crate::linejump::TraceEvent::Line); let frame_trace = py_frame.trace.borrow().clone(); if !matches!(frame_trace, Object::None) { let result = self.invoke_observe_hook( @@ -4233,6 +4515,7 @@ impl Interpreter { /// `'line'`, the callback's return value replaces the per-frame /// trace; `sys.monitoring` observes INSTRUCTION. fn fire_opcode_event(&mut self, py_frame: &Rc) -> Result<(), RuntimeError> { + let _event = TraceEventGuard::new(py_frame, crate::linejump::TraceEvent::Opcode); let frame_trace = py_frame.trace.borrow().clone(); if !matches!(frame_trace, Object::None) { let result = self.invoke_observe_hook( @@ -4254,6 +4537,7 @@ impl Interpreter { py_frame: &Rc, value: &Object, ) -> Result<(), RuntimeError> { + let _event = TraceEventGuard::new(py_frame, crate::linejump::TraceEvent::Return); let frame_trace = py_frame.trace.borrow().clone(); if !matches!(frame_trace, Object::None) { let _ = self.invoke_observe_hook( @@ -4285,6 +4569,7 @@ impl Interpreter { py_frame: &Rc, value: &Object, ) -> Result<(), RuntimeError> { + let _event = TraceEventGuard::new(py_frame, crate::linejump::TraceEvent::Yield); let frame_trace = py_frame.trace.borrow().clone(); if !matches!(frame_trace, Object::None) { let _ = self.invoke_observe_hook( @@ -4305,6 +4590,7 @@ impl Interpreter { py_frame: &Rc, exc: &PyException, ) -> Result<(), RuntimeError> { + let _event = TraceEventGuard::new(py_frame, crate::linejump::TraceEvent::Exception); let frame_trace = py_frame.trace.borrow().clone(); if !matches!(frame_trace, Object::None) { // CPython passes a 3-tuple (type, value, traceback). We @@ -4355,6 +4641,7 @@ impl Interpreter { /// unwind path, while `sys.monitoring` observes `PY_UNWIND` rather /// than `PY_RETURN`. Fires nothing on the fast no-observer path. fn fire_unwind_event(&mut self, py_frame: &Rc) -> Result<(), RuntimeError> { + let _event = TraceEventGuard::new(py_frame, crate::linejump::TraceEvent::Return); let frame_trace = py_frame.trace.borrow().clone(); if !matches!(frame_trace, Object::None) { let _ = self.invoke_observe_hook( @@ -6910,6 +7197,8 @@ impl Interpreter { trace: RefCell::new(Object::None), gen_owner: RefCell::new(None), override_lineno: Cell::new(None), + trace_event: Cell::new(crate::linejump::TraceEvent::None), + pending_jump: Cell::new(None), last_line: Cell::new(None), trace_lines: Cell::new(true), trace_opcodes: Cell::new(false), @@ -18041,13 +18330,12 @@ impl Interpreter { fr.trace_opcodes.set(value.is_truthy()); Ok(()) } - "f_lineno" => match value { - Object::Int(i) if i >= 0 => { - fr.override_lineno.set(Some(i as u32)); - Ok(()) - } - _ => Err(type_error("f_lineno must be a non-negative int")), - }, + "f_lineno" => { + let Object::Int(new_lineno) = value else { + return Err(value_error("lineno must be an integer")); + }; + self.frame_set_lineno(fr, new_lineno) + } _ => Err(attribute_error(format!( "'frame' object attribute '{}' is read-only", name @@ -25203,7 +25491,17 @@ impl Interpreter { } }; let code_rc = match (exec_src, source) { - (None, Object::Code(c)) => c, + (None, Object::Code(c)) => { + // CPython rejects closure code up front (`exec` takes no + // closure to populate the cells): running it would hit + // `LOAD_DEREF` with no cell (RFC 0050 severity-1 crash). + if !c.freevars.is_empty() { + return Err(type_error( + "code object passed to exec() may not contain free variables", + )); + } + c + } (Some(src), _) => { // A malformed source must surface as `SyntaxError` (with a // location), exactly like `compile()` — CPython's `exec` @@ -25305,6 +25603,13 @@ impl Interpreter { } let src = match source { Object::Code(c) => { + // CPython rejects closure code up front (`eval` takes no + // closure to populate the cells) — see `do_exec_call`. + if !c.freevars.is_empty() { + return Err(type_error( + "code object passed to eval() may not contain free variables", + )); + } // `eval`-mode code returns its expression value (see // `compile_eval_with_source`); run it in the combined // namespace and hand that value straight back. @@ -25991,8 +26296,12 @@ impl Interpreter { let (code, source_for_diag) = if let Some(cached) = crate::pycache::try_load(path) { (cached, String::new()) } else { - let source = std::fs::read_to_string(path) + // PEP 263: imported sources go through the same BOM/coding-cookie + // decode as the tokenizer (a plain `read_to_string` would reject + // any non-UTF-8 module, e.g. `# coding: gbk`). + let raw = std::fs::read(path) .map_err(|e| import_error(format!("failed to read '{}': {e}", path.display())))?; + let source = decode_source_bytes(&raw, &filename)?; let module = weavepy_parser::parse_module(&source) .map_err(|e| parse_error_to_syntax_error(&e, &source, &filename))?; let code = weavepy_compiler::compile_module_with_source(&module, &source, &filename) @@ -26233,6 +26542,30 @@ fn line_col_text(source: &str, byte: u32) -> (u32, u32, String) { (line, col, text) } +/// Route the parser's `\N{NAME}` escapes through the generated UCD +/// 15.1.0 tables (RFC 0050 WS4), honouring a poisoned +/// `sys.modules['unicodedata']` the way CPython's tokenizer does (its +/// escape decoder imports `unicodedata` through the live runtime). +/// Idempotent; installed from `Interpreter::default` and from embedding +/// entry points that parse before an interpreter exists. +pub fn install_parser_unicode_hook() { + weavepy_parser::set_unicode_name_resolver(|name| { + use weavepy_parser::UnicodeNameResolution as R; + if let Some(ptr) = crate::vm_singletons::current_interpreter_ptr() { + // SAFETY: published by an enclosing VM frame on this thread. + let interp = unsafe { &mut *ptr }; + if matches!(interp.cache.get("unicodedata"), Some(Object::None)) { + return R::Unavailable; + } + } + // Aliases resolve (CPython's `\N{NULL}`); named sequences do not. + match crate::stdlib::ucd::lookup_with_aliases(name) { + Some(cp) => R::Code(cp), + None => R::Unknown, + } + }); +} + /// Decode a Python source buffer per PEP 263: an optional UTF-8 BOM, /// then an optional `# -*- coding: NAME -*-` cookie on line 1 or 2, /// defaulting to strict UTF-8. Mirrors CPython's tokenizer setup — @@ -26331,7 +26664,30 @@ fn decode_source_bytes_inner( } return Err(e); } - return crate::stdlib::codecs_mod::decode_bytes(payload, &enc, "strict").map_err(|_| { + let decoded = + crate::stdlib::codecs_mod::decode_bytes(payload, &enc, "strict").or_else(|e| { + // Registry-backed codecs (the frozen CJK modules, custom + // `codecs.register` entries) need a live interpreter, but the + // CLI decodes the main script before one exists. Boot a + // scratch interpreter just for this decode — rare (only + // non-native cookie encodings) and CPython's tokenizer always + // has the full runtime available at this point anyway. + if crate::vm_singletons::current_interpreter_ptr().is_none() { + let mut scratch = Interpreter::default(); + let guard = + crate::vm_singletons::publish_interpreter_ptr(std::ptr::from_mut::< + Interpreter, + >( + &mut scratch + )); + let res = crate::stdlib::codecs_mod::decode_bytes(payload, &enc, "strict"); + drop(guard); + res + } else { + Err(e) + } + }); + return decoded.map_err(|_| { crate::error::syntax_error(format!("encoding problem for '{filename}': {enc}")) }); } diff --git a/crates/weavepy-vm/src/linejump.rs b/crates/weavepy-vm/src/linejump.rs new file mode 100644 index 0000000..3feaeb0 --- /dev/null +++ b/crates/weavepy-vm/src/linejump.rs @@ -0,0 +1,525 @@ +//! RFC 0050 — real `frame.f_lineno` assignment ("set next statement"). +//! +//! CPython lets a *trace function* move a live frame to a different line +//! by assigning `frame.f_lineno`, subject to stack-safety rules +//! (`Objects/frameobject.c:frame_setlineno`). The legality analysis +//! models the evaluation stack at every instruction offset as a stack of +//! abstract *kinds* (`Iterator` / `Except` / `Object` / `Null`), packed +//! 3 bits per entry into an `i64` exactly like CPython's `mark_stacks`. +//! A jump is legal when the target's kind-stack can be reached from the +//! current one by popping values; applying it pops the frame's value +//! stack down to the target depth and (WeavePy-specific) pops the +//! separate `exc_handlers`/`exc_info` bookkeeping for any `except` +//! blocks the jump leaves. +//! +//! WeavePy divergence from CPython's model: our `PUSH_EXC_INFO` / +//! `POP_EXCEPT` track the handled exception on a side stack rather than +//! as a value-stack slot, so the analysis carries a parallel per-offset +//! *exception depth* and the jump plan records how many side-stack +//! entries to pop. The handler-entry exception *instance* (pushed by +//! `handle_exception`) is still a value-stack slot and is marked +//! `Except`, which is what makes "can't jump into an 'except' block" +//! fall out the same way it does in CPython. + +use weavepy_compiler::bytecode::{Instruction, OpCode}; +use weavepy_compiler::{CodeObject, Constant}; + +use crate::error::{value_error, RuntimeError}; + +/// Abstract stack-slot kinds, numerically identical to CPython's so the +/// packing/compatibility logic can be ported verbatim. +#[derive(Clone, Copy, PartialEq, Eq)] +#[repr(i64)] +enum Kind { + Iterator = 1, + Except = 2, + Object = 3, + Null = 4, +} + +const BITS_PER_BLOCK: i64 = 3; +const MASK: i64 = (1 << BITS_PER_BLOCK) - 1; +const UNINITIALIZED: i64 = -2; +const OVERFLOWED: i64 = -1; +const EMPTY_STACK: i64 = 0; +const MAX_STACK_ENTRIES: i64 = 63 / BITS_PER_BLOCK; +const WILL_OVERFLOW: u64 = 1 << ((MAX_STACK_ENTRIES - 1) * BITS_PER_BLOCK); + +fn push_kind(stack: i64, kind: Kind) -> i64 { + if stack < 0 || (stack as u64) >= WILL_OVERFLOW { + OVERFLOWED + } else { + (stack << BITS_PER_BLOCK) | kind as i64 + } +} + +fn pop_kind(stack: i64) -> i64 { + stack >> BITS_PER_BLOCK +} + +fn top_kind(stack: i64) -> i64 { + stack & MASK +} + +fn peek_kind(stack: i64, n: u32) -> i64 { + (stack >> (BITS_PER_BLOCK * i64::from(n - 1))) & MASK +} + +fn stack_depth(mut stack: i64) -> u32 { + let mut d = 0; + while stack > 0 { + stack = pop_kind(stack); + d += 1; + } + d +} + +fn swap_kinds(stack: i64, n: u32) -> i64 { + if n < 2 { + return stack; + } + let to_swap = peek_kind(stack, n); + let top = top_kind(stack); + let shift = BITS_PER_BLOCK * i64::from(n - 1); + let replaced_low = (stack & !(MASK << shift)) | (top << shift); + (replaced_low & !MASK) | to_swap +} + +fn pop_to_level(mut stack: i64, level: u32) -> i64 { + if level == 0 { + return EMPTY_STACK; + } + let max_item: i64 = MASK; + let level_max_stack = max_item << ((i64::from(level) - 1) * BITS_PER_BLOCK); + while stack > level_max_stack { + stack = pop_kind(stack); + } + stack +} + +fn compatible_kind(from: i64, to: i64) -> bool { + if to == 0 { + return false; + } + if to == Kind::Object as i64 { + return from != Kind::Null as i64; + } + if to == Kind::Null as i64 { + return true; + } + from == to +} + +fn compatible_stack(mut from_stack: i64, to_stack: i64) -> bool { + if from_stack < 0 || to_stack < 0 { + return false; + } + let mut to = to_stack; + while from_stack > to { + from_stack = pop_kind(from_stack); + } + while from_stack != 0 { + if !compatible_kind(top_kind(from_stack), top_kind(to)) { + return false; + } + from_stack = pop_kind(from_stack); + to = pop_kind(to); + } + to == 0 +} + +fn explain_incompatible_stack(to_stack: i64) -> &'static str { + if to_stack == OVERFLOWED { + return "stack is too deep to analyze"; + } + if to_stack == UNINITIALIZED { + return "can't jump into an exception handler, or code may be unreachable"; + } + match top_kind(to_stack) { + k if k == Kind::Except as i64 => { + "can't jump into an 'except' block as there's no exception" + } + k if k == Kind::Iterator as i64 => "can't jump into the body of a for loop", + _ => "incompatible stacks", + } +} + +/// The trace event a frame is currently dispatching (mirrors the subset +/// of `sys.monitoring` events CPython consults in `frame_setlineno`). +#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] +pub enum TraceEvent { + #[default] + None, + Call, + Line, + Return, + Exception, + Opcode, + Yield, +} + +/// A validated pending jump, stored on the `PyFrame` by the `f_lineno` +/// setter and applied to the live `Frame` by the dispatch loop. +#[derive(Clone, Copy, Debug)] +pub struct PendingJump { + /// Instruction index to resume at. + pub target_pc: u32, + /// Value-stack depth at the target (pop down to this). + pub target_depth: u32, + /// How many `exc_handlers`/`exc_info` entries the jump leaves. + pub exc_pops: u32, +} + +/// Per-offset analysis result. +struct Marked { + stacks: Vec, + exc_depths: Vec, +} + +/// First offsets of each line: `linestarts[i] = line` when instruction +/// `i` starts a new line (mirrors CPython's `marklines`), else -1. +fn marklines(code: &CodeObject) -> Vec { + let n = code.instructions.len(); + let mut out = vec![-1i64; n]; + let mut last_line: i64 = -1; + for (i, slot) in out.iter_mut().enumerate() { + let line = i64::from(code.linetable.get(i).copied().unwrap_or(0)); + if line != last_line && line != 0 { + *slot = line; + last_line = line; + } else if line != 0 { + last_line = line; + } + } + out +} + +/// The size of the keyword-names tuple feeding a `CallKw` at `i`, when +/// statically determinable (the compiler always emits `LoadConst names` +/// immediately before `CallKw`). +fn callkw_names_len(code: &CodeObject, i: usize) -> Option { + if i == 0 { + return None; + } + let prev = code.instructions.get(i - 1)?; + if prev.op != OpCode::LoadConst { + return None; + } + match code.constants.get(prev.arg as usize)? { + Constant::Tuple(items) => Some(items.len()), + _ => None, + } +} + +/// `(pops, pushes)` for the plain-effect opcodes (everything without +/// bespoke kind or control-flow handling in `mark_stacks`). `None` +/// marks the offset unanalyzable. +fn plain_effect(code: &CodeObject, i: usize, ins: Instruction) -> Option<(u32, u32)> { + use OpCode as O; + let arg = ins.arg; + Some(match ins.op { + O::Nop | O::Resume | O::MakeCell | O::SetupAnnotations | O::EndFor => (0, 0), + // WeavePy's generator bootstrap suspends and *resumes at the + // next instruction* with an unchanged stack (the generator + // object lands on the caller's stack, not this frame's) — + // unlike CPython, where RETURN_GENERATOR pushes the generator + // and is followed by POP_TOP. + O::ReturnGenerator => (0, 0), + O::DeleteFast | O::DeleteGlobal | O::DeleteName | O::DeleteDeref => (0, 0), + O::LoadConst + | O::LoadName + | O::LoadGlobal + | O::LoadFast + | O::LoadDeref + | O::LoadClosure + | O::LoadClassderef + | O::LoadBuildClass + | O::LoadAssertionError => (0, 1), + O::StoreFast | O::StoreGlobal | O::StoreName | O::StoreDeref => (1, 0), + O::LoadAttr | O::UnaryOp => (1, 1), + O::StoreAttr => (2, 0), + O::DeleteAttr => (1, 0), + O::BinarySubscr | O::BinaryOp | O::CompareOp | O::IsOp | O::ContainsOp => (2, 1), + O::StoreSubscr => (3, 0), + O::DeleteSubscr => (2, 0), + O::PopTop | O::PrintExpr | O::ImportStar | O::DictUpdate => (1, 0), + O::Call => (arg + 1, 1), + O::CallKw => { + let kwc = u32::try_from(callkw_names_len(code, i)?).ok()?; + (arg + kwc + 2, 1) + } + O::CallEx => (2 + arg, 1), + O::BuildList | O::BuildTuple | O::BuildSet | O::BuildString => (arg, 1), + O::BuildMap => (2 * arg, 1), + O::ListAppend | O::SetAdd => (1, 0), + O::MapAdd => (2, 0), + O::UnpackSequence => (1, arg), + O::UnpackEx => (1, (arg >> 8) + 1 + (arg & 0xFF)), + O::MakeFunction => (1 + (arg & 0xF).count_ones(), 1), + O::BuildSlice => (3, 1), + O::CheckExcMatch => (1, 1), + O::CheckEGMatch => (2, 2), + O::PrepReraiseStar => (2, 1), + O::ImportName => (2, 1), + O::ImportFrom => (0, 1), + O::FormatValue => (if arg & 0x4 != 0 { 2 } else { 1 }, 1), + O::YieldValue => (1, 1), + O::EndSend => (2, 1), + O::GetAnext => (0, 1), + O::EndAsyncFor => (2, 0), + O::BeforeWith | O::BeforeAsyncWith => (1, 2), + O::MatchSequence | O::MatchMapping | O::GetLen => (0, 1), + O::MatchClass => (3, 1), + O::MatchKeys => (1, 1), + // Handled specially in `mark_stacks`; unreachable here. + O::PopJumpIfFalse + | O::PopJumpIfTrue + | O::JumpForward + | O::JumpBackward + | O::GetIter + | O::GetAiter + | O::GetYieldFromIter + | O::GetAwaitable + | O::ForIter + | O::Send + | O::CopyTop + | O::Swap + | O::PushExcInfo + | O::PopExcept + | O::WithExceptStart + | O::ReturnValue + | O::RaiseVarargs + | O::Reraise => return None, + }) +} + +/// Merge a successor state, returning whether anything changed (drives +/// the fixpoint worklist). +fn merge(stacks: &mut [i64], exc_depths: &mut [i32], idx: usize, stack: i64, exc: i32) -> bool { + let mut changed = false; + if idx < stacks.len() { + if stacks[idx] == UNINITIALIZED { + stacks[idx] = stack; + changed = true; + } else if stacks[idx] != stack && stacks[idx] != OVERFLOWED { + // Conflicting flows (shouldn't happen with compiler-emitted + // code) — poison rather than mis-analyze. + stacks[idx] = OVERFLOWED; + changed = true; + } + if exc_depths[idx] == -1 { + exc_depths[idx] = exc; + changed = true; + } + } + changed +} + +/// Compute the abstract kind-stack and exception-handler depth at every +/// instruction offset (CPython `mark_stacks`, adapted to WeavePy's +/// instruction set and split exception bookkeeping). +fn mark_stacks(code: &CodeObject) -> Marked { + use OpCode as O; + let n = code.instructions.len(); + let mut stacks = vec![UNINITIALIZED; n + 1]; + let mut exc_depths = vec![-1i32; n + 1]; + stacks[0] = EMPTY_STACK; + exc_depths[0] = 0; + let mut todo = true; + while todo { + todo = false; + for i in 0..n { + let cur = stacks[i]; + if cur == UNINITIALIZED { + continue; + } + let exc = exc_depths[i].max(0); + let ins = code.instructions[i]; + let next_i = i + 1; + let arg = ins.arg; + match ins.op { + O::PopJumpIfFalse | O::PopJumpIfTrue => { + let after = pop_kind(cur); + let target = next_i + arg as usize; + todo |= merge(&mut stacks, &mut exc_depths, target, after, exc); + todo |= merge(&mut stacks, &mut exc_depths, next_i, after, exc); + } + O::JumpForward => { + let target = next_i + arg as usize; + todo |= merge(&mut stacks, &mut exc_depths, target, cur, exc); + } + O::JumpBackward => { + let target = next_i.saturating_sub(arg as usize); + todo |= merge(&mut stacks, &mut exc_depths, target, cur, exc); + } + O::GetIter | O::GetAiter | O::GetYieldFromIter | O::GetAwaitable => { + let after = push_kind(pop_kind(cur), Kind::Iterator); + todo |= merge(&mut stacks, &mut exc_depths, next_i, after, exc); + } + O::ForIter => { + // Fallthrough: loop body sees [.., iter, value]. + let body = push_kind(cur, Kind::Object); + todo |= merge(&mut stacks, &mut exc_depths, next_i, body, exc); + // Exhaustion: WeavePy pops the iterator *before* + // jumping (END_FOR is a no-op). + let target = next_i + arg as usize; + todo |= merge(&mut stacks, &mut exc_depths, target, pop_kind(cur), exc); + } + O::Send => { + // [.., iter, v] on both paths ([.., iter, yielded] + // fallthrough / [.., iter, retval] jump). + let target = next_i + arg as usize; + todo |= merge(&mut stacks, &mut exc_depths, target, cur, exc); + todo |= merge(&mut stacks, &mut exc_depths, next_i, cur, exc); + } + O::CopyTop => { + let after = push_kind(cur, kind_of(top_kind(cur))); + todo |= merge(&mut stacks, &mut exc_depths, next_i, after, exc); + } + O::Swap => { + let after = swap_kinds(cur, arg.max(2)); + todo |= merge(&mut stacks, &mut exc_depths, next_i, after, exc); + } + O::PushExcInfo => { + todo |= merge(&mut stacks, &mut exc_depths, next_i, cur, exc + 1); + } + O::PopExcept => { + todo |= merge(&mut stacks, &mut exc_depths, next_i, cur, (exc - 1).max(0)); + } + O::WithExceptStart => { + // [.., __exit__(O), exc(E)] -> [.., exc(E), result(O)] + let below = pop_kind(pop_kind(cur)); + let after = push_kind(push_kind(below, Kind::Except), Kind::Object); + todo |= merge(&mut stacks, &mut exc_depths, next_i, after, exc); + } + O::ReturnValue | O::RaiseVarargs | O::Reraise => { + // Block enders: no fallthrough. + } + _ => { + if let Some((pops, pushes)) = plain_effect(code, i, ins) { + let mut after = cur; + for _ in 0..pops { + after = pop_kind(after); + } + for _ in 0..pushes { + after = push_kind(after, Kind::Object); + } + todo |= merge(&mut stacks, &mut exc_depths, next_i, after, exc); + } else { + todo |= merge(&mut stacks, &mut exc_depths, next_i, OVERFLOWED, exc); + } + } + } + } + // Exception-table edges: the handler entry sees the protected + // range's stack popped to the recorded depth plus the pushed + // exception instance. + for h in &code.exception_table { + let start = h.start as usize; + let handler = h.handler as usize; + if start < stacks.len() && stacks[start] != UNINITIALIZED { + if handler < stacks.len() && stacks[handler] == UNINITIALIZED { + let target = push_kind(pop_to_level(stacks[start], h.depth), Kind::Except); + stacks[handler] = target; + exc_depths[handler] = exc_depths[start].max(0); + todo = true; + } + } + } + } + Marked { stacks, exc_depths } +} + +fn kind_of(raw: i64) -> Kind { + match raw { + k if k == Kind::Iterator as i64 => Kind::Iterator, + k if k == Kind::Except as i64 => Kind::Except, + k if k == Kind::Null as i64 => Kind::Null, + _ => Kind::Object, + } +} + +/// Validate a `f_lineno` assignment and compute the jump plan. +/// +/// `cur_pc` is the frame's current instruction index; `suspended` is +/// true when jumping from a generator's yield ('return'-after-yield +/// trace event), where the analysis stack includes the resume slot the +/// physical stack doesn't hold yet. +pub fn compute_jump( + code: &CodeObject, + cur_pc: u32, + new_lineno: i64, + suspended: bool, +) -> Result<(PendingJump, u32), RuntimeError> { + let first_lineno = i64::from(code.linetable.iter().copied().find(|l| *l > 0).unwrap_or(1)); + if new_lineno < first_lineno { + return Err(value_error(format!( + "line {new_lineno} comes before the current code block" + ))); + } + let n = code.instructions.len(); + let lines = marklines(code); + // First line at-or-after the requested one that actually starts an + // instruction run (CPython `first_line_not_before`). + let mut resolved = i64::MAX; + for &l in &lines { + if l >= new_lineno && l < resolved { + resolved = l; + } + } + if resolved == i64::MAX { + return Err(value_error(format!( + "line {new_lineno} comes after the current code block" + ))); + } + let marked = mark_stacks(code); + let mut start_stack = *marked.stacks.get(cur_pc as usize).unwrap_or(&UNINITIALIZED); + let start_exc = marked + .exc_depths + .get(cur_pc as usize) + .copied() + .unwrap_or(-1) + .max(0); + if suspended { + // Account for the resume slot the yield hasn't pushed yet. + start_stack = pop_kind(start_stack); + } + let mut best_stack = OVERFLOWED; + let mut best_addr: Option = None; + let mut err_msg: Option<&'static str> = None; + for (i, &l) in lines.iter().enumerate().take(n) { + if l != resolved { + continue; + } + let target_stack = marked.stacks[i]; + let target_exc = marked.exc_depths[i].max(0); + if target_exc <= start_exc && compatible_stack(start_stack, target_stack) { + if best_addr.is_none() || target_stack > best_stack { + best_stack = target_stack; + best_addr = Some(i); + } + } else if err_msg.is_none() { + err_msg = Some(if start_stack == OVERFLOWED { + "stack to deep to analyze" + } else if start_stack == UNINITIALIZED { + "can't jump from unreachable code" + } else if target_exc > start_exc { + "can't jump into an 'except' block as there's no exception" + } else { + explain_incompatible_stack(target_stack) + }); + } + } + let Some(addr) = best_addr else { + return Err(value_error( + err_msg.unwrap_or("cannot find bytecode for specified line"), + )); + }; + let target_exc = marked.exc_depths[addr].max(0); + let jump = PendingJump { + target_pc: addr as u32, + target_depth: stack_depth(best_stack), + exc_pops: u32::try_from(start_exc - target_exc).unwrap_or(0), + }; + Ok((jump, u32::try_from(resolved).unwrap_or(0))) +} diff --git a/crates/weavepy-vm/src/object.rs b/crates/weavepy-vm/src/object.rs index 82000d7..5b83c6a 100644 --- a/crates/weavepy-vm/src/object.rs +++ b/crates/weavepy-vm/src/object.rs @@ -395,11 +395,21 @@ pub struct PyFrame { /// `frame.clear()` tear down the suspended generator like /// CPython's `frame_clear`. pub gen_owner: RefCell>>, - /// Per-frame `f_lineno` override. CPython lets debuggers set - /// `f_lineno` to jump to a different line; we keep storage so - /// reads round-trip, even though writes don't actually move the - /// program counter. + /// Per-frame `f_lineno` override. Set alongside a validated + /// [`Self::pending_jump`] so reads report the jump target until + /// the dispatch loop applies it (RFC 0050); cleared on apply. pub override_lineno: Cell>, + /// The trace event this frame is currently dispatching. CPython's + /// `frame_setlineno` gates `f_lineno` assignment on the event kind + /// (`'line'` and yield events allow jumps; `'call'`/`'return'`/ + /// `'exception'`/`'opcode'` refuse). Set/cleared by the + /// `fire_*_event` dispatchers (RFC 0050). + pub trace_event: Cell, + /// A validated pending line-jump: the `f_lineno` setter runs the + /// legality analysis (`linejump::compute_jump`) and parks the plan + /// here; the dispatch loop applies it to the live frame right + /// after the trace callback returns (RFC 0050). + pub pending_jump: Cell>, /// Most recently observed source line on this frame, used by /// the dispatcher to know when to fire a `'line'` event. `None` /// means "no line event has fired on this frame yet" — the @@ -3804,6 +3814,9 @@ impl PyFile { Some(cont) if !self.text_start_of_stream.get() => cont.to_owned(), _ => enc.clone(), }; + // Text-model codec check happened at wrapper construction; per-write + // codec calls must not repeat it (`test_io.test_illegal_encoder`). + let _exempt = crate::stdlib::codecs_mod::io_text_exempt_guard(); let out = crate::stdlib::codecs_mod::encode_str(&translated, &effective, &errors)?; self.text_start_of_stream.set(false); Ok(out) @@ -3842,6 +3855,9 @@ impl PyFile { crate::stdlib::codecs_mod::decode_bytes(bytes, enc, errors) } let errors = self.errors_name(); + // Text-model codec check happened at wrapper construction; per-read + // codec calls must not repeat it (`test_io.test_illegal_decoder`). + let _exempt = crate::stdlib::codecs_mod::io_text_exempt_guard(); let decoded = match &*self.encoding.borrow() { Some(enc) => decode_or_bridge(&bytes, enc, &errors)?, None if errors == "strict" => { @@ -8482,22 +8498,11 @@ fn bytes_membership(haystack: &[u8], item: &Object) -> Result bool { - if c == ' ' { - return true; - } - use unicode_properties::{GeneralCategory as GC, UnicodeGeneralCategory}; - !matches!( - c.general_category(), - GC::Control - | GC::Format - | GC::Surrogate - | GC::PrivateUse - | GC::Unassigned - | GC::LineSeparator - | GC::ParagraphSeparator - | GC::SpaceSeparator - ) + crate::unicode_case::is_printable(c) } fn bytes_repr(b: &[u8]) -> String { diff --git a/crates/weavepy-vm/src/stdlib/codecs_engine.rs b/crates/weavepy-vm/src/stdlib/codecs_engine.rs new file mode 100644 index 0000000..60c0291 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/codecs_engine.rs @@ -0,0 +1,1558 @@ +//! Unified codec engine (RFC 0050 WS2). +//! +//! Faithful ports of CPython 3.13's UTF-8/16/32/7, ASCII and Latin-1 +//! coders (`Objects/unicodeobject.c` + `Objects/stringlib/codecs.h`) +//! with the *unified error-handler protocol*: the fast path scans until +//! an error, then the handler is resolved **by name** — built-ins run +//! natively, anything else calls the callable registered through +//! `codecs.register_error` with a real `UnicodeDecodeError`/ +//! `UnicodeEncodeError`, applies the `(replacement, new_position)` +//! result (including bytes replacements on encode and backward +//! positions), and the scan continues. Decoders speak the *stateful* +//! protocol: `final=false` leaves a trailing incomplete sequence +//! unconsumed and reports how many bytes were consumed. +//! +//! Text is processed as raw code points (`u32`, lone surrogates +//! allowed) so PEP 383 `surrogateescape` and `surrogatepass` round-trip +//! through [`Object::str_from_codepoints`]/[`Object::WStr`]. + +use crate::error::{type_error, RuntimeError}; +use crate::object::Object; + +// --------------------------------------------------------------------------- +// Handler resolution +// --------------------------------------------------------------------------- + +/// A resolved error handler: a built-in dispatched natively, or a custom +/// callable registered via `codecs.register_error`. +#[derive(Clone)] +enum Handler { + Strict, + Ignore, + Replace, + BackslashReplace, + XmlCharRefReplace, + NameReplace, + SurrogateEscape, + SurrogatePass, + Custom(Object), +} + +fn resolve_handler(name: &str) -> Result { + Ok(match name { + "strict" => Handler::Strict, + "ignore" => Handler::Ignore, + "replace" => Handler::Replace, + "backslashreplace" => Handler::BackslashReplace, + "xmlcharrefreplace" => Handler::XmlCharRefReplace, + "namereplace" => Handler::NameReplace, + "surrogateescape" => Handler::SurrogateEscape, + "surrogatepass" => Handler::SurrogatePass, + _ => Handler::Custom(lookup_error_callable(name)?), + }) +} + +/// `codecs.lookup_error(name)` through the live interpreter (custom +/// handlers live in the frozen `codecs.py` registry). +fn lookup_error_callable(name: &str) -> Result { + let unknown = || crate::error::lookup_error(format!("unknown error handler name '{name}'")); + let ptr = crate::vm_singletons::current_interpreter_ptr().ok_or_else(unknown)?; + // SAFETY: pointer published by an enclosing VM frame on this thread; + // the GIL keeps the reentrant access exclusive (same contract as + // `codecs_mod::with_interp`). + let interp = unsafe { &mut *ptr }; + let codecs = interp.import_path("codecs").map_err(|_| unknown())?; + let lookup = interp + .load_attr_public(&codecs, "lookup_error") + .map_err(|_| unknown())?; + interp.call_object(lookup, &[Object::from_str(name)], &[]) +} + +/// The byte-order-resolved "standard" encoding name used in error payloads +/// (`utf-16-le`, not `utf-16`) — CPython names the concrete codec. +fn call_custom(handler: &Object, exc: &Object) -> Result { + let ptr = crate::vm_singletons::current_interpreter_ptr() + .ok_or_else(|| crate::error::runtime_error("no running interpreter"))?; + // SAFETY: see `lookup_error_callable`. + let interp = unsafe { &mut *ptr }; + interp.call_object(handler.clone(), &[exc.clone()], &[]) +} + +fn get_attr(obj: &Object, name: &str) -> Result { + let ptr = crate::vm_singletons::current_interpreter_ptr() + .ok_or_else(|| crate::error::runtime_error("no running interpreter"))?; + // SAFETY: see `lookup_error_callable`. + let interp = unsafe { &mut *ptr }; + interp.load_attr_public(obj, name) +} + +/// Code points of any string object (`Str` fast path, `WStr` raw points). +pub fn str_codepoints(obj: &Object) -> Option> { + match obj { + Object::Str(s) => Some(s.chars().map(|c| c as u32).collect()), + Object::WStr(cps) => Some(cps.to_vec()), + _ => None, + } +} + +// --------------------------------------------------------------------------- +// Decode driver +// --------------------------------------------------------------------------- + +/// Mutable decode context threaded through a decoder loop. The handler may +/// *replace the input* (by assigning `exc.object`), so `input` is owned. +struct DecCtx { + encoding: String, + errors: String, + handler: Option, + input: Vec, +} + +impl DecCtx { + fn new(encoding: &str, errors: &str, input: &[u8]) -> Self { + DecCtx { + encoding: encoding.to_owned(), + errors: errors.to_owned(), + handler: None, + input: input.to_vec(), + } + } + + fn handler(&mut self) -> Result { + if self.handler.is_none() { + self.handler = Some(resolve_handler(&self.errors)?); + } + Ok(self.handler.clone().unwrap()) + } + + fn error_object(&self, start: usize, end: usize, reason: &str) -> Object { + crate::builtin_types::make_unicode_decode_error( + &self.encoding, + &self.input, + start, + end, + reason, + ) + } + + /// Resolve a decode error over `input[start..end]`; extends `out` with + /// the replacement and returns the position to continue scanning from. + fn on_error( + &mut self, + out: &mut Vec, + start: usize, + end: usize, + reason: &str, + ) -> Result { + match self.handler()? { + Handler::Strict => Err(RuntimeError::PyException(crate::error::PyException::new( + self.error_object(start, end, reason), + ))), + Handler::Ignore => Ok(end), + Handler::Replace => { + out.push(0xFFFD); + Ok(end) + } + Handler::BackslashReplace => { + for &b in &self.input[start..end] { + out.extend(format!("\\x{b:02x}").chars().map(|c| c as u32)); + } + Ok(end) + } + Handler::SurrogateEscape => { + for &b in &self.input[start..end] { + if b < 128 { + // PEP 383 only smuggles bytes >= 0x80; an ASCII byte + // in an illegal sequence is a hard error. + return Err(RuntimeError::PyException(crate::error::PyException::new( + self.error_object(start, end, reason), + ))); + } + out.push(0xDC00 + u32::from(b)); + } + Ok(end) + } + Handler::SurrogatePass => { + // Accept exactly the CESU-8 / UTF-16 / UTF-32 encoded lone + // surrogate at `start`; anything else is the original error. + if let Some((cp, len)) = + decode_encoded_surrogate(&self.encoding, &self.input[start..]) + { + out.push(cp); + Ok(start + len) + } else { + Err(RuntimeError::PyException(crate::error::PyException::new( + self.error_object(start, end, reason), + ))) + } + } + Handler::XmlCharRefReplace | Handler::NameReplace => Err(type_error( + "don't know how to handle UnicodeDecodeError in error callback", + )), + Handler::Custom(h) => { + let exc = self.error_object(start, end, reason); + let res = call_custom(&h, &exc)?; + let items: Vec = match &res { + Object::Tuple(t) if t.len() == 2 => t.to_vec(), + _ => { + return Err(type_error( + "decoding error handler must return (str, int) tuple", + )) + } + }; + let rep = str_codepoints(&items[0]).ok_or_else(|| { + type_error("decoding error handler must return (str, int) tuple") + })?; + let mut newpos = match &items[1] { + Object::Int(i) => *i, + _ => { + return Err(type_error( + "decoding error handler must return (str, int) tuple", + )) + } + }; + // The handler may have replaced `exc.object`; re-fetch it + // (CPython raises TypeError when it's no longer bytes — + // ignoring the mutation would loop forever). + let o = get_attr(&exc, "object")?; + self.input = o + .as_bytes_view() + .ok_or_else(|| type_error("object attribute must be bytes"))?; + let insize = self.input.len() as i64; + if newpos < 0 { + newpos += insize; + } + if newpos < 0 || newpos > insize { + return Err(crate::error::index_error(format!( + "position {newpos} from error handler out of bounds" + ))); + } + out.extend(rep); + Ok(newpos as usize) + } + } + } +} + +/// Decode the lone-surrogate byte sequence at the front of `rest` for the +/// `surrogatepass` handler. Returns `(code point, bytes consumed)`. +fn decode_encoded_surrogate(encoding: &str, rest: &[u8]) -> Option<(u32, usize)> { + let key = standard_key(encoding); + match key { + "utf8" => { + if rest.len() >= 3 + && rest[0] == 0xED + && (0xA0..=0xBF).contains(&rest[1]) + && (0x80..=0xBF).contains(&rest[2]) + { + let cp = ((u32::from(rest[0]) & 0x0F) << 12) + | ((u32::from(rest[1]) & 0x3F) << 6) + | (u32::from(rest[2]) & 0x3F); + Some((cp, 3)) + } else { + None + } + } + "utf16le" | "utf16be" => { + if rest.len() >= 2 { + let u = if key == "utf16le" { + u16::from_le_bytes([rest[0], rest[1]]) + } else { + u16::from_be_bytes([rest[0], rest[1]]) + }; + if (0xD800..=0xDFFF).contains(&u) { + return Some((u32::from(u), 2)); + } + } + None + } + "utf32le" | "utf32be" => { + if rest.len() >= 4 { + let v = if key == "utf32le" { + u32::from_le_bytes([rest[0], rest[1], rest[2], rest[3]]) + } else { + u32::from_be_bytes([rest[0], rest[1], rest[2], rest[3]]) + }; + if (0xD800..=0xDFFF).contains(&v) { + return Some((v, 4)); + } + } + None + } + _ => None, + } +} + +/// Normalise an error-payload encoding name to a family key for +/// `surrogatepass` (mirrors CPython's `get_standard_encoding`). +fn standard_key(encoding: &str) -> &'static str { + let norm: String = encoding + .chars() + .filter(|c| c.is_ascii_alphanumeric()) + .map(|c| c.to_ascii_lowercase()) + .collect(); + match norm.as_str() { + "utf8" | "utf8sig" | "cp65001" => "utf8", + "utf16le" => "utf16le", + "utf16be" => "utf16be", + // Byte-order-less names resolve to native (little-endian) order. + "utf16" | "u16" => "utf16le", + "utf32le" => "utf32le", + "utf32be" => "utf32be", + "utf32" | "u32" => "utf32le", + _ => "unknown", + } +} + +// --------------------------------------------------------------------------- +// unicode-escape / raw-unicode-escape decoders +// --------------------------------------------------------------------------- + +/// Faithful port of CPython's `_PyUnicode_DecodeUnicodeEscapeInternal2`. +/// Returns `(text, consumed, first_invalid_escape_warning)` — the warning +/// message (e.g. ``invalid escape sequence '\z'``) that the caller emits as +/// a `DeprecationWarning`, or `None`. +pub fn unicode_escape_decode( + data: &[u8], + errors: &str, + final_: bool, +) -> Result<(Object, usize, Option), RuntimeError> { + let mut ctx = DecCtx::new("unicodeescape", errors, data); + let mut out: Vec = Vec::with_capacity(data.len()); + let mut warn: Option = None; + let mut consumed = data.len(); + let hexval = |c: u8| -> Option { + match c { + b'0'..=b'9' => Some(u32::from(c - b'0')), + b'a'..=b'f' => Some(u32::from(c - b'a') + 10), + b'A'..=b'F' => Some(u32::from(c - b'A') + 10), + _ => None, + } + }; + let mut i = 0usize; + 'outer: while i < ctx.input.len() { + let c = ctx.input[i]; + i += 1; + if c != b'\\' { + out.push(u32::from(c)); + continue; + } + let start = i - 1; + if i >= ctx.input.len() { + if !final_ { + consumed = start; + break; + } + i = ctx.on_error(&mut out, start, i, "\\ at end of string")?; + continue; + } + let c = ctx.input[i]; + i += 1; + match c { + b'\n' => {} + b'\\' => out.push(u32::from(b'\\')), + b'\'' => out.push(u32::from(b'\'')), + b'"' => out.push(u32::from(b'"')), + b'b' => out.push(0x08), + b'f' => out.push(0x0C), + b't' => out.push(u32::from(b'\t')), + b'n' => out.push(u32::from(b'\n')), + b'r' => out.push(u32::from(b'\r')), + b'v' => out.push(0x0B), + b'a' => out.push(0x07), + b'0'..=b'7' => { + let mut ch = u32::from(c - b'0'); + if i < ctx.input.len() && (b'0'..=b'7').contains(&ctx.input[i]) { + ch = (ch << 3) + u32::from(ctx.input[i] - b'0'); + i += 1; + if i < ctx.input.len() && (b'0'..=b'7').contains(&ctx.input[i]) { + ch = (ch << 3) + u32::from(ctx.input[i] - b'0'); + i += 1; + } + } + if ch > 0o377 && warn.is_none() { + warn = Some(format!("invalid octal escape sequence '\\{ch:o}'")); + } + out.push(ch); + } + b'x' | b'u' | b'U' => { + let (count, message) = match c { + b'x' => (2usize, "truncated \\xXX escape"), + b'u' => (4, "truncated \\uXXXX escape"), + _ => (8, "truncated \\UXXXXXXXX escape"), + }; + let mut ch: u32 = 0; + let mut k = 0usize; + loop { + if k == count { + break; + } + if i >= ctx.input.len() { + if !final_ { + consumed = start; + break 'outer; + } + i = ctx.on_error(&mut out, start, i, message)?; + continue 'outer; + } + match hexval(ctx.input[i]) { + Some(v) => ch = (ch << 4) + v, + None => { + i = ctx.on_error(&mut out, start, i, message)?; + continue 'outer; + } + } + i += 1; + k += 1; + } + if ch > 0x0010_FFFF { + i = ctx.on_error(&mut out, start, i, "illegal Unicode character")?; + continue; + } + out.push(ch); + } + b'N' => { + let message = "malformed \\N character escape"; + if i >= ctx.input.len() { + if !final_ { + consumed = start; + break; + } + i = ctx.on_error(&mut out, start, i, message)?; + continue; + } + if ctx.input[i] == b'{' { + let name_start = i + 1; + let mut j = name_start; + while j < ctx.input.len() && ctx.input[j] != b'}' { + j += 1; + } + if j >= ctx.input.len() { + if !final_ { + consumed = start; + break; + } + i = ctx.on_error(&mut out, start, j, message)?; + continue; + } + if j > name_start { + let name = String::from_utf8_lossy(&ctx.input[name_start..j]).into_owned(); + i = j + 1; + if let Some(ch) = crate::stdlib::unicodedata_mod::name_to_char(&name) { + out.push(ch as u32); + continue; + } + i = ctx.on_error(&mut out, start, i, "unknown Unicode character name")?; + continue; + } + i = j; + } + i = ctx.on_error(&mut out, start, i, message)?; + } + _ => { + if warn.is_none() { + warn = Some(format!("invalid escape sequence '\\{}'", c as char)); + } + out.push(u32::from(b'\\')); + out.push(u32::from(c)); + } + } + } + Ok((Object::str_from_codepoints(out), consumed, warn)) +} + +/// Faithful port of CPython's `_PyUnicode_DecodeRawUnicodeEscapeStateful`. +pub fn raw_unicode_escape_decode( + data: &[u8], + errors: &str, + final_: bool, +) -> Result<(Object, usize), RuntimeError> { + let mut ctx = DecCtx::new("rawunicodeescape", errors, data); + let mut out: Vec = Vec::with_capacity(data.len()); + let mut consumed = data.len(); + let hexval = |c: u8| -> Option { + match c { + b'0'..=b'9' => Some(u32::from(c - b'0')), + b'a'..=b'f' => Some(u32::from(c - b'a') + 10), + b'A'..=b'F' => Some(u32::from(c - b'A') + 10), + _ => None, + } + }; + let mut i = 0usize; + 'outer: while i < ctx.input.len() { + let c = ctx.input[i]; + i += 1; + // A non-backslash — or a trailing backslash in final mode — is a + // Unicode ordinal (latin-1 identity). + if c != b'\\' || (i >= ctx.input.len() && final_) { + out.push(u32::from(c)); + continue; + } + let start = i - 1; + if i >= ctx.input.len() { + // !final: leave the trailing backslash unconsumed. + consumed = start; + break; + } + let c = ctx.input[i]; + i += 1; + let (count, message) = match c { + b'u' => (4usize, "truncated \\uXXXX escape"), + b'U' => (8, "truncated \\UXXXXXXXX escape"), + _ => { + out.push(u32::from(b'\\')); + out.push(u32::from(c)); + continue; + } + }; + let mut ch: u32 = 0; + let mut k = 0usize; + loop { + if k == count { + break; + } + if i >= ctx.input.len() { + if !final_ { + consumed = start; + break 'outer; + } + i = ctx.on_error(&mut out, start, i, message)?; + continue 'outer; + } + match hexval(ctx.input[i]) { + Some(v) => ch = (ch << 4) + v, + None => { + i = ctx.on_error(&mut out, start, i, message)?; + continue 'outer; + } + } + i += 1; + k += 1; + } + if ch > 0x0010_FFFF { + i = ctx.on_error(&mut out, start, i, "\\Uxxxxxxxx out of range")?; + continue; + } + out.push(ch); + } + Ok((Object::str_from_codepoints(out), consumed)) +} + +// --------------------------------------------------------------------------- +// Charmap (single-byte) codecs +// --------------------------------------------------------------------------- + +/// Sentinel for an unmapped position in a 256-entry charmap decode table +/// (CPython's `Lib/encodings/*.py` tables use `'\ufffe'` the same way). +pub const CHARMAP_UNDEFINED: u32 = 0xFFFE; + +/// Charmap decode: `table[b]` is the code point for byte `b`, +/// [`CHARMAP_UNDEFINED`] marks an unmapped position. Runs the full error +/// handler protocol (codec name `'charmap'`, like CPython's +/// `charmap_decode`). +pub fn charmap_decode_table( + data: &[u8], + errors: &str, + table: &[u32; 256], +) -> Result<(Object, usize), RuntimeError> { + let mut ctx = DecCtx::new("charmap", errors, data); + let mut out: Vec = Vec::with_capacity(data.len()); + let mut i = 0usize; + while i < ctx.input.len() { + let cp = table[ctx.input[i] as usize]; + if cp == CHARMAP_UNDEFINED { + i = ctx.on_error(&mut out, i, i + 1, "character maps to ")?; + } else { + out.push(cp); + i += 1; + } + } + let consumed = ctx.input.len(); + Ok((Object::str_from_codepoints(out), consumed)) +} + +/// Charmap encode via the reverse of a 256-entry decode table. Runs the +/// full error handler protocol; handler text replacements are re-encoded +/// through the same charmap (CPython `charmap_encode` semantics). +pub fn charmap_encode_table( + cps: &[u32], + errors: &str, + table: &[u32; 256], +) -> Result, RuntimeError> { + let mut rev = std::collections::HashMap::with_capacity(256); + for (b, &cp) in table.iter().enumerate() { + if cp != CHARMAP_UNDEFINED { + rev.entry(cp).or_insert(b as u8); + } + } + let mut ctx = EncCtx::new("charmap", errors, cps); + encode_loop( + &mut ctx, + "character maps to ", + |cp, out| match rev.get(&cp) { + Some(&b) => { + out.push(b); + true + } + None => false, + }, + ) +} + +// --------------------------------------------------------------------------- +// UTF-8 decoder +// --------------------------------------------------------------------------- + +/// CPython's stateful UTF-8 decode: returns the decoded text and the number +/// of input bytes consumed (< len when `!final_` and the input ends in an +/// incomplete sequence). +pub fn utf8_decode( + data: &[u8], + errors: &str, + final_: bool, +) -> Result<(Object, usize), RuntimeError> { + utf8_decode_named(data, errors, final_, "utf-8") +} + +/// [`utf8_decode`] with an explicit error-payload encoding name (the +/// `utf-8-sig` wrapper reports errors as `utf-8-sig`... CPython reports +/// plain `utf-8`, so this is used for both). +fn utf8_decode_named( + data: &[u8], + errors: &str, + final_: bool, + name: &str, +) -> Result<(Object, usize), RuntimeError> { + let mut ctx = DecCtx::new(name, errors, data); + let mut out: Vec = Vec::with_capacity(data.len()); + let mut i = 0usize; + loop { + let s = &ctx.input; + let n = s.len(); + if i >= n { + break; + } + let b = s[i]; + if b < 0x80 { + out.push(u32::from(b)); + i += 1; + continue; + } + // Multibyte sequence — port of `stringlib/codecs.h utf8_decode`. + enum Scan { + Ok(u32, usize), + Err(usize, &'static str), // span, reason + Incomplete(usize), // bytes available in the partial seq + } + let is_cont = |x: u8| (0x80..=0xBF).contains(&x); + let scan = if b < 0xC2 { + // \x80-\xBF stray continuation, \xC0-\xC1 overlong. + Scan::Err(1, "invalid start byte") + } else if b < 0xE0 { + if i + 1 >= n { + Scan::Incomplete(1) + } else if !is_cont(s[i + 1]) { + Scan::Err(1, "invalid continuation byte") + } else { + Scan::Ok( + ((u32::from(b) & 0x1F) << 6) | (u32::from(s[i + 1]) & 0x3F), + 2, + ) + } + } else if b < 0xF0 { + if i + 1 >= n { + Scan::Incomplete(1) + } else { + let b2 = s[i + 1]; + if !is_cont(b2) || (if b2 < 0xA0 { b == 0xE0 } else { b == 0xED }) { + Scan::Err(1, "invalid continuation byte") + } else if i + 2 >= n { + Scan::Incomplete(2) + } else if !is_cont(s[i + 2]) { + Scan::Err(2, "invalid continuation byte") + } else { + Scan::Ok( + ((u32::from(b) & 0x0F) << 12) + | ((u32::from(b2) & 0x3F) << 6) + | (u32::from(s[i + 2]) & 0x3F), + 3, + ) + } + } + } else if b < 0xF5 { + if i + 1 >= n { + Scan::Incomplete(1) + } else { + let b2 = s[i + 1]; + if !is_cont(b2) || (if b2 < 0x90 { b == 0xF0 } else { b == 0xF4 }) { + Scan::Err(1, "invalid continuation byte") + } else if i + 2 >= n { + Scan::Incomplete(2) + } else if !is_cont(s[i + 2]) { + Scan::Err(2, "invalid continuation byte") + } else if i + 3 >= n { + Scan::Incomplete(3) + } else if !is_cont(s[i + 3]) { + Scan::Err(3, "invalid continuation byte") + } else { + Scan::Ok( + ((u32::from(b) & 0x07) << 18) + | ((u32::from(b2) & 0x3F) << 12) + | ((u32::from(s[i + 2]) & 0x3F) << 6) + | (u32::from(s[i + 3]) & 0x3F), + 4, + ) + } + } + } else { + Scan::Err(1, "invalid start byte") + }; + match scan { + Scan::Ok(cp, len) => { + out.push(cp); + i += len; + } + Scan::Incomplete(avail) => { + if !final_ { + // Leave the partial sequence for the next chunk. + return Ok((Object::str_from_codepoints(out), i)); + } + let end = i + avail; + i = ctx.on_error( + &mut out, + i, + end.min(ctx.input.len()), + "unexpected end of data", + )?; + } + Scan::Err(span, reason) => { + // CPython special case: a truncated surrogate `ED A0-BF` at + // the very end of a non-final chunk is *incomplete*, not an + // error (the next chunk may extend it... it can't become + // valid, but `surrogatepass` needs the full 3 bytes). + if !final_ + && b == 0xED + && i + 2 == ctx.input.len() + && (0xA0..=0xBF).contains(&ctx.input[i + 1]) + { + return Ok((Object::str_from_codepoints(out), i)); + } + i = ctx.on_error(&mut out, i, i + span, reason)?; + } + } + } + let consumed = ctx.input.len(); + Ok((Object::str_from_codepoints(out), consumed)) +} + +// --------------------------------------------------------------------------- +// UTF-16 / UTF-32 decoders +// --------------------------------------------------------------------------- + +/// CPython's `PyUnicode_DecodeUTF16Stateful`: `byteorder` < 0 is LE, > 0 is +/// BE, 0 sniffs a BOM (defaulting to native/LE). Returns the decoded text, +/// bytes consumed, and the (possibly BOM-updated) byte order. +pub fn utf16_decode( + data: &[u8], + errors: &str, + mut byteorder: i32, + final_: bool, +) -> Result<(Object, usize, i32), RuntimeError> { + let mut start = 0usize; + if byteorder == 0 && data.len() >= 2 { + let bom = (u32::from(data[1]) << 8) | u32::from(data[0]); + if bom == 0xFEFF { + start = 2; + byteorder = -1; + } else if bom == 0xFFFE { + start = 2; + byteorder = 1; + } + } + let big = byteorder > 0; + let encoding = if big { "utf-16-be" } else { "utf-16-le" }; + let mut ctx = DecCtx::new(encoding, errors, data); + let mut out: Vec = Vec::with_capacity(data.len() / 2); + let mut i = start; + loop { + let s = &ctx.input; + let n = s.len(); + if i >= n { + break; + } + if n - i < 2 { + // Odd trailing byte. + if !final_ { + return Ok((Object::str_from_codepoints(out), i, byteorder)); + } + i = ctx.on_error(&mut out, i, n, "truncated data")?; + continue; + } + let rd = |s: &[u8], j: usize| -> u32 { + if big { + (u32::from(s[j]) << 8) | u32::from(s[j + 1]) + } else { + (u32::from(s[j + 1]) << 8) | u32::from(s[j]) + } + }; + let u = rd(s, i); + if !(0xD800..=0xDFFF).contains(&u) { + out.push(u); + i += 2; + continue; + } + if u >= 0xDC00 { + // Lone low surrogate first: "illegal encoding", span 2. + i = ctx.on_error(&mut out, i, i + 2, "illegal encoding")?; + continue; + } + // High surrogate: need the pair. + if n - i < 4 { + if !final_ { + return Ok((Object::str_from_codepoints(out), i, byteorder)); + } + i = ctx.on_error(&mut out, i, n, "unexpected end of data")?; + continue; + } + let u2 = rd(s, i + 2); + if (0xDC00..=0xDFFF).contains(&u2) { + out.push(0x1_0000 + ((u - 0xD800) << 10) + (u2 - 0xDC00)); + i += 4; + } else { + i = ctx.on_error(&mut out, i, i + 2, "illegal UTF-16 surrogate")?; + } + } + let consumed = ctx.input.len(); + Ok((Object::str_from_codepoints(out), consumed, byteorder)) +} + +/// CPython's `PyUnicode_DecodeUTF32Stateful` (same byteorder protocol). +pub fn utf32_decode( + data: &[u8], + errors: &str, + mut byteorder: i32, + final_: bool, +) -> Result<(Object, usize, i32), RuntimeError> { + let mut start = 0usize; + if byteorder == 0 && data.len() >= 4 { + if data[..4] == [0xFF, 0xFE, 0x00, 0x00] { + start = 4; + byteorder = -1; + } else if data[..4] == [0x00, 0x00, 0xFE, 0xFF] { + start = 4; + byteorder = 1; + } + } + let big = byteorder > 0; + let encoding = if big { "utf-32-be" } else { "utf-32-le" }; + let mut ctx = DecCtx::new(encoding, errors, data); + let mut out: Vec = Vec::with_capacity(data.len() / 4); + let mut i = start; + loop { + let s = &ctx.input; + let n = s.len(); + if i >= n { + break; + } + if n - i < 4 { + if !final_ { + return Ok((Object::str_from_codepoints(out), i, byteorder)); + } + i = ctx.on_error(&mut out, i, n, "truncated data")?; + continue; + } + let v = if big { + u32::from_be_bytes([s[i], s[i + 1], s[i + 2], s[i + 3]]) + } else { + u32::from_le_bytes([s[i], s[i + 1], s[i + 2], s[i + 3]]) + }; + if (0xD800..=0xDFFF).contains(&v) { + i = ctx.on_error( + &mut out, + i, + i + 4, + "code point in surrogate code point range(0xd800, 0xe000)", + )?; + } else if v < 0x11_0000 { + out.push(v); + i += 4; + } else { + i = ctx.on_error(&mut out, i, i + 4, "code point not in range(0x110000)")?; + } + } + let consumed = ctx.input.len(); + Ok((Object::str_from_codepoints(out), consumed, byteorder)) +} + +// --------------------------------------------------------------------------- +// ASCII / Latin-1 decoders +// --------------------------------------------------------------------------- + +pub fn ascii_decode(data: &[u8], errors: &str) -> Result<(Object, usize), RuntimeError> { + let mut ctx = DecCtx::new("ascii", errors, data); + let mut out: Vec = Vec::with_capacity(data.len()); + let mut i = 0usize; + while i < ctx.input.len() { + let b = ctx.input[i]; + if b < 0x80 { + out.push(u32::from(b)); + i += 1; + } else { + i = ctx.on_error(&mut out, i, i + 1, "ordinal not in range(128)")?; + } + } + let consumed = ctx.input.len(); + Ok((Object::str_from_codepoints(out), consumed)) +} + +pub fn latin1_decode(data: &[u8], _errors: &str) -> Result<(Object, usize), RuntimeError> { + // Latin-1 decode can never fail: bytes are ordinals. + let s: String = data.iter().map(|&b| b as char).collect(); + Ok((Object::from_str(s), data.len())) +} + +// --------------------------------------------------------------------------- +// UTF-7 decoder +// --------------------------------------------------------------------------- + +const fn is_base64(c: u8) -> bool { + c.is_ascii_alphanumeric() || c == b'+' || c == b'/' +} + +fn from_base64(c: u8) -> u32 { + match c { + b'A'..=b'Z' => u32::from(c - b'A'), + b'a'..=b'z' => u32::from(c - b'a') + 26, + b'0'..=b'9' => u32::from(c - b'0') + 52, + b'+' => 62, + _ => 63, + } +} + +const B64_CHARS: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/// Port of `PyUnicode_DecodeUTF7Stateful`. +pub fn utf7_decode( + data: &[u8], + errors: &str, + final_: bool, +) -> Result<(Object, usize), RuntimeError> { + let mut ctx = DecCtx::new("utf7", errors, data); + let mut out: Vec = Vec::with_capacity(data.len()); + + let mut in_shift = false; + let mut shift_out_start = 0usize; // output length at shift start + let mut start_in_pos = 0usize; // input index of the '+' opening the shift + let mut base64bits: u32 = 0; + let mut base64buffer: u64 = 0; + let mut surrogate: u32 = 0; + + let mut i = 0usize; + 'outer: while i < ctx.input.len() { + let ch = ctx.input[i]; + if in_shift { + if is_base64(ch) { + base64buffer = (base64buffer << 6) | u64::from(from_base64(ch)); + base64bits += 6; + i += 1; + if base64bits >= 16 { + let out_ch = ((base64buffer >> (base64bits - 16)) & 0xFFFF) as u32; + base64bits -= 16; + base64buffer &= (1u64 << base64bits) - 1; + if surrogate != 0 { + if (0xDC00..=0xDFFF).contains(&out_ch) { + out.push(0x1_0000 + ((surrogate - 0xD800) << 10) + (out_ch - 0xDC00)); + surrogate = 0; + continue; + } + out.push(surrogate); + surrogate = 0; + } + if (0xD800..=0xDBFF).contains(&out_ch) { + surrogate = out_ch; + } else { + out.push(out_ch); + } + } + } else { + // Leaving a base-64 section. + in_shift = false; + if base64bits > 0 { + if base64bits >= 6 { + i += 1; + base64bits = 0; + base64buffer = 0; + surrogate = 0; + i = ctx.on_error( + &mut out, + start_in_pos, + i, + "partial character in shift sequence", + )?; + continue; + } else if base64buffer != 0 { + i += 1; + base64bits = 0; + base64buffer = 0; + surrogate = 0; + i = ctx.on_error( + &mut out, + start_in_pos, + i, + "non-zero padding bits in shift sequence", + )?; + continue; + } + } + base64bits = 0; + base64buffer = 0; + if surrogate != 0 && ch <= 127 && ch != b'+' { + out.push(surrogate); + } + surrogate = 0; + if ch == b'-' { + i += 1; // '-' is absorbed + } + } + } else if ch == b'+' { + start_in_pos = i; + i += 1; + if i < ctx.input.len() && ctx.input[i] == b'-' { + i += 1; + out.push(u32::from(b'+')); + } else if i < ctx.input.len() && !is_base64(ctx.input[i]) { + i += 1; + i = ctx.on_error(&mut out, start_in_pos, i, "ill-formed sequence")?; + } else { + in_shift = true; + surrogate = 0; + shift_out_start = out.len(); + base64bits = 0; + base64buffer = 0; + } + } else if ch <= 127 { + out.push(u32::from(ch)); + i += 1; + } else { + start_in_pos = i; + i += 1; + i = ctx.on_error(&mut out, start_in_pos, i, "unexpected special character")?; + } + continue 'outer; + } + + // End of input. + if in_shift && final_ { + in_shift = false; + if surrogate != 0 || base64bits >= 6 || (base64bits > 0 && base64buffer != 0) { + let end = ctx.input.len(); + i = ctx.on_error(&mut out, start_in_pos, end, "unterminated shift sequence")?; + // A skipping handler may resume mid-input; keep it simple and + // decode the remainder as direct characters. + while i < ctx.input.len() { + let ch = ctx.input[i]; + if ch <= 127 && ch != b'+' { + out.push(u32::from(ch)); + i += 1; + } else { + break; + } + } + } + } + + if in_shift { + // Non-final chunk ends mid-shift: back off to the shift start. + out.truncate(shift_out_start); + return Ok((Object::str_from_codepoints(out), start_in_pos)); + } + let consumed = ctx.input.len().max(i).min(ctx.input.len()); + Ok((Object::str_from_codepoints(out), consumed)) +} + +// --------------------------------------------------------------------------- +// Encode driver +// --------------------------------------------------------------------------- + +/// Mutable encode context: the handler may replace `exc.object`. +struct EncCtx { + encoding: String, + errors: String, + handler: Option, + input: Vec, +} + +impl EncCtx { + fn new(encoding: &str, errors: &str, input: &[u32]) -> Self { + EncCtx { + encoding: encoding.to_owned(), + errors: errors.to_owned(), + handler: None, + input: input.to_vec(), + } + } + + fn handler(&mut self) -> Result { + if self.handler.is_none() { + self.handler = Some(resolve_handler(&self.errors)?); + } + Ok(self.handler.clone().unwrap()) + } + + fn error_object(&self, start: usize, end: usize, reason: &str) -> Object { + crate::builtin_types::make_unicode_encode_error_obj( + &self.encoding, + Object::str_from_codepoints(self.input.clone()), + start, + end, + reason, + ) + } + + fn strict(&self, start: usize, end: usize, reason: &str) -> RuntimeError { + RuntimeError::PyException(crate::error::PyException::new( + self.error_object(start, end, reason), + )) + } + + /// Resolve an encode error over `input[start..end]`. Returns the + /// replacement (text still to be encoded by the caller's codec, or raw + /// bytes) and the position to continue from. + fn on_error( + &mut self, + start: usize, + end: usize, + reason: &str, + ) -> Result<(Replacement, usize), RuntimeError> { + match self.handler()? { + Handler::Strict => Err(self.strict(start, end, reason)), + Handler::Ignore => Ok((Replacement::Bytes(Vec::new()), end)), + // '?' per unencodable point, encoded through the codec (2 bytes + // per '?' in UTF-16). + Handler::Replace => Ok((Replacement::Ascii("?".repeat(end - start)), end)), + Handler::BackslashReplace => { + let mut s = String::new(); + for &cp in &self.input[start..end] { + if cp <= 0xFF { + s.push_str(&format!("\\x{cp:02x}")); + } else if cp <= 0xFFFF { + s.push_str(&format!("\\u{cp:04x}")); + } else { + s.push_str(&format!("\\U{cp:08x}")); + } + } + Ok((Replacement::Ascii(s), end)) + } + Handler::XmlCharRefReplace => { + let mut s = String::new(); + for &cp in &self.input[start..end] { + s.push_str(&format!("&#{cp};")); + } + Ok((Replacement::Ascii(s), end)) + } + Handler::NameReplace => { + let mut s = String::new(); + for &cp in &self.input[start..end] { + match char::from_u32(cp).and_then(crate::stdlib::unicodedata_mod::char_name) { + Some(name) => s.push_str(&format!("\\N{{{name}}}")), + None if cp <= 0xFF => s.push_str(&format!("\\x{cp:02x}")), + None if cp <= 0xFFFF => s.push_str(&format!("\\u{cp:04x}")), + None => s.push_str(&format!("\\U{cp:08x}")), + } + } + Ok((Replacement::Ascii(s), end)) + } + Handler::SurrogateEscape => { + let mut b = Vec::with_capacity(end - start); + for (j, &cp) in self.input[start..end].iter().enumerate() { + if (0xDC80..=0xDCFF).contains(&cp) { + b.push((cp - 0xDC00) as u8); + } else { + // CPython smuggles the leading DC80-DCFF bytes inline + // and reports the error from the first non-smuggleable + // surrogate (`exc.start` past the handled prefix). + return Err(self.strict(start + j, end, reason)); + } + } + Ok((Replacement::Bytes(b), end)) + } + Handler::SurrogatePass => { + let key = standard_key(&self.encoding); + let mut b = Vec::new(); + for &cp in &self.input[start..end] { + if !(0xD800..=0xDFFF).contains(&cp) { + return Err(self.strict(start, end, reason)); + } + match key { + "utf8" => { + b.push(0xE0 | (cp >> 12) as u8); + b.push(0x80 | ((cp >> 6) & 0x3F) as u8); + b.push(0x80 | (cp & 0x3F) as u8); + } + "utf16le" => b.extend_from_slice(&(cp as u16).to_le_bytes()), + "utf16be" => b.extend_from_slice(&(cp as u16).to_be_bytes()), + "utf32le" => b.extend_from_slice(&cp.to_le_bytes()), + "utf32be" => b.extend_from_slice(&cp.to_be_bytes()), + _ => return Err(self.strict(start, end, reason)), + } + } + Ok((Replacement::Bytes(b), end)) + } + Handler::Custom(h) => { + let exc = self.error_object(start, end, reason); + let res = call_custom(&h, &exc)?; + let items: Vec = match &res { + Object::Tuple(t) if t.len() == 2 => t.to_vec(), + _ => { + return Err(type_error( + "encoding error handler must return (str/bytes, int) tuple", + )) + } + }; + let rep = if let Some(cps) = str_codepoints(&items[0]) { + Replacement::Text(cps) + } else if let Some(b) = items[0].as_bytes_view() { + Replacement::CustomBytes(b) + } else { + return Err(type_error( + "encoding error handler must return (str/bytes, int) tuple", + )); + }; + let mut newpos = match &items[1] { + Object::Int(i) => *i, + _ => { + return Err(type_error( + "encoding error handler must return (str/bytes, int) tuple", + )) + } + }; + let o = get_attr(&exc, "object")?; + self.input = str_codepoints(&o) + .ok_or_else(|| type_error("object attribute must be unicode"))?; + let insize = self.input.len() as i64; + if newpos < 0 { + newpos += insize; + } + if newpos < 0 || newpos > insize { + return Err(crate::error::index_error(format!( + "position {newpos} from error handler out of bounds" + ))); + } + Ok((rep, newpos as usize)) + } + } + } +} + +/// An encode error handler's replacement value. +#[derive(Debug)] +pub enum Replacement { + /// Text that must be re-encoded by the calling codec (a custom + /// handler's `str` result). + Text(Vec), + /// ASCII text from a built-in `backslashreplace`-style handler, + /// re-encoded through the calling codec. + Ascii(String), + /// Raw bytes emitted verbatim (PEP 383 surrogateescape / + /// surrogatepass — CPython writes these inline even when they break + /// UTF-16/32 unit alignment). + Bytes(Vec), + /// Bytes from a *custom* handler; must keep the output unit-aligned. + CustomBytes(Vec), +} + +// --------------------------------------------------------------------------- +// Encoders +// --------------------------------------------------------------------------- + +/// Encode with a per-code-point emitter: `emit` returns `true` if it encoded +/// the point, `false` to run the error handler. Handler `Text` replacements +/// are re-encoded through `emit` (a still-unencodable point raises). +/// `unit` is the codec's code-unit width: CPython's UTF-16/32 encoders +/// reject bytes replacements that aren't a whole number of units. +/// `ascii_repl`: the UTF encoders only accept *ASCII* str replacements +/// (CPython re-raises the original error otherwise); charmap-style codecs +/// re-encode the replacement through the map instead. +fn encode_loop_units( + ctx: &mut EncCtx, + reason: &str, + unit: usize, + ascii_repl: bool, + mut emit: impl FnMut(u32, &mut Vec) -> bool, +) -> Result, RuntimeError> { + let mut out: Vec = Vec::with_capacity(ctx.input.len()); + let mut i = 0usize; + while i < ctx.input.len() { + let cp = ctx.input[i]; + if emit(cp, &mut out) { + i += 1; + continue; + } + // Collect the full run of unencodable points (CPython batches them + // into a single handler call). + let start = i; + let mut end = i + 1; + while end < ctx.input.len() && { + let mut probe = Vec::new(); + !emit_probe(&mut emit, ctx.input[end], &mut probe) + } { + end += 1; + } + let (rep, newpos) = ctx.on_error(start, end, reason)?; + match rep { + // Built-in byte replacements (surrogateescape/surrogatepass) are + // emitted verbatim — CPython writes them inline even when they + // break UTF-16/32 unit alignment. + Replacement::Bytes(b) => out.extend(b), + Replacement::CustomBytes(b) => { + // A custom handler's bytes must keep the output unit-aligned. + if unit > 1 && b.len() % unit != 0 { + return Err(ctx.strict(start, start + 1, reason)); + } + out.extend(b) + } + // Built-in text replacements (backslashreplace/…) are pure ASCII + // and get encoded through the codec itself (`\u` in UTF-16 is + // 4 bytes, not 2). + Replacement::Ascii(s) => { + for c in s.chars() { + if !emit(c as u32, &mut out) { + return Err(ctx.strict(start, end, reason)); + } + } + } + Replacement::Text(cps) => { + if ascii_repl && cps.iter().any(|&rc| rc >= 0x80) { + // CPython's UTF encoders only accept ASCII str + // replacements; anything else re-raises the original + // error at the handler position. + return Err(ctx.strict(start, start + 1, reason)); + } + for &rc in &cps { + if !emit(rc, &mut out) { + return Err(ctx.strict(start, end, reason)); + } + } + } + } + i = newpos; + } + Ok(out) +} + +/// [`encode_loop_units`] for single-byte codecs (any replacement length, +/// replacements re-encoded through the codec itself). +fn encode_loop( + ctx: &mut EncCtx, + reason: &str, + emit: impl FnMut(u32, &mut Vec) -> bool, +) -> Result, RuntimeError> { + encode_loop_units(ctx, reason, 1, false, emit) +} + +/// Probe whether `emit` accepts `cp` without keeping its output. +fn emit_probe( + emit: &mut impl FnMut(u32, &mut Vec) -> bool, + cp: u32, + scratch: &mut Vec, +) -> bool { + emit(cp, scratch) +} + +pub fn utf8_encode(cps: &[u32], errors: &str) -> Result, RuntimeError> { + let mut ctx = EncCtx::new("utf-8", errors, cps); + encode_loop_units( + &mut ctx, + "surrogates not allowed", + 1, + true, + |cp, out| match char::from_u32(cp) { + Some(ch) => { + let mut buf = [0u8; 4]; + out.extend_from_slice(ch.encode_utf8(&mut buf).as_bytes()); + true + } + None => false, + }, + ) +} + +pub fn ascii_encode(cps: &[u32], errors: &str) -> Result, RuntimeError> { + let mut ctx = EncCtx::new("ascii", errors, cps); + encode_loop(&mut ctx, "ordinal not in range(128)", |cp, out| { + if cp < 0x80 { + out.push(cp as u8); + true + } else { + false + } + }) +} + +pub fn latin1_encode(cps: &[u32], errors: &str) -> Result, RuntimeError> { + let mut ctx = EncCtx::new("latin-1", errors, cps); + encode_loop(&mut ctx, "ordinal not in range(256)", |cp, out| { + if cp < 0x100 { + out.push(cp as u8); + true + } else { + false + } + }) +} + +/// UTF-16 encode. `byteorder` < 0 LE, > 0 BE, 0 native-with-BOM. +pub fn utf16_encode(cps: &[u32], errors: &str, byteorder: i32) -> Result, RuntimeError> { + let big = byteorder > 0; + let name = if byteorder == 0 { + "utf-16" + } else if big { + "utf-16-be" + } else { + "utf-16-le" + }; + let mut ctx = EncCtx::new(name, errors, cps); + let push16 = move |out: &mut Vec, u: u16| { + if big { + out.extend_from_slice(&u.to_be_bytes()); + } else { + out.extend_from_slice(&u.to_le_bytes()); + } + }; + let mut body = encode_loop_units(&mut ctx, "surrogates not allowed", 2, true, |cp, out| { + if (0xD800..=0xDFFF).contains(&cp) { + false + } else if cp <= 0xFFFF { + push16(out, cp as u16); + true + } else { + let v = cp - 0x1_0000; + push16(out, 0xD800 + (v >> 10) as u16); + push16(out, 0xDC00 + (v & 0x3FF) as u16); + true + } + })?; + if byteorder == 0 { + let mut with_bom = Vec::with_capacity(body.len() + 2); + with_bom.extend_from_slice(&[0xFF, 0xFE]); // native (LE) BOM + with_bom.append(&mut body); + return Ok(with_bom); + } + Ok(body) +} + +/// UTF-32 encode (same byteorder protocol). +pub fn utf32_encode(cps: &[u32], errors: &str, byteorder: i32) -> Result, RuntimeError> { + let big = byteorder > 0; + let name = if byteorder == 0 { + "utf-32" + } else if big { + "utf-32-be" + } else { + "utf-32-le" + }; + let mut ctx = EncCtx::new(name, errors, cps); + let push32 = move |out: &mut Vec, u: u32| { + if big { + out.extend_from_slice(&u.to_be_bytes()); + } else { + out.extend_from_slice(&u.to_le_bytes()); + } + }; + let mut body = encode_loop_units(&mut ctx, "surrogates not allowed", 4, true, |cp, out| { + if (0xD800..=0xDFFF).contains(&cp) { + false + } else { + push32(out, cp); + true + } + })?; + if byteorder == 0 { + let mut with_bom = Vec::with_capacity(body.len() + 4); + with_bom.extend_from_slice(&[0xFF, 0xFE, 0x00, 0x00]); + with_bom.append(&mut body); + return Ok(with_bom); + } + Ok(body) +} + +/// Port of `_PyUnicode_EncodeUTF7` (conservative sets; `set O` and +/// whitespace are base64-encoded, matching `_codecs.utf_7_encode`). +pub fn utf7_encode(cps: &[u32], _errors: &str) -> Result, RuntimeError> { + // Category table from CPython: 0 = Set D (direct), 1 = Set O, + // 2 = whitespace, 3 = special. + const CAT: [u8; 128] = [ + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3, // + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, // + 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 3, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, // + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1, // + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 3, + ]; + // `_codecs.utf_7_encode` calls with base64SetO=0, base64WhiteSpace=0, + // i.e. Set O *and* whitespace are encoded directly = false/true? + // CPython: directO = !base64SetO (true), directWS = !base64WhiteSpace + // (true) — Set O and whitespace pass through directly. + let encode_direct = |cp: u32| cp > 0 && cp < 128 && matches!(CAT[cp as usize], 0..=2); + let is_b64 = |cp: u32| cp < 128 && is_base64(cp as u8); + + let mut out: Vec = Vec::with_capacity(cps.len() * 3); + let mut in_shift = false; + let mut base64bits: u32 = 0; + let mut base64buffer: u64 = 0; + + let encode_char = |ch: u32, out: &mut Vec, base64bits: &mut u32, base64buffer: &mut u64| { + let push_units = |u: u32, out: &mut Vec, bits: &mut u32, buf: &mut u64| { + *bits += 16; + *buf = (*buf << 16) | u64::from(u); + while *bits >= 6 { + out.push(B64_CHARS[((*buf >> (*bits - 6)) & 0x3F) as usize]); + *bits -= 6; + } + }; + if ch >= 0x1_0000 { + let v = ch - 0x1_0000; + push_units(0xD800 + (v >> 10), out, base64bits, base64buffer); + push_units(0xDC00 + (v & 0x3FF), out, base64bits, base64buffer); + } else { + push_units(ch, out, base64bits, base64buffer); + } + }; + + for &ch in cps { + if in_shift { + if encode_direct(ch) { + if base64bits > 0 { + out.push(B64_CHARS[((base64buffer << (6 - base64bits)) & 0x3F) as usize]); + base64buffer = 0; + base64bits = 0; + } + in_shift = false; + if is_b64(ch) || ch == u32::from(b'-') { + out.push(b'-'); + } + out.push(ch as u8); + } else { + encode_char(ch, &mut out, &mut base64bits, &mut base64buffer); + } + } else if ch == u32::from(b'+') { + out.push(b'+'); + out.push(b'-'); + } else if encode_direct(ch) { + out.push(ch as u8); + } else { + out.push(b'+'); + in_shift = true; + encode_char(ch, &mut out, &mut base64bits, &mut base64buffer); + } + } + if base64bits > 0 { + out.push(B64_CHARS[((base64buffer << (6 - base64bits)) & 0x3F) as usize]); + } + if in_shift { + out.push(b'-'); + } + Ok(out) +} diff --git a/crates/weavepy-vm/src/stdlib/codecs_mod.rs b/crates/weavepy-vm/src/stdlib/codecs_mod.rs index 44d4fbc..598be60 100644 --- a/crates/weavepy-vm/src/stdlib/codecs_mod.rs +++ b/crates/weavepy-vm/src/stdlib/codecs_mod.rs @@ -45,6 +45,11 @@ pub fn build(_cache: &ModuleCache) -> Rc { register(&mut d, "lookup", b_lookup); register(&mut d, "utf_8_encode", b_utf8_encode); register(&mut d, "utf_8_decode", b_utf8_decode); + register(&mut d, "utf_7_encode", b_utf7_encode); + register(&mut d, "utf_7_decode", b_utf7_decode); + register(&mut d, "utf_16_ex_decode", b_utf16_ex_decode); + register(&mut d, "utf_32_ex_decode", b_utf32_ex_decode); + register(&mut d, "readbuffer_encode", b_readbuffer_encode); register(&mut d, "utf_16_encode", b_utf16_encode); register(&mut d, "utf_16_decode", b_utf16_decode); register(&mut d, "utf_16_le_encode", b_utf16_le_encode); @@ -183,6 +188,15 @@ fn arg_bytes(args: &[Object], idx: usize, name: &str) -> Result, Runtime } } +/// Buffer *or* `str` argument (CPython's `s*` converter: a `str` argument +/// yields its UTF-8 bytes) — `unicode_escape_decode` and friends accept both. +fn arg_bytes_or_str_utf8(args: &[Object], idx: usize, name: &str) -> Result, RuntimeError> { + match args.get(idx) { + Some(Object::Str(s)) => Ok(s.as_bytes().to_vec()), + _ => arg_bytes(args, idx, name), + } +} + fn arg_errors(args: &[Object], idx: usize) -> String { match args.get(idx) { Some(Object::Str(s)) => s.to_string(), @@ -221,19 +235,96 @@ fn lookup_encoding(name: &str) -> Option<&'static Encoding> { "utf16be" => Encoding::for_label(b"utf-16be"), "windows1252" | "cp1252" | "1252" => Encoding::for_label(b"windows-1252"), "macroman" => Encoding::for_label(b"macintosh"), - "shiftjis" | "sjis" | "csshiftjis" => Encoding::for_label(b"shift_jis"), - "gb2312" | "gbk" | "936" => Encoding::for_label(b"gbk"), - "big5" | "csbig5" => Encoding::for_label(b"big5"), - "euckr" | "ksc56011987" => Encoding::for_label(b"euc-kr"), - "eucjp" | "ujis" => Encoding::for_label(b"euc-jp"), - // WHATWG only lists the hyphenated form, which our normaliser strips. - "iso2022jp" | "csiso2022jp" => Encoding::for_label(b"iso-2022-jp"), + // The CJK codecs live in frozen Python modules with CPython-parity + // tables and state machines (RFC 0050 WS3: `_codec_cjk_dbcs`, + // `_codec_cjk_ext`, `_codec_euc_jis_2004`). `encoding_rs` must never + // claim them: WHATWG's shift_jis index IS Windows-31J (cp932), its + // euc-kr IS the unified-hangul cp949, its big5 carries the HKSCS + // extensions, its iso-2022-jp state machine differs from CPython's, + // and it maps iso-2022-kr / hz labels onto the data-destroying + // "replacement" encoding. The catch-all `for_label` below is + // post-filtered for the same reason (labels like "csksc56011987" or + // "xsjis" also resolve to WHATWG CJK indices). + "iso2022jp" | "csiso2022jp" | "iso2022kr" | "csiso2022kr" | "hzgb2312" => None, // KOI8 Cyrillic — `encoding_rs` knows these, but only under the // hyphenated WHATWG labels our normaliser strips. "koi8r" | "cskoi8r" => Encoding::for_label(b"koi8-r"), "koi8u" => Encoding::for_label(b"koi8-u"), - _ => Encoding::for_label(normalised.as_bytes()), + _ => Encoding::for_label(normalised.as_bytes()).filter(|enc| { + !matches!( + enc.name(), + "Shift_JIS" + | "EUC-JP" + | "EUC-KR" + | "GBK" + | "gb18030" + | "Big5" + | "ISO-2022-JP" + | "replacement" + ) + }), + } +} + +// ---------- single-byte (charmap) codec tables ---------- + +/// Decode table (byte → code point, `CHARMAP_UNDEFINED` = unmapped) for a +/// single-byte codec, built lazily from `encoding_rs`'s index and cached +/// forever. `cp437` (absent from WHATWG) and `cp1252` (whose WHATWG index +/// wrongly fills CPython's five undefined slots) come from the local +/// CPython-shaped tables instead. +fn sbcs_decode_table(encoding: &str) -> Option<&'static [u32; 256]> { + use crate::stdlib::codecs_engine::CHARMAP_UNDEFINED; + use std::collections::HashMap; + use std::sync::{Mutex, OnceLock}; + + let key = encoding_key(encoding); + static CACHE: OnceLock>> = OnceLock::new(); + let cache = CACHE.get_or_init(|| Mutex::new(HashMap::new())); + if let Some(t) = cache.lock().unwrap().get(&key) { + return Some(*t); + } + let mut table = [CHARMAP_UNDEFINED; 256]; + for (i, slot) in table.iter_mut().take(0x80).enumerate() { + *slot = i as u32; + } + match key.as_str() { + "cp437" | "437" | "ibm437" => { + for (i, &c) in CP437_HIGH.iter().enumerate() { + table[0x80 + i] = c as u32; + } + } + "cp1252" | "windows1252" | "1252" => { + for (i, &c) in CP1252_HIGH.iter().enumerate() { + if let Some(c) = c { + table[0x80 + i] = c as u32; + } + } + } + // `ascii`/`latin1` have dedicated engine codecs (and their WHATWG + // labels alias the lenient windows-1252 superset, so the generic + // path below must never see them). + "ascii" | "latin1" | "iso88591" => return None, + _ => { + let enc = lookup_encoding(encoding)?; + // Reject non-single-byte codecs, and any label WHATWG smears + // onto windows-1252 (CPython's cp1252 differs — handled above). + if !enc.is_single_byte() || enc == encoding_rs::WINDOWS_1252 { + return None; + } + for b in 0x80..=0xFFu8 { + if let Some(s) = enc.decode_without_bom_handling_and_without_replacement(&[b]) { + let mut chars = s.chars(); + if let (Some(c), None) = (chars.next(), chars.next()) { + table[b as usize] = c as u32; + } + } + } + } } + let leaked: &'static [u32; 256] = Box::leak(Box::new(table)); + cache.lock().unwrap().insert(key, leaked); + Some(leaked) } // ---------- generic encode/decode dispatcher ---------- @@ -379,25 +470,23 @@ pub fn encode_codepoints( return encode_str(&s, encoding, errors); } let key = encoding_key(encoding); + use crate::stdlib::codecs_engine as engine; let out = match key.as_str() { - "utf8" => { - let mut out = Vec::with_capacity(cps.len()); - encode_utf8_codepoints(cps, errors, &mut out)?; - out - } + "utf8" => engine::utf8_encode(cps, errors)?, "utf8sig" => { let mut out = vec![0xEF, 0xBB, 0xBF]; - encode_utf8_codepoints(cps, errors, &mut out)?; + out.extend(engine::utf8_encode(cps, errors)?); out } - "ascii" => encode_charmap_codepoints(cps, errors, "ascii", 0x80)?, - "latin1" | "iso88591" => encode_charmap_codepoints(cps, errors, "latin-1", 0x100)?, - "utf16le" => encode_utf16_codepoints(cps, false, false, errors)?, - "utf16be" => encode_utf16_codepoints(cps, true, false, errors)?, - "utf16" => encode_utf16_codepoints(cps, false, true, errors)?, - "utf32le" => encode_utf32_codepoints(cps, false, false, errors)?, - "utf32be" => encode_utf32_codepoints(cps, true, false, errors)?, - "utf32" => encode_utf32_codepoints(cps, false, true, errors)?, + "ascii" => engine::ascii_encode(cps, errors)?, + "latin1" | "iso88591" => engine::latin1_encode(cps, errors)?, + "utf16le" => engine::utf16_encode(cps, errors, -1)?, + "utf16be" => engine::utf16_encode(cps, errors, 1)?, + "utf16" => engine::utf16_encode(cps, errors, 0)?, + "utf32le" => engine::utf32_encode(cps, errors, -1)?, + "utf32be" => engine::utf32_encode(cps, errors, 1)?, + "utf32" => engine::utf32_encode(cps, errors, 0)?, + "utf7" => engine::utf7_encode(cps, errors)?, // The escape codecs operate on raw code points, so lone surrogates // are representable (CPython encodes '\udfff' as the escape bytes). "rawunicodeescape" => { @@ -423,7 +512,22 @@ pub fn encode_codepoints( } out } + _ if sbcs_decode_table(encoding).is_some() => { + let table = sbcs_decode_table(encoding).expect("just checked"); + engine::charmap_encode_table(cps, errors, table)? + } _ => { + // Registry-backed codec (CJK, custom `codecs.register` codecs): + // hand the surrogate-bearing string to the Python codec whole so + // its own error-handler protocol runs (CPython never pre-screens + // surrogates for these). + if sbcs_decode_table(encoding).is_none() && lookup_encoding(encoding).is_none() { + if let Some(out) = + encode_via_registry_obj(Object::WStr(cps.into()), encoding, errors)? + { + return Ok(out); + } + } // Any other codec: encode maximal scalar runs through the normal // string engine and resolve each lone surrogate via the error // handler (`surrogatepass` is invalid for non-UTF codecs, so it @@ -463,140 +567,6 @@ pub fn encode_codepoints( Ok(out) } -/// Encode code points as UTF-8, resolving lone surrogates per `errors`. -fn encode_utf8_codepoints( - cps: &[u32], - errors: &str, - out: &mut Vec, -) -> Result<(), RuntimeError> { - for (i, &cp) in cps.iter().enumerate() { - if let Some(ch) = char::from_u32(cp) { - let mut buf = [0u8; 4]; - out.extend_from_slice(ch.encode_utf8(&mut buf).as_bytes()); - } else { - match errors { - // WTF-8 / CESU-8 three-byte form for the lone surrogate. - "surrogatepass" => { - out.push(0xE0 | (cp >> 12) as u8); - out.push(0x80 | ((cp >> 6) & 0x3F) as u8); - out.push(0x80 | (cp & 0x3F) as u8); - } - // PEP 383: U+DC80..U+DCFF map back to the original 0x80..0xFF. - "surrogateescape" if (0xDC80..=0xDCFF).contains(&cp) => { - out.push((cp - 0xDC00) as u8); - } - "ignore" => {} - "replace" => out.push(b'?'), - "backslashreplace" => out.extend_from_slice(format!("\\u{cp:04x}").as_bytes()), - "xmlcharrefreplace" => out.extend_from_slice(format!("&#{cp};").as_bytes()), - _ => return Err(surrogate_encode_error("utf-8", cps, i)), - } - } - } - Ok(()) -} - -/// Encode code points for a single-byte charmap codec (`ascii`, `latin-1`) -/// where `limit` is the exclusive upper bound of directly-encodable code -/// points (0x80 for ASCII, 0x100 for Latin-1). Lone surrogates resolve via -/// `errors` (PEP 383 `surrogateescape` maps U+DC80..U+DCFF to a raw byte). -fn encode_charmap_codepoints( - cps: &[u32], - errors: &str, - codec: &str, - limit: u32, -) -> Result, RuntimeError> { - let mut out = Vec::with_capacity(cps.len()); - for (i, &cp) in cps.iter().enumerate() { - if cp < limit { - out.push(cp as u8); - } else if (0xD800..=0xDFFF).contains(&cp) { - match errors { - "surrogateescape" if (0xDC80..=0xDCFF).contains(&cp) => { - out.push((cp - 0xDC00) as u8); - } - "ignore" => {} - "replace" => out.push(b'?'), - "backslashreplace" => out.extend_from_slice(format!("\\u{cp:04x}").as_bytes()), - "xmlcharrefreplace" => out.extend_from_slice(format!("&#{cp};").as_bytes()), - _ => return Err(surrogate_encode_error(codec, cps, i)), - } - } else { - // A scalar above the charmap range: defer to the normal engine for - // the canonical error/handler behaviour over this single point. - let s: String = char::from_u32(cp).into_iter().collect(); - out.extend(encode_str(&s, codec, errors)?); - } - } - Ok(out) -} - -/// Encode code points as UTF-16 (`big`-endian when set, BOM-prefixed when -/// `bom`). Lone surrogates pass through as their own 16-bit code unit under -/// `surrogatepass`; otherwise they raise. -fn encode_utf16_codepoints( - cps: &[u32], - big: bool, - bom: bool, - errors: &str, -) -> Result, RuntimeError> { - let mut out = Vec::with_capacity(cps.len() * 2 + 2); - let push_u16 = |out: &mut Vec, u: u16| { - if big { - out.extend_from_slice(&u.to_be_bytes()); - } else { - out.extend_from_slice(&u.to_le_bytes()); - } - }; - if bom { - push_u16(&mut out, 0xFEFF); - } - for (i, &cp) in cps.iter().enumerate() { - if (0xD800..=0xDFFF).contains(&cp) { - if errors == "surrogatepass" { - push_u16(&mut out, cp as u16); - } else { - return Err(surrogate_encode_error("utf-16", cps, i)); - } - } else if cp <= 0xFFFF { - push_u16(&mut out, cp as u16); - } else { - let v = cp - 0x1_0000; - push_u16(&mut out, 0xD800 + (v >> 10) as u16); - push_u16(&mut out, 0xDC00 + (v & 0x3FF) as u16); - } - } - Ok(out) -} - -/// Encode code points as UTF-32. Lone surrogates pass through under -/// `surrogatepass`; otherwise they raise. -fn encode_utf32_codepoints( - cps: &[u32], - big: bool, - bom: bool, - errors: &str, -) -> Result, RuntimeError> { - let mut out = Vec::with_capacity(cps.len() * 4 + 4); - let push_u32 = |out: &mut Vec, u: u32| { - if big { - out.extend_from_slice(&u.to_be_bytes()); - } else { - out.extend_from_slice(&u.to_le_bytes()); - } - }; - if bom { - push_u32(&mut out, 0xFEFF); - } - for (i, &cp) in cps.iter().enumerate() { - if (0xD800..=0xDFFF).contains(&cp) && errors != "surrogatepass" { - return Err(surrogate_encode_error("utf-32", cps, i)); - } - push_u32(&mut out, cp); - } - Ok(out) -} - /// `UnicodeEncodeError` for a lone surrogate at `pos` in a code-point sequence. /// The `.object` attribute keeps the surrogate-bearing `WStr` so the message /// names the real offending code point; type/positions/reason match CPython. @@ -619,6 +589,43 @@ pub fn decode_bytes_obj( errors: &str, ) -> Result { check_error_handler(errors)?; + // The UTF/ASCII/Latin-1 family routes through the unified engine + // (RFC 0050 WS2): every error handler — built-in *and* custom via + // `codecs.register_error` — resolves uniformly, and surrogate-producing + // handlers yield a `WStr` transparently. + use crate::stdlib::codecs_engine as engine; + let key = encoding_key(encoding); + match key.as_str() { + "utf8" => return Ok(engine::utf8_decode(bytes, errors, true)?.0), + "utf8sig" => { + let body = bytes.strip_prefix(&[0xEF, 0xBB, 0xBF][..]).unwrap_or(bytes); + return Ok(engine::utf8_decode(body, errors, true)?.0); + } + "ascii" => return Ok(engine::ascii_decode(bytes, errors)?.0), + "latin1" | "iso88591" => return Ok(engine::latin1_decode(bytes, errors)?.0), + "utf16" => return Ok(engine::utf16_decode(bytes, errors, 0, true)?.0), + "utf16le" => return Ok(engine::utf16_decode(bytes, errors, -1, true)?.0), + "utf16be" => return Ok(engine::utf16_decode(bytes, errors, 1, true)?.0), + "utf32" => return Ok(engine::utf32_decode(bytes, errors, 0, true)?.0), + "utf32le" => return Ok(engine::utf32_decode(bytes, errors, -1, true)?.0), + "utf32be" => return Ok(engine::utf32_decode(bytes, errors, 1, true)?.0), + "utf7" => return Ok(engine::utf7_decode(bytes, errors, true)?.0), + "unicodeescape" => { + let (obj, _, warn) = engine::unicode_escape_decode(bytes, errors, true)?; + if let Some(msg) = warn { + emit_deprecation(&msg)?; + } + return Ok(obj); + } + "rawunicodeescape" => return Ok(engine::raw_unicode_escape_decode(bytes, errors, true)?.0), + _ => { + // Single-byte codecs route through the charmap engine so + // custom handlers and surrogate-producing handlers work. + if let Some(table) = sbcs_decode_table(encoding) { + return Ok(engine::charmap_decode_table(bytes, errors, table)?.0); + } + } + } if let Some(cps) = decode_special_codepoints(bytes, encoding, errors)? { return Ok(Object::str_from_codepoints(cps)); } @@ -919,7 +926,7 @@ fn decode_via_registry( encoding: &str, errors: &str, ) -> Result, RuntimeError> { - let Some(codec) = registry_codec_attr(encoding, "decode")? else { + let Some(codec) = registry_codec_attr_text(encoding, "decode", "codecs.decode()")? else { return Ok(None); }; let key = encoding.to_owned(); @@ -932,54 +939,80 @@ fn decode_via_registry( ) }); REGISTRY_INFLIGHT.with(|s| s.borrow_mut().retain(|e| e != &key)); - let out = res?; + // CPython's `_PyCodec_DecodeInternal` notes every escaping exception + // with the codec it came from (`wrap_codec_error`). + let out = res.map_err(|e| add_codec_note(e, "decoding", encoding))?; let first = match &out { Object::Tuple(t) if !t.is_empty() => t[0].clone(), other => other.clone(), }; match first { Object::Str(s) => Ok(Some(s.to_string())), - // A codec was found and run, but returned a non-`str` result. This is - // the `io.TextIOWrapper` read path consuming a binary-transform codec - // (`quopri`/`hex`) whose `_is_text_encoding` guard was bypassed: CPython - // raises `TypeError` from `textio.c`, not a `LookupError` - // (`test_io.test_illegal_decoder`). + // A codec was found and run, but returned a non-`str` result — an + // unflagged binary-transform codec driven through the text model. + // CPython's `_PyCodec_DecodeText` raises this exact `TypeError`. other => Err(type_error(format!( - "decoder should return a string result, not '{}'", - other.type_name() + "'{encoding}' decoder returned '{}' instead of 'str'; \ + use codecs.decode() to decode to arbitrary types", + other.type_name_owned() ))), } } +/// Attach CPython's `wrap_codec_error` note ("encoding with 'X' codec +/// failed") to an escaping exception; non-exception errors pass through. +fn add_codec_note(err: RuntimeError, operation: &str, encoding: &str) -> RuntimeError { + if let RuntimeError::PyException(pyexc) = &err { + let note = format!("{operation} with '{encoding}' codec failed"); + let instance = pyexc.instance.clone(); + let _ = with_interp(|interp| { + let add = interp.load_attr_public(&instance, "add_note")?; + interp.call_object(add, &[Object::from_str(note.clone())], &[]) + }); + } + err +} + /// `encode` counterpart to [`decode_via_registry`]. fn encode_via_registry( s: &str, encoding: &str, errors: &str, ) -> Result>, RuntimeError> { - let Some(codec) = registry_codec_attr(encoding, "encode")? else { + encode_via_registry_obj(Object::from_str(s), encoding, errors) +} + +/// Object-taking variant of [`encode_via_registry`]: a surrogate-bearing +/// `WStr` is handed to the Python codec whole, so its own error-handler +/// machinery decides what happens to the lone surrogates (CPython gives the +/// codec the original str; e.g. the CJK codecs run custom handlers per +/// unencodable character rather than failing up front). +fn encode_via_registry_obj( + s: Object, + encoding: &str, + errors: &str, +) -> Result>, RuntimeError> { + let Some(codec) = registry_codec_attr_text(encoding, "encode", "codecs.encode()")? else { return Ok(None); }; let key = encoding.to_owned(); REGISTRY_INFLIGHT.with(|st| st.borrow_mut().push(key.clone())); - let res = with_interp(|interp| { - interp.call_object(codec, &[Object::from_str(s), Object::from_str(errors)], &[]) - }); + let res = with_interp(|interp| interp.call_object(codec, &[s, Object::from_str(errors)], &[])); REGISTRY_INFLIGHT.with(|st| st.borrow_mut().retain(|e| e != &key)); - let out = res?; + let out = res.map_err(|e| add_codec_note(e, "encoding", encoding))?; let first = match &out { Object::Tuple(t) if !t.is_empty() => t[0].clone(), other => other.clone(), }; match first.as_bytes_view() { Some(b) => Ok(Some(b)), - // Codec found and run, but returned a non-bytes result — the - // `io.TextIOWrapper` write path over a binary-transform codec - // (`rot13`) whose `_is_text_encoding` guard was bypassed. CPython's - // `textio.c` raises `TypeError` (`test_io.test_illegal_encoder`). + // Codec found and run, but returned a non-bytes result — an + // unflagged binary-transform codec driven through the text model. + // CPython's `_PyCodec_EncodeText` raises this exact `TypeError`. None => Err(type_error(format!( - "encoder should return a bytes object, not '{}'", - first.type_name() + "'{encoding}' encoder returned '{}' instead of 'bytes'; \ + use codecs.encode() to encode to arbitrary types", + first.type_name_owned() ))), } } @@ -1003,6 +1036,53 @@ pub fn codec_one_shot_decode_is_none(encoding: &str) -> bool { } fn registry_codec_attr(encoding: &str, attr: &str) -> Result, RuntimeError> { + registry_codec_attr_inner(encoding, attr, None) +} + +// The text-model `_is_text_encoding` rejection belongs at `TextIOWrapper` +// *construction* (CPython `_PyCodec_LookupTextEncoding`); the wrapper's own +// read/write operations must keep working even if the flag is flipped back +// afterwards (`test_io.test_illegal_decoder` constructs under a temporarily +// text-flagged quopri and expects `read()` to reach the codec and fail with +// TypeError, not LookupError). `PyFile` holds this scoped exemption around +// its per-operation codec calls. +thread_local! { + static IO_TEXT_EXEMPT: std::cell::Cell = const { std::cell::Cell::new(false) }; +} + +/// RAII guard suppressing the text-model check for the current thread. +#[derive(Debug)] +pub struct IoTextExemptGuard(bool); + +pub fn io_text_exempt_guard() -> IoTextExemptGuard { + let prev = IO_TEXT_EXEMPT.with(|c| c.replace(true)); + IoTextExemptGuard(prev) +} + +impl Drop for IoTextExemptGuard { + fn drop(&mut self) { + let prev = self.0; + IO_TEXT_EXEMPT.with(|c| c.set(prev)); + } +} + +/// [`registry_codec_attr`] for the *text model* (`str.encode` / +/// `bytes.decode`): a codec flagged `_is_text_encoding=False` raises +/// CPython's `_PyCodec_LookupTextEncoding` `LookupError` with the +/// operation-appropriate `alternate_command` hint. +fn registry_codec_attr_text( + encoding: &str, + attr: &str, + alternate_command: &str, +) -> Result, RuntimeError> { + registry_codec_attr_inner(encoding, attr, Some(alternate_command)) +} + +fn registry_codec_attr_inner( + encoding: &str, + attr: &str, + text_only_hint: Option<&str>, +) -> Result, RuntimeError> { if crate::vm_singletons::current_interpreter_ptr().is_none() { return Ok(None); } @@ -1021,6 +1101,19 @@ fn registry_codec_attr(encoding: &str, attr: &str) -> Result, Run Ok(i) => i, Err(_) => return Ok(None), }; + if let Some(hint) = text_only_hint { + if !IO_TEXT_EXEMPT.with(|c| c.get()) { + let is_text = interp + .load_attr_public(&info, "_is_text_encoding") + .map(|o| o.is_truthy()) + .unwrap_or(true); + if !is_text { + return Err(crate::error::lookup_error(format!( + "'{encoding}' is not a text encoding; use {hint} to handle arbitrary codecs" + ))); + } + } + } match interp.load_attr_public(&info, attr) { Ok(c) => Ok(Some(c)), Err(_) => Ok(None), @@ -1028,6 +1121,18 @@ fn registry_codec_attr(encoding: &str, attr: &str) -> Result, Run }) } +/// The canonical CPython codec name for `encoding` +/// (`codecs.lookup(...).name`): `latin1` → `iso8859-1`. Used at startup to +/// report `sys.std*.encoding` normalized, matching `config_init_stdio`. +/// `None` when the registry can't resolve the name (unknown codec, or no +/// interpreter published on this thread). +pub fn canonical_codec_name(encoding: &str) -> Option { + match registry_codec_attr_inner(encoding, "name", None) { + Ok(Some(Object::Str(s))) => Some(s.to_string()), + _ => None, + } +} + /// Run `f` with the current interpreter. The pointer is published by an /// enclosing VM frame on this thread and the GIL keeps the reentrant access /// exclusive (same contract as `io_full::validate_text_encoding`). @@ -1041,80 +1146,80 @@ fn with_interp( f(interp) } +/// Emit a `DeprecationWarning` from the unicode-escape codec (CPython's +/// `_PyUnicode_DecodeUnicodeEscapeStateful` warns about the first invalid +/// escape sequence). An escalating warnings filter turns this into an error. +fn emit_deprecation(msg: &str) -> Result<(), RuntimeError> { + with_interp(|interp| interp.warn_deprecation_from_builtin(msg.to_owned())) +} + /// Handle special-case encodings whose semantics don't quite match /// `encoding_rs`'s default behaviour (utf-8 with `surrogateescape`, /// latin-1, raw_unicode_escape, etc.). fn encode_special(s: &str, encoding: &str, errors: &str) -> Result>, RuntimeError> { let key = encoding_key(encoding); + // The UTF/ASCII/Latin-1 family routes through the unified engine so + // *custom* error handlers (`codecs.register_error`) work from + // `str.encode` too, not just the `_codecs` entry points (RFC 0050 WS2). + let cps = || -> Vec { s.chars().map(|c| c as u32).collect() }; Ok(match key.as_str() { - "utf8" => Some(encode_utf8(s, errors)?), + "utf8" => Some(crate::stdlib::codecs_engine::utf8_encode(&cps(), errors)?), "utf8sig" => { // UTF-8 with a leading BOM (CPython `utf_8_sig`). The stateless // codec always prepends the BOM; the BOM-once-per-stream nuance // lives in the incremental encoder (frozen `codecs.py`). let mut out = vec![0xEF, 0xBB, 0xBF]; - out.extend(encode_utf8(s, errors)?); + out.extend(crate::stdlib::codecs_engine::utf8_encode(&cps(), errors)?); Some(out) } - "ascii" => Some(encode_ascii(s, errors)?), - "latin1" | "iso88591" => Some(encode_latin1(s, errors)?), - "utf16" => Some(encode_utf16(s, false, true)), - "utf16le" => Some(encode_utf16(s, false, false)), - "utf16be" => Some(encode_utf16(s, true, false)), - "utf32" => Some(encode_utf32(s, false, true)), - "utf32le" => Some(encode_utf32(s, false, false)), - "utf32be" => Some(encode_utf32(s, true, false)), + "ascii" => Some(crate::stdlib::codecs_engine::ascii_encode(&cps(), errors)?), + "latin1" | "iso88591" => Some(crate::stdlib::codecs_engine::latin1_encode(&cps(), errors)?), + "utf16" => Some(crate::stdlib::codecs_engine::utf16_encode( + &cps(), + errors, + 0, + )?), + "utf16le" => Some(crate::stdlib::codecs_engine::utf16_encode( + &cps(), + errors, + -1, + )?), + "utf16be" => Some(crate::stdlib::codecs_engine::utf16_encode( + &cps(), + errors, + 1, + )?), + "utf32" => Some(crate::stdlib::codecs_engine::utf32_encode( + &cps(), + errors, + 0, + )?), + "utf32le" => Some(crate::stdlib::codecs_engine::utf32_encode( + &cps(), + errors, + -1, + )?), + "utf32be" => Some(crate::stdlib::codecs_engine::utf32_encode( + &cps(), + errors, + 1, + )?), "rawunicodeescape" => Some(encode_raw_unicode_escape(s)), "unicodeescape" => Some(encode_unicode_escape(s)), - "cp437" | "437" | "ibm437" => Some(encode_cp437(s, errors)?), - "cp1252" | "windows1252" | "1252" => Some(encode_cp1252(s, errors)?), - "utf7" => Some(encode_utf7(s)), - "iso2022jp" | "csiso2022jp" => Some(encode_iso2022jp(s, errors)?), - _ => None, + "utf7" => Some(crate::stdlib::codecs_engine::utf7_encode(&cps(), errors)?), + // Any single-byte codec (iso-8859-*, cp*, koi8-*, mac-*): the + // charmap engine, so custom error handlers work uniformly. + _ => match sbcs_decode_table(encoding) { + Some(table) => Some(crate::stdlib::codecs_engine::charmap_encode_table( + &cps(), + errors, + table, + )?), + None => None, + }, }) } -/// ISO-2022-JP encode with CPython semantics. `encoding_rs` follows the -/// WHATWG spec and *errors* on ESC/SO/SI in the input (anti-injection rule), -/// but CPython's codec passes all ASCII through verbatim — `email.charset` -/// depends on re-encoding an ASCII string that already contains raw ESC -/// shift sequences. Pass ASCII runs through untouched and encode non-ASCII -/// runs via `encoding_rs` (each run yields a self-contained -/// `ESC $ B … ESC ( B` sequence, matching CPython's output). -fn encode_iso2022jp(s: &str, errors: &str) -> Result, RuntimeError> { - let enc = Encoding::for_label(b"iso-2022-jp").expect("encoding_rs knows iso-2022-jp"); - let mut out = Vec::with_capacity(s.len()); - let mut rest = s; - while !rest.is_empty() { - let ascii_end = rest.find(|c: char| !c.is_ascii()).unwrap_or(rest.len()); - out.extend_from_slice(&rest.as_bytes()[..ascii_end]); - rest = &rest[ascii_end..]; - if rest.is_empty() { - break; - } - let run_end = rest.find(|c: char| c.is_ascii()).unwrap_or(rest.len()); - let (bytes, _, has_replacements) = enc.encode(&rest[..run_end]); - if has_replacements { - match errors { - "ignore" => {} - "replace" => out.push(b'?'), - _ => { - return Err(value_error( - "'iso-2022-jp' codec can't encode input".to_owned(), - )) - } - } - if errors == "ignore" || errors == "replace" { - rest = &rest[run_end..]; - continue; - } - } - out.extend_from_slice(&bytes); - rest = &rest[run_end..]; - } - Ok(out) -} - fn decode_special( bytes: &[u8], encoding: &str, @@ -1136,12 +1241,28 @@ fn decode_special( "utf32" => Some(decode_utf32(bytes, None)?), "utf32le" => Some(decode_utf32(bytes, Some(false))?), "utf32be" => Some(decode_utf32(bytes, Some(true))?), - "rawunicodeescape" => Some(decode_raw_unicode_escape(bytes)?), - "unicodeescape" => Some(decode_unicode_escape(bytes)?), - "cp437" | "437" | "ibm437" => Some(decode_cp437(bytes)), - "cp1252" | "windows1252" | "1252" => Some(decode_cp1252(bytes, errors)?), + "rawunicodeescape" => Some( + crate::stdlib::codecs_engine::raw_unicode_escape_decode(bytes, errors, true)? + .0 + .to_str(), + ), + "unicodeescape" => { + let (obj, _, warn) = + crate::stdlib::codecs_engine::unicode_escape_decode(bytes, errors, true)?; + if let Some(msg) = warn { + emit_deprecation(&msg)?; + } + Some(obj.to_str()) + } "utf7" => Some(decode_utf7(bytes, errors)?), - _ => None, + _ => match sbcs_decode_table(encoding) { + Some(table) => Some( + crate::stdlib::codecs_engine::charmap_decode_table(bytes, errors, table)? + .0 + .to_str(), + ), + None => None, + }, }) } @@ -1168,45 +1289,6 @@ const CP437_HIGH: [char; 128] = [ '\u{00b0}', '\u{2219}', '\u{00b7}', '\u{221a}', '\u{207f}', '\u{00b2}', '\u{25a0}', '\u{00a0}', ]; -fn decode_cp437(bytes: &[u8]) -> String { - bytes - .iter() - .map(|&b| { - if b < 0x80 { - b as char - } else { - CP437_HIGH[(b - 0x80) as usize] - } - }) - .collect() -} - -fn encode_cp437(s: &str, errors: &str) -> Result, RuntimeError> { - let mut out = Vec::with_capacity(s.len()); - for (i, c) in s.chars().enumerate() { - if (c as u32) < 0x80 { - out.push(c as u8); - } else if let Some(pos) = CP437_HIGH.iter().position(|&h| h == c) { - out.push(0x80 + pos as u8); - } else { - match errors { - "ignore" => {} - "replace" => out.push(b'?'), - _ => { - return Err(crate::error::unicode_encode_error( - "charmap", - s, - i, - i + 1, - "character maps to ", - )) - } - } - } - } - Ok(out) -} - // ---------- cp1252 (Windows-1252, strict charmap) ---------- // // `encoding_rs` implements the *WHATWG* windows-1252 index, which fills the five @@ -1353,73 +1435,6 @@ const CP1252_HIGH: [Option; 128] = [ Some('\u{00FF}'), ]; -fn decode_cp1252(bytes: &[u8], errors: &str) -> Result { - let mut out = String::with_capacity(bytes.len()); - for (i, &b) in bytes.iter().enumerate() { - let mapped = if b < 0x80 { - Some(b as char) - } else { - CP1252_HIGH[(b - 0x80) as usize] - }; - match mapped { - Some(c) => out.push(c), - None => match errors { - "ignore" => {} - "replace" => out.push('\u{FFFD}'), - "backslashreplace" => out.push_str(&format!("\\x{b:02x}")), - _ => { - return Err(crate::error::unicode_decode_error( - "charmap", - bytes, - i, - i + 1, - "character maps to ", - )) - } - }, - } - } - Ok(out) -} - -fn encode_cp1252(s: &str, errors: &str) -> Result, RuntimeError> { - let mut out = Vec::with_capacity(s.len()); - for (i, c) in s.chars().enumerate() { - let cp = c as u32; - if cp < 0x80 { - out.push(cp as u8); - } else if let Some(pos) = CP1252_HIGH.iter().position(|&h| h == Some(c)) { - out.push(0x80 + pos as u8); - } else { - match errors { - "ignore" => {} - "replace" => out.push(b'?'), - "backslashreplace" => { - let esc = if cp < 0x100 { - format!("\\x{cp:02x}") - } else if cp < 0x10000 { - format!("\\u{cp:04x}") - } else { - format!("\\U{cp:08x}") - }; - out.extend_from_slice(esc.as_bytes()); - } - "xmlcharrefreplace" => out.extend_from_slice(format!("&#{cp};").as_bytes()), - _ => { - return Err(crate::error::unicode_encode_error( - "charmap", - s, - i, - i + 1, - "character maps to ", - )) - } - } - } - } - Ok(out) -} - // ---------- UTF-7 (RFC 2152) ---------- // // `encoding_rs` has no UTF-7, but real code drives it (e.g. `tarfile` opened @@ -1430,21 +1445,6 @@ fn encode_cp1252(s: &str, errors: &str) -> Result, RuntimeError> { // UTF-8, lone surrogates produced by malformed input become U+FFFD (the same // concession the UTF-8 surrogateescape path makes). -const UTF7_BASE64: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -/// CPython `utf7_category`: 0=Set D, 1=Set O, 2=whitespace, 3=must-base64. -#[rustfmt::skip] -const UTF7_CATEGORY: [u8; 128] = [ - 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 2, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 3, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 1, 1, 1, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 3, 3, -]; - #[inline] fn utf7_is_base64(c: u32) -> bool { if c > 127 { @@ -1470,25 +1470,12 @@ fn utf7_from_base64(c: u32) -> u64 { } } -#[inline] -fn utf7_to_base64(n: u64) -> u8 { - UTF7_BASE64[(n & 0x3f) as usize] -} - /// `DECODE_DIRECT`: an ASCII byte (other than `+`) that decodes as itself. #[inline] fn utf7_decode_direct(c: u32) -> bool { c <= 127 && c != u32::from(b'+') } -/// `ENCODE_DIRECT(c, directO=1, directWS=1)` — the Python codec passes -/// `base64SetO=0`/`base64WhiteSpace=0`, so every ASCII char outside category 3 -/// is emitted literally. -#[inline] -fn utf7_encode_direct(c: u32) -> bool { - c > 0 && c < 128 && UTF7_CATEGORY[c as usize] != 3 -} - /// Push a (possibly surrogate) code point; WeavePy `str` can't hold lone /// surrogates, so they degrade to U+FFFD (see module note). #[inline] @@ -1496,68 +1483,6 @@ fn utf7_push(out: &mut String, cp: u32) { out.push(char::from_u32(cp).unwrap_or('\u{FFFD}')); } -fn encode_utf7(s: &str) -> Vec { - let mut out: Vec = Vec::with_capacity(s.len()); - let mut in_shift = false; - let mut base64bits: u32 = 0; - let mut base64buffer: u64 = 0; - for c in s.chars() { - let mut ch = c as u32; - if in_shift { - if utf7_encode_direct(ch) { - if base64bits > 0 { - out.push(utf7_to_base64(base64buffer << (6 - base64bits))); - base64buffer = 0; - base64bits = 0; - } - in_shift = false; - if utf7_is_base64(ch) || ch == u32::from(b'-') { - out.push(b'-'); - } - out.push(ch as u8); - continue; - } - // else: fall through to encode_char. - } else if ch == u32::from(b'+') { - out.push(b'+'); - out.push(b'-'); - continue; - } else if utf7_encode_direct(ch) { - out.push(ch as u8); - continue; - } else { - out.push(b'+'); - in_shift = true; - // fall through to encode_char. - } - // encode_char: accumulate UTF-16 code unit(s) into the base64 buffer. - if ch >= 0x10000 { - let v = ch - 0x10000; - let hi = 0xD800 + (v >> 10); - base64bits += 16; - base64buffer = (base64buffer << 16) | u64::from(hi); - while base64bits >= 6 { - out.push(utf7_to_base64(base64buffer >> (base64bits - 6))); - base64bits -= 6; - } - ch = 0xDC00 + (v & 0x3FF); - } - base64bits += 16; - base64buffer = (base64buffer << 16) | u64::from(ch); - while base64bits >= 6 { - out.push(utf7_to_base64(base64buffer >> (base64bits - 6))); - base64bits -= 6; - } - } - if base64bits > 0 { - out.push(utf7_to_base64(base64buffer << (6 - base64bits))); - } - if in_shift { - out.push(b'-'); - } - out -} - fn decode_utf7(bytes: &[u8], errors: &str) -> Result { let mut out = String::with_capacity(bytes.len()); let mut in_shift = false; @@ -1675,30 +1600,6 @@ fn decode_utf7(bytes: &[u8], errors: &str) -> Result { Ok(out) } -fn encode_utf16(s: &str, big: bool, with_bom: bool) -> Vec { - let mut out = Vec::with_capacity(s.len() * 2 + 2); - if with_bom { - if big { - out.extend_from_slice(&[0xFE, 0xFF]); - } else { - out.extend_from_slice(&[0xFF, 0xFE]); - } - } - let mut buf = [0u16; 2]; - for c in s.chars() { - let u = c.encode_utf16(&mut buf); - for code in u.iter() { - let bytes = if big { - code.to_be_bytes() - } else { - code.to_le_bytes() - }; - out.extend_from_slice(&bytes); - } - } - out -} - fn decode_utf16(bytes: &[u8], explicit_be: Option) -> Result { let (be, payload) = match explicit_be { Some(b) => (b, bytes), @@ -1734,28 +1635,6 @@ fn decode_utf16(bytes: &[u8], explicit_be: Option) -> Result Vec { - let mut out = Vec::with_capacity(s.len() * 4 + 4); - if with_bom { - // Default BOM for non-explicit utf-32 is little-endian (CPython default). - if big { - out.extend_from_slice(&[0x00, 0x00, 0xFE, 0xFF]); - } else { - out.extend_from_slice(&[0xFF, 0xFE, 0x00, 0x00]); - } - } - for c in s.chars() { - let cp = c as u32; - let bytes = if big { - cp.to_be_bytes() - } else { - cp.to_le_bytes() - }; - out.extend_from_slice(&bytes); - } - out -} - fn decode_utf32(bytes: &[u8], explicit_be: Option) -> Result { let (be, payload) = match explicit_be { Some(b) => (b, bytes), @@ -1842,25 +1721,6 @@ pub fn codec_is_newline_unsafe(encoding: &str) -> bool { // ---------- UTF-8 ---------- -fn encode_utf8(s: &str, errors: &str) -> Result, RuntimeError> { - if errors == "surrogateescape" { - // Map U+DC80..U+DCFF back to 0x80..0xFF. - let mut out = Vec::with_capacity(s.len()); - for c in s.chars() { - let cp = c as u32; - if (0xDC80..=0xDCFF).contains(&cp) { - out.push((cp - 0xDC00) as u8); - } else { - let mut buf = [0u8; 4]; - out.extend_from_slice(c.encode_utf8(&mut buf).as_bytes()); - } - } - Ok(out) - } else { - Ok(s.as_bytes().to_vec()) - } -} - fn decode_utf8(bytes: &[u8], errors: &str) -> Result { // Strict (and unknown-handler) failures raise a real // `UnicodeDecodeError` with CPython's payload and message shape: @@ -1981,27 +1841,6 @@ impl FromUtf8Lenient for String { // ---------- ASCII / Latin-1 ---------- -fn encode_ascii(s: &str, errors: &str) -> Result, RuntimeError> { - let mut out = Vec::with_capacity(s.len()); - for (pos, c) in s.chars().enumerate() { - let cp = c as u32; - if cp < 0x80 { - out.push(cp as u8); - } else { - handle_encode_error( - &mut out, - s, - pos, - c, - errors, - "ascii", - "ordinal not in range(128)", - )?; - } - } - Ok(out) -} - fn decode_ascii(bytes: &[u8], errors: &str) -> Result { let mut out = String::with_capacity(bytes.len()); for (pos, &b) in bytes.iter().enumerate() { @@ -2014,90 +1853,10 @@ fn decode_ascii(bytes: &[u8], errors: &str) -> Result { Ok(out) } -fn encode_latin1(s: &str, errors: &str) -> Result, RuntimeError> { - let mut out = Vec::with_capacity(s.len()); - for (pos, c) in s.chars().enumerate() { - let cp = c as u32; - if cp < 0x100 { - out.push(cp as u8); - } else { - handle_encode_error( - &mut out, - s, - pos, - c, - errors, - "latin-1", - "ordinal not in range(256)", - )?; - } - } - Ok(out) -} - fn decode_latin1(bytes: &[u8]) -> String { bytes.iter().map(|&b| b as char).collect() } -fn handle_encode_error( - out: &mut Vec, - source: &str, - pos: usize, - c: char, - errors: &str, - encoding: &str, - reason: &str, -) -> Result<(), RuntimeError> { - match errors { - // Strict mode raises a real `UnicodeEncodeError` (a `ValueError` - // subclass) carrying the canonical `(encoding, object, start, end, - // reason)` payload, matching CPython — not a bare `ValueError`. - "strict" => Err(crate::error::unicode_encode_error( - encoding, - source, - pos, - pos + 1, - reason, - )), - "ignore" => Ok(()), - "replace" => { - out.push(b'?'); - Ok(()) - } - "backslashreplace" => { - let cp = c as u32; - let s = if cp <= 0xFF { - format!("\\x{:02x}", cp) - } else if cp <= 0xFFFF { - format!("\\u{:04x}", cp) - } else { - format!("\\U{:08x}", cp) - }; - out.extend_from_slice(s.as_bytes()); - Ok(()) - } - "namereplace" | "xmlcharrefreplace" => { - let s = format!("&#{};", c as u32); - out.extend_from_slice(s.as_bytes()); - Ok(()) - } - // `surrogateescape`/`surrogatepass` only have meaning for *surrogate* - // code points (U+DC80..U+DCFF / U+D800..U+DFFF). This strict-`str` - // encode path operates on a Rust `&str`, whose chars can never be - // surrogates, so a non-encodable char here is a genuine error: CPython - // raises `UnicodeEncodeError` (e.g. `'ë'.encode('ascii', - // 'surrogateescape')`), not "unknown error handler". - "surrogateescape" | "surrogatepass" => Err(crate::error::unicode_encode_error( - encoding, - source, - pos, - pos + 1, - reason, - )), - _ => Err(value_error(format!("unknown error handler: {errors}"))), - } -} - fn handle_decode_error( out: &mut String, input: &[u8], @@ -2153,39 +1912,6 @@ fn encode_raw_unicode_escape(s: &str) -> Vec { out } -fn decode_raw_unicode_escape(bytes: &[u8]) -> Result { - let mut out = String::with_capacity(bytes.len()); - let mut i = 0; - while i < bytes.len() { - if bytes[i] == b'\\' && i + 1 < bytes.len() { - match bytes[i + 1] { - b'u' if i + 6 <= bytes.len() => { - let hex = std::str::from_utf8(&bytes[i + 2..i + 6]) - .map_err(|_| value_error("bad raw_unicode_escape"))?; - let cp = u32::from_str_radix(hex, 16) - .map_err(|_| value_error("bad raw_unicode_escape"))?; - out.push(char::from_u32(cp).unwrap_or('\u{FFFD}')); - i += 6; - continue; - } - b'U' if i + 10 <= bytes.len() => { - let hex = std::str::from_utf8(&bytes[i + 2..i + 10]) - .map_err(|_| value_error("bad raw_unicode_escape"))?; - let cp = u32::from_str_radix(hex, 16) - .map_err(|_| value_error("bad raw_unicode_escape"))?; - out.push(char::from_u32(cp).unwrap_or('\u{FFFD}')); - i += 10; - continue; - } - _ => {} - } - } - out.push(bytes[i] as char); - i += 1; - } - Ok(out) -} - fn encode_unicode_escape(s: &str) -> Vec { let mut out = Vec::with_capacity(s.len()); for c in s.chars() { @@ -2194,9 +1920,9 @@ fn encode_unicode_escape(s: &str) -> Vec { '\n' => out.extend_from_slice(b"\\n"), '\r' => out.extend_from_slice(b"\\r"), '\t' => out.extend_from_slice(b"\\t"), - '\'' => out.extend_from_slice(b"\\'"), - '"' => out.extend_from_slice(b"\""), - ch if (ch as u32) < 0x20 => { + // Quotes stay literal — escaping them is `repr`'s job, not the + // codec's (CPython `PyUnicode_AsUnicodeEscapeString`). + ch if (ch as u32) < 0x20 || ch == '\x7f' => { out.extend_from_slice(format!("\\x{:02x}", ch as u32).as_bytes()); } ch if (ch as u32) < 0x80 => { @@ -2216,95 +1942,6 @@ fn encode_unicode_escape(s: &str) -> Vec { out } -fn decode_unicode_escape(bytes: &[u8]) -> Result { - let mut out = String::with_capacity(bytes.len()); - let mut i = 0; - while i < bytes.len() { - if bytes[i] == b'\\' && i + 1 < bytes.len() { - let next = bytes[i + 1]; - match next { - b'\\' => { - out.push('\\'); - i += 2; - } - b'n' => { - out.push('\n'); - i += 2; - } - b'r' => { - out.push('\r'); - i += 2; - } - b't' => { - out.push('\t'); - i += 2; - } - b'\'' => { - out.push('\''); - i += 2; - } - b'"' => { - out.push('"'); - i += 2; - } - b'a' => { - out.push('\x07'); - i += 2; - } - b'b' => { - out.push('\x08'); - i += 2; - } - b'f' => { - out.push('\x0C'); - i += 2; - } - b'v' => { - out.push('\x0B'); - i += 2; - } - b'0' => { - out.push('\0'); - i += 2; - } - b'x' if i + 4 <= bytes.len() => { - let hex = std::str::from_utf8(&bytes[i + 2..i + 4]) - .map_err(|_| value_error("bad \\x escape"))?; - let cp = - u32::from_str_radix(hex, 16).map_err(|_| value_error("bad \\x escape"))?; - out.push(char::from_u32(cp).unwrap_or('\u{FFFD}')); - i += 4; - } - b'u' if i + 6 <= bytes.len() => { - let hex = std::str::from_utf8(&bytes[i + 2..i + 6]) - .map_err(|_| value_error("bad \\u escape"))?; - let cp = - u32::from_str_radix(hex, 16).map_err(|_| value_error("bad \\u escape"))?; - out.push(char::from_u32(cp).unwrap_or('\u{FFFD}')); - i += 6; - } - b'U' if i + 10 <= bytes.len() => { - let hex = std::str::from_utf8(&bytes[i + 2..i + 10]) - .map_err(|_| value_error("bad \\U escape"))?; - let cp = - u32::from_str_radix(hex, 16).map_err(|_| value_error("bad \\U escape"))?; - out.push(char::from_u32(cp).unwrap_or('\u{FFFD}')); - i += 10; - } - other => { - out.push('\\'); - out.push(other as char); - i += 2; - } - } - } else { - out.push(bytes[i] as char); - i += 1; - } - } - Ok(out) -} - // ---------- per-encoding wrapper functions used by the frozen layer ---------- macro_rules! enc_decoder { @@ -2338,27 +1975,246 @@ macro_rules! enc_encoder { }; } -enc_encoder!(b_utf8_encode, "utf-8"); -enc_decoder!(b_utf8_decode, "utf-8"); -enc_encoder!(b_utf16_encode, "utf-16"); -enc_decoder!(b_utf16_decode, "utf-16"); -enc_encoder!(b_utf16_le_encode, "utf-16-le"); -enc_decoder!(b_utf16_le_decode, "utf-16-le"); -enc_encoder!(b_utf16_be_encode, "utf-16-be"); -enc_decoder!(b_utf16_be_decode, "utf-16-be"); -enc_encoder!(b_utf32_encode, "utf-32"); -enc_decoder!(b_utf32_decode, "utf-32"); -enc_encoder!(b_utf32_le_encode, "utf-32-le"); -enc_decoder!(b_utf32_le_decode, "utf-32-le"); -enc_encoder!(b_utf32_be_encode, "utf-32-be"); -enc_decoder!(b_utf32_be_decode, "utf-32-be"); -enc_encoder!(b_ascii_encode, "ascii"); -enc_decoder!(b_ascii_decode, "ascii"); -enc_encoder!(b_latin1_encode, "latin-1"); -enc_decoder!(b_latin1_decode, "latin-1"); enc_encoder!(b_cp1252_encode, "cp1252"); enc_decoder!(b_cp1252_decode, "cp1252"); + +// ---------- engine-backed entry points (RFC 0050 WS2) ---------- +// +// These expose CPython's exact `_codecs` signatures: decoders speak the +// stateful protocol (`final=False` leaves a trailing incomplete sequence +// unconsumed), the `_ex` variants return `(text, consumed, byteorder)`, +// and every coder resolves error handlers through the unified machinery +// in `codecs_engine` (built-ins natively, custom handlers via the live +// `codecs.register_error` registry). + +use crate::stdlib::codecs_engine as engine; + +/// Truthiness of the optional `final` flag argument. +fn arg_final(args: &[Object], idx: usize) -> bool { + args.get(idx).is_some_and(|o| o.is_truthy()) +} + +/// Like [`arg_final`], but defaulting to `true` when absent (the escape +/// codecs' `final=True` default). +fn arg_final_default_true(args: &[Object], idx: usize) -> bool { + args.get(idx).is_none_or(|o| o.is_truthy()) +} + +/// The optional `byteorder` int argument (0 = sniff BOM / native). +fn arg_byteorder(args: &[Object], idx: usize) -> i32 { + match args.get(idx) { + Some(Object::Int(i)) => (*i).clamp(i64::from(i32::MIN), i64::from(i32::MAX)) as i32, + _ => 0, + } +} + +/// The text argument as raw code points (`Str` fast path, `WStr` raw). +fn arg_text_codepoints(args: &[Object], idx: usize, name: &str) -> Result, RuntimeError> { + match args.get(idx) { + Some(o) => engine::str_codepoints(o).ok_or_else(|| { + type_error(format!( + "{name}() argument 'str' must be str, not {}", + o.type_name() + )) + }), + None => Err(type_error(format!("{name}() missing required argument"))), + } +} + +fn enc_tuple(bytes: Vec, nchars: usize) -> Object { + Object::new_tuple(vec![Object::new_bytes(bytes), Object::Int(nchars as i64)]) +} + +fn dec_tuple(text: Object, consumed: usize) -> Object { + Object::new_tuple(vec![text, Object::Int(consumed as i64)]) +} + +fn b_utf8_encode(args: &[Object]) -> Result { + let cps = arg_text_codepoints(args, 0, "utf_8_encode")?; + let errors = arg_errors(args, 1); + Ok(enc_tuple(engine::utf8_encode(&cps, &errors)?, cps.len())) +} + +fn b_utf8_decode(args: &[Object]) -> Result { + let bytes = arg_bytes(args, 0, "utf_8_decode")?; + let errors = arg_errors(args, 1); + let (text, consumed) = engine::utf8_decode(&bytes, &errors, arg_final(args, 2))?; + Ok(dec_tuple(text, consumed)) +} + +fn b_utf7_encode(args: &[Object]) -> Result { + let cps = arg_text_codepoints(args, 0, "utf_7_encode")?; + let errors = arg_errors(args, 1); + Ok(enc_tuple(engine::utf7_encode(&cps, &errors)?, cps.len())) +} + +fn b_utf7_decode(args: &[Object]) -> Result { + let bytes = arg_bytes(args, 0, "utf_7_decode")?; + let errors = arg_errors(args, 1); + let (text, consumed) = engine::utf7_decode(&bytes, &errors, arg_final(args, 2))?; + Ok(dec_tuple(text, consumed)) +} + +fn b_ascii_encode(args: &[Object]) -> Result { + let cps = arg_text_codepoints(args, 0, "ascii_encode")?; + let errors = arg_errors(args, 1); + Ok(enc_tuple(engine::ascii_encode(&cps, &errors)?, cps.len())) +} + +fn b_ascii_decode(args: &[Object]) -> Result { + let bytes = arg_bytes(args, 0, "ascii_decode")?; + let errors = arg_errors(args, 1); + let (text, consumed) = engine::ascii_decode(&bytes, &errors)?; + Ok(dec_tuple(text, consumed)) +} + +fn b_latin1_encode(args: &[Object]) -> Result { + let cps = arg_text_codepoints(args, 0, "latin_1_encode")?; + let errors = arg_errors(args, 1); + Ok(enc_tuple(engine::latin1_encode(&cps, &errors)?, cps.len())) +} + +fn b_latin1_decode(args: &[Object]) -> Result { + let bytes = arg_bytes(args, 0, "latin_1_decode")?; + let errors = arg_errors(args, 1); + let (text, consumed) = engine::latin1_decode(&bytes, &errors)?; + Ok(dec_tuple(text, consumed)) +} + +fn b_readbuffer_encode(args: &[Object]) -> Result { + // Any buffer (str encodes as UTF-8) copied out verbatim. + let bytes = match args.first() { + Some(Object::Str(s)) => s.as_bytes().to_vec(), + Some(o) => match o.as_bytes_view() { + Some(b) => b, + // Other buffer-protocol objects (`array.array`): copy out via + // their `tobytes()`. + None => with_interp(|interp| { + let m = interp.load_attr_public(o, "tobytes")?; + interp.call_object(m, &[], &[]) + }) + .ok() + .and_then(|r| r.as_bytes_view()) + .ok_or_else(|| { + type_error(format!( + "readbuffer_encode() argument 'data' must be read-only bytes-like object, not {}", + o.type_name_owned() + )) + })?, + }, + None => return Err(type_error("readbuffer_encode() missing required argument")), + }; + let len = bytes.len(); + Ok(enc_tuple(bytes, len)) +} + +macro_rules! utf1632_encode { + ($name:ident, $engine:path, $pyname:literal, $byteorder:expr) => { + fn $name(args: &[Object]) -> Result { + let cps = arg_text_codepoints(args, 0, $pyname)?; + let errors = arg_errors(args, 1); + // Byte-order-less variants take an optional byteorder argument. + let bo: i32 = match $byteorder { + Some(fixed) => fixed, + None => arg_byteorder(args, 2), + }; + Ok(enc_tuple($engine(&cps, &errors, bo)?, cps.len())) + } + }; +} + +macro_rules! utf1632_decode { + ($name:ident, $engine:path, $pyname:literal, $byteorder:expr, ex $ex:literal) => { + fn $name(args: &[Object]) -> Result { + let bytes = arg_bytes(args, 0, $pyname)?; + let errors = arg_errors(args, 1); + let (bo, final_) = match $byteorder { + Some(fixed) => (fixed, arg_final(args, 2)), + None if $ex => (arg_byteorder(args, 2), arg_final(args, 3)), + None => (0, arg_final(args, 2)), + }; + let (text, consumed, out_bo) = $engine(&bytes, &errors, bo, final_)?; + if $ex { + Ok(Object::new_tuple(vec![ + text, + Object::Int(consumed as i64), + Object::Int(i64::from(out_bo)), + ])) + } else { + Ok(dec_tuple(text, consumed)) + } + } + }; +} + +utf1632_encode!( + b_utf16_encode, + engine::utf16_encode, + "utf_16_encode", + None:: +); +utf1632_encode!( + b_utf16_le_encode, + engine::utf16_encode, + "utf_16_le_encode", + Some(-1) +); +utf1632_encode!( + b_utf16_be_encode, + engine::utf16_encode, + "utf_16_be_encode", + Some(1) +); +utf1632_encode!( + b_utf32_encode, + engine::utf32_encode, + "utf_32_encode", + None:: +); +utf1632_encode!( + b_utf32_le_encode, + engine::utf32_encode, + "utf_32_le_encode", + Some(-1) +); +utf1632_encode!( + b_utf32_be_encode, + engine::utf32_encode, + "utf_32_be_encode", + Some(1) +); + +utf1632_decode!(b_utf16_decode, engine::utf16_decode, "utf_16_decode", None::, ex false); +utf1632_decode!(b_utf16_le_decode, engine::utf16_decode, "utf_16_le_decode", Some(-1), ex false); +utf1632_decode!(b_utf16_be_decode, engine::utf16_decode, "utf_16_be_decode", Some(1), ex false); +utf1632_decode!(b_utf16_ex_decode, engine::utf16_decode, "utf_16_ex_decode", None::, ex true); +utf1632_decode!(b_utf32_decode, engine::utf32_decode, "utf_32_decode", None::, ex false); +utf1632_decode!(b_utf32_le_decode, engine::utf32_decode, "utf_32_le_decode", Some(-1), ex false); +utf1632_decode!(b_utf32_be_decode, engine::utf32_decode, "utf_32_be_decode", Some(1), ex false); +utf1632_decode!(b_utf32_ex_decode, engine::utf32_decode, "utf_32_ex_decode", None::, ex true); enc_encoder!(b_raw_unicode_escape_encode, "raw_unicode_escape"); -enc_decoder!(b_raw_unicode_escape_decode, "raw_unicode_escape"); enc_encoder!(b_unicode_escape_encode, "unicode_escape"); -enc_decoder!(b_unicode_escape_decode, "unicode_escape"); + +/// `_codecs.raw_unicode_escape_decode(data, errors="strict", final=True)`. +fn b_raw_unicode_escape_decode(args: &[Object]) -> Result { + let bytes = arg_bytes_or_str_utf8(args, 0, "raw_unicode_escape_decode")?; + let errors = arg_errors(args, 1); + let final_ = arg_final_default_true(args, 2); + let (obj, consumed) = + crate::stdlib::codecs_engine::raw_unicode_escape_decode(&bytes, &errors, final_)?; + Ok(Object::new_tuple(vec![obj, Object::Int(consumed as i64)])) +} + +/// `_codecs.unicode_escape_decode(data, errors="strict", final=True)`. +/// Emits CPython's first-invalid-escape `DeprecationWarning`. +fn b_unicode_escape_decode(args: &[Object]) -> Result { + let bytes = arg_bytes_or_str_utf8(args, 0, "unicode_escape_decode")?; + let errors = arg_errors(args, 1); + let final_ = arg_final_default_true(args, 2); + let (obj, consumed, warn) = + crate::stdlib::codecs_engine::unicode_escape_decode(&bytes, &errors, final_)?; + if let Some(msg) = warn { + emit_deprecation(&msg)?; + } + Ok(Object::new_tuple(vec![obj, Object::Int(consumed as i64)])) +} diff --git a/crates/weavepy-vm/src/stdlib/io.rs b/crates/weavepy-vm/src/stdlib/io.rs index 844c9c7..d2d9846 100644 --- a/crates/weavepy-vm/src/stdlib/io.rs +++ b/crates/weavepy-vm/src/stdlib/io.rs @@ -1555,11 +1555,10 @@ fn tw_buffer(inst: &crate::types::PyInstance) -> Result, RuntimeError /// CPython's `io.open`/`TextIOWrapper` accept the special encoding name /// `"locale"`, which resolves to the current locale's encoding (the result of /// `locale.getpreferredencoding(False)`); `codecs.lookup("locale")` itself -/// raises. WeavePy's text layer is UTF-8, so `"locale"` maps to `"utf-8"` -/// (`test_io.test_reconfigure_locale`). +/// raises (`test_io.test_reconfigure_locale`). fn resolve_locale_encoding(name: &str) -> String { if name.eq_ignore_ascii_case("locale") { - "utf-8".to_owned() + crate::stdlib::locale_mod::current_codeset() } else { name.to_owned() } @@ -2659,7 +2658,16 @@ fn tw_init(args: &[Object], kwargs: &[(String, Object)]) -> Result "utf-8".to_owned(), + // `None`/missing: UTF-8 under UTF-8 mode, else the locale encoding — + // reported under its codeset name (`_Py_GetLocaleEncoding`; "UTF-8" + // on a UTF-8 host locale, `test_io.test_default_encoding`). + Some(Object::None) | None => { + if crate::vm_singletons::utf8_mode() { + "utf-8".to_owned() + } else { + crate::stdlib::locale_mod::current_codeset() + } + } // A lone-surrogate encoding name can't be UTF-8-encoded for the codec // lookup, so CPython raises `UnicodeEncodeError` (not `TypeError`): // `test_constructor`: `encoding='\udcfe'`. @@ -3165,6 +3173,9 @@ fn tw_ensure_decoded(inst: &Rc) -> Result<(), RuntimeE // working; the output is un-bridged back to a `WStr` on the way out. A // surrogate-free decode takes the verbatim fast path (`bridge_*` is // identity), so non-surrogate streams are byte-for-byte unchanged. + // Text-model codec check happened at wrapper construction; per-read codec + // calls must not repeat it (`test_io.test_illegal_decoder`). + let _exempt = crate::stdlib::codecs_mod::io_text_exempt_guard(); let text_obj = crate::stdlib::codecs_mod::decode_bytes_obj(&raw, &encoding, &errors)?; let is_wstr = matches!(text_obj, Object::WStr(_)); let text = crate::builtins::bridge_str_of(&text_obj).unwrap_or_default(); @@ -3320,6 +3331,8 @@ fn tw_fill_chunk(inst: &Rc) -> Result<(), RuntimeError utf8_complete_prefix_len(&combined) }; let (to_decode, leftover) = combined.split_at(safe); + // Text-model check happened at construction, not per read. + let _exempt = crate::stdlib::codecs_mod::io_text_exempt_guard(); let text_obj = crate::stdlib::codecs_mod::decode_bytes_obj(to_decode, &encoding, &errors)?; let is_wstr = matches!(text_obj, Object::WStr(_)); let text = crate::builtins::bridge_str_of(&text_obj).unwrap_or_default(); @@ -3403,6 +3416,8 @@ fn tw_byte_position(inst: &crate::types::PyInstance) -> Result 0, }; let errors = tw_errors(inst); + // Text-model check happened at construction, not per operation. + let _exempt = crate::stdlib::codecs_mod::io_text_exempt_guard(); // A bridged snapshot must be un-bridged before re-encoding so the // byte cookie reflects the *original* surrogate bytes, not the PUA // stand-ins. @@ -3507,7 +3522,12 @@ fn tw_write(args: &[Object]) -> Result { } None => encoding.clone(), }; - let bytes = crate::stdlib::codecs_mod::encode_str(&translated, &effective_encoding, &errors)?; + // Text-model codec check happened at wrapper construction; per-write + // codec calls must not repeat it (`test_io.test_illegal_encoder`). + let bytes = { + let _exempt = crate::stdlib::codecs_mod::io_text_exempt_guard(); + crate::stdlib::codecs_mod::encode_str(&translated, &effective_encoding, &errors)? + }; // Any successful write leaves the stream past its start. tw_set(&inst, "_start_of_stream", Object::Bool(false)); // CPython's C `TextIOWrapper` does not push every encoded write straight to diff --git a/crates/weavepy-vm/src/stdlib/io_full.rs b/crates/weavepy-vm/src/stdlib/io_full.rs index 8c5a22b..7c134d8 100644 --- a/crates/weavepy-vm/src/stdlib/io_full.rs +++ b/crates/weavepy-vm/src/stdlib/io_full.rs @@ -420,13 +420,21 @@ fn apply_text_config( return Ok(()); } if let Some(Object::Str(enc)) = encoding { - // CPython resolves the codec at construction time (via - // `_PyCodec_LookupTextEncoding`), so an unknown encoding raises - // `LookupError` from `open()`/`TextIOWrapper(...)` — not later at the - // first read. Validate against the live codec registry so e.g. - // `tempfile.TemporaryFile(encoding='bad-encoding')` fails eagerly. - validate_text_encoding(enc)?; - f.set_encoding(enc); + // The `"locale"` sentinel (PEP 597, produced by `io.text_encoding` + // outside UTF-8 mode) resolves to the locale's encoding before + // hitting the codec registry, which knows no codec by that name + // (CPython does the same in `TextIOWrapper`). + if enc.as_ref().eq_ignore_ascii_case("locale") { + f.set_encoding(&crate::stdlib::locale_mod::current_codeset()); + } else { + // CPython resolves the codec at construction time (via + // `_PyCodec_LookupTextEncoding`), so an unknown encoding raises + // `LookupError` from `open()`/`TextIOWrapper(...)` — not later at + // the first read. Validate against the live codec registry so e.g. + // `tempfile.TemporaryFile(encoding='bad-encoding')` fails eagerly. + validate_text_encoding(enc)?; + f.set_encoding(enc); + } } if let Some(Object::Str(err)) = errors { // CPython's TextIOWrapper validates the error handler eagerly under diff --git a/crates/weavepy-vm/src/stdlib/locale_mod.rs b/crates/weavepy-vm/src/stdlib/locale_mod.rs index 92fe68a..53fe6d3 100644 --- a/crates/weavepy-vm/src/stdlib/locale_mod.rs +++ b/crates/weavepy-vm/src/stdlib/locale_mod.rs @@ -1,11 +1,14 @@ -//! The `_locale` module — RFC 0023. +//! The `_locale` module — RFC 0050 WS5. //! -//! A pragmatic, host-agnostic locale shim. We expose the constants -//! and entry points that `locale.py` references but always serve the -//! "C" locale data: `localeconv()` returns the POSIX defaults and -//! `setlocale()` rejects any change other than `C`/`POSIX`. Real -//! libc-driven locales are reserved for a follow-up RFC because -//! they require careful thread-safety and Windows differences. +//! Backed by the host C library: `setlocale`/`localeconv`/`nl_langinfo` +//! call straight into libc (the process-global C locale, exactly like +//! CPython's `_localemodule.c`), `strcoll`/`strxfrm` use the wide-char +//! collation entry points (`wcscoll`/`wcsxfrm`), and `getencoding` +//! reports the `LC_CTYPE` codeset. Strings coming back from libc are +//! decoded with `mbstowcs` under the current `LC_CTYPE`, mirroring +//! CPython's `PyUnicode_DecodeLocale`. + +use std::ffi::{CStr, CString}; use crate::sync::Rc; use crate::sync::RefCell; @@ -14,16 +17,44 @@ use crate::error::{value_error, RuntimeError}; use crate::import::ModuleCache; use crate::object::{BuiltinFn, DictData, DictKey, Object, PyModule}; -// libc constants — mirror the values CPython exports. -pub const LC_ALL: i64 = 6; -pub const LC_CTYPE: i64 = 0; -pub const LC_NUMERIC: i64 = 1; -pub const LC_TIME: i64 = 2; -pub const LC_COLLATE: i64 = 3; -pub const LC_MONETARY: i64 = 4; -pub const LC_MESSAGES: i64 = 5; +// Wide-char/multibyte libc entry points the `libc` crate doesn't bind. +unsafe extern "C" { + fn mbstowcs( + dest: *mut libc::wchar_t, + src: *const libc::c_char, + n: libc::size_t, + ) -> libc::size_t; + fn wcscoll(a: *const libc::wchar_t, b: *const libc::wchar_t) -> libc::c_int; + fn wcsxfrm( + dest: *mut libc::wchar_t, + src: *const libc::wchar_t, + n: libc::size_t, + ) -> libc::size_t; +} + +// Category constants — the host libc's values (CPython exports these +// verbatim from `locale.h`). +pub const LC_ALL: i64 = libc::LC_ALL as i64; +pub const LC_CTYPE: i64 = libc::LC_CTYPE as i64; +pub const LC_NUMERIC: i64 = libc::LC_NUMERIC as i64; +pub const LC_TIME: i64 = libc::LC_TIME as i64; +pub const LC_COLLATE: i64 = libc::LC_COLLATE as i64; +pub const LC_MONETARY: i64 = libc::LC_MONETARY as i64; +pub const LC_MESSAGES: i64 = libc::LC_MESSAGES as i64; pub const CHAR_MAX: i64 = 127; +/// `setlocale(LC_CTYPE, "")` — adopt the environment's `LC_CTYPE` locale, +/// as CPython's pre-init does (`_Py_SetLocaleFromEnv`). Called once at +/// interpreter start so `nl_langinfo(CODESET)`/`localeconv` and the +/// `locale` module observe the user's locale rather than plain `"C"`. +pub fn init_from_env() { + let empty = CString::new("").expect("static"); + // SAFETY: `setlocale` with a valid category and NUL-terminated string. + unsafe { + libc::setlocale(libc::LC_CTYPE, empty.as_ptr()); + } +} + pub fn build(_cache: &ModuleCache) -> Rc { let dict = Rc::new(RefCell::new(DictData::default())); { @@ -44,6 +75,11 @@ pub fn build(_cache: &ModuleCache) -> Rc { ] { d.insert(DictKey(Object::from_static(name)), Object::Int(val)); } + // `nl_langinfo` item constants (langinfo.h). Grouped exactly like + // CPython's `langinfo_constants` table. + for &(name, val) in langinfo_constants() { + d.insert(DictKey(Object::from_static(name)), Object::Int(val)); + } d.insert( DictKey(Object::from_static("Error")), Object::Type(crate::builtin_types::builtin_types().value_error.clone()), @@ -52,10 +88,6 @@ pub fn build(_cache: &ModuleCache) -> Rc { DictKey(Object::from_static("setlocale")), builtin("setlocale", l_setlocale), ); - d.insert( - DictKey(Object::from_static("getlocale")), - builtin("getlocale", l_getlocale), - ); d.insert( DictKey(Object::from_static("localeconv")), builtin("localeconv", l_localeconv), @@ -72,6 +104,10 @@ pub fn build(_cache: &ModuleCache) -> Rc { DictKey(Object::from_static("nl_langinfo")), builtin("nl_langinfo", l_nl_langinfo), ); + d.insert( + DictKey(Object::from_static("getencoding")), + builtin("getencoding", l_getencoding), + ); } Rc::new(PyModule { name: "_locale".to_owned(), @@ -89,67 +125,297 @@ fn builtin(name: &'static str, body: fn(&[Object]) -> Result Result { - let loc = match args.get(1) { - Some(Object::Str(s)) => s.to_string(), - Some(Object::None) | None => "C".to_owned(), - _ => return Err(value_error("setlocale: locale must be str or None")), +/// Decode a libc C string under the current `LC_CTYPE` locale, mirroring +/// CPython's `PyUnicode_DecodeLocale`: `mbstowcs` first, with a Latin-1 +/// byte-for-byte fallback for undecodable content. +fn decode_locale_cstr(ptr: *const libc::c_char) -> String { + if ptr.is_null() { + return String::new(); + } + // SAFETY: libc handed us a NUL-terminated string. + let bytes = unsafe { CStr::from_ptr(ptr) }.to_bytes(); + if bytes.is_empty() { + return String::new(); + } + if let Ok(s) = std::str::from_utf8(bytes) { + return s.to_owned(); + } + // SAFETY: `ptr` is NUL-terminated; the first call sizes the buffer. + unsafe { + let needed = mbstowcs(std::ptr::null_mut(), ptr, 0); + if needed != usize::MAX { + let mut buf = vec![0 as libc::wchar_t; needed + 1]; + let written = mbstowcs(buf.as_mut_ptr(), ptr, needed + 1); + if written != usize::MAX { + return buf[..written] + .iter() + .filter_map(|&w| char::from_u32(w as u32)) + .collect(); + } + } + } + // Undecodable in the current locale: fall back to Latin-1 so the data + // is at least preserved byte-for-byte. + bytes.iter().map(|&b| b as char).collect() +} + +fn arg_category(args: &[Object], fname: &str) -> Result { + let cat = match args.first() { + Some(Object::Int(n)) => *n, + Some(Object::Bool(b)) => i64::from(*b), + _ => { + return Err(crate::error::type_error(format!( + "{fname}: category must be an integer" + ))) + } }; - if loc == "C" || loc == "POSIX" || loc.is_empty() { - return Ok(Object::from_static("C")); + let lo = LC_ALL.min(LC_CTYPE).min(LC_MESSAGES); + let hi = LC_ALL + .max(LC_CTYPE) + .max(LC_NUMERIC) + .max(LC_TIME) + .max(LC_COLLATE) + .max(LC_MONETARY) + .max(LC_MESSAGES); + if !(lo..=hi).contains(&cat) { + return Err(value_error("invalid locale category")); } - // Pretend success — we don't have real libc integration yet. - Ok(Object::from_str(loc)) + Ok(cat as libc::c_int) } -fn l_getlocale(_args: &[Object]) -> Result { - Ok(Object::new_tuple(vec![Object::None, Object::None])) +fn l_setlocale(args: &[Object]) -> Result { + let category = arg_category(args, "setlocale")?; + match args.get(1) { + // Query the current locale for the category. + Some(Object::None) | None => { + // SAFETY: NULL locale queries without modifying. + let cur = unsafe { libc::setlocale(category, std::ptr::null()) }; + if cur.is_null() { + return Err(value_error("locale query failed")); + } + Ok(Object::from_str(decode_locale_cstr(cur))) + } + Some(Object::Str(s)) => { + let requested = CString::new(s.as_ref()) + .map_err(|_| value_error("embedded null byte in locale name"))?; + // SAFETY: valid category + NUL-terminated locale name. + let res = unsafe { libc::setlocale(category, requested.as_ptr()) }; + if res.is_null() { + return Err(value_error("unsupported locale setting")); + } + Ok(Object::from_str(decode_locale_cstr(res))) + } + Some(_) => Err(crate::error::type_error( + "setlocale: locale must be str or None", + )), + } +} + +/// CPython's `copy_grouping`: the lconv grouping byte string becomes a list +/// of ints, keeping a trailing `CHAR_MAX` terminator and stopping there. +fn copy_grouping(ptr: *const libc::c_char) -> Object { + if ptr.is_null() { + return Object::new_list(vec![]); + } + // SAFETY: lconv grouping fields are NUL-terminated byte strings. + let bytes = unsafe { CStr::from_ptr(ptr) }.to_bytes(); + let mut out = Vec::new(); + for &b in bytes { + out.push(Object::Int(i64::from(b))); + if i64::from(b) == CHAR_MAX { + break; + } + } + Object::new_list(out) } fn l_localeconv(_args: &[Object]) -> Result { let mut d = DictData::default(); - macro_rules! ins { - ($k:literal, $v:expr) => { - d.insert(DictKey(Object::from_static($k)), $v); - }; + // SAFETY: `localeconv` returns a pointer to static libc storage, valid + // until the next `localeconv`/`setlocale` call; we copy everything out + // immediately. + let lc = unsafe { &*libc::localeconv() }; + let mut ins_str = |k: &'static str, p: *const libc::c_char| { + d.insert( + DictKey(Object::from_static(k)), + Object::from_str(decode_locale_cstr(p)), + ); + }; + ins_str("decimal_point", lc.decimal_point); + ins_str("thousands_sep", lc.thousands_sep); + ins_str("int_curr_symbol", lc.int_curr_symbol); + ins_str("currency_symbol", lc.currency_symbol); + ins_str("mon_decimal_point", lc.mon_decimal_point); + ins_str("mon_thousands_sep", lc.mon_thousands_sep); + ins_str("positive_sign", lc.positive_sign); + ins_str("negative_sign", lc.negative_sign); + let mut ins = |k: &'static str, v: Object| { + d.insert(DictKey(Object::from_static(k)), v); + }; + ins("grouping", copy_grouping(lc.grouping)); + ins("mon_grouping", copy_grouping(lc.mon_grouping)); + for (k, v) in [ + ("int_frac_digits", lc.int_frac_digits), + ("frac_digits", lc.frac_digits), + ("p_cs_precedes", lc.p_cs_precedes), + ("p_sep_by_space", lc.p_sep_by_space), + ("n_cs_precedes", lc.n_cs_precedes), + ("n_sep_by_space", lc.n_sep_by_space), + ("p_sign_posn", lc.p_sign_posn), + ("n_sign_posn", lc.n_sign_posn), + ] { + ins(k, Object::Int(i64::from(v))); } - ins!("decimal_point", Object::from_static(".")); - ins!("thousands_sep", Object::from_static("")); - ins!("grouping", Object::new_list(vec![])); - ins!("int_curr_symbol", Object::from_static("")); - ins!("currency_symbol", Object::from_static("")); - ins!("mon_decimal_point", Object::from_static("")); - ins!("mon_thousands_sep", Object::from_static("")); - ins!("mon_grouping", Object::new_list(vec![])); - ins!("positive_sign", Object::from_static("")); - ins!("negative_sign", Object::from_static("")); - ins!("int_frac_digits", Object::Int(CHAR_MAX)); - ins!("frac_digits", Object::Int(CHAR_MAX)); - ins!("p_cs_precedes", Object::Int(CHAR_MAX)); - ins!("p_sep_by_space", Object::Int(CHAR_MAX)); - ins!("n_cs_precedes", Object::Int(CHAR_MAX)); - ins!("n_sep_by_space", Object::Int(CHAR_MAX)); - ins!("p_sign_posn", Object::Int(CHAR_MAX)); - ins!("n_sign_posn", Object::Int(CHAR_MAX)); Ok(Object::Dict(Rc::new(RefCell::new(d)))) } +/// A NUL-terminated wide-char copy of `s` for `wcscoll`/`wcsxfrm`. +fn to_wide(s: &str) -> Vec { + let mut v: Vec = s.chars().map(|c| c as u32 as libc::wchar_t).collect(); + v.push(0); + v +} + +fn arg_str(args: &[Object], idx: usize, fname: &str) -> Result { + match args.get(idx) { + Some(Object::Str(s)) => Ok(s.to_string()), + _ => Err(crate::error::type_error(format!( + "{fname}() argument must be str" + ))), + } +} + fn l_strcoll(args: &[Object]) -> Result { - let a = args.first().map(|o| o.to_str()).unwrap_or_default(); - let b = args.get(1).map(|o| o.to_str()).unwrap_or_default(); - use std::cmp::Ordering; - Ok(Object::Int(match a.cmp(&b) { - Ordering::Less => -1, - Ordering::Equal => 0, - Ordering::Greater => 1, - })) + let a = to_wide(&arg_str(args, 0, "strcoll")?); + let b = to_wide(&arg_str(args, 1, "strcoll")?); + // SAFETY: both buffers are NUL-terminated wide strings. + let r = unsafe { wcscoll(a.as_ptr(), b.as_ptr()) }; + Ok(Object::Int(i64::from(r))) } fn l_strxfrm(args: &[Object]) -> Result { - Ok(args.first().cloned().unwrap_or(Object::from_static(""))) + let s = arg_str(args, 0, "strxfrm")?; + let src = to_wide(&s); + // SAFETY: sizing call with a NULL destination, then a copy into a + // buffer of the reported length (+1 for the terminator). + unsafe { + let needed = wcsxfrm(std::ptr::null_mut(), src.as_ptr(), 0); + if needed == usize::MAX { + return Err(value_error("invalid string for strxfrm")); + } + let mut buf = vec![0 as libc::wchar_t; needed + 1]; + let written = wcsxfrm(buf.as_mut_ptr(), src.as_ptr(), needed + 1); + if written == usize::MAX || written > needed { + return Err(value_error("invalid string for strxfrm")); + } + Ok(Object::from_str( + buf[..written] + .iter() + .filter_map(|&w| char::from_u32(w as u32)) + .collect::(), + )) + } } fn l_nl_langinfo(args: &[Object]) -> Result { - let _ = args; - Ok(Object::from_static("")) + let item = match args.first() { + Some(Object::Int(n)) => *n, + _ => { + return Err(crate::error::type_error( + "nl_langinfo() argument must be an integer", + )) + } + }; + if !langinfo_constants().iter().any(|(_, v)| *v == item) { + return Err(value_error("unsupported langinfo constant")); + } + // SAFETY: `item` was validated against the platform's known constants. + let ptr = unsafe { libc::nl_langinfo(item as libc::nl_item) }; + Ok(Object::from_str(decode_locale_cstr(ptr))) +} + +/// The current `LC_CTYPE` codeset (`nl_langinfo(CODESET)`), with the +/// UTF-8 fallback CPython's `_Py_GetLocaleEncoding` applies when the +/// codeset is empty. +pub fn current_codeset() -> String { + // SAFETY: CODESET is a valid langinfo item on all supported hosts. + let ptr = unsafe { libc::nl_langinfo(libc::CODESET) }; + let name = decode_locale_cstr(ptr); + if name.is_empty() { + "UTF-8".to_owned() + } else { + name + } +} + +/// `_locale.getencoding()` — the current `LC_CTYPE` codeset. +fn l_getencoding(_args: &[Object]) -> Result { + Ok(Object::from_str(current_codeset())) +} + +/// The `nl_langinfo` item constants exported on this platform, mirroring +/// CPython's `langinfo_constants` table in `_localemodule.c`. +fn langinfo_constants() -> &'static [(&'static str, i64)] { + static CONSTANTS: std::sync::OnceLock> = std::sync::OnceLock::new(); + CONSTANTS + .get_or_init(|| { + vec![ + ("CODESET", i64::from(libc::CODESET)), + ("D_T_FMT", i64::from(libc::D_T_FMT)), + ("D_FMT", i64::from(libc::D_FMT)), + ("T_FMT", i64::from(libc::T_FMT)), + ("T_FMT_AMPM", i64::from(libc::T_FMT_AMPM)), + ("AM_STR", i64::from(libc::AM_STR)), + ("PM_STR", i64::from(libc::PM_STR)), + ("DAY_1", i64::from(libc::DAY_1)), + ("DAY_2", i64::from(libc::DAY_2)), + ("DAY_3", i64::from(libc::DAY_3)), + ("DAY_4", i64::from(libc::DAY_4)), + ("DAY_5", i64::from(libc::DAY_5)), + ("DAY_6", i64::from(libc::DAY_6)), + ("DAY_7", i64::from(libc::DAY_7)), + ("ABDAY_1", i64::from(libc::ABDAY_1)), + ("ABDAY_2", i64::from(libc::ABDAY_2)), + ("ABDAY_3", i64::from(libc::ABDAY_3)), + ("ABDAY_4", i64::from(libc::ABDAY_4)), + ("ABDAY_5", i64::from(libc::ABDAY_5)), + ("ABDAY_6", i64::from(libc::ABDAY_6)), + ("ABDAY_7", i64::from(libc::ABDAY_7)), + ("MON_1", i64::from(libc::MON_1)), + ("MON_2", i64::from(libc::MON_2)), + ("MON_3", i64::from(libc::MON_3)), + ("MON_4", i64::from(libc::MON_4)), + ("MON_5", i64::from(libc::MON_5)), + ("MON_6", i64::from(libc::MON_6)), + ("MON_7", i64::from(libc::MON_7)), + ("MON_8", i64::from(libc::MON_8)), + ("MON_9", i64::from(libc::MON_9)), + ("MON_10", i64::from(libc::MON_10)), + ("MON_11", i64::from(libc::MON_11)), + ("MON_12", i64::from(libc::MON_12)), + ("ABMON_1", i64::from(libc::ABMON_1)), + ("ABMON_2", i64::from(libc::ABMON_2)), + ("ABMON_3", i64::from(libc::ABMON_3)), + ("ABMON_4", i64::from(libc::ABMON_4)), + ("ABMON_5", i64::from(libc::ABMON_5)), + ("ABMON_6", i64::from(libc::ABMON_6)), + ("ABMON_7", i64::from(libc::ABMON_7)), + ("ABMON_8", i64::from(libc::ABMON_8)), + ("ABMON_9", i64::from(libc::ABMON_9)), + ("ABMON_10", i64::from(libc::ABMON_10)), + ("ABMON_11", i64::from(libc::ABMON_11)), + ("ABMON_12", i64::from(libc::ABMON_12)), + ("RADIXCHAR", i64::from(libc::RADIXCHAR)), + ("THOUSEP", i64::from(libc::THOUSEP)), + ("YESEXPR", i64::from(libc::YESEXPR)), + ("NOEXPR", i64::from(libc::NOEXPR)), + ("CRNCYSTR", i64::from(libc::CRNCYSTR)), + ("ERA", i64::from(libc::ERA)), + ("ERA_D_T_FMT", i64::from(libc::ERA_D_T_FMT)), + ("ERA_D_FMT", i64::from(libc::ERA_D_FMT)), + ("ERA_T_FMT", i64::from(libc::ERA_T_FMT)), + ("ALT_DIGITS", i64::from(libc::ALT_DIGITS)), + ] + }) + .as_slice() } diff --git a/crates/weavepy-vm/src/stdlib/marshal_mod.rs b/crates/weavepy-vm/src/stdlib/marshal_mod.rs index 83c9f4e..3bb3772 100644 --- a/crates/weavepy-vm/src/stdlib/marshal_mod.rs +++ b/crates/weavepy-vm/src/stdlib/marshal_mod.rs @@ -374,7 +374,7 @@ impl MarshalWriter { self.write_int(co.kwonly_count as i32); self.write_int(cp.stacksize as i32); self.write_int(code_flags(co) as i32); - self.write_value(&Object::new_bytes(cp.co_code))?; + self.write_value(&Object::new_bytes(cp.co_code.clone()))?; let consts: Vec = co .constants .iter() @@ -384,7 +384,7 @@ impl MarshalWriter { self.write_value(&Object::new_tuple(consts))?; self.write_value(&strs_to_tuple(&co.names))?; self.write_value(&strs_to_tuple(&cp.localsplusnames))?; - self.write_value(&Object::new_bytes(cp.localspluskinds))?; + self.write_value(&Object::new_bytes(cp.localspluskinds.clone()))?; self.write_value(&Object::from_str(co.filename.clone()))?; self.write_value(&Object::from_str(co.name.clone()))?; // PEP 3155 qualified name, computed at compile time from lexical @@ -392,8 +392,8 @@ impl MarshalWriter { // unmarshalled function/class keeps a faithful `__qualname__`. self.write_value(&Object::from_str(co.qualname.clone()))?; self.write_int(cp.firstlineno as i32); - self.write_value(&Object::new_bytes(cp.co_linetable))?; - self.write_value(&Object::new_bytes(cp.co_exceptiontable))?; + self.write_value(&Object::new_bytes(cp.co_linetable.clone()))?; + self.write_value(&Object::new_bytes(cp.co_exceptiontable.clone()))?; Ok(()) } } @@ -761,6 +761,7 @@ impl<'a> MarshalReader<'a> { is_coroutine: flags & CO_COROUTINE != 0, is_async_generator: flags & CO_ASYNC_GENERATOR != 0, is_iterable_coroutine: flags & CO_ITERABLE_COROUTINE != 0, + cp_cache: cpython_code::CpCache::default(), }; Ok(Object::Code(Rc::new(co))) } diff --git a/crates/weavepy-vm/src/stdlib/mod.rs b/crates/weavepy-vm/src/stdlib/mod.rs index 646f845..ff2f095 100644 --- a/crates/weavepy-vm/src/stdlib/mod.rs +++ b/crates/weavepy-vm/src/stdlib/mod.rs @@ -19,6 +19,7 @@ pub mod ast_mod; pub mod binascii_mod; pub mod bisect_accel; pub mod bz2_mod; +pub mod codecs_engine; pub mod codecs_mod; pub mod csv_mod; pub mod datetime_mod; @@ -63,7 +64,7 @@ pub mod testinternalcapi_mod; pub mod thread; pub mod time; pub mod tracemalloc_real; -mod unicode_decomp_data; +pub mod ucd; pub mod unicodedata_mod; pub mod weakref_mod; pub mod zlib_mod; @@ -254,7 +255,9 @@ pub fn register_all(cache: &ModuleCache) { } fn frozen_sources() -> &'static [FrozenSource] { - &[ + // A `static`, not a promoted local: the table is far past clippy's + // stack-array budget (`large_stack_arrays`). + static SOURCES: &[FrozenSource] = &[ FrozenSource { name: "builtins", source: include_str!("python/builtins.py"), @@ -1327,6 +1330,387 @@ fn frozen_sources() -> &'static [FrozenSource] { source: include_str!("python/encodings/cp737.py"), is_package: false, }, + // Vendored verbatim from CPython 3.13 for code that reaches into the + // `encodings` package directly (`encodings.ascii.StreamReader`, + // `from encodings.rot_13 import rot13`, the always-raising + // `undefined` codec). + FrozenSource { + name: "encodings.ascii", + source: include_str!("python/encodings/ascii.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.utf_8", + source: include_str!("python/encodings/utf_8.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.rot_13", + source: include_str!("python/encodings/rot_13.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.undefined", + source: include_str!("python/encodings/undefined.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.base64_codec", + source: include_str!("python/encodings/base64_codec.py"), + is_package: false, + }, + // gencodec.py charmap codepages vendored verbatim from CPython 3.13; + // they ride the frozen `codecs.charmap_encode`/`charmap_decode`. + FrozenSource { + name: "encodings.cp856", + source: include_str!("python/encodings/cp856.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp874", + source: include_str!("python/encodings/cp874.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp875", + source: include_str!("python/encodings/cp875.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1006", + source: include_str!("python/encodings/cp1006.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1125", + source: include_str!("python/encodings/cp1125.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1140", + source: include_str!("python/encodings/cp1140.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.koi8_t", + source: include_str!("python/encodings/koi8_t.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.kz1048", + source: include_str!("python/encodings/kz1048.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_arabic", + source: include_str!("python/encodings/mac_arabic.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.palmos", + source: include_str!("python/encodings/palmos.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.ptcp154", + source: include_str!("python/encodings/ptcp154.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.tis_620", + source: include_str!("python/encodings/tis_620.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.charmap", + source: include_str!("python/encodings/charmap.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.latin_1", + source: include_str!("python/encodings/latin_1.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1026", + source: include_str!("python/encodings/cp1026.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1250", + source: include_str!("python/encodings/cp1250.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1251", + source: include_str!("python/encodings/cp1251.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1252", + source: include_str!("python/encodings/cp1252.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1253", + source: include_str!("python/encodings/cp1253.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1254", + source: include_str!("python/encodings/cp1254.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1255", + source: include_str!("python/encodings/cp1255.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1256", + source: include_str!("python/encodings/cp1256.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1257", + source: include_str!("python/encodings/cp1257.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp1258", + source: include_str!("python/encodings/cp1258.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp273", + source: include_str!("python/encodings/cp273.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp424", + source: include_str!("python/encodings/cp424.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp437", + source: include_str!("python/encodings/cp437.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp500", + source: include_str!("python/encodings/cp500.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp720", + source: include_str!("python/encodings/cp720.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp775", + source: include_str!("python/encodings/cp775.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp850", + source: include_str!("python/encodings/cp850.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp852", + source: include_str!("python/encodings/cp852.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp855", + source: include_str!("python/encodings/cp855.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp857", + source: include_str!("python/encodings/cp857.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp858", + source: include_str!("python/encodings/cp858.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp860", + source: include_str!("python/encodings/cp860.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp861", + source: include_str!("python/encodings/cp861.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp862", + source: include_str!("python/encodings/cp862.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp863", + source: include_str!("python/encodings/cp863.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp864", + source: include_str!("python/encodings/cp864.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp865", + source: include_str!("python/encodings/cp865.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp866", + source: include_str!("python/encodings/cp866.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.cp869", + source: include_str!("python/encodings/cp869.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.hp_roman8", + source: include_str!("python/encodings/hp_roman8.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_1", + source: include_str!("python/encodings/iso8859_1.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_2", + source: include_str!("python/encodings/iso8859_2.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_3", + source: include_str!("python/encodings/iso8859_3.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_4", + source: include_str!("python/encodings/iso8859_4.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_5", + source: include_str!("python/encodings/iso8859_5.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_6", + source: include_str!("python/encodings/iso8859_6.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_7", + source: include_str!("python/encodings/iso8859_7.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_8", + source: include_str!("python/encodings/iso8859_8.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_9", + source: include_str!("python/encodings/iso8859_9.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_10", + source: include_str!("python/encodings/iso8859_10.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_11", + source: include_str!("python/encodings/iso8859_11.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_13", + source: include_str!("python/encodings/iso8859_13.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_14", + source: include_str!("python/encodings/iso8859_14.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_15", + source: include_str!("python/encodings/iso8859_15.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.iso8859_16", + source: include_str!("python/encodings/iso8859_16.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.koi8_r", + source: include_str!("python/encodings/koi8_r.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.koi8_u", + source: include_str!("python/encodings/koi8_u.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_croatian", + source: include_str!("python/encodings/mac_croatian.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_cyrillic", + source: include_str!("python/encodings/mac_cyrillic.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_farsi", + source: include_str!("python/encodings/mac_farsi.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_greek", + source: include_str!("python/encodings/mac_greek.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_iceland", + source: include_str!("python/encodings/mac_iceland.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_latin2", + source: include_str!("python/encodings/mac_latin2.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_roman", + source: include_str!("python/encodings/mac_roman.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_romanian", + source: include_str!("python/encodings/mac_romanian.py"), + is_package: false, + }, + FrozenSource { + name: "encodings.mac_turkish", + source: include_str!("python/encodings/mac_turkish.py"), + is_package: false, + }, // RFC 0042 WS5 — application-protocol clients, vendored verbatim from // CPython 3.13. They ride the WS1 `socket`/`makefile()` and WS2 `ssl` // stacks (`*_SSL` variants, `starttls`/`stls`). `nntplib`/`telnetlib` @@ -1455,6 +1839,47 @@ fn frozen_sources() -> &'static [FrozenSource] { source: include_str!("python/_codec_euc_jis_2004.py"), is_package: false, }, + // RFC 0050 WS3 — the stateful CJK escape codecs CPython implements in + // Modules/cjkcodecs (hz, iso2022_jp/_1/_2/_2004/_3/_ext, iso2022_kr, + // johab, shift_jis_2004, shift_jisx0213). Charsets bridge onto the + // euc_jp/euc_kr/gb2312 backends and the euc_jis_2004 tables; loaded + // lazily by `codecs._lookup_uncached`. + FrozenSource { + name: "_codec_cjk_ext", + source: include_str!("python/_codec_cjk_ext.py"), + is_package: false, + }, + // RFC 0050 WS3 — the stateless CJK DBCS codecs (euc_kr, cp949, + // euc_jp, cp932, shift_jis, gb2312, gbk, gb18030, big5, cp950, + // big5hkscs) with CPython-parity mapping tables probed from CPython + // 3.13 itself (`tools/gen_cjk_dbcs_tables.py`). Loaded lazily by + // `codecs._lookup_uncached`. + FrozenSource { + name: "_cjk_tables", + source: include_str!("python/_cjk_tables.py"), + is_package: false, + }, + FrozenSource { + name: "_codec_cjk_dbcs", + source: include_str!("python/_codec_cjk_dbcs.py"), + is_package: false, + }, + // Shared plumbing for the three frozen CJK codec modules above: + // multibytecodec.c's error-callback protocol, the `errors` getset, + // and `StreamReader.read(None)` support. + FrozenSource { + name: "_cjk_common", + source: include_str!("python/_cjk_common.py"), + is_package: false, + }, + // The `_multibytecodec` module surface (CPython's C base types for + // the CJK codecs). WeavePy's CJK codecs are frozen Python modules, + // so only the module-level names matter here. + FrozenSource { + name: "_multibytecodec", + source: include_str!("python/_multibytecodec.py"), + is_package: false, + }, FrozenSource { name: "weakref", source: include_str!("python/weakref.py"), @@ -2422,5 +2847,6 @@ fn frozen_sources() -> &'static [FrozenSource] { source: include_str!("python/_testcapi.py"), is_package: false, }, - ] + ]; + SOURCES } diff --git a/crates/weavepy-vm/src/stdlib/python/_cjk_common.py b/crates/weavepy-vm/src/stdlib/python/_cjk_common.py new file mode 100644 index 0000000..5c182af --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/_cjk_common.py @@ -0,0 +1,256 @@ +"""Shared plumbing for WeavePy's frozen CJK codec ports. + +Reproduces `Modules/cjkcodecs/multibytecodec.c`'s error-callback protocol +(`multibytecodec_encerror` / `multibytecodec_decerror`) so the three codec +modules (`_codec_cjk_dbcs`, `_codec_cjk_ext`, `_codec_euc_jis_2004`) behave +exactly like CPython's C classes: + +- a custom handler must return a ``(str-or-bytes, int)`` tuple when encoding + and a ``(str, int)`` tuple when decoding — anything else is a + ``TypeError``; +- an out-of-bounds resume position is an ``IndexError`` (after negative + wrap-around), not a silent clamp; +- ``errors`` on the incremental codecs is a getset (``del enc.errors`` + raises ``AttributeError`` — `test_incrementalencoder_del_segfault`); +- the multibyte stream readers accept ``None`` size hints and final-flush + their decoder at EOF (a trailing partial sequence raises); +- ``getstate``/``setstate`` use the C layout: encoders pack + ``[npending][pending as UTF-8][8 codec state bytes]`` into a + little-endian int, decoders exchange ``(buffered bytes, state int)``. +""" + +from codecs import StreamReader, lookup_error as _lookup_error + +_REASON = "illegal multibyte sequence" +_REASON_INCOMPLETE = "incomplete multibyte sequence" + +# multibytecodec.h: MAXENCPENDING = 2 UCS4 chars (8 UTF-8 bytes at the +# Python level), MAXDECPENDING = 8 bytes, sizeof(MULTIBYTECODEC_STATE.c) = 8. +MAXENCPENDING = 8 +MAXDECPENDING = 8 +STATE_SIZE = 8 + + +def _backslash(ch): + c = ord(ch) + if c >= 0x10000: + return "\\U%08x" % c + if c >= 0x100: + return "\\u%04x" % c + return "\\x%02x" % c + + +def enc_handle(name, errors, s, start, end, reason=_REASON): + """Resolve an unencodable run -> (replacement, new_index). The + replacement may be ``str`` (must be re-encoded by the caller with + strict errors) or ``bytes`` (emitted verbatim).""" + if errors == "strict": + raise UnicodeEncodeError(name, s, start, end, reason) + if errors == "ignore": + return ("", end) + if errors == "replace": + return ("?" * (end - start), end) + if errors == "xmlcharrefreplace": + return ("".join("&#%d;" % ord(c) for c in s[start:end]), end) + if errors == "backslashreplace": + return ("".join(_backslash(c) for c in s[start:end]), end) + if errors == "namereplace": + import unicodedata + + parts = [] + for c in s[start:end]: + try: + parts.append("\\N{%s}" % unicodedata.name(c)) + except ValueError: + parts.append(_backslash(c)) + return ("".join(parts), end) + handler = _lookup_error(errors) + r = handler(UnicodeEncodeError(name, s, start, end, reason)) + if ( + not isinstance(r, tuple) + or len(r) != 2 + or not isinstance(r[0], (str, bytes)) + or not isinstance(r[1], int) + ): + raise TypeError("encoding error handler must return (str, int) tuple") + rep, newpos = r + if newpos < 0: + newpos += len(s) + if newpos < 0 or newpos > len(s): + raise IndexError( + "position %d from error handler out of bounds" % newpos + ) + return (rep, newpos) + + +def dec_handle(name, errors, data, start, end, reason): + """Resolve an undecodable run -> (str, new_index).""" + if errors == "strict": + raise UnicodeDecodeError(name, bytes(data), start, end, reason) + if errors == "ignore": + return ("", end) + if errors == "replace": + return ("\ufffd", end) + if errors == "backslashreplace": + return ("".join("\\x%02x" % b for b in data[start:end]), end) + handler = _lookup_error(errors) + r = handler(UnicodeDecodeError(name, bytes(data), start, end, reason)) + if ( + not isinstance(r, tuple) + or len(r) != 2 + or not isinstance(r[0], str) + or not isinstance(r[1], int) + ): + raise TypeError("decoding error handler must return (str, int) tuple") + rep, newpos = r + if newpos < 0: + newpos += len(data) + if newpos < 0 or newpos > len(data): + raise IndexError( + "position %d from error handler out of bounds" % newpos + ) + return (rep, newpos) + + +def enc_getstate(pending, statebytes=b""): + """Pack an incremental encoder's state exactly like + ``MultibyteIncrementalEncoder.getstate``: a little-endian int of + ``[len(pending-utf8)][pending-utf8][codec state bytes]``.""" + u8 = pending.encode("utf-8") + return int.from_bytes(bytes((len(u8),)) + u8 + bytes(statebytes), "little") + + +def enc_setstate(state): + """Unpack ``setstate`` input -> (pending_str, statebytes). + Mirrors the C validation: int-only argument, unsigned and bounded + (OverflowError), pending capped at MAXENCPENDING (UnicodeError) and + strictly decoded as UTF-8 (UnicodeDecodeError).""" + if not isinstance(state, int): + raise TypeError( + "setstate() argument must be int, not %s" % type(state).__name__ + ) + raw = state.to_bytes(1 + MAXENCPENDING + STATE_SIZE, "little") + npending = raw[0] + if npending > MAXENCPENDING: + raise UnicodeError("pending buffer too large") + pending = raw[1:1 + npending].decode("utf-8") + return (pending, raw[1 + npending:1 + npending + STATE_SIZE]) + + +def dec_setstate(state, name): + """Unpack decoder ``setstate`` input -> (buffer_bytes, flags_int).""" + if not isinstance(state, tuple): + raise TypeError( + "setstate() argument must be tuple, not %s" % type(state).__name__ + ) + if ( + len(state) != 2 + or type(state[0]) is not bytes + or not isinstance(state[1], int) + ): + raise TypeError("setstate(): illegal state argument") + buf, flags = state + flags.to_bytes(STATE_SIZE, "little") # OverflowError parity with C + if len(buf) > MAXDECPENDING: + raise UnicodeDecodeError( + name, buf, 0, len(buf), "pending buffer too large" + ) + return (buf, flags) + + +class MbEncStateMixin: + """C-layout ``getstate``/``setstate`` for encoders whose only state is a + pending string held in ``self._pending`` (the codec state bytes stay + zero).""" + + def getstate(self): + return enc_getstate(self._pending) + + def setstate(self, state): + pending, _statebytes = enc_setstate(state) + self._pending = pending + + +class MbDecStateMixin: + """C-layout ``getstate``/``setstate`` for decoders whose only state is a + buffered byte tail in ``self._buffer``; the state int is carried + verbatim (CPython round-trips the raw ``state.c`` bytes).""" + + name = None + _flags = 0 + + def getstate(self): + return (self._buffer, self._flags) + + def setstate(self, state): + self._buffer, self._flags = dec_setstate(state, self.name) + + +class ErrorsProperty: + """CPython's multibyte codec objects expose ``errors`` as a getset: + it can be read and assigned but not deleted.""" + + @property + def errors(self): + return self._errors + + @errors.setter + def errors(self, value): + self._errors = value + + +class MbStreamReaderMixin: + """CPython's MultibyteStreamReader accepts ``None`` size hints + (``read(None)`` = read everything) and finalizes the decoder at EOF, so + a dangling partial multibyte sequence raises (`test_bug1728403`); the + generic ``codecs.StreamReader`` does neither.""" + + def _decode_flush(self): + """Final-decode whatever the reader is still holding at EOF.""" + dec = getattr(self, "_decoder", None) + if dec is not None: + return dec.decode(b"", True) + return "" + + def read(self, size=-1, chars=-1, firstline=False): + # codecs.StreamReader.read with two changes: a None size hint reads + # everything, and hitting EOF final-flushes the decoder. + if size is None: + size = -1 + if self.linebuffer: + self.charbuffer = self._empty_charbuffer.join(self.linebuffer) + self.linebuffer = None + if chars < 0: + chars = size + while True: + if chars >= 0 and len(self.charbuffer) >= chars: + break + if size < 0: + newdata = self.stream.read() + else: + newdata = self.stream.read(size) + data = self.bytebuffer + newdata + if data: + try: + newchars, decodedbytes = self.decode(data, self.errors) + except UnicodeDecodeError as exc: + if not firstline: + raise + newchars, decodedbytes = self.decode( + data[: exc.start], self.errors + ) + lines = newchars.splitlines(keepends=True) + if len(lines) <= 1: + raise + self.bytebuffer = data[decodedbytes:] + self.charbuffer += newchars + if not newdata: + self.charbuffer += self._decode_flush() + break + if chars < 0: + result = self.charbuffer + self.charbuffer = self._empty_charbuffer + else: + result = self.charbuffer[:chars] + self.charbuffer = self.charbuffer[chars:] + return result diff --git a/crates/weavepy-vm/src/stdlib/python/_cjk_tables.py b/crates/weavepy-vm/src/stdlib/python/_cjk_tables.py new file mode 100644 index 0000000..c905a02 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/_cjk_tables.py @@ -0,0 +1,8023 @@ +"""Packed CJK DBCS mapping tables (generated; do not edit). + +Generated by `tools/gen_cjk_dbcs_tables.py` by probing CPython +3.13.13's cjkcodecs. See `_codec_cjk_dbcs` for the codec +state machines that consume these tables.""" + +import base64 as _b64 + +LEAD_LO, TRAIL_LO, NTRAIL = 0x81, 0x40, 191 + +def _g(s): + return _b64.b64decode(s) + +# ---- euc_kr ---- +EUC_KR_DEC = _g( + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////wAwATACMLcAJSAmIKgAAzCtABUgJSI8/zwiGCAZIBwgHSAUMBUw" + "CDAJMAowCzAMMA0wDjAPMBAwETCxANcA9wBgImQiZSIeIjQisAAyIDMgAyErIeD/4f/l/0ImQCYgIqUiEiMCIgciYSJSIqcA" + "OyAGJgUmyyXPJc4lxyXGJaEloCWzJbIlvSW8JZIhkCGRIZMhlCETMGoiayIaIj0iHSI1IisiLCIIIgsihiKHIoIigyIqIiki" + "JyIoIuL/////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////////////////////SIdQhACIDIrQAXv/HAtgC" + "3QLaAtkCuADbAqEAvwDQAi4iESIPIqQACSEwIMElwCW3JbYlZCZgJmEmZSZnJmMmmSLIJaMl0CXRJZIlpCWlJaglpyWmJakl" + "aCYPJg4mHCYeJrYAICAhIJUhlyGZIZYhmCFtJmkmaiZsJn8yHDIWIcczIiHCM9gzISGsIK4A////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////Af8C/wP/BP8F/wb/B/8I/wn/Cv8L/wz/Df8O/w//EP8R/xL/E/8U/xX/Fv8X/xj/Gf8a/xv/HP8d/x7/H/8g/yH/" + "Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov87/+b/Pf8+/z//QP9B/0L/Q/9E/0X/" + "Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/W/9c/13/4///////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////zExMjEzMTQxNTE2MTcxODE5MToxOzE8MT0xPjE/MUAxQTFCMUMxRDFFMUYx" + "RzFIMUkxSjFLMUwxTTFOMU8xUDFRMVIxUzFUMVUxVjFXMVgxWTFaMVsxXDFdMV4xXzFgMWExYjFjMf//ZTFmMWcxaDFpMWox" + "azFsMW0xbjFvMXAxcTFyMXMxdDF1MXYxdzF4MXkxejF7MXwxfTF+MX8xgDGBMYIxgzGEMYUxhjGHMYgxiTGKMYsxjDGNMY4x" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////9wIXEhciFzIXQhdSF2IXcheCF5If//" + "//////////9gIWEhYiFjIWQhZSFmIWchaCFpIf//////////////////kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58D" + "oAOhA6MDpAOlA6YDpwOoA6kD/////////////////////7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QD" + "xQPGA8cDyAPJA///////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "ACUCJQwlECUYJRQlHCUsJSQlNCU8JQElAyUPJRMlGyUXJSMlMyUrJTslSyUgJS8lKCU3JT8lHSUwJSUlOCVCJRIlESUaJRkl" + "FiUVJQ4lDSUeJR8lISUiJSYlJyUpJSolLSUuJTElMiU1JTYlOSU6JT0lPiVAJUElQyVEJUUlRiVHJUglSSVKJf//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////5UzljOXMxMhmDPEM6MzpDOlM6YzmTOaM5sznDOdM54znzOgM6EzojPKM40zjjOPM88z" + "iDOJM8gzpzOoM7AzsTOyM7MztDO1M7YztzO4M7kzgDOBM4IzgzOEM7ozuzO8M70zvjO/M5AzkTOSM5MzlDMmIcAzwTOKM4sz" + "jDPWM8UzrTOuM68z2zOpM6ozqzOsM90z0DPTM8MzyTPcM8Yz////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////GANAAqgAmAf//MgH//z8BQQHYAFIBugDeAGYB" + "SgH//2AyYTJiMmMyZDJlMmYyZzJoMmkyajJrMmwybTJuMm8ycDJxMnIyczJ0MnUydjJ3MngyeTJ6Mnsy0CTRJNIk0yTUJNUk" + "1iTXJNgk2STaJNsk3CTdJN4k3yTgJOEk4iTjJOQk5STmJOck6CTpJGAkYSRiJGMkZCRlJGYkZyRoJGkkaiRrJGwkbSRuJL0A" + "UyFUIbwAvgBbIVwhXSFeIf//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////5gARAfAA" + "JwExATMBOAFAAUIB+ABTAd8A/gBnAUsBSQEAMgEyAjIDMgQyBTIGMgcyCDIJMgoyCzIMMg0yDjIPMhAyETISMhMyFDIVMhYy" + "FzIYMhkyGjIbMpwknSSeJJ8koCShJKIkoySkJKUkpiSnJKgkqSSqJKskrCStJK4krySwJLEksiSzJLQktSR0JHUkdiR3JHgk" + "eSR6JHskfCR9JH4kfySAJIEkgiS5ALIAswB0IH8ggSCCIIMghCD/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////0EwQjBDMEQwRTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYwVzBYMFkwWjBbMFww" + "XTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgwaTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHowezB8MH0wfjB/MIAw" + "gTCCMIMwhDCFMIYwhzCIMIkwijCLMIwwjTCOMI8wkDCRMJIwkzD/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////+hMKIwozCkMKUwpjCnMKgwqTCqMKswrDCtMK4wrzCwMLEw" + "sjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w0DDRMNIw0zDUMNUw" + "1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw4jDjMOQw5TDmMOcw6DDpMOow6zDsMO0w7jDvMPAw8TDyMPMw9DD1MPYw////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////EAQRBBIEEwQUBBUE" + "AQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8E////////////////////////" + "////////////////MAQxBDIEMwQ0BDUEUQQ2BDcEOAQ5BDoEOwQ8BD0EPgQ/BEAEQQRCBEMERARFBEYERwRIBEkESgRLBEwE" + "TQROBE8E////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////wCsAawErAesCKwJrAqsEKwRrBKsE6wUrBWsFqwXrBmsGqwbrBysHawgrCSsLKwtrC+sMKwxrDisOaw8rECsS6xNrFSs" + "WKxcrHCscax0rHeseKx6rICsgayDrISshayGrImsiqyLrIyskKyUrJysnayfrKCsoayorKmsqqysrK+ssKy4rLmsu6y8rL2s" + "wazErMiszKzVrNes4KzhrOSs56zorOqs7KzvrPCs8azzrPWs9qz8rP2sAK0ErQat////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////8MrQ2tD60RrRitHK0grSmtLK0trTStNa04rTytRK1FrUetSa1QrVStWK1hrWOt" + "bK1trXCtc610rXWtdq17rXytfa1/rYGtgq2IrYmtjK2QrZytna2krbetwK3BrcStyK3QrdGt063creCt5K34rfmt/K3/rQCu" + "Aa4IrgmuC64NrhSuMK4xrjSuN644rjquQK5BrkOuRa5GrkquTK5Nrk6uUK5UrlauXK5drl+uYK5hrmWuaK5prmyucK54rv//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////ea57rnyufa6EroWujK68rr2uvq7ArsSu" + "zK7Nrs+u0K7Rrtiu2a7cruiu667trvSu+K78rgevCK8NrxCvLK8trzCvMq80rzyvPa8/r0GvQq9Dr0ivSa9Qr1yvXa9kr2Wv" + "ea+Ar4SviK+Qr5Gvla+cr7ivua+8r8Cvx6/Ir8mvy6/Nr86v1K/cr+iv6a/wr/Gv9K/4rwCwAbAEsAywELAUsBywHbAosESw" + "RbBIsEqwTLBOsFOwVLBVsFewWbD/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////12w" + "fLB9sICwhLCMsI2wj7CRsJiwmbCasJywn7CgsKGworCosKmwq7CssK2wrrCvsLGws7C0sLWwuLC8sMSwxbDHsMiwybDQsNGw" + "1LDYsOCw5bAIsQmxC7EMsRCxErETsRixGbEbsRyxHbEjsSSxJbEosSyxNLE1sTexOLE5sUCxQbFEsUixULFRsVSxVbFYsVyx" + "YLF4sXmxfLGAsYKxiLGJsYuxjbGSsZOxlLGYsZyxqLHMsdCx1LHcsd2x////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////fseix6bHssfCx+bH7sf2xBLIFsgiyC7IMshSyFbIXshmyILI0sjyyWLJcsmCyaLJpsnSy" + "dbJ8soSyhbKJspCykbKUspiymbKasqCyobKjsqWyprKqsqyysLK0ssiyybLMstCy0rLYstmy27LdsuKy5LLlsuay6LLrsuyy" + "7bLusu+y87L0svWy97L4svmy+rL7sv+yALMBswSzCLMQsxGzE7MUsxWzHLNUs1WzVrNYs1uzXLNes1+zZLNls///////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////Z7Nps2uzbrNws3GzdLN4s4CzgbODs4SzhbOMs5Cz" + "lLOgs6GzqLOss8SzxbPIs8uzzLPOs9Cz1LPVs9ez2bPbs92z4LPks+iz/LMQtBi0HLQgtCi0KbQrtDS0ULRRtFS0WLRgtGG0" + "Y7RltGy0gLSItJ20pLSotKy0tbS3tLm0wLTEtMi00LTVtNy03bTgtOO05LTmtOy07bTvtPG0+LQUtRW1GLUbtRy1JLUltSe1" + "KLUptSq1MLUxtTS1OLX/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////0C1QbVDtUS1" + "RbVLtUy1TbVQtVS1XLVdtV+1YLVhtaC1obWktai1qrWrtbC1sbWztbS1tbW7tby1vbXAtcS1zLXNtc+10LXRtdi17LUQthG2" + "FLYYtiW2LLY0tki2ZLZotpy2nbagtqS2q7astrG21LbwtvS2+LYAtwG3Bbcotym3LLcvtzC3OLc5tzu3RLdIt0y3VLdVt2C3" + "ZLdot3C3cbdzt3W3fLd9t4C3hLeMt423j7eQt5G3kreWt5e3////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////+Yt5m3nLegt6i3qbert6y3rbe0t7W3uLfHt8m37Lftt/C39Lf8t/23/7cAuAG4B7gIuAm4DLgQuBi4" + "GbgbuB24JLgluCi4LLg0uDW4N7g4uDm4QLhEuFG4U7hcuF24YLhkuGy4bbhvuHG4eLh8uI24qLiwuLS4uLjAuMG4w7jFuMy4" + "0LjUuN2437jhuOi46bjsuPC4+Lj5uPu4/bgEuRi5ILk8uT25QLlEuUy5T7lRuVi5WblcuWC5aLlpuf//////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////a7ltuXS5dbl4uXy5hLmFuYe5ibmKuY25jrmsua25sLm0uby5" + "vbm/ucG5yLnJucy5zrnPudC50bnSudi52bnbud253rnhueO55Lnluei57Ln0ufW597n4ufm5+rkAugG6CLoVuji6Obo8ukC6" + "QrpIukm6S7pNuk66U7pUulW6WLpcumS6Zbpnumi6abpwunG6dLp4uoO6hLqFuoe6jLqouqm6q7qsurC6srq4urm6u7q9usS6" + "yLrYutm6/Lr/////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////wC7BLsNuw+7EbsYuxy7" + "ILspuyu7NLs1uza7OLs7uzy7Pbs+u0S7RbtHu0m7TbtPu1C7VLtYu2G7Y7tsu4i7jLuQu6S7qLusu7S7t7vAu8S7yLvQu9O7" + "+Lv5u/y7/7sAvAK8CLwJvAu8DLwNvA+8EbwUvBW8FrwXvBi8G7wcvB28HrwfvCS8JbwnvCm8LbwwvDG8NLw4vEC8QbxDvES8" + "RbxJvEy8TbxQvF28hLyFvIi8i7yMvI68lLyVvJe8////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////+ZvJq8oLyhvKS8p7yovLC8sbyzvLS8tby8vL28wLzEvM28z7zQvNG81bzYvNy89Lz1vPa8+Lz8vAS9Bb0HvQm9" + "EL0UvSS9LL1AvUi9Sb1MvVC9WL1ZvWS9aL2AvYG9hL2HvYi9ib2KvZC9kb2TvZW9mb2avZy9pL2wvbi91L3Vvdi93L3pvfC9" + "9L34vQC+A74Fvgy+Db4QvhS+HL4dvh++RL5Fvki+TL5OvlS+Vb5Xvlm+Wr5bvmC+Yb5kvv//////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////aL5qvnC+cb5zvnS+db57vny+fb6AvoS+jL6Nvo++kL6Rvpi+mb6ovtC+" + "0b7Uvte+2L7gvuO+5L7lvuy+Ab8Ivwm/GL8Zvxu/HL8dv0C/Qb9Ev0i/UL9Rv1W/lL+wv8W/zL/Nv9C/1L/cv9+/4b88wFHA" + "WMBcwGDAaMBpwJDAkcCUwJjAoMChwKPApcCswK3Ar8CwwLPAtMC1wLbAvMC9wL/AwMDBwMXAyMDJwMzA0MDYwNnA28DcwN3A" + "5MD/////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////+XA6MDswPTA9cD3wPnAAMEEwQjB" + "EMEVwRzBHcEewR/BIMEjwSTBJsEnwSzBLcEvwTDBMcE2wTjBOcE8wUDBSMFJwUvBTMFNwVTBVcFYwVzBZMFlwWfBaMFpwXDB" + "dMF4wYXBjMGNwY7BkMGUwZbBnMGdwZ/BocGlwajBqcGswbDBvcHEwcjBzMHUwdfB2MHgweTB6MHwwfHB88H8wf3BAMIEwgzC" + "DcIPwhHCGMIZwhzCH8IgwijCKcIrwi3C////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//8vwjHCMsI0wkjCUMJRwlTCWMJgwmXCbMJtwnDCdMJ8wn3Cf8KBwojCicKQwpjCm8KdwqTCpcKowqzCrcK0wrXCt8K5wtzC" + "3cLgwuPC5MLrwuzC7cLvwvHC9sL4wvnC+8L8wgDDCMMJwwzDDcMTwxTDFcMYwxzDJMMlwyjDKcNFw2jDacNsw3DDcsN4w3nD" + "fMN9w4TDiMOMw8DD2MPZw9zD38Pgw+LD6MPpw+3D9MP1w/jDCMQQxCTELMQwxP//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////NMQ8xD3ESMRkxGXEaMRsxHTEdcR5xIDElMScxLjEvMTpxPDE8cT0xPjE+sT/xADF" + "AcUMxRDFFMUcxSjFKcUsxTDFOMU5xTvFPcVExUXFSMVJxUrFTMVNxU7FU8VUxVXFV8VYxVnFXcVexWDFYcVkxWjFcMVxxXPF" + "dMV1xXzFfcWAxYTFh8WMxY3Fj8WRxZXFl8WYxZzFoMWpxbTFtcW4xbnFu8W8xb3FvsXExcXFxsXHxcjFycXKxczFzsX/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////9DF0cXUxdjF4MXhxePF5cXsxe3F7sXwxfTF" + "9sX3xfzF/cX+xf/FAMYBxgXGBsYHxgjGDMYQxhjGGcYbxhzGJMYlxijGLMYtxi7GMMYzxjTGNcY3xjnGO8ZAxkHGRMZIxlDG" + "UcZTxlTGVcZcxl3GYMZsxm/GccZ4xnnGfMaAxojGicaLxo3GlMaVxpjGnMakxqXGp8apxrDGsca0xrjGuca6xsDGwcbDxsXG" + "zMbNxtDG1Mbcxt3G4MbhxujG////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////////////////////////////////////pxuzG" + "8Mb4xvnG/cYExwXHCMcMxxTHFccXxxnHIMchxyTHKMcwxzHHM8c1xzfHPMc9x0DHRMdKx0zHTcdPx1HHUsdTx1THVcdWx1fH" + "WMdcx2DHaMdrx3THdcd4x3zHfcd+x4PHhMeFx4fHiMeJx4rHjseQx5HHlMeWx5fHmMeax6DHocejx6THpcemx6zHrcewx7TH" + "vMe9x7/HwMfBx8jHycfMx87H0MfYx93H5Mfox+zHAMgByATICMgKyP//////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////EMgRyBPIFcgWyBzIHcggyCTILMgtyC/IMcg4yDzIQMhIyEnITMhNyFTIcMhxyHTIeMh6yIDI" + "gciDyIXIhsiHyIvIjMiNyJTIncifyKHIqMi8yL3IxMjIyMzI1MjVyNfI2cjgyOHI5Mj1yPzI/cgAyQTJBckGyQzJDckPyRHJ" + "GMksyTTJUMlRyVTJWMlgyWHJY8lsyXDJdMl8yYjJicmMyZDJmMmZyZvJncnAycHJxMnHycjJysnQydHJ08n/////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////9XJ1snZydrJ3MndyeDJ4snkyefJ7Mntye/J8MnxyfjJ" + "+cn8yQDKCMoJygvKDMoNyhTKGMopykzKTcpQylTKXMpdyl/KYMphymjKfcqEypjKvMq9ysDKxMrMys3Kz8rRytPK2MrZyuDK" + "7Mr0ygjLEMsUyxjLIMshy0HLSMtJy0zLUMtYy1nLXctky3jLecucy7jL1Mvky+fL6csMzA3MEMwUzBzMHcwhzCLMJ8wozCnM" + "LMwuzDDMOMw5zDvM////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////88zD3MPsxEzEXM" + "SMxMzFTMVcxXzFjMWcxgzGTMZsxozHDMdcyYzJnMnMygzKjMqcyrzKzMrcy0zLXMuMy8zMTMxczHzMnM0MzUzOTM7MzwzAHN" + "CM0JzQzNEM0YzRnNG80dzSTNKM0szTnNXM1gzWTNbM1tzW/Ncc14zYjNlM2VzZjNnM2kzaXNp82pzbDNxM3MzdDN6M3szfDN" + "+M35zfvN/c0EzgjODM4UzhnOIM4hziTOKM4wzjHOM841zv//////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////WM5ZzlzOX85gzmHOaM5pzmvObc50znXOeM58zoTOhc6HzonOkM6RzpTOmM6gzqHOo86kzqXOrM6tzsHO" + "5M7lzujO687szvTO9c73zvjO+c4AzwHPBM8IzxDPEc8TzxXPHM8gzyTPLM8tzy/PMM8xzzjPVM9Vz1jPXM9kz2XPZ89pz3DP" + "cc90z3jPgM+Fz4zPoc+oz7DPxM/gz+HP5M/oz/DP8c/zz/XP/M8A0ATQEdAY0C3QNNA10DjQPND/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////0TQRdBH0EnQUNBU0FjQYNBs0G3QcNB00HzQfdCB0KTQpdCo0KzQ" + "tNC10LfQudDA0MHQxNDI0MnQ0NDR0NPQ1NDV0NzQ3dDg0OTQ7NDt0O/Q8NDx0PjQDdEw0THRNNE40TrRQNFB0UPRRNFF0UzR" + "TdFQ0VTRXNFd0V/RYdFo0WzRfNGE0YjRoNGh0aTRqNGw0bHRs9G10brRvNHA0djR9NH40QfSCdIQ0izSLdIw0jTSPNI90j/S" + "QdJI0lzS////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9k0oDSgdKE0ojSkNKR0pXS" + "nNKg0qTSrNKx0rjSudK80r/SwNLC0sjSydLL0tTS2NLc0uTS5dLw0vHS9NL40gDTAdMD0wXTDNMN0w7TENMU0xbTHNMd0x/T" + "INMh0yXTKNMp0yzTMNM40znTO9M80z3TRNNF03zTfdOA04TTjNON04/TkNOR05jTmdOc06DTqNOp06vTrdO007jTvNPE08XT" + "yNPJ09DT2NPh0+PT7NPt0/DT9NP80/3T/9MB1P//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////CNQd1EDURNRc1GDUZNRt1G/UeNR51HzUf9SA1ILUiNSJ1IvUjdSU1KnUzNTQ1NTU3NTf1OjU7NTw1PjU+9T91ATV" + "CNUM1RTVFdUX1TzVPdVA1UTVTNVN1U/VUdVY1VnVXNVg1WXVaNVp1WvVbdV01XXVeNV81YTVhdWH1YjVidWQ1aXVyNXJ1czV" + "0NXS1djV2dXb1d3V5NXl1ejV7NX01fXV99X51QDWAdYE1gjWENYR1hPWFNYV1hzWINb/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////yTWLdY41jnWPNZA1kXWSNZJ1kvWTdZR1lTWVdZY1lzWZ9Zp1nDWcdZ01oPW" + "hdaM1o3WkNaU1p3Wn9ah1qjWrNaw1rnWu9bE1sXWyNbM1tHW1NbX1tnW4Nbk1ujW8Nb11vzW/dYA1wTXEdcY1xnXHNcg1yjX" + "Kdcr1y3XNNc11zjXPNdE10fXSddQ11HXVNdW11fXWNdZ12DXYddj12XXadds13DXdNd8133XgdeI14nXjNeQ15jXmdeb153X" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "PU9zT0dQ+VCgUu9TdVTlVAlWwVq2W4dmtme3Z+9nTGvCc8J1PHrbggSDV4iIiDaKyIzPjfuO5o/VmTtSdFMEVGpgZGG8a89z" + "GoG6idKJo5WDTwpSvlh4WeZZcl55XsdhwGNGZ+xnf2iXb052C3f1eAh6/3ohfJ2AboJxguuKk5VrTp1V92Y0bqN47XpbhBCJ" + "Toeol9hSTlcqWExdH2G+YSFiYmXRZ0RqG24YdbN143awdzp9r5BRlFKUlZ//////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////yNTrFwydduAQJKYlVtSCFjcWaFcF123XjpfSl93YV9senWGdeB8c32xfYx/VIEhgpGF" + "QYkbi/ySTZZHnMtO904LUPFRT1g3YT5haGE5ZeppEW+ldYZ21naHe6WCy4QA+aeTi5WAVaJbUVcB+bN8uX+1kShQu1NFXOhd" + "0mJuY9pk52QgbqxwW3ndjR6OAvl9kEWS+JJ+TvZOZVD+XfpeBmFXaXGBVIZHjnWTK5peTpFQcGdAaAlRjVKSUqJq////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////+8dxCS1J6rUi9g8o9IUKlh7WPKZDxohGrAb4iB" + "oYmUlgVYfXKscgR1eX1tfqmAi4l0i2OQUZ2JYnpsVG9QfTp/I4p8UUphnXsZi1eSjJOsTtNPHlC+UAZRwVLNUn9TcFeDWJpe" + "kV92YaxhzmRsZW9mu2b0Zpdoh22FcPFwn3SldMp02XVseOx433r2ekV9k30VgD+AG4GWg2aLFY8VkOGTA5g4mFqa6JvCT1NV" + "OlhRWWNbRly4YBJiQmiwaP//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////6Giqbkx1" + "eHbOeD16+3xrfnx+CIqhij+MjpbEneRT6VNKVHFU+lbRWWRbO1yrXvdiN2VFZXJloGavZ8FpvWz8dZB2fnc/epR/A4ChgI+B" + "5oL9gvCDwYUxiLSIpYoD+ZyPLpPHlmeY2JoTn+1Um2XyZo9oQHo3jGCd8FZkVxFdBmaxaM1o/m4odJ6I5JtobAT5qJqbT2xR" + "cVGfUlRb5V1QYG1g8WKnYztl2XN6eqOGooyPlzJO4VsIYpxn3HT/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////9F504OHirKK6I1OkEuTRpjTXuhp/4XtkAX5oFGYW+xbY2H6aD5rTHAvdNh0oXtQf8WDwImrjNyV" + "KJkuUl1g7GICkIpPSVEhU9lY417gZjhtmnDCctZzUHvxgFuUZlObY2t/Vk6AUEpY3lgqYCdh0GLQaUGbj1sYfbGAX4+kTtFQ" + "rFSsVQxboF3nXSplTmUhaEtq4XKOdu93Xn35f6CBToXfhgOPTo/KkAOZVZqrmxhORU5dTsdO8U93Uf5S////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////9AU+NT5VOOVBRWdVeiV8dbh13QXvxh2GJRZbhn6WfLaVBr" + "xmvsa0JsnW54cNdylnMDdL936Xd2en99CYD8gQWCCoLfgmKIM4v8jMCOEZCxkGSStpLSmUWa6ZzXnZyfC1dAXMqDoJerl7Se" + "G1SYeqR/2YjNjuGQAFhIXJhjn3quWxNfeXqueo6CrI4mUDhS+FJ3UwhX82JyYwprw203d6VTV3NohXaO1ZU6Z8NqcG9tisyO" + "S5kG+XdmeGu0jP//////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////PJsH+etTLVdOWcZj" + "+2nqc0V4unrFev58dYSPiXONNZColftSR1dHdWB7zIMekgj5WGpLUUtSh1IfYthodWmZlsVQpFLkUsNhpGU5aP9pfnRLe7mC" + "64OyiTmL0Y9JmQn5yk6XWdJkEWaOajR0gXm9eamCfoh/iF+JCvkmkwtPylMlYHFicmwafWZ9mE5iUdx3r4ABTw5PdlGAUdxV" + "aFY7V/pX/FcUWUdZk1nEW5BcDl3xXX5ezF+AYtdl42X/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////x5nH2deZ8toxGhfajprI2x9bIJsx22YcyZ0KnSCdKN0eHV/dYF473hBeUd5SHl6eZV7AH26fYh/BoAtgIyA" + "GIpPi0iMd40hkyST4phRmQ6aD5plmpKeyn12TwlU7mJUaNGRq1U6UQv5DPkcWuZhDfnPYv9iDvkP+RD5EfkS+RP5o5AU+RX5" + "FvkX+Rj5/ooZ+Rr5G/kc+ZZmHflWcR75H/njliD5T2N6Y1dTIfmPZ2Bpc24i+Td1I/kk+SX5////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////8NfSb5J/lyiMpWGFoo+Sn5Kvkr+Sz5Q04t+WdRSFnwZxCALvlzWXRe" + "mmTKefVfbGDIYntj51vXW6pSL/l0WSlfEmAw+TH5MvlZdDP5NPk1+Tb5N/k4+dGZOfk6+Tv5PPk9+T75P/lA+UH5QvlD+cNv" + "RPlF+b+Bso/xYEb5R/lmgUj5Sfk/XEr5S/lM+U35TvlP+VD5UfnpWiWKe2cQfVL5U/lU+VX5VvlX+f2AWPlZ+Txc5Ww/U7pu" + "Glk2g///////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////OU62TkZPrlUYV8dYVl+3ZeZl" + "gGq1a01u7Xfveh583n3LhpKIMpFbk7tkvm96c7h1VJBWVU1XumHUZMdm4W1bbm1vuW/wdUOAvYFBhYOJx4paix+Tk2xTdVR7" + "D45dkBBVAlhYWGJeB2KeZOBodnXWfLOH6J7jTohXblcnWQ1csVw2XoVfNGLhZLNz+oGLiLiMipbbnoVbt1+zYBJQAFIwUhZX" + "NVhXWA5cYFz2XItdpl6SX7xgEWOJYxdkQ2j/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////lowmrYbSFu1G7kb/5x3HZ5d7F5O3oEhKmJ7YzzjUiOA5AUkFOQ/ZBNk3aW3JfSawZwWHKicmhzY3e/eeR7m36Ai6lY" + "x2BmZf1lvmaMbB5xyXFajBOYbU6Bet1OrFHNUdVSDFSnYXFnUGjfaB5tfG+8dbN35Xr0gGOEhZJcUZdlXGeTZ9h1x3pzg1r5" + "RowXkC2Yb1zAgZqCQZBvkA2Sl1+dXVlqyHF7dkl75IUEiyeRMJqHVfZhW/lpdoV/////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////8/hrqH+IiPkFz5G23ZcN5zYX09hF35apHxmV75gk51UwRrEms+cBtyLYYenkxS" + "o49QXeVkLGUWa+tvQ3ycfs2FZIm9icli2IEfiMpeF2dqbfxyBXRvdIKH3pCGTw1doF8KhLdRoGNlda5OBlBpUclRgWgRaq58" + "sXznfG+C0oobj8+Rtk83UfVSQlTsXm5hPmLFZdpq/m8qedyFI4itlWKaapqXns6em1LGZndrHXAreWKPQpeQYQBiI2Ujb///" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////SXGJdPR9b4DuhCaPI5BKk71RF1KjUgxt" + "yHDCiMlegmWua8JvPnx1c+RONk/5Vl/5uly6XRxgsnMte5p/zn9GgB6QNJL2lkiXGJhhn4tPp2+uebSRt5beUmD5iGTEZNNq" + "Xm8YcBBy53YBgAaGXIbvjQWPMpdvm/qddZ6MeH95oH3JgwSTf56TntaK31gEXydnJ3DPdGB8foAhUShwYnLKeMKM2oz0jPeW" + "hk7aUO5b1l6ZZc5xQnatd0qA/IT/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////3yQ" + "J5uNn9hYQVpiXBNq2m0Pbzt2L303fh6FOInkk0uWiVLSZfNntGlBbZxuD3AJdGB0WXUkdmt4LItemG1RLmJ4lpZPK1AZXept" + "uH0qj4tfRGEXaGH5hpbSUouA3FHMUV5pHHq+ffGDdZbaTylSmFMPVA5VZVynYE5nqGhsbYFy+HIGdIN0YvnidWx8eX+4f4mD" + "z4jhiMyR0JHilsmbHVR+b9BxmHT6haqOo5ZXnJ+el2fLbTN06IEWlyx4////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////LeiB7knxpZGp08nW8eOh4rJlUm7ue3ltVXiBvnIGrg4iQB05NUyla0l1OX2JhPWNpZvxm" + "/24rb2NwnncshBOFO4gTj0WZO5wcVbliK2erbAmDaol6l6FOhFnYX9lfG2eyfVR/koIrg72DHo+ZkMtXuVmSWtBbJ2aaZ4Vo" + "z2tkcXV/t4zjjIGQRZsIgYqMTJZAmqWeX1sTbBtz8nbfdgyEqlGTiU1RlVHJUslolGwEdyB3v33sfWKXtZ7Fbv//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////EYWlUQ1UfVQOZp1mJ2mfbr92kXcXg8KEn4dpkZiS" + "9JyCiK5PklHfUsZZPV5VYXhkeWSuZtBnIWrNa9trX3JhckF0OHfbdxeAvIIFgwCLKIuMjChnkGxncu52ZndGeqmdf2uSbCJZ" + "JmeZhG9Tk1iZWd9ez2M0ZnNnOm4rc9d614Iok9lS612uYcthCmLHYqtk4GVZaWZry2shcfdzXXVGfh6CAoNqhaOKv4wnl2Gd" + "qFjYnhFQDlI7VE9Vh2X/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////3ZsCn0LfV6A" + "ioaAle+W/1KVbGlyc1SaWj5cS11MX65fKme2aGNpPG5Ebgl3c3yOf4eFDov3j2GX9J63XLZgDWGrYU9l+2X8ZRFs72yfc8lz" + "4X2UlcZbHIcQi11SWlPNYg9ksmQ0ZzhqymzAc550lHuVfBt+ioE2goSF64/5lsGZNE9KU81T21PMYixkAGWRZcNp7mxYb+1z" + "VHUiduR2/HbQePt4LHlGfSyC4IfUjxKY75jDUtRipWQkblFv////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////98dsuNsZFiku6aQ5sjUI1QSleoWShcR153Xz9iPmW5ZcFlCWaLZ5xpwm7FeCF9qoCAgSuCs4KhhIyG" + "KooXi6aQMpaQnw1Q809j+flXmF/cYpJjb2dDbhlxw3bMgNqA9Ij1iBmJ4Iwpj02RapYvT3BPG17PZyJofXZ+dkSbYV4Kamlx" + "1HFqdWT5QX5DhemF3JgQT097cH+lleFRBl61aD5sTmzbbK9yxHsDg9VsOnT7UIhSwVjYZJdqp3RWdv//////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////p3gXhuKVOZdl+V5TAV+Ki6iPr4+KkCVSpXdJnAifGU4CUHVR" + "W1x3Xh5mOmbEZ8Vos3ABdcV1yXndeiePIJkImt1PIVgxWPZbbmZlaxFtem59b+RzK3Xpg9yIE4lcixSPD0/VUBBTXFOTW6lf" + "DWePeXmBL4MUhQeJhok5jzuPpZkSnCxndk74T0lZAVzvXPBcZ2PSaP1wonErdCt+7IQChyKQ0pLznA1O2E7vT4VQVlJvUiZU" + "kFTgVytZZlr/////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////1pbdVvMW5xeZvl2Yndl" + "p2VubaVuNnImez98Nn9QgVGBmoFAgpmCqYMDiqCM5oz7jHSNuo3okNyRHJZEltmZ55wXUwZSKVR0VrNYVFluWf9fpGFuYhBm" + "fmwaccZ2iXzefBt9rILBjPCWZ/lbTxdff1/CYildC2faaHx4Q35snRVOmVAVUypTUVODWWJah16yYIphSWJ5YpBlh2enadRr" + "1mvXa9hruGxo+TV0+nUSeJF41XnYeYN8y33hf6WA////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////8+gcKB8oMah+iIuYpsi7uMGZFel9uYO5+sVipbbF+MZbNqr2tcbfFvFXBdcq1zp4zTjDuYkWE3bFiAAZpNTotO" + "m07VTjpPPE9/T99P/1DyU/hTBlXjVdtW61hiWRFa61v6WwRc810rXplfHWBoY5xlr2X2Z/tnrWh7a5ls12wjbglwRXMCeD55" + "QHlgecF56XsXfXJ9hoANgo6D0YTHht+IUIpeih2L3Ixmja2PqpD8mN+ZnZ5KUmn5FGdq+f//////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////mFAqUnFcY2VVbMpzI3WddZd7nIR4kTCXd06SZLprXnGphQlOa/lJZ+5o" + "F26fghiFa4j3Y4FvEpKvmApOt1DPUB9RRlWqVRdWQFsZXOBcOF6KXqBewl7zYFFoYWpYbj1yQHLAcvh2ZXmxe9R/84j0iXOK" + "YYzejByXXli9dP2Mx1Vs+WF6In1ygnJyH3UldW35GXuFWPtYvF2PXrZekF9VYJJif2NNZZFm2Wb4ZhZo8miAcl50bntufdZ9" + "cn//////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////+WAEoKvhX+Jk4odkOSSzZ4gnxVZ" + "bVktXtxgFGZzZpBnUGzFbV9v83epeMaEy5Erk9lOylBIUYRVC1ujW0difmXLZTJufXEBdER0h3S/dGx2qnnafVV+qH96gbOB" + "OYIahuyHdYrjjXiQkZIllE2ZrptoU1FcVGnEbCltK24MgpuFO4ktiqqK6pZnn2FSuWaya5Z+/ocNjYOVXZYdZYlt7nFu+c5X" + "01msWydg+mAQYh9mX2Ypc/lz23YBd2x7////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//9WgHKAZYGgipKRFk7iUnJrF20Fejl7MH1v+bCM7FMvVlFYtVsPXBFc4l1AYoNjFGQtZrNovGyIba9uH3CkcNJxJnWPdY51" + "GXYRe+B7K3wgfTl9LIVthQeGNIoNkGGQtZC3kvaXN5rXT2xcX2eRbZ98jH4WixaNH5BrW/1dDWTAhFyQ4ZiHc4tbmmB+Z95t" + "H4qmigGQDJg3UnD5UXCOeJaTcIjXke5P11P9VdpWglf9WMJaiFurXMBcJV4BYf//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////DWJLYohjHGQ2ZXhlOWqKazRsGW0xb+dx6XJ4cwd0snQmdmF3wHlXeup6uXyPfax9" + "YX6efymBMYOQhNqE6oWWiLCKkIs4j0KQg5BskZaSuZKLlqeWqJbWlgCXCJiWmdOaGpvUU35YGVlwW79b0W1ab59xIXS5dIWA" + "/YPhXYdfql9CYOxlEmhvaVNqiWs1bfNt43P+dqx3TXsUfSOBHIJAg/SEY4ViisSKh5EekwaYtJkMYlOI8I9lkgddJ13/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////2ldX3SdgWiH1W/+YtJ/NolyiR5OWE7nUN1S" + "R1N/YgdmaX4FiF6WjU8ZUzZWy1mkWjhcTlxNXAJeEV9DYL1lL2ZCZr5n9Gccc+J3OnnFf5SEzYSWiWaKaYrhilWMeoz0V9Rb" + "D19vYO1iDWmWa1xuhHHSe1WHWIv+jt+Y/pg4T4FP4U97VCBauFs8YbBlaGb8cTN1XnkzfU6B44GYg6qFzoUDhwqKq46bj3H5" + "xY8xWaRb5luJYOlbC1zDX4Fs////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////////////9y+fFt" + "C3Aada+C9orATkFTc/nZlg9snk7ET1JRXlUlWuhcEWJZcr2CqoP+hlmIHYo/lsWWE5kJnV2dClizXL1dRF7hYBVh4WMCaiVu" + "ApFUk06YEJx3n4lbuFwJY09mSGg8d8GWjZdUmJ+boWUBi8uOvJU1Valc1l21XpdmTHb0g8eV01i8Ys5yKJ3wTi5ZD2A7ZoNr" + "53kmnZNTwFTDVxZdG2HWZq9tjXh+gpiWRJeEU3xilmOybQp+S4FNmP//////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////+2pMf6+dGp5fTjtQtlEcWflg9mMwaTpyNoB0+c6RMV91+Xb5BH3lgm+Eu4TlhY2Od/lvT3j5" + "efnkWENbWWDaYxhlbWWYZnr5SmkjagttAXBscdJ1DXazeXB6e/mKf3z5RIl9+ZOLwJF9ln75CpkEV6FfvGUBbwB2pnmeiq2Z" + "WptsnwRRtmGRYo1qxoFDUDBYZl8JcQCK+op8WxaG+k88UbRWRFmpY/ltql1taYZRiE5ZT3/5gPmB+YJZgvn/////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////4P5X2tdbIT5tXQWeYX5B4JFgjmDP49dj4b5GJmH+Yj5" + "ifmmTor531d5XxNmi/mM+at1eX5vi435BpBbmqVWJ1j4WR9atFuO+fZej/mQ+VBjO2OR+T1ph2y/bI5tk231bRRvkvnfcDZx" + "WXGT+cNx1XGU+U94b3iV+XV7432W+S9+l/lNiN+OmPmZ+Zr5W5Kb+facnPmd+Z75hWCFbZ/5sXGg+aH5sZWtU6L5o/mk+dNn" + "pfmOcDBxMHR2gtKC////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////+m+buV5Zp9nsRm" + "p/nBcUmEqPmp+UtYqvmr+bhdcV+s+SBmjmZ5aa5pOGzzbDZuQW/abxtwL3BQcd9xcHOt+Vt0rvnUdMh2TnqTfq/5sPnxgmCK" + "zo+x+UiTsvkZl7P5tPlCTipQtfkIUuFT82ZtbMpvCnN/d2J6roLdhQKGtvnUiGOKfYtrjLf5s5K4+ROXEJiUTg1PyU+yUEhT" + "PlQzVNpVYli6WGdZG1rkW59gufnKYVZl/2VkZqdoWmyzb///////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////z3CscVJzfXsIh6SKMpwHn0tcg2xEc4lzOpKrbmV0H3ZpehV+CoZAUcVYwWTudBV1cHbBf5WQzZZUmSZu" + "5nSpeqp65YHZhniHG4pJWoxbm1uhaABpY22pcxN0LHSXeOl9638YgVWBnoNMjC6WEZjwZoBf+mWJZ2psi3MtUANaamvudxZZ" + "bF3NXSVzT3W6+bv55VD5US9YLVmWWdpZ5Vu8+b35ol3XYhZkk2T+ZL753Ga/+UhqwPn/cWR0wfn/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////4h6r3pHfl5+AIBwgcL574eBiSCLWZDD+YCQUpl+YTJrdG0ffiWJ" + "sY/RT61Ql1HHUsdXiVi5W7heQmGVaYxtZ262bpRxYnQodSx1c4A4g8mECo6Uk96TxPmOTlFPdlAqUchTy1PzU4db01skXBph" + "gmH0ZVtyl3NAdMJ2UHmRebl5Bn29f4uC1YVehsKPR5D1kOqRhZbolumW1lJnX+1lMWYvaFxxNnrBkAqYkU7F+VJqnmuQb4lx" + "GIC4glOF////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9LkJWW8pb7lxqFMZuQTopx" + "xJZDUZ9T4VQTVxJXo1ebWsRaw1soYD9h9GOFbDltcm6QbjByP3NXdNGCgYhFj2CQxvlilliYG50IZ4qNXpJNT0lQ3lBxUw1X" + "1FkBWglccGGQZi1uMnJLdO99w4AOhGaEP4Vfh1uIGIkCi1WQy5dPm3NOkU8SUWpRx/kvValVelulW3xefV6+XqBg32AIYQlh" + "xGM4ZQlnyPnUZ9pnyflhaWJpuWwnbcr5OG7L+f//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////4W82czdzzPlcdDF1zflSds75z/mtff6BOITViJiK24rtijCOQo5KkD6QepBJkcmRbpPQ+dH5CVjS+dNriYCygNP5" + "1PlBUWtZOVzV+db5ZG+nc+SAB43X+ReSj5XY+dn52vnb+X+ADmIccGh9jYfc+aBXaWBHYbdrvoqAkrGWWU4fVOttLYVwlvOX" + "7pjWY+NskZDdUclhuoH5nZ1PGlAAUZxbD2H/YexkBWnFa5F143epf2SCj4X7h2OIvIr/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////3CLq5GMTuVOCk/d+d75N1noWd/58l0bX1tfIWDg+eH54vnj+T5y5XPk+XB1" + "zXXl+ft55vkMgDOAhIDhglGD5/no+b2Ms4yHkOn56vn0mAyZ6/ns+TdwynbKf8x//H8ai7pOwU4DUnBT7fm9VOBW+1nFWxVf" + "zV9ubu757/lqfTWD8PmTho2K8fltl3eX8vnz+QBOWk9+T/lY5WWibjiQsJO5mftO7FiKWdlZQWD0+fX5FHr2+U+Dw4xlUURT" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////////////3+fj5+fnNTmlSVVu/gtROOlKoVMlZ" + "/1lQW1dbXFtjYEhhy26ZcG5xhnP3dLV1wXgrfQWA6oEogxeFyYXuiseMzJZcT/pSvFarZShmfHC4cDVyvX2NgkyRwJZynXFb" + "52iYa3pv3naRXKtmW2+0eyp8NojclghO104gUzRYu1jvWGxZB1wzXoReNV+MY7JmVmcfaqNqDGs/b0Zy+vlQc4t04HqnfHiB" + "34HngYqDbIQjhZSFz4XdiBONrJF3lf//////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "nJaNUclUKFewW01iUGc9aJNoPW7Tbn1wIX7BiKGMCY9Ln06fLXKPe82KGpNHT05PMlGAVNBZlV61YnVnbmkXaq5sGm7Zcipz" + "vXW4ezV954L5g1eE94Vbiq+Mh44ZkLiQzpZfn+NSClThWsJbWGR1ZfRuxHL7+YR2TXobe018Pn7ff3uDK4vKjGSN4Y1fjuqP" + "+Y9pkNGTQ096T7NQaFF4UU1SalJhWHxYYFkIXFVc216bYDBiE2i/awhssW//////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////05xIHQwdTh1UXVydkx7i3ute8Z7j35uij6PSY8/kpOSIpMrlPuWWphrmB6ZB1IqYphi" + "WW1kdsp6wHt2fWBTvlyXXjhvuXCYfBGXjpvenqVjemR2hwFOlU6tTlxQdVBIVMNZmltAXq1e916BX8VgOmM/ZXRlzGV2Znhm" + "/mdoaYlqY2tAbMBt6G0fbl5uHnChcI5z/XM6dVt3h3iOeQt6fXq+fI59R4ICiuqKnowtkUqR2JFmksySIJMGl1aX////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////9clwKYDp82UpFSfFUkWB1eH1+MYNBjr2jfb215" + "LHvNgbqF/Yj4ikSOjZFklpuWPZdMmEqfzk9GUctRqVIyVhRfa1+qY81k6WVBZvpm+WYdZ51o12j9aRVvbm9nceVxKnKqdDp3" + "Vnlaed95IHqVepd833xEfXB+h4D7haSGVIq/ipmNgY4gkG2Q45E7ltWW5ZzPZQd8s43Dk1hbClxSU9liHXMnUJdbnl+wYGth" + "1WjZbS50LnpCfZx9MX5rgf//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////Ko41jn6T" + "GJRQT1BX5l2nXitjan87Tk9Pj09aUN1ZxIBqVGhU/lVPWZlb3l3aXl1mMWfxZypo6GwybUpujW+3cOBzh3VMfAJ9LH2ifR+C" + "24Y7ioWKcI2KjjOPMZBOkVKRRJTQmfl6pXzKTwFRxlHIV+9b+1xZZj1qWm2WbuxvDHFvdeN6IoghkHWQy5b/mQGDLU7yTkaI" + "zZF9U9tqa2lBbHqEnliOYf5m72LdcBF1x3VSfriESYsIjUtO6lP/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////6tUMFdAV9dfAWMHY29kL2XoZXpmnWezZ2JrYGyabCxv5XcleEl5V3kZfaKAAoHzgZ2Ct4IYh4yK" + "/PkEjb6NcpD0dhl6N3pUfneAB1XUVXVYL2MiZElmS2ZtaJtphGslbbFuzXNodKF0W3W5deF2HneLd+Z5CX4dfvuBL4WXiDqK" + "0YzrjrCPMpCtk2OWc5YHl4RP8VPqWclaGV5OaMZ0vnXpeZJ6o4HthuqMzI3tj59lFWf9+fdXV2/dfS+P////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////2k8aWtV/yYYRvFE6YTx9QyVPfVW9d7l0ha2Rry3iae/75" + "SY7Kjm6QSWM+ZEB3hHovk3+Uap+wZK9v5nGodNp0xHoSfIJ+snyYfpqLCo19lBCZTJk5Ut9b5mQtZy597VDDU3lYWGFZYfph" + "rGXZepKLlosJUCFQdVIxVTxa4F5wXzRhXmUMZjZmombNacRuMm8WcyF2k3o5gVmC1oO8hLVQ8FfAW+hbaV+hYyZ4tX3cgyGF" + "x5H1kYpR9WdWe///////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////rIzEUbtZvWBVhhxQ" + "//lUUjpcfWEaYtNi8mSlZcxuIHYKgWCOX5a7lt9OQ1OYVSlZ3V3FZMls+m2Uc396G4KmheSMEI53kOeR4ZUhlsaX+FHyVIZV" + "uV+kZIhvtH0fj02PNZTJUBZcvmz7bRt1u3c9fGR8eYrCih5YvlkWXndjUnKKdWt33Iq8jBKP8150ZvhtfYDBg8uKUZfWmwD6" + "Q1L/ZpVt727gfeaKLpBekNSaHVJ/UuhUlGGEYttiomj/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////xJpWmk1apJwJnFdeAF5DnnSeQ16loB4gtWCSYNJhYKMhY1ikYuRrpHDT9FW7XHXdwCH+In4W9ZfUWeokOJT" + "Wlj1W6RggWFgZD1+cIAlhYOSrmSsUBRdAGecWL1iqGMOaXhpHmprbrp2y3m7gimEz4qojf2PEpFLkZyREJMYk5qT25Y2mg2c" + "EU5cdV15+npRe8l7Ln7EhFmOdI74jhCQJWY/aUN0+lEuZ9yeRVHgX5Zs8oddiHeItGC1gQOE////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////8FjdZTOVQ0VjZaMVyKcOB/WoAGge2Bo42JkV+a8p10UMROoFP7YCxu" + "ZFyITyRQ5FXZXF9eZWCUaLtsxG2+cdR19HVhdhp6SXrHfft9bn/0gamGHI/JlrOZUp9HUsVS7ZiqiQNO0mcGb7VP4luVZ4hs" + "eG0bdCd43ZF8k8SH5Hkxeutf1k6kVD5VrlilWfBgU2LWYjZnVWk1gkCWsZndmSxQU1NEVXxXAfpYYgL64mRrZt1nwW/vbyJ0" + "OHQXiv//////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////OJRRVAZWZldIX5phTmtYcK1w" + "u32VimpZK4GiYwh3PYCqjFRYLWS7aZVbEV5vbgP6aYVMUfBTKlkgYEthhmtwbPBsHnvOgNSCxo2wkLGYBPrHZKRvkWQEZU5R" + "EFQfVw6KX2F2aAX623VSe3F9GpAGWMxpf4EqiQCQOZh4UFdZrFmVYg+QKptdYXly1pVhV0Za9F2KYq1k+mR3Z+JsPm0scjZ0" + "NHh3f62C240XmCRSQld/Z0hy43SpjKaPEZL/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////yqWa1HtU0xjaU8EVZZgV2WbbH9tTHL9chd6h4mdjG1fjm/5cKiBDmG/T09QQWJHcsd76H3pf02QrZcZmraMaldzXrBn" + "DYRViiBUFltjXuJeCl+DZbqAPYWJlVuWSE8FUw1TD1OGVPpUA1cDXhZgm2KxYlVjBvrhbGZtsXUyeN6AL4HegmGEsoSNiBKJ" + "C5Dqkv2YkZtFXrRm3WYRcAZyB/r1T31Sal9TYVNnGWoCb+J0aHloiHmMx5jEmEOa////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////BVB96U2n3ikqMqJiumXxfq2Kyda52q4h/kEKWOVM8X8VfzGzMc2J1i3VGe/6C" + "nZlPTjyQC05VT6ZTD1nIXjBms2xVdHeDZofAjFCQHpcVnNFYeFtQhhSLtJ3SW2hgjWDxZVdsIm+jbxpwVX/wf5GVkpVQltOX" + "clJEj/1RK1S4VGNVilW7arVt2H1mgpySd5Z5nghUyFTSduSGpJXUlVyWok4JT+5Z5lr3XVJgl2JtZ0Fohmwvbjh/m4Aqgv//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////CPoJ+gWYpU5VULNUk1daWWlbs1vIYXdp" + "d20jcPmH44lyiueKgpDtmbiavlI4aBZQeF5PZ0eDTIirThFUrlbmcxWR/5cJmVeZmZlTVp9YW4YxirJh9mp7c9KOR2uqllea" + "VVkAcmuNaZfUT/RcJl/4YVtm62yrcIRzuXP+cyl3TXdDfWJ9I343glKICvrijEmSb5hRW3R6QIgBmMxa4E9UUz5Z/Vw+Y3lt" + "+XIFgQeBooPPkjCYqE5EURFSi1f/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////2Jf" + "wmzObgVwUHCvcJJx6XNpdEqDoodhiAiQopCjk6iZblFXX+BgZ2GzZlmFSo6vkYuXTk6STnxU1Vj6WH1ZtVwnXzZiSGIKZmdm" + "62tpbc9tVm74bpRv4G/pb11w0HIldFp04HSTdlx5ynwefuGApoJrhL+EToZfhnSHd4tqjKyTAJhlmNFgFmJ3kVpaD2b3bT5u" + "P3RCm/1f2mAPe8RUGF9ebNNsKm3YcAV9eYYMijudFlOMVAVbOmprcHV1////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////+Neb55sYLvg3GKQYuojHSXC/r0ZCtluni7eGt6OE6aVVBZplt7XqNg22Nha2VmU2gZbmVx" + "sHQIfYSQaZolnDtt0W4+c0GMypXwUUxeqF9NYPZgMGFMYUNmRGalacFsX27JbmJvTHGcdId2wXsnfFKDV4dRkI2Ww54vU95W" + "+16KX2JglGD3YWZmA2ecau5trm9wcGpzan6+gTSD1IaoisSMg1Jyc5Zba2oElO5UhlZdW0hlhWXJZp9ojW3Gbf//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////O3K0gHWRTZqvTxlQmlMOVDxUiVXFVT9ejF89Z2Zx" + "3XMFkNtS81JkWM5YBHGPcftxsIUTiohmqIWnVYRmSnExhElTmVXBa1lfvV/uY4lmR3Hxih2Pvp4RTzpky3BmdWeGZGBOi/id" + "R1H2UQhTNm34gNGeFWYja5hw1XUDVHlcB30WiiBrPWtGazhUcGA9bdV/CILWUN5RnFVrVs1W7FkJWwxemWGYYTFiXmbmZplx" + "uXG6cadyp3kAerJ/cIr/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +EUC_KR_ENC_EXC = {0x3164: b'\xa4\xd4'} +EUC_KR_ENC_REJECT = frozenset() + +# ---- cp949 ---- +CP949_DEC = _g( + "//8CrAOsBawGrAusDKwNrA6sD6wYrB6sH6whrCKsI6wlrCasJ6worCmsKqwrrC6sMqwzrDSs////////////////Naw2rDes" + "Oqw7rD2sPqw/rEGsQqxDrESsRaxGrEesSKxJrEqsTKxOrE+sUKxRrFKsU6xVrP///////////////1asV6xZrFqsW6xdrF6s" + "X6xgrGGsYqxjrGSsZaxmrGesaKxprGqsa6xsrG2sbqxvrHKsc6x1rHaseax7rHysfax+rH+sgqyHrIisjayOrI+skaySrJOs" + "layWrJesmKyZrJqsm6yerKKso6ykrKWspqynrKusrayurLGssqyzrLSstay2rLesuqy+rL+swKzCrMOsxazGrMesyazKrMus" + "zazOrM+s0KzRrNKs06zUrNas2KzZrNqs26zcrN2s3qzfrOKs46zlrOas6azrrO2s7qzyrPSs96z4rPms+qz7rP6s/6wBrQKt" + "A60FrQetCK0JrQqtC60OrRCtEq0Trf//FK0VrRatF60ZrRqtG60drR6tH60hrSKtI60krSWtJq0nrSitKq0rrS6tL60wrTGt" + "Mq0zrf///////////////zatN605rTqtO609rT6tP61ArUGtQq1DrUatSK1KrUutTK1NrU6tT61RrVKtU61VrVatV63/////" + "//////////9ZrVqtW61crV2tXq1frWCtYq1krWWtZq1nrWitaa1qrWutbq1vrXGtcq13rXitea16rX6tgK2DrYStha2GrYet" + "iq2LrY2tjq2PrZGtkq2TrZStla2WrZetmK2ZrZqtm62erZ+toK2hraKto62lraatp62oramtqq2rraytra2ura+tsK2xrbKt" + "s620rbWttq24rbmtuq27rbytva2+rb+twq3DrcWtxq3Hrcmtyq3Lrcytza3Orc+t0q3UrdWt1q3Xrdit2a3ardut3a3erd+t" + "4a3ireOt5a3mreet6K3preqt663sre2t7q3vrfCt8a3yrfOt9K31rfat963///qt+639rf6tAq4DrgSuBa4GrgeuCq4Mrg6u" + "D64QrhGuEq4TrhWuFq4XrhiuGa4arhuuHK7///////////////8drh6uH64griGuIq4jriSuJa4mrieuKK4priquK64sri2u" + "Lq4vrjKuM641rjauOa47rjyu////////////////Pa4+rj+uQq5ErkeuSK5JrkuuT65RrlKuU65VrleuWK5ZrlquW65ermKu" + "Y65krmauZ65qrmuuba5urm+uca5yrnOudK51rnaud656rn6uf66AroGugq6Droauh66Iromuiq6Lro2ujq6PrpCuka6SrpOu" + "lK6Vrpaul66Yrpmumq6brpyuna6erp+uoK6hrqKuo66krqWupq6nrqiuqa6qrquurK6trq6ur66wrrGusq6zrrSuta62rreu" + "uK65rrquu66/rsGuwq7DrsWuxq7Hrsiuya7Krsuuzq7SrtOu1K7Vrtau167artuu3a7ert+u4K7hruKu467kruWu///mrueu" + "6a7qruyu7q7vrvCu8a7yrvOu9a72rveu+a76rvuu/a7+rv+uAK8BrwKvA68ErwWv////////////////Bq8JrwqvC68Mrw6v" + "D68RrxKvE68UrxWvFq8XrxivGa8arxuvHK8drx6vH68gryGvIq8jr////////////////ySvJa8mryevKK8pryqvK68ury+v" + "Ma8zrzWvNq83rzivOa86rzuvPq9Ar0SvRa9Gr0evSq9Lr0yvTa9Or0+vUa9Sr1OvVK9Vr1avV69Yr1mvWq9br16vX69gr2Gv" + "Yq9jr2avZ69or2mvaq9rr2yvba9ur2+vcK9xr3Kvc690r3Wvdq93r3iveq97r3yvfa9+r3+vga+Cr4Ovha+Gr4evia+Kr4uv" + "jK+Nr46vj6+Sr5OvlK+Wr5evmK+Zr5qvm6+dr56vn6+gr6Gvoq+jr6Svpa+mr6evqK+pr6qvq6+sr62vrq+vr7Cvsa+yr7Ov" + "tK+1r7avt6+6r7uvva++r///v6/Br8Kvw6/Er8Wvxq/Kr8yvz6/Qr9Gv0q/Tr9Wv1q/Xr9iv2a/ar9uv3a/er9+v4K/hr///" + "/////////////+Kv46/kr+Wv5q/nr+qv66/sr+2v7q/vr/Kv86/1r/av96/5r/qv+6/8r/2v/q//rwKwA7D/////////////" + "//8FsAawB7AIsAmwCrALsA2wDrAPsBGwErATsBWwFrAXsBiwGbAasBuwHrAfsCCwIbAisCOwJLAlsCawJ7ApsCqwK7AssC2w" + "LrAvsDCwMbAysDOwNLA1sDawN7A4sDmwOrA7sDywPbA+sD+wQLBBsEKwQ7BGsEewSbBLsE2wT7BQsFGwUrBWsFiwWrBbsFyw" + "XrBfsGCwYbBisGOwZLBlsGawZ7BosGmwarBrsGywbbBusG+wcLBxsHKwc7B0sHWwdrB3sHiwebB6sHuwfrB/sIGwgrCDsIWw" + "hrCHsIiwibCKsIuwjrCQsJKwk7CUsJWwlrCXsJuwnbCesKOwpLD//6WwprCnsKqwsLCysLawt7C5sLqwu7C9sL6wv7DAsMGw" + "wrDDsMawyrDLsMywzbDOsM+w0rD////////////////TsNWw1rDXsNmw2rDbsNyw3bDesN+w4bDisOOw5LDmsOew6LDpsOqw" + "67DssO2w7rDvsPCw////////////////8bDysPOw9LD1sPaw97D4sPmw+rD7sPyw/bD+sP+wALEBsQKxA7EEsQWxBrEHsQqx" + "DbEOsQ+xEbEUsRWxFrEXsRqxHrEfsSCxIbEisSaxJ7EpsSqxK7EtsS6xL7EwsTGxMrEzsTaxOrE7sTyxPbE+sT+xQrFDsUWx" + "RrFHsUmxSrFLsUyxTbFOsU+xUrFTsVaxV7FZsVqxW7FdsV6xX7FhsWKxY7FksWWxZrFnsWixabFqsWuxbLFtsW6xb7FwsXGx" + "crFzsXSxdbF2sXexerF7sX2xfrF/sYGxg7GEsYWxhrGHsYqxjLGOsY+xkLGRsZWxlrGXsZmxmrGbsZ2x//+esZ+xoLGhsaKx" + "o7GksaWxprGnsamxqrGrsayxrbGusa+xsLGxsbKxs7G0sbWxtrG3sbix////////////////ubG6sbuxvLG9sb6xv7HAscGx" + "wrHDscSxxbHGscexyLHJscqxy7HNsc6xz7HRsdKx07HVsf///////////////9ax17HYsdmx2rHbsd6x4LHhseKx47HkseWx" + "5rHnseqx67Htse6x77HxsfKx87H0sfWx9rH3sfix+rH8sf6x/7EAsgGyArIDsgayB7IJsgqyDbIOsg+yELIRshKyE7IWshiy" + "GrIbshyyHbIesh+yIbIisiOyJLIlsiayJ7IosimyKrIrsiyyLbIusi+yMLIxsjKyM7I1sjayN7I4sjmyOrI7sj2yPrI/skCy" + "QbJCskOyRLJFskayR7JIskmySrJLskyyTbJOsk+yULJRslKyU7JUslWyVrJXslmyWrJbsl2yXrJfsmGyYrJjsmSyZbJmsmey" + "arJrsmyybbJusv//b7JwsnGycrJzsnayd7J4snmyerJ7sn2yfrJ/soCygbKCsoOyhrKHsoiyirKLsoyyjbKOsv//////////" + "/////4+ykrKTspWylrKXspuynLKdsp6yn7KisqSyp7Kosqmyq7Ktsq6yr7KxsrKys7K1srayt7L///////////////+4srmy" + "urK7sryyvbK+sr+ywLLBssKyw7LEssWyxrLHssqyy7LNss6yz7LRstOy1LLVstay17Lastyy3rLfsuCy4bLjsuey6bLqsvCy" + "8bLysvay/LL9sv6yArMDswWzBrMHswmzCrMLswyzDbMOsw+zErMWsxezGLMZsxqzG7Mdsx6zH7MgsyGzIrMjsySzJbMmsyez" + "KLMpsyqzK7Mssy2zLrMvszCzMbMyszOzNLM1szazN7M4szmzOrM7szyzPbM+sz+zQLNBs0KzQ7NEs0WzRrNHs0izSbNKs0uz" + "TLNNs06zT7NQs1GzUrNTs1ezWbNas12zYLNhs2KzY7P//2azaLNqs2yzbbNvs3Kzc7N1s3azd7N5s3qze7N8s32zfrN/s4Kz" + "hrOHs4izibOKs4uzjbP///////////////+Os4+zkbOSs5OzlbOWs5ezmLOZs5qzm7Ocs52znrOfs6Kzo7Oks6WzprOns6mz" + "qrOrs62z////////////////rrOvs7CzsbOys7OztLO1s7azt7O4s7mzurO7s7yzvbO+s7+zwLPBs8Kzw7PGs8ezybPKs82z" + "z7PRs9Kz07PWs9iz2rPcs96z37Phs+Kz47Pls+az57Pps+qz67Pss+2z7rPvs/Cz8bPys/Oz9LP1s/az97P4s/mz+rP7s/2z" + "/rP/swC0AbQCtAO0BLQFtAa0B7QItAm0CrQLtAy0DbQOtA+0EbQStBO0FLQVtBa0F7QZtBq0G7QdtB60H7QhtCK0I7QktCW0" + "JrQntCq0LLQttC60L7QwtDG0MrQztDW0NrQ3tDi0ObQ6tDu0PLQ9tD60P7RAtEG0QrRDtES0//9FtEa0R7RItEm0SrRLtEy0" + "TbROtE+0UrRTtFW0VrRXtFm0WrRbtFy0XbRetF+0YrRktGa0////////////////Z7RotGm0arRrtG20brRvtHC0cbRytHO0" + "dLR1tHa0d7R4tHm0erR7tHy0fbR+tH+0gbSCtP///////////////4O0hLSFtIa0h7SJtIq0i7SMtI20jrSPtJC0kbSStJO0" + "lLSVtJa0l7SYtJm0mrSbtJy0nrSftKC0obSitKO0pbSmtKe0qbSqtKu0rbSutK+0sLSxtLK0s7S0tLa0uLS6tLu0vLS9tL60" + "v7TBtMK0w7TFtMa0x7TJtMq0y7TMtM20zrTPtNG00rTTtNS01rTXtNi02bTatNu03rTftOG04rTltOe06LTptOq067TutPC0" + "8rTztPS09bT2tPe0+bT6tPu0/LT9tP60/7QAtQG1ArUDtQS1BbUGtQe1CLUJtQq1C7UMtQ21DrUPtRC1EbUStRO1FrUXtRm1" + "GrUdtf//HrUftSC1IbUitSO1JrUrtSy1LbUutS+1MrUztTW1NrU3tTm1OrU7tTy1PbU+tT+1QrVGtf///////////////0e1" + "SLVJtUq1TrVPtVG1UrVTtVW1VrVXtVi1WbVatVu1XrVitWO1ZLVltWa1Z7VotWm1arX///////////////9rtWy1bbVutW+1" + "cLVxtXK1c7V0tXW1drV3tXi1ebV6tXu1fLV9tX61f7WAtYG1grWDtYS1hbWGtYe1iLWJtYq1i7WMtY21jrWPtZC1kbWStZO1" + "lLWVtZa1l7WYtZm1mrWbtZy1nbWetZ+1orWjtaW1prWntam1rLWtta61r7Wytba1t7W4tbm1urW+tb+1wbXCtcO1xbXGtce1" + "yLXJtcq1y7XOtdK107XUtdW11rXXtdm12rXbtdy13bXetd+14LXhteK147XkteW15rXntei16bXqteu17bXute+18LXxtfK1" + "87X0tfW19rX3tfi1+bX6tfu1/LX9tf61/7X//wC2AbYCtgO2BLYFtga2B7YItgm2CrYLtgy2DbYOtg+2ErYTthW2FrYXthm2" + "GrYbthy2Hbb///////////////8eth+2ILYhtiK2I7Yktia2J7Yotim2KrYrti22LrYvtjC2MbYytjO2NbY2tje2OLY5tjq2" + "////////////////O7Y8tj22PrY/tkC2QbZCtkO2RLZFtka2R7ZJtkq2S7ZMtk22TrZPtlC2UbZStlO2VLZVtla2V7ZYtlm2" + "WrZbtly2XbZetl+2YLZhtmK2Y7Zltma2Z7Zptmq2a7Zstm22brZvtnC2cbZytnO2dLZ1tna2d7Z4tnm2erZ7tny2fbZ+tn+2" + "gLaBtoK2g7aEtoW2hraHtoi2ibaKtou2jLaNto62j7aQtpG2kraTtpS2lbaWtpe2mLaZtpq2m7aetp+2obaitqO2pbamtqe2" + "qLaptqq2rbautq+2sLaytrO2tLa1tra2t7a4trm2ura7try2vba+tr+2wLbBtsK2///DtsS2xbbGtse2yLbJtsq2y7bMts22" + "zrbPttC20bbSttO21bbWtte22LbZttq227bctt22////////////////3rbftuC24bbituO25Lbltua257botum26rbrtuy2" + "7bbutu+28bbytvO29bb2tve2+bb6tv////////////////u2/Lb9tv62/7YCtwO3BLcGtwe3CLcJtwq3C7cMtw23DrcPtxC3" + "EbcStxO3FLcVtxa3F7cYtxm3Grcbtxy3Hbcetx+3ILchtyK3I7cktyW3Jrcntyq3K7ctty63MbcytzO3NLc1tza3N7c6tzy3" + "Pbc+tz+3QLdBt0K3Q7dFt0a3R7dJt0q3S7dNt063T7dQt1G3UrdTt1a3V7dYt1m3Wrdbt1y3Xbdet1+3Ybdit2O3Zbdmt2e3" + "abdqt2u3bLdtt263b7dyt3S3drd3t3i3ebd6t3u3frd/t4G3greDt4W3hreHt4i3ibeKt4u3jreTt5S3lbeat5u3nbeet///" + "n7eht6K3o7ekt6W3prent6q3rrevt7C3sbeyt7O3tre3t7m3ure7t7y3vbe+t7+3wLfBt////////////////8K3w7fEt8W3" + "xrfIt8q3y7fMt823zrfPt9C30bfSt9O31LfVt9a317fYt9m32rfbt9y33bf////////////////et9+34Lfht+K347fkt+W3" + "5rfnt+i36bfqt+u37rfvt/G38rfzt/W39rf3t/i3+bf6t/u3/rcCuAO4BLgFuAa4CrgLuA24DrgPuBG4ErgTuBS4FbgWuBe4" + "GrgcuB64H7gguCG4IrgjuCa4J7gpuCq4K7gtuC64L7gwuDG4MrgzuDa4Org7uDy4Pbg+uD+4QbhCuEO4RbhGuEe4SLhJuEq4" + "S7hMuE24TrhPuFC4UrhUuFW4VrhXuFi4WbhauFu4XrhfuGG4YrhjuGW4ZrhnuGi4abhquGu4brhwuHK4c7h0uHW4drh3uHm4" + "erh7uH24frh/uIC4gbiCuIO4hLj//4W4hriHuIi4ibiKuIu4jLiOuI+4kLiRuJK4k7iUuJW4lriXuJi4mbiauJu4nLiduJ64" + "n7j///////////////+guKG4orijuKS4pbimuKe4qbiquKu4rLituK64r7ixuLK4s7i1uLa4t7i5uLq4u7i8uL24////////" + "////////vri/uMK4xLjGuMe4yLjJuMq4y7jNuM64z7jRuNK407jVuNa417jYuNm42rjbuNy43rjguOK447jkuOW45rjnuOq4" + "67jtuO6477jxuPK487j0uPW49rj3uPq4/Lj+uP+4ALkBuQK5A7kFuQa5B7kIuQm5CrkLuQy5DbkOuQ+5ELkRuRK5E7kUuRW5" + "FrkXuRm5GrkbuRy5HbkeuR+5IbkiuSO5JLkluSa5J7kouSm5KrkruSy5LbkuuS+5MLkxuTK5M7k0uTW5Nrk3uTi5Obk6uTu5" + "Prk/uUG5QrlDuUW5RrlHuUi5SblKuUu5TblOuVC5UrlTuVS5VblWuVe5//9auVu5XbleuV+5YbliuWO5ZLlluWa5Z7lquWy5" + "brlvuXC5cblyuXO5drl3uXm5erl7uX25////////////////frl/uYC5gbmCuYO5hrmIuYu5jLmPuZC5kbmSuZO5lLmVuZa5" + "l7mYuZm5mrmbuZy5nbmeuf///////////////5+5oLmhuaK5o7mkuaW5prmnuai5qbmquau5rrmvubG5srmzubW5trm3ubi5" + "ubm6ubu5vrnAucK5w7nEucW5xrnHucq5y7nNudO51LnVuda517naudy537ngueK55rnnuem56rnrue257rnvufC58bnyufO5" + "9rn7ufy5/bn+uf+5AroDugS6BboGuge6CboKugu6DLoNug66D7oQuhG6EroTuhS6FroXuhi6Gboauhu6HLoduh66H7oguiG6" + "IrojuiS6Jbomuie6KLopuiq6K7osui26LrovujC6MboyujO6NLo1uja6N7o6uju6Pbo+uj+6QbpDukS6RbpGuv//R7pKuky6" + "T7pQulG6UrpWule6Wbpaulu6Xbpeul+6YLphumK6Y7pmumq6a7psum26brpvuv///////////////3K6c7p1una6d7p5unq6" + "e7p8un26frp/uoC6gbqCuoa6iLqJuoq6i7qNuo66j7qQupG6krr///////////////+TupS6lbqWupe6mLqZupq6m7qcup26" + "nrqfuqC6obqiuqO6pLqluqa6p7qquq26rrqvurG6s7q0urW6trq3urq6vLq+ur+6wLrBusK6w7rFusa6x7rJusq6y7rMus26" + "zrrPutC60brSutO61LrVuta617rautu63Lrdut6637rguuG64rrjuuS65brmuue66Lrpuuq667rsuu267rrvuvC68bryuvO6" + "9Lr1uva697r4uvm6+rr7uv26/rr/ugG7ArsDuwW7BrsHuwi7CbsKuwu7DLsOuxC7ErsTuxS7FbsWuxe7Gbsauxu7Hbseux+7" + "IbsiuyO7JLsluya7J7v//yi7Krssuy27LrsvuzC7MbsyuzO7N7s5uzq7P7tAu0G7QrtDu0a7SLtKu0u7TLtOu1G7Urv/////" + "//////////9Tu1W7VrtXu1m7Wrtbu1y7Xbteu1+7YLtiu2S7Zbtmu2e7aLtpu2q7a7ttu267b7twu3G7////////////////" + "crtzu3S7dbt2u3e7eLt5u3q7e7t8u327frt/u4C7gbuCu4O7hLuFu4a7h7uJu4q7i7uNu467j7uRu5K7k7uUu5W7lruXu5i7" + "mbuau5u7nLudu567n7ugu6G7oruju6W7prunu6m7qruru627rruvu7C7sbuyu7O7tbu2u7i7ubu6u7u7vLu9u767v7vBu8K7" + "w7vFu8a7x7vJu8q7y7vMu827zrvPu9G70rvUu9W71rvXu9i72bvau9u73Lvdu96737vgu+G74rvju+S75bvmu+e76Lvpu+q7" + "67vsu+277rvvu/C78bvyu/O79Lv1u/a797v6u/u7/bv+uwG8//8DvAS8BbwGvAe8CrwOvBC8ErwTvBm8GrwgvCG8IrwjvCa8" + "KLwqvCu8LLwuvC+8MrwzvDW8////////////////Nrw3vDm8Orw7vDy8Pbw+vD+8QrxGvEe8SLxKvEu8TrxPvFG8UrxTvFS8" + "VbxWvFe8WLxZvP///////////////1q8W7xcvF68X7xgvGG8YrxjvGS8ZbxmvGe8aLxpvGq8a7xsvG28brxvvHC8cbxyvHO8" + "dLx1vHa8d7x4vHm8erx7vHy8fbx+vH+8gLyBvIK8g7yGvIe8ibyKvI28j7yQvJG8kryTvJa8mLybvJy8nbyevJ+8oryjvKW8" + "prypvKq8q7ysvK28rryvvLK8try3vLi8uby6vLu8vry/vMG8wrzDvMW8xrzHvMi8ybzKvMu8zLzOvNK807zUvNa817zZvNq8" + "27zdvN6837zgvOG84rzjvOS85bzmvOe86LzpvOq867zsvO287rzvvPC88bzyvPO897z5vPq8+7z9vP///rz/vAC9Ab0CvQO9" + "Br0IvQq9C70MvQ29Dr0PvRG9Er0TvRW9Fr0XvRi9Gb0avRu9HL0dvf///////////////x69H70gvSG9Ir0jvSW9Jr0nvSi9" + "Kb0qvSu9Lb0uvS+9ML0xvTK9M700vTW9Nr03vTi9Ob3///////////////86vTu9PL09vT69P71BvUK9Q71EvUW9Rr1HvUq9" + "S71NvU69T71RvVK9U71UvVW9Vr1XvVq9W71cvV29Xr1fvWC9Yb1ivWO9Zb1mvWe9ab1qvWu9bL1tvW69b71wvXG9cr1zvXS9" + "db12vXe9eL15vXq9e718vX29fr1/vYK9g72FvYa9i72MvY29jr2PvZK9lL2WvZe9mL2bvZ29nr2fvaC9ob2ivaO9pb2mvae9" + "qL2pvaq9q72sva29rr2vvbG9sr2zvbS9tb22vbe9ub26vbu9vL29vb69v73AvcG9wr3DvcS9xb3Gvce9yL3Jvcq9y73Mvc29" + "zr3PvdC90b3//9K9073Wvde92b3avdu93b3evd+94L3hveK9473kveW95r3nvei96r3rvey97b3uve+98b3/////////////" + "///yvfO99b32vfe9+b36vfu9/L39vf69/70BvgK+BL4Gvge+CL4Jvgq+C74Ovg++Eb4SvhO+////////////////Fb4Wvhe+" + "GL4Zvhq+G74eviC+Ib4iviO+JL4lvia+J74ovim+Kr4rviy+Lb4uvi++ML4xvjK+M740vjW+Nr43vji+Ob46vju+PL49vj6+" + "P75AvkG+Qr5Dvka+R75Jvkq+S75Nvk++UL5RvlK+U75Wvli+XL5dvl6+X75ivmO+Zb5mvme+ab5rvmy+bb5uvm++cr52vne+" + "eL55vnq+fr5/voG+gr6DvoW+hr6Hvoi+ib6Kvou+jr6SvpO+lL6Vvpa+l76avpu+nL6dvp6+n76gvqG+or6jvqS+pb6mvqe+" + "qb6qvqu+rL6tvq6+r76wvrG+sr6zvrS+tb62vre+//+4vrm+ur67vry+vb6+vr++wL7BvsK+w77EvsW+xr7Hvsi+yb7Kvsu+" + "zL7Nvs6+z77SvtO+////////////////1b7Wvtm+2r7bvty+3b7evt++4b7ivua+577ovum+6r7rvu2+7r7vvvC+8b7yvvO+" + "9L71vv////////////////a+9774vvm++r77vvy+/b7+vv++AL8CvwO/BL8Fvwa/B78Kvwu/DL8Nvw6/D78QvxG/Er8TvxS/" + "Fb8Wvxe/Gr8evx+/IL8hvyK/I78kvyW/Jr8nvyi/Kb8qvyu/LL8tvy6/L78wvzG/Mr8zvzS/Nb82vze/OL85vzq/O788vz2/" + "Pr8/v0K/Q79Fv0a/R79Jv0q/S79Mv02/Tr9Pv1K/U79Uv1a/V79Yv1m/Wr9bv1y/Xb9ev1+/YL9hv2K/Y79kv2W/Zr9nv2i/" + "ab9qv2u/bL9tv26/b79wv3G/cr9zv3S/db92v3e/eL95v3q/e798v32/fr9/v4C/gb+Cv///g7+Ev4W/hr+Hv4i/ib+Kv4u/" + "jL+Nv46/j7+Qv5G/kr+Tv5W/lr+Xv5i/mb+av5u/nL+dv////////////////56/n7+gv6G/or+jv6S/pb+mv6e/qL+pv6q/" + "q7+sv62/rr+vv7G/sr+zv7S/tb+2v7e/uL////////////////+5v7q/u7+8v72/vr+/v8C/wb/Cv8O/xL/Gv8e/yL/Jv8q/" + "y7/Ov8+/0b/Sv9O/1b/Wv9e/2L/Zv9q/27/dv96/4L/iv+O/5L/lv+a/57/ov+m/6r/rv+y/7b/uv++/8L/xv/K/87/0v/W/" + "9r/3v/i/+b/6v/u//L/9v/6//78AwAHAAsADwATABcAGwAfACMAJwArAC8AMwA3ADsAPwBDAEcASwBPAFMAVwBbAF8AYwBnA" + "GsAbwBzAHcAewB/AIMAhwCLAI8AkwCXAJsAnwCjAKcAqwCvALMAtwC7AL8AwwDHAMsAzwDTANcA2wDfAOMA5wDrAO8A9wD7A" + "P8D//0DAQcBCwEPARMBFwEbAR8BIwEnASsBLwEzATcBOwE/AUMBSwFPAVMBVwFbAV8BZwFrAW8D///////////////9dwF7A" + "X8BhwGLAY8BkwGXAZsBnwGrAa8BswG3AbsBvwHDAccBywHPAdMB1wHbAd8B4wHnA////////////////esB7wHzAfcB+wH/A" + "gMCBwILAg8CEwIXAhsCHwIjAicCKwIvAjMCNwI7Aj8CSwJPAlcCWwJfAmcCawJvAnMCdwJ7An8CiwKTApsCnwKjAqcCqwKvA" + "rsCxwLLAt8C4wLnAusC7wL7AwsDDwMTAxsDHwMrAy8DNwM7Az8DRwNLA08DUwNXA1sDXwNrA3sDfwODA4cDiwOPA5sDnwOnA" + "6sDrwO3A7sDvwPDA8cDywPPA9sD4wPrA+8D8wP3A/sD/wAHBAsEDwQXBBsEHwQnBCsELwQzBDcEOwQ/BEcESwRPBFMEWwRfB" + "GMEZwRrBG8EhwSLBJcEowSnBKsErwS7B//8ywTPBNME1wTfBOsE7wT3BPsE/wUHBQsFDwUTBRcFGwUfBSsFOwU/BUMFRwVLB" + "U8FWwVfB////////////////WcFawVvBXcFewV/BYMFhwWLBY8FmwWrBa8FswW3BbsFvwXHBcsFzwXXBdsF3wXnBesF7wf//" + "/////////////3zBfcF+wX/BgMGBwYLBg8GEwYbBh8GIwYnBisGLwY/BkcGSwZPBlcGXwZjBmcGawZvBnsGgwaLBo8GkwabB" + "p8GqwavBrcGuwa/BscGywbPBtMG1wbbBt8G4wbnBusG7wbzBvsG/wcDBwcHCwcPBxcHGwcfBycHKwcvBzcHOwc/B0MHRwdLB" + "08HVwdbB2cHawdvB3MHdwd7B38HhweLB48HlwebB58HpwerB68Hswe3B7sHvwfLB9MH1wfbB98H4wfnB+sH7wf7B/8EBwgLC" + "A8IFwgbCB8IIwgnCCsILwg7CEMISwhPCFMIVwhbCF8IawhvCHcIewiHCIsIjwv//JMIlwibCJ8IqwizCLsIwwjPCNcI2wjfC" + "OMI5wjrCO8I8wj3CPsI/wkDCQcJCwkPCRMJFwv///////////////0bCR8JJwkrCS8JMwk3CTsJPwlLCU8JVwlbCV8JZwlrC" + "W8Jcwl3CXsJfwmHCYsJjwmTCZsL///////////////9nwmjCacJqwmvCbsJvwnHCcsJzwnXCdsJ3wnjCecJ6wnvCfsKAwoLC" + "g8KEwoXChsKHworCi8KMwo3CjsKPwpHCksKTwpTClcKWwpfCmcKawpzCnsKfwqDCocKiwqPCpsKnwqnCqsKrwq7Cr8KwwrHC" + "ssKzwrbCuMK6wrvCvMK9wr7Cv8LAwsHCwsLDwsTCxcLGwsfCyMLJwsrCy8LMws3CzsLPwtDC0cLSwtPC1MLVwtbC18LYwtnC" + "2sLbwt7C38LhwuLC5cLmwufC6MLpwurC7sLwwvLC88L0wvXC98L6wv3C/sL/wgHDAsMDwwTDBcMGwwfDCsMLww7DD8P//xDD" + "EcMSwxbDF8MZwxrDG8Mdwx7DH8MgwyHDIsMjwybDJ8MqwyvDLMMtwy7DL8MwwzHDMsP///////////////8zwzTDNcM2wzfD" + "OMM5wzrDO8M8wz3DPsM/w0DDQcNCw0PDRMNGw0fDSMNJw0rDS8NMw03D////////////////TsNPw1DDUcNSw1PDVMNVw1bD" + "V8NYw1nDWsNbw1zDXcNew1/DYMNhw2LDY8Nkw2XDZsNnw2rDa8Ntw27Db8Nxw3PDdMN1w3bDd8N6w3vDfsN/w4DDgcOCw4PD" + "hcOGw4fDicOKw4vDjcOOw4/DkMORw5LDk8OUw5XDlsOXw5jDmcOaw5vDnMOdw57Dn8Ogw6HDosOjw6TDpcOmw6fDqMOpw6rD" + "q8Osw63DrsOvw7DDscOyw7PDtMO1w7bDt8O4w7nDusO7w7zDvcO+w7/DwcPCw8PDxMPFw8bDx8PIw8nDysPLw8zDzcPOw8/D" + "0MPRw9LD08PUw9XD1sPXw9rD///bw93D3sPhw+PD5MPlw+bD58Pqw+vD7MPuw+/D8MPxw/LD88P2w/fD+cP6w/vD/MP9w/7D" + "/////////////////8MAxAHEAsQDxATEBcQGxAfECcQKxAvEDMQNxA7ED8QRxBLEE8QUxBXEFsQXxBjEGcQaxP//////////" + "/////xvEHMQdxB7EH8QgxCHEIsQjxCXEJsQnxCjEKcQqxCvELcQuxC/EMcQyxDPENcQ2xDfEOMQ5xDrEO8Q+xD/EQMRBxELE" + "Q8RExEXERsRHxEnESsRLxEzETcROxE/EUMRRxFLEU8RUxFXEVsRXxFjEWcRaxFvEXMRdxF7EX8RgxGHEYsRjxGbEZ8RpxGrE" + "a8RtxG7Eb8RwxHHEcsRzxHbEd8R4xHrEe8R8xH3EfsR/xIHEgsSDxITEhcSGxIfEiMSJxIrEi8SMxI3EjsSPxJDEkcSSxJPE" + "lcSWxJfEmMSZxJrEm8SdxJ7En8SgxKHEosSjxKTEpcSmxKfEqMSpxP//qsSrxKzErcSuxK/EsMSxxLLEs8S0xLXEtsS3xLnE" + "usS7xL3EvsS/xMDEwcTCxMPExMTFxP///////////////8bEx8TIxMnEysTLxMzEzcTOxM/E0MTRxNLE08TUxNXE1sTXxNjE" + "2cTaxNvE3MTdxN7E38T////////////////gxOHE4sTjxOTE5cTmxOfE6MTqxOvE7MTtxO7E78TyxPPE9cT2xPfE+cT7xPzE" + "/cT+xALFA8UExQXFBsUHxQjFCcUKxQvFDcUOxQ/FEcUSxRPFFcUWxRfFGMUZxRrFG8UdxR7FH8UgxSHFIsUjxSTFJcUmxSfF" + "KsUrxS3FLsUvxTHFMsUzxTTFNcU2xTfFOsU8xT7FP8VAxUHFQsVDxUbFR8VLxU/FUMVRxVLFVsVaxVvFXMVfxWLFY8VlxWbF" + "Z8VpxWrFa8VsxW3FbsVvxXLFdsV3xXjFecV6xXvFfsV/xYHFgsWDxYXFhsWIxYnFisWLxY7FkMWSxZPFlMX//5bFmcWaxZvF" + "ncWexZ/FocWixaPFpMWlxabFp8WoxarFq8Wsxa3FrsWvxbDFscWyxbPFtsX///////////////+3xbrFv8XAxcHFwsXDxcvF" + "zcXPxdLF08XVxdbF18XZxdrF28Xcxd3F3sXfxeLF5MXmxefF////////////////6MXpxerF68XvxfHF8sXzxfXF+MX5xfrF" + "+8UCxgPGBMYJxgrGC8YNxg7GD8YRxhLGE8YUxhXGFsYXxhrGHcYexh/GIMYhxiLGI8YmxifGKcYqxivGL8YxxjLGNsY4xjrG" + "PMY9xj7GP8ZCxkPGRcZGxkfGScZKxkvGTMZNxk7GT8ZSxlbGV8ZYxlnGWsZbxl7GX8ZhxmLGY8ZkxmXGZsZnxmjGacZqxmvG" + "bcZuxnDGcsZzxnTGdcZ2xnfGesZ7xn3GfsZ/xoHGgsaDxoTGhcaGxofGisaMxo7Gj8aQxpHGksaTxpbGl8aZxprGm8adxp7G" + "n8agxqHGosajxqbG//+oxqrGq8asxq3GrsavxrLGs8a1xrbGt8a7xrzGvca+xr/GwsbExsbGx8bIxsnGysbLxs7G////////" + "////////z8bRxtLG08bVxtbG18bYxtnG2sbbxt7G38bixuPG5MblxubG58bqxuvG7cbuxu/G8cbyxv////////////////PG" + "9Mb1xvbG98b6xvvG/Mb+xv/GAMcBxwLHA8cGxwfHCccKxwvHDccOxw/HEMcRxxLHE8cWxxjHGscbxxzHHccexx/HIscjxyXH" + "JscnxynHKscrxyzHLccuxy/HMsc0xzbHOMc5xzrHO8c+xz/HQcdCx0PHRcdGx0fHSMdJx0vHTsdQx1nHWsdbx13HXsdfx2HH" + "Ysdjx2THZcdmx2fHacdqx2zHbcdux2/HcMdxx3LHc8d2x3fHecd6x3vHf8eAx4HHgseGx4vHjMeNx4/HkseTx5XHmcebx5zH" + "nceex5/Hosenx6jHqceqx6vHrsevx7HHssezx7XHtse3x///uMe5x7rHu8e+x8LHw8fEx8XHxsfHx8rHy8fNx8/H0cfSx9PH" + "1MfVx9bH18fZx9rH28fcx////////////////97H38fgx+HH4sfjx+XH5sfnx+nH6sfrx+3H7sfvx/DH8cfyx/PH9Mf1x/bH" + "98f4x/nH+sf////////////////7x/zH/cf+x//HAsgDyAXIBsgHyAnIC8gMyA3IDsgPyBLIFMgXyBjIGcgayBvIHsgfyCHI" + "IsgjyCXIJsgnyCjIKcgqyCvILsgwyDLIM8g0yDXINsg3yDnIOsg7yD3IPsg/yEHIQshDyETIRchGyEfISshLyE7IT8hQyFHI" + "UshTyFXIVshXyFjIWchayFvIXMhdyF7IX8hgyGHIYshjyGTIZchmyGfIaMhpyGrIa8hsyG3IbshvyHLIc8h1yHbId8h5yHvI" + "fMh9yH7If8iCyITIiMiJyIrIjsiPyJDIkciSyJPIlciWyJfImMiZyJrIm8icyJ7IoMiiyKPIpMj//6XIpsinyKnIqsiryKzI" + "rciuyK/IsMixyLLIs8i0yLXItsi3yLjIuci6yLvIvsi/yMDIwcj////////////////CyMPIxcjGyMfIycjKyMvIzcjOyM/I" + "0MjRyNLI08jWyNjI2sjbyNzI3cjeyN/I4sjjyOXI////////////////5sjnyOjI6cjqyOvI7MjtyO7I78jwyPHI8sjzyPTI" + "9sj3yPjI+cj6yPvI/sj/yAHJAskDyQfJCMkJyQrJC8kOyQAwATACMLcAJSAmIKgAAzCtABUgJSI8/zwiGCAZIBwgHSAUMBUw" + "CDAJMAowCzAMMA0wDjAPMBAwETCxANcA9wBgImQiZSIeIjQisAAyIDMgAyErIeD/4f/l/0ImQCYgIqUiEiMCIgciYSJSIqcA" + "OyAGJgUmyyXPJc4lxyXGJaEloCWzJbIlvSW8JZIhkCGRIZMhlCETMGoiayIaIj0iHSI1IisiLCIIIgsihiKHIoIigyIqIiki" + "JyIoIuL///8QyRLJE8kUyRXJFskXyRnJGskbyRzJHckeyR/JIMkhySLJI8kkySXJJsknySjJKckqySvJ////////////////" + "LckuyS/JMMkxyTLJM8k1yTbJN8k4yTnJOsk7yTzJPck+yT/JQMlByULJQ8lEyUXJRslHyf///////////////0jJSclKyUvJ" + "TMlNyU7JT8lSyVPJVclWyVfJWclayVvJXMldyV7JX8liyWTJZclmyWfJaMlpyWrJa8ltyW7Jb8nSIdQhACIDIrQAXv/HAtgC" + "3QLaAtkCuADbAqEAvwDQAi4iESIPIqQACSEwIMElwCW3JbYlZCZgJmEmZSZnJmMmmSLIJaMl0CXRJZIlpCWlJaglpyWmJakl" + "aCYPJg4mHCYeJrYAICAhIJUhlyGZIZYhmCFtJmkmaiZsJn8yHDIWIcczIiHCM9gzISGsIK4A////////////////////////" + "////////////////////////////////////////cclyyXPJdcl2yXfJeMl5yXrJe8l9yX7Jf8mAyYHJgsmDyYTJhcmGyYfJ" + "ismLyY3JjsmPyf///////////////5HJksmTyZTJlcmWyZfJmsmcyZ7Jn8mgyaHJosmjyaTJpcmmyafJqMmpyarJq8msya3J" + "rsn///////////////+vybDJscmyybPJtMm1ybbJt8m4ybnJusm7ybzJvcm+yb/JwsnDycXJxsnJycvJzMnNyc7Jz8nSydTJ" + "18nYydvJAf8C/wP/BP8F/wb/B/8I/wn/Cv8L/wz/Df8O/w//EP8R/xL/E/8U/xX/Fv8X/xj/Gf8a/xv/HP8d/x7/H/8g/yH/" + "Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov87/+b/Pf8+/z//QP9B/0L/Q/9E/0X/" + "Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/W/9c/13/4////97J38nhyePJ5cnmyejJ6cnqyevJ" + "7snyyfPJ9Mn1yfbJ98n6yfvJ/cn+yf/JAcoCygPKBMr///////////////8FygbKB8oKyg7KD8oQyhHKEsoTyhXKFsoXyhnK" + "GsobyhzKHcoeyh/KIMohyiLKI8okyiXK////////////////JsonyijKKsoryizKLcouyi/KMMoxyjLKM8o0yjXKNso3yjjK" + "Oco6yjvKPMo9yj7KP8pAykHKQspDykTKRcpGyjExMjEzMTQxNTE2MTcxODE5MToxOzE8MT0xPjE/MUAxQTFCMUMxRDFFMUYx" + "RzFIMUkxSjFLMUwxTTFOMU8xUDFRMVIxUzFUMVUxVjFXMVgxWTFaMVsxXDFdMV4xXzFgMWExYjFjMWQxZTFmMWcxaDFpMWox" + "azFsMW0xbjFvMXAxcTFyMXMxdDF1MXYxdzF4MXkxejF7MXwxfTF+MX8xgDGBMYIxgzGEMYUxhjGHMYgxiTGKMYsxjDGNMY4x" + "//9HykjKScpKykvKTspPylHKUspTylXKVspXyljKWcpaylvKXspiymPKZMplymbKZ8ppymrK////////////////a8psym3K" + "bspvynDKccpyynPKdMp1ynbKd8p4ynnKesp7ynzKfsp/yoDKgcqCyoPKhcqGyv///////////////4fKiMqJyorKi8qMyo3K" + "jsqPypDKkcqSypPKlMqVypbKl8qZyprKm8qcyp3KnsqfyqDKocqiyqPKpMqlyqbKp8pwIXEhciFzIXQhdSF2IXcheCF5If//" + "//////////9gIWEhYiFjIWQhZSFmIWchaCFpIf//////////////////kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58D" + "oAOhA6MDpAOlA6YDpwOoA6kD/////////////////////7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QD" + "xQPGA8cDyAPJA///////////////////qMqpyqrKq8qsyq3KrsqvyrDKscqyyrPKtMq1yrbKt8q4yrnKusq7yr7Kv8rBysLK" + "w8rFyv///////////////8bKx8rIysnKysrLys7K0MrSytTK1crWytfK2srbytzK3creyt/K4criyuPK5MrlyubK58r/////" + "///////////oyunK6srryu3K7srvyvDK8cryyvPK9cr2yvfK+Mr5yvrK+8r8yv3K/sr/ygDLAcsCywPLBMsFywbLB8sJywrL" + "ACUCJQwlECUYJRQlHCUsJSQlNCU8JQElAyUPJRMlGyUXJSMlMyUrJTslSyUgJS8lKCU3JT8lHSUwJSUlOCVCJRIlESUaJRkl" + "FiUVJQ4lDSUeJR8lISUiJSYlJyUpJSolLSUuJTElMiU1JTYlOSU6JT0lPiVAJUElQyVEJUUlRiVHJUglSSVKJf//////////" + "/////////////////////////////////////////////////////////////wvLDMsNyw7LD8sRyxLLE8sVyxbLF8sZyxrL" + "G8scyx3LHssfyyLLI8skyyXLJssnyyjLKcv///////////////8qyyvLLMstyy7LL8swyzHLMsszyzTLNcs2yzfLOMs5yzrL" + "O8s8yz3LPss/y0DLQstDy0TL////////////////RctGy0fLSstLy03LTstPy1HLUstTy1TLVctWy1fLWstby1zLXstfy2DL" + "Yctiy2PLZctmy2fLaMtpy2rLa8tsy5UzljOXMxMhmDPEM6MzpDOlM6YzmTOaM5sznDOdM54znzOgM6EzojPKM40zjjOPM88z" + "iDOJM8gzpzOoM7AzsTOyM7MztDO1M7YztzO4M7kzgDOBM4IzgzOEM7ozuzO8M70zvjO/M5AzkTOSM5MzlDMmIcAzwTOKM4sz" + "jDPWM8UzrTOuM68z2zOpM6ozqzOsM90z0DPTM8MzyTPcM8Yz//////////////////////////////////////////9ty27L" + "b8twy3HLcstzy3TLdct2y3fLest7y3zLfct+y3/LgMuBy4LLg8uEy4XLhsuHy4jL////////////////icuKy4vLjMuNy47L" + "j8uQy5HLksuTy5TLlcuWy5fLmMuZy5rLm8udy57Ln8ugy6HLosujy////////////////6TLpcumy6fLqMupy6rLq8usy63L" + "rsuvy7DLscuyy7PLtMu1y7bLt8u5y7rLu8u8y73Lvsu/y8DLwcvCy8PLxMvGANAAqgAmAf//MgH//z8BQQHYAFIBugDeAGYB" + "SgH//2AyYTJiMmMyZDJlMmYyZzJoMmkyajJrMmwybTJuMm8ycDJxMnIyczJ0MnUydjJ3MngyeTJ6Mnsy0CTRJNIk0yTUJNUk" + "1iTXJNgk2STaJNsk3CTdJN4k3yTgJOEk4iTjJOQk5STmJOck6CTpJGAkYSRiJGMkZCRlJGYkZyRoJGkkaiRrJGwkbSRuJL0A" + "UyFUIbwAvgBbIVwhXSFeIf//xcvGy8fLyMvJy8rLy8vMy83LzsvPy9DL0cvSy9PL1cvWy9fL2MvZy9rL28vcy93L3svfy///" + "/////////////+DL4cviy+PL5cvmy+jL6svry+zL7cvuy+/L8Mvxy/LL88v0y/XL9sv3y/jL+cv6y/vL/Mv/////////////" + "///9y/7L/8sAzAHMAswDzATMBcwGzAfMCMwJzArMC8wOzA/MEcwSzBPMFcwWzBfMGMwZzBrMG8wezB/MIMwjzCTM5gARAfAA" + "JwExATMBOAFAAUIB+ABTAd8A/gBnAUsBSQEAMgEyAjIDMgQyBTIGMgcyCDIJMgoyCzIMMg0yDjIPMhAyETISMhMyFDIVMhYy" + "FzIYMhkyGjIbMpwknSSeJJ8koCShJKIkoySkJKUkpiSnJKgkqSSqJKskrCStJK4krySwJLEksiSzJLQktSR0JHUkdiR3JHgk" + "eSR6JHskfCR9JH4kfySAJIEkgiS5ALIAswB0IH8ggSCCIIMghCD//yXMJswqzCvMLcwvzDHMMswzzDTMNcw2zDfMOsw/zEDM" + "QcxCzEPMRsxHzEnMSsxLzE3MTsz///////////////9PzFDMUcxSzFPMVsxazFvMXMxdzF7MX8xhzGLMY8xlzGfMacxqzGvM" + "bMxtzG7Mb8xxzHLM////////////////c8x0zHbMd8x4zHnMesx7zHzMfcx+zH/MgMyBzILMg8yEzIXMhsyHzIjMicyKzIvM" + "jMyNzI7Mj8yQzJHMksyTzEEwQjBDMEQwRTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYwVzBYMFkwWjBbMFww" + "XTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgwaTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHowezB8MH0wfjB/MIAw" + "gTCCMIMwhDCFMIYwhzCIMIkwijCLMIwwjTCOMI8wkDCRMJIwkzD///////////////////////////////+UzJXMlsyXzJrM" + "m8ydzJ7Mn8yhzKLMo8ykzKXMpsynzKrMrsyvzLDMscyyzLPMtsy3zLnM////////////////usy7zL3Mvsy/zMDMwczCzMPM" + "xszIzMrMy8zMzM3MzszPzNHM0szTzNXM1szXzNjM2czazP///////////////9vM3MzdzN7M38zgzOHM4szjzOXM5sznzOjM" + "6czqzOvM7czuzO/M8czyzPPM9Mz1zPbM98z4zPnM+sz7zPzM/cyhMKIwozCkMKUwpjCnMKgwqTCqMKswrDCtMK4wrzCwMLEw" + "sjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w0DDRMNIw0zDUMNUw" + "1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw4jDjMOQw5TDmMOcw6DDpMOow6zDsMO0w7jDvMPAw8TDyMPMw9DD1MPYw////////" + "/////////////////sz/zADNAs0DzQTNBc0GzQfNCs0LzQ3NDs0PzRHNEs0TzRTNFc0WzRfNGs0czR7NH80gzf//////////" + "/////yHNIs0jzSXNJs0nzSnNKs0rzS3NLs0vzTDNMc0yzTPNNM01zTbNN804zTrNO808zT3NPs3///////////////8/zUDN" + "Qc1CzUPNRM1FzUbNR81IzUnNSs1LzUzNTc1OzU/NUM1RzVLNU81UzVXNVs1XzVjNWc1azVvNXc1ezV/NEAQRBBIEEwQUBBUE" + "AQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8E////////////////////////" + "////////////////MAQxBDIEMwQ0BDUEUQQ2BDcEOAQ5BDoEOwQ8BD0EPgQ/BEAEQQRCBEMERARFBEYERwRIBEkESgRLBEwE" + "TQROBE8E/////////////////////////////////////2HNYs1jzWXNZs1nzWjNac1qzWvNbs1wzXLNc810zXXNds13zXnN" + "es17zXzNfc1+zX/NgM3///////////////+BzYLNg82EzYXNhs2HzYnNis2LzYzNjc2OzY/NkM2RzZLNk82WzZfNmc2azZvN" + "nc2ezZ/N////////////////oM2hzaLNo82mzajNqs2rzazNrc2uza/Nsc2yzbPNtM21zbbNt824zbnNus27zbzNvc2+zb/N" + "wM3BzcLNw83Fzf//////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////////////////////GzcfNyM3JzcrNy83Nzc7N" + "z83RzdLN083UzdXN1s3XzdjN2c3azdvN3M3dzd7N383gzeHN////////////////4s3jzeTN5c3mzefN6c3qzevN7c3uze/N" + "8c3yzfPN9M31zfbN9836zfzN/s3/zQDOAc4Czv///////////////wPOBc4GzgfOCc4KzgvODc4Ozg/OEM4RzhLOE84VzhbO" + "F84YzhrOG84czh3OHs4fziLOI84lzibOJ84pzirOK87/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////LM4tzi7OL84yzjTONs43zjjOOc46zjvOPM49zj7OP85AzkHOQs5DzkTORc5GzkfOSM5Jzv///////////////0rO" + "S85Mzk3OTs5PzlDOUc5SzlPOVM5VzlbOV85azlvOXc5ezmLOY85kzmXOZs5nzmrObM7///////////////9uzm/OcM5xznLO" + "c852znfOec56znvOfc5+zn/OgM6BzoLOg86GzojOis6LzozOjc6Ozo/Oks6TzpXOls6XzpnO////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////5rOm86czp3Ons6fzqLOps6nzqjOqc6qzqvOrs6vzrDOsc6yzrPOtM61zrbO" + "t864zrnOus7///////////////+7zrzOvc6+zr/OwM7CzsPOxM7FzsbOx87IzsnOys7LzszOzc7Ozs/O0M7RztLO087UztXO" + "////////////////1s7XztjO2c7aztvO3M7dzt7O387gzuHO4s7jzubO587pzurO7c7uzu/O8M7xzvLO8872zvrO+878zv3O" + "/s7/zgCsAawErAesCKwJrAqsEKwRrBKsE6wUrBWsFqwXrBmsGqwbrBysHawgrCSsLKwtrC+sMKwxrDisOaw8rECsS6xNrFSs" + "WKxcrHCscax0rHeseKx6rICsgayDrISshayGrImsiqyLrIyskKyUrJysnayfrKCsoayorKmsqqysrK+ssKy4rLmsu6y8rL2s" + "wazErMiszKzVrNes4KzhrOSs56zorOqs7KzvrPCs8azzrPWs9qz8rP2sAK0ErQat//8CzwPPBc8GzwfPCc8KzwvPDM8Nzw7P" + "D88SzxTPFs8XzxjPGc8azxvPHc8ezx/PIc8izyPP////////////////Jc8mzyfPKM8pzyrPK88uzzLPM880zzXPNs83zznP" + "Os87zzzPPc8+zz/PQM9Bz0LPQ89Ez////////////////0XPRs9Hz0jPSc9Kz0vPTM9Nz07PT89Qz1HPUs9Tz1bPV89Zz1rP" + "W89dz17PX89gz2HPYs9jz2bPaM9qz2vPbM8MrQ2tD60RrRitHK0grSmtLK0trTStNa04rTytRK1FrUetSa1QrVStWK1hrWOt" + "bK1trXCtc610rXWtdq17rXytfa1/rYGtgq2IrYmtjK2QrZytna2krbetwK3BrcStyK3QrdGt063creCt5K34rfmt/K3/rQCu" + "Aa4IrgmuC64NrhSuMK4xrjSuN644rjquQK5BrkOuRa5GrkquTK5Nrk6uUK5UrlauXK5drl+uYK5hrmWuaK5prmyucK54rv//" + "bc9uz2/Pcs9zz3XPds93z3nPes97z3zPfc9+z3/Pgc+Cz4PPhM+Gz4fPiM+Jz4rPi8+Nz////////////////47Pj8+Qz5HP" + "ks+Tz5TPlc+Wz5fPmM+Zz5rPm8+cz53Pns+fz6DPos+jz6TPpc+mz6fPqc////////////////+qz6vPrM+tz67Pr8+xz7LP" + "s8+0z7XPts+3z7jPuc+6z7vPvM+9z77Pv8/Az8HPws/Dz8XPxs/Hz8jPyc/Kz8vPea57rnyufa6EroWujK68rr2uvq7ArsSu" + "zK7Nrs+u0K7Rrtiu2a7cruiu667trvSu+K78rgevCK8NrxCvLK8trzCvMq80rzyvPa8/r0GvQq9Dr0ivSa9Qr1yvXa9kr2Wv" + "ea+Ar4SviK+Qr5Gvla+cr7ivua+8r8Cvx6/Ir8mvy6/Nr86v1K/cr+iv6a/wr/Gv9K/4rwCwAbAEsAywELAUsBywHbAosESw" + "RbBIsEqwTLBOsFOwVLBVsFewWbD//8zPzc/Oz8/P0M/Rz9LP08/Uz9XP1s/Xz9jP2c/az9vP3M/dz97P38/iz+PP5c/mz+fP" + "6c/////////////////qz+vP7M/tz+7P78/yz/TP9s/3z/jP+c/6z/vP/c/+z//PAdAC0APQBdAG0AfQCNAJ0ArQ////////" + "////////C9AM0A3QDtAP0BDQEtAT0BTQFdAW0BfQGdAa0BvQHNAd0B7QH9Ag0CHQItAj0CTQJdAm0CfQKNAp0CrQK9As0F2w" + "fLB9sICwhLCMsI2wj7CRsJiwmbCasJywn7CgsKGworCosKmwq7CssK2wrrCvsLGws7C0sLWwuLC8sMSwxbDHsMiwybDQsNGw" + "1LDYsOCw5bAIsQmxC7EMsRCxErETsRixGbEbsRyxHbEjsSSxJbEosSyxNLE1sTexOLE5sUCxQbFEsUixULFRsVSxVbFYsVyx" + "YLF4sXmxfLGAsYKxiLGJsYuxjbGSsZOxlLGYsZyxqLHMsdCx1LHcsd2x//8u0C/QMNAx0DLQM9A20DfQOdA60DvQPdA+0D/Q" + "QNBB0ELQQ9BG0EjQStBL0EzQTdBO0E/Q////////////////UdBS0FPQVdBW0FfQWdBa0FvQXNBd0F7QX9Bh0GLQY9Bk0GXQ" + "ZtBn0GjQadBq0GvQbtBv0P///////////////3HQctBz0HXQdtB30HjQedB60HvQftB/0IDQgtCD0ITQhdCG0IfQiNCJ0IrQ" + "i9CM0I3QjtCP0JDQkdCS0JPQlNDfseix6bHssfCx+bH7sf2xBLIFsgiyC7IMshSyFbIXshmyILI0sjyyWLJcsmCyaLJpsnSy" + "dbJ8soSyhbKJspCykbKUspiymbKasqCyobKjsqWyprKqsqyysLK0ssiyybLMstCy0rLYstmy27LdsuKy5LLlsuay6LLrsuyy" + "7bLusu+y87L0svWy97L4svmy+rL7sv+yALMBswSzCLMQsxGzE7MUsxWzHLNUs1WzVrNYs1uzXLNes1+zZLNls///ldCW0JfQ" + "mNCZ0JrQm9Cc0J3QntCf0KDQodCi0KPQptCn0KnQqtCr0K3QrtCv0LDQsdCy0P///////////////7PQttC40LrQu9C80L3Q" + "vtC/0MLQw9DF0MbQx9DK0MvQzNDN0M7Qz9DS0NbQ19DY0NnQ2tD////////////////b0N7Q39Dh0OLQ49Dl0ObQ59Do0OnQ" + "6tDr0O7Q8tDz0PTQ9dD20PfQ+dD60PvQ/ND90P7Q/9AA0QHRAtED0QTRZ7Nps2uzbrNws3GzdLN4s4CzgbODs4SzhbOMs5Cz" + "lLOgs6GzqLOss8SzxbPIs8uzzLPOs9Cz1LPVs9ez2bPbs92z4LPks+iz/LMQtBi0HLQgtCi0KbQrtDS0ULRRtFS0WLRgtGG0" + "Y7RltGy0gLSItJ20pLSotKy0tbS3tLm0wLTEtMi00LTVtNy03bTgtOO05LTmtOy07bTvtPG0+LQUtRW1GLUbtRy1JLUltSe1" + "KLUptSq1MLUxtTS1OLX//wXRBtEH0QjRCdEK0QvRDNEO0Q/RENER0RLRE9EU0RXRFtEX0RjRGdEa0RvRHNEd0R7RH9H/////" + "//////////8g0SHRItEj0STRJdEm0SfRKNEp0SrRK9Es0S3RLtEv0TLRM9E10TbRN9E50TvRPNE90T7R////////////////" + "P9FC0UbRR9FI0UnRStFL0U7RT9FR0VLRU9FV0VbRV9FY0VnRWtFb0V7RYNFi0WPRZNFl0WbRZ9Fp0WrRa9Ft0UC1QbVDtUS1" + "RbVLtUy1TbVQtVS1XLVdtV+1YLVhtaC1obWktai1qrWrtbC1sbWztbS1tbW7tby1vbXAtcS1zLXNtc+10LXRtdi17LUQthG2" + "FLYYtiW2LLY0tki2ZLZotpy2nbagtqS2q7astrG21LbwtvS2+LYAtwG3Bbcotym3LLcvtzC3OLc5tzu3RLdIt0y3VLdVt2C3" + "ZLdot3C3cbdzt3W3fLd9t4C3hLeMt423j7eQt5G3kreWt5e3//9u0W/RcNFx0XLRc9F00XXRdtF30XjRedF60XvRfdF+0X/R" + "gNGB0YLRg9GF0YbRh9GJ0YrR////////////////i9GM0Y3RjtGP0ZDRkdGS0ZPRlNGV0ZbRl9GY0ZnRmtGb0ZzRndGe0Z/R" + "otGj0aXRptGn0f///////////////6nRqtGr0azRrdGu0a/RstG00bbRt9G40bnRu9G90b7Rv9HB0cLRw9HE0cXRxtHH0cjR" + "ydHK0cvRzNHN0c7Rz9GYt5m3nLegt6i3qbert6y3rbe0t7W3uLfHt8m37Lftt/C39Lf8t/23/7cAuAG4B7gIuAm4DLgQuBi4" + "GbgbuB24JLgluCi4LLg0uDW4N7g4uDm4QLhEuFG4U7hcuF24YLhkuGy4bbhvuHG4eLh8uI24qLiwuLS4uLjAuMG4w7jFuMy4" + "0LjUuN2437jhuOi46bjsuPC4+Lj5uPu4/bgEuRi5ILk8uT25QLlEuUy5T7lRuVi5WblcuWC5aLlpuf//0NHR0dLR09HU0dXR" + "1tHX0dnR2tHb0dzR3dHe0d/R4NHh0eLR49Hk0eXR5tHn0ejR6dHq0f///////////////+vR7NHt0e7R79Hw0fHR8tHz0fXR" + "9tH30fnR+tH70fzR/dH+0f/RANIB0gLSA9IE0gXSBtL///////////////8I0grSC9IM0g3SDtIP0hHSEtIT0hTSFdIW0hfS" + "GNIZ0hrSG9Ic0h3SHtIf0iDSIdIi0iPSJNIl0ibSJ9Io0inSa7ltuXS5dbl4uXy5hLmFuYe5ibmKuY25jrmsua25sLm0uby5" + "vbm/ucG5yLnJucy5zrnPudC50bnSudi52bnbud253rnhueO55Lnluei57Ln0ufW597n4ufm5+rkAugG6CLoVuji6Obo8ukC6" + "QrpIukm6S7pNuk66U7pUulW6WLpcumS6Zbpnumi6abpwunG6dLp4uoO6hLqFuoe6jLqouqm6q7qsurC6srq4urm6u7q9usS6" + "yLrYutm6/Lr//yrSK9Iu0i/SMdIy0jPSNdI20jfSONI50jrSO9I+0kDSQtJD0kTSRdJG0kfSSdJK0kvSTNL/////////////" + "//9N0k7ST9JQ0lHSUtJT0lTSVdJW0lfSWNJZ0lrSW9Jd0l7SX9Jg0mHSYtJj0mXSZtJn0mjS////////////////adJq0mvS" + "bNJt0m7Sb9Jw0nHSctJz0nTSddJ20nfSeNJ50nrSe9J80n3SftJ/0oLSg9KF0obSh9KJ0orSi9KM0gC7BLsNuw+7EbsYuxy7" + "ILspuyu7NLs1uza7OLs7uzy7Pbs+u0S7RbtHu0m7TbtPu1C7VLtYu2G7Y7tsu4i7jLuQu6S7qLusu7S7t7vAu8S7yLvQu9O7" + "+Lv5u/y7/7sAvAK8CLwJvAu8DLwNvA+8EbwUvBW8FrwXvBi8G7wcvB28HrwfvCS8JbwnvCm8LbwwvDG8NLw4vEC8QbxDvES8" + "RbxJvEy8TbxQvF28hLyFvIi8i7yMvI68lLyVvJe8//+N0o7Sj9KS0pPSlNKW0pfSmNKZ0prSm9Kd0p7Sn9Kh0qLSo9Kl0qbS" + "p9Ko0qnSqtKr0q3S////////////////rtKv0rDSstKz0rTStdK20rfSutK70r3SvtLB0sPSxNLF0sbSx9LK0szSzdLO0s/S" + "0NLR0v///////////////9LS09LV0tbS19LZ0trS29Ld0t7S39Lg0uHS4tLj0ubS59Lo0unS6tLr0uzS7dLu0u/S8tLz0vXS" + "9tL30vnS+tKZvJq8oLyhvKS8p7yovLC8sbyzvLS8tby8vL28wLzEvM28z7zQvNG81bzYvNy89Lz1vPa8+Lz8vAS9Bb0HvQm9" + "EL0UvSS9LL1AvUi9Sb1MvVC9WL1ZvWS9aL2AvYG9hL2HvYi9ib2KvZC9kb2TvZW9mb2avZy9pL2wvbi91L3Vvdi93L3pvfC9" + "9L34vQC+A74Fvgy+Db4QvhS+HL4dvh++RL5Fvki+TL5OvlS+Vb5Xvlm+Wr5bvmC+Yb5kvv//+9L80v3S/tL/0gLTBNMG0wfT" + "CNMJ0wrTC9MP0xHTEtMT0xXTF9MY0xnTGtMb0x7TItMj0////////////////yTTJtMn0yrTK9Mt0y7TL9Mx0zLTM9M00zXT" + "NtM30zrTPtM/00DTQdNC00PTRtNH00jTSdP///////////////9K00vTTNNN007TT9NQ01HTUtNT01TTVdNW01fTWNNZ01rT" + "W9Nc013TXtNf02DTYdNi02PTZNNl02bTZ9No02nTaL5qvnC+cb5zvnS+db57vny+fb6AvoS+jL6Nvo++kL6Rvpi+mb6ovtC+" + "0b7Uvte+2L7gvuO+5L7lvuy+Ab8Ivwm/GL8Zvxu/HL8dv0C/Qb9Ev0i/UL9Rv1W/lL+wv8W/zL/Nv9C/1L/cv9+/4b88wFHA" + "WMBcwGDAaMBpwJDAkcCUwJjAoMChwKPApcCswK3Ar8CwwLPAtMC1wLbAvMC9wL/AwMDBwMXAyMDJwMzA0MDYwNnA28DcwN3A" + "5MD//2rTa9Ns023TbtNv03DTcdNy03PTdNN103bTd9N403nTetN7037Tf9OB04LTg9OF04bTh9P///////////////+I04nT" + "itOL047TktOT05TTldOW05fTmtOb053TntOf06HTotOj06TTpdOm06fTqtOs067T////////////////r9Ow07HTstOz07XT" + "ttO307nTutO7073TvtO/08DTwdPC08PTxtPH08rTy9PM083TztPP09HT0tPT09TT1dPW0+XA6MDswPTA9cD3wPnAAMEEwQjB" + "EMEVwRzBHcEewR/BIMEjwSTBJsEnwSzBLcEvwTDBMcE2wTjBOcE8wUDBSMFJwUvBTMFNwVTBVcFYwVzBZMFlwWfBaMFpwXDB" + "dMF4wYXBjMGNwY7BkMGUwZbBnMGdwZ/BocGlwajBqcGswbDBvcHEwcjBzMHUwdfB2MHgweTB6MHwwfHB88H8wf3BAMIEwgzC" + "DcIPwhHCGMIZwhzCH8IgwijCKcIrwi3C///X09nT2tPb09zT3dPe09/T4NPi0+TT5dPm0+fT6NPp0+rT69Pu0+/T8dPy0/PT" + "9dP20/fT////////////////+NP50/rT+9P+0wDUAtQD1ATUBdQG1AfUCdQK1AvUDNQN1A7UD9QQ1BHUEtQT1BTUFdQW1P//" + "/////////////xfUGNQZ1BrUG9Qc1B7UH9Qg1CHUItQj1CTUJdQm1CfUKNQp1CrUK9Qs1C3ULtQv1DDUMdQy1DPUNNQ11DbU" + "N9QvwjHCMsI0wkjCUMJRwlTCWMJgwmXCbMJtwnDCdMJ8wn3Cf8KBwojCicKQwpjCm8KdwqTCpcKowqzCrcK0wrXCt8K5wtzC" + "3cLgwuPC5MLrwuzC7cLvwvHC9sL4wvnC+8L8wgDDCMMJwwzDDcMTwxTDFcMYwxzDJMMlwyjDKcNFw2jDacNsw3DDcsN4w3nD" + "fMN9w4TDiMOMw8DD2MPZw9zD38Pgw+LD6MPpw+3D9MP1w/jDCMQQxCTELMQwxP//ONQ51DrUO9Q81D3UPtQ/1EHUQtRD1EXU" + "RtRH1EjUSdRK1EvUTNRN1E7UT9RQ1FHUUtRT1P///////////////1TUVdRW1FfUWNRZ1FrUW9Rd1F7UX9Rh1GLUY9Rl1GbU" + "Z9Ro1GnUatRr1GzUbtRw1HHUctT///////////////9z1HTUddR21HfUetR71H3UftSB1IPUhNSF1IbUh9SK1IzUjtSP1JDU" + "kdSS1JPUldSW1JfUmNSZ1JrUm9Sc1J3UNMQ8xD3ESMRkxGXEaMRsxHTEdcR5xIDElMScxLjEvMTpxPDE8cT0xPjE+sT/xADF" + "AcUMxRDFFMUcxSjFKcUsxTDFOMU5xTvFPcVExUXFSMVJxUrFTMVNxU7FU8VUxVXFV8VYxVnFXcVexWDFYcVkxWjFcMVxxXPF" + "dMV1xXzFfcWAxYTFh8WMxY3Fj8WRxZXFl8WYxZzFoMWpxbTFtcW4xbnFu8W8xb3FvsXExcXFxsXHxcjFycXKxczFzsX//57U" + "n9Sg1KHUotSj1KTUpdSm1KfUqNSq1KvUrNSt1K7Ur9Sw1LHUstSz1LTUtdS21LfUuNT///////////////+51LrUu9S81L3U" + "vtS/1MDUwdTC1MPUxNTF1MbUx9TI1MnUytTL1M3UztTP1NHU0tTT1NXU////////////////1tTX1NjU2dTa1NvU3dTe1ODU" + "4dTi1OPU5NTl1ObU59Tp1OrU69Tt1O7U79Tx1PLU89T01PXU9tT31PnU+tT81NDF0cXUxdjF4MXhxePF5cXsxe3F7sXwxfTF" + "9sX3xfzF/cX+xf/FAMYBxgXGBsYHxgjGDMYQxhjGGcYbxhzGJMYlxijGLMYtxi7GMMYzxjTGNcY3xjnGO8ZAxkHGRMZIxlDG" + "UcZTxlTGVcZcxl3GYMZsxm/GccZ4xnnGfMaAxojGicaLxo3GlMaVxpjGnMakxqXGp8apxrDGsca0xrjGuca6xsDGwcbDxsXG" + "zMbNxtDG1Mbcxt3G4MbhxujG///+1P/UANUB1QLVA9UF1QbVB9UJ1QrVC9UN1Q7VD9UQ1RHVEtUT1RbVGNUZ1RrVG9Uc1R3V" + "////////////////HtUf1SDVIdUi1SPVJNUl1SbVJ9Uo1SnVKtUr1SzVLdUu1S/VMNUx1TLVM9U01TXVNtU31f//////////" + "/////zjVOdU61TvVPtU/1UHVQtVD1UXVRtVH1UjVSdVK1UvVTtVQ1VLVU9VU1VXVVtVX1VrVW9Vd1V7VX9Vh1WLVY9XpxuzG" + "8Mb4xvnG/cYExwXHCMcMxxTHFccXxxnHIMchxyTHKMcwxzHHM8c1xzfHPMc9x0DHRMdKx0zHTcdPx1HHUsdTx1THVcdWx1fH" + "WMdcx2DHaMdrx3THdcd4x3zHfcd+x4PHhMeFx4fHiMeJx4rHjseQx5HHlMeWx5fHmMeax6DHocejx6THpcemx6zHrcewx7TH" + "vMe9x7/HwMfBx8jHycfMx87H0MfYx93H5Mfox+zHAMgByATICMgKyP//ZNVm1WfVatVs1W7Vb9Vw1XHVctVz1XbVd9V51XrV" + "e9V91X7Vf9WA1YHVgtWD1YbVitWL1f///////////////4zVjdWO1Y/VkdWS1ZPVlNWV1ZbVl9WY1ZnVmtWb1ZzVndWe1Z/V" + "oNWh1aLVo9Wk1abVp9X///////////////+o1anVqtWr1azVrdWu1a/VsNWx1bLVs9W01bXVttW31bjVudW61bvVvNW91b7V" + "v9XA1cHVwtXD1cTVxdXG1cfVEMgRyBPIFcgWyBzIHcggyCTILMgtyC/IMcg4yDzIQMhIyEnITMhNyFTIcMhxyHTIeMh6yIDI" + "gciDyIXIhsiHyIvIjMiNyJTIncifyKHIqMi8yL3IxMjIyMzI1MjVyNfI2cjgyOHI5Mj1yPzI/cgAyQTJBckGyQzJDckPyRHJ" + "GMksyTTJUMlRyVTJWMlgyWHJY8lsyXDJdMl8yYjJicmMyZDJmMmZyZvJncnAycHJxMnHycjJysnQydHJ08n//8rVy9XN1c7V" + "z9XR1dPV1NXV1dbV19Xa1dzV3tXf1eDV4dXi1ePV5tXn1enV6tXr1e3V7tX////////////////v1fDV8dXy1fPV9tX41frV" + "+9X81f3V/tX/1QLWA9YF1gbWB9YJ1grWC9YM1g3WDtYP1hLW////////////////FtYX1hjWGdYa1hvWHdYe1h/WIdYi1iPW" + "JdYm1ifWKNYp1irWK9Ys1i7WL9Yw1jHWMtYz1jTWNdY21jfWOtY71tXJ1snZydrJ3MndyeDJ4snkyefJ7Mntye/J8MnxyfjJ" + "+cn8yQDKCMoJygvKDMoNyhTKGMopykzKTcpQylTKXMpdyl/KYMphymjKfcqEypjKvMq9ysDKxMrMys3Kz8rRytPK2MrZyuDK" + "7Mr0ygjLEMsUyxjLIMshy0HLSMtJy0zLUMtYy1nLXctky3jLecucy7jL1Mvky+fL6csMzA3MEMwUzBzMHcwhzCLMJ8wozCnM" + "LMwuzDDMOMw5zDvM//891j7WP9ZB1kLWQ9ZE1kbWR9ZK1kzWTtZP1lDWUtZT1lbWV9ZZ1lrWW9Zd1l7WX9Zg1mHW////////" + "////////YtZj1mTWZdZm1mjWatZr1mzWbdZu1m/WctZz1nXWdtZ31njWedZ61nvWfNZ91n7Wf9aA1v///////////////4HW" + "gtaE1obWh9aI1onWitaL1o7Wj9aR1pLWk9aV1pbWl9aY1pnWmtab1pzWntag1qLWo9ak1qXWptan1qnWqtY8zD3MPsxEzEXM" + "SMxMzFTMVcxXzFjMWcxgzGTMZsxozHDMdcyYzJnMnMygzKjMqcyrzKzMrcy0zLXMuMy8zMTMxczHzMnM0MzUzOTM7MzwzAHN" + "CM0JzQzNEM0YzRnNG80dzSTNKM0szTnNXM1gzWTNbM1tzW/Ncc14zYjNlM2VzZjNnM2kzaXNp82pzbDNxM3MzdDN6M3szfDN" + "+M35zfvN/c0EzgjODM4UzhnOIM4hziTOKM4wzjHOM841zv//q9at1q7Wr9ax1rLWs9a01rXWtta31rjWuta81r3Wvta/1sDW" + "wdbC1sPWxtbH1snWytbL1v///////////////83WztbP1tDW0tbT1tXW1tbY1trW29bc1t3W3tbf1uHW4tbj1uXW5tbn1unW" + "6tbr1uzW7db////////////////u1u/W8dby1vPW9Nb21vfW+Nb51vrW+9b+1v/WAdcC1wPXBdcG1wfXCNcJ1wrXC9cM1w3X" + "DtcP1xDXEtcT1xTXWM5ZzlzOX85gzmHOaM5pzmvObc50znXOeM58zoTOhc6HzonOkM6RzpTOmM6gzqHOo86kzqXOrM6tzsHO" + "5M7lzujO687szvTO9c73zvjO+c4AzwHPBM8IzxDPEc8TzxXPHM8gzyTPLM8tzy/PMM8xzzjPVM9Vz1jPXM9kz2XPZ89pz3DP" + "cc90z3jPgM+Fz4zPoc+oz7DPxM/gz+HP5M/oz/DP8c/zz/XP/M8A0ATQEdAY0C3QNNA10DjQPND//xXXFtcX1xrXG9cd1x7X" + "H9ch1yLXI9ck1yXXJtcn1yrXLNcu1y/XMNcx1zLXM9c21zfXOdf///////////////861zvXPdc+1z/XQNdB10LXQ9dF10bX" + "SNdK10vXTNdN107XT9dS11PXVdda11vXXNdd117X////////////////X9di12TXZtdn12jXatdr123Xbtdv13HXctdz13XX" + "dtd313jXedd613vXftd/14DXgteD14TXhdeG14fXiteL10TQRdBH0EnQUNBU0FjQYNBs0G3QcNB00HzQfdCB0KTQpdCo0KzQ" + "tNC10LfQudDA0MHQxNDI0MnQ0NDR0NPQ1NDV0NzQ3dDg0OTQ7NDt0O/Q8NDx0PjQDdEw0THRNNE40TrRQNFB0UPRRNFF0UzR" + "TdFQ0VTRXNFd0V/RYdFo0WzRfNGE0YjRoNGh0aTRqNGw0bHRs9G10brRvNHA0djR9NH40QfSCdIQ0izSLdIw0jTSPNI90j/S" + "QdJI0lzS//+N147Xj9eR15LXk9eU15XXlteX15rXnNee15/XoNeh16LXo9f/////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9k0oDSgdKE0ojSkNKR0pXS" + "nNKg0qTSrNKx0rjSudK80r/SwNLC0sjSydLL0tTS2NLc0uTS5dLw0vHS9NL40gDTAdMD0wXTDNMN0w7TENMU0xbTHNMd0x/T" + "INMh0yXTKNMp0yzTMNM40znTO9M80z3TRNNF03zTfdOA04TTjNON04/TkNOR05jTmdOc06DTqNOp06vTrdO007jTvNPE08XT" + "yNPJ09DT2NPh0+PT7NPt0/DT9NP80/3T/9MB1P//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////CNQd1EDURNRc1GDUZNRt1G/UeNR51HzUf9SA1ILUiNSJ1IvUjdSU1KnUzNTQ1NTU3NTf1OjU7NTw1PjU+9T91ATV" + "CNUM1RTVFdUX1TzVPdVA1UTVTNVN1U/VUdVY1VnVXNVg1WXVaNVp1WvVbdV01XXVeNV81YTVhdWH1YjVidWQ1aXVyNXJ1czV" + "0NXS1djV2dXb1d3V5NXl1ejV7NX01fXV99X51QDWAdYE1gjWENYR1hPWFNYV1hzWINb/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////yTWLdY41jnWPNZA1kXWSNZJ1kvWTdZR1lTWVdZY1lzWZ9Zp1nDWcdZ01oPW" + "hdaM1o3WkNaU1p3Wn9ah1qjWrNaw1rnWu9bE1sXWyNbM1tHW1NbX1tnW4Nbk1ujW8Nb11vzW/dYA1wTXEdcY1xnXHNcg1yjX" + "Kdcr1y3XNNc11zjXPNdE10fXSddQ11HXVNdW11fXWNdZ12DXYddj12XXadds13DXdNd8133XgdeI14nXjNeQ15jXmdeb153X" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "PU9zT0dQ+VCgUu9TdVTlVAlWwVq2W4dmtme3Z+9nTGvCc8J1PHrbggSDV4iIiDaKyIzPjfuO5o/VmTtSdFMEVGpgZGG8a89z" + "GoG6idKJo5WDTwpSvlh4WeZZcl55XsdhwGNGZ+xnf2iXb052C3f1eAh6/3ohfJ2AboJxguuKk5VrTp1V92Y0bqN47XpbhBCJ" + "Toeol9hSTlcqWExdH2G+YSFiYmXRZ0RqG24YdbN143awdzp9r5BRlFKUlZ//////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////yNTrFwydduAQJKYlVtSCFjcWaFcF123XjpfSl93YV9senWGdeB8c32xfYx/VIEhgpGF" + "QYkbi/ySTZZHnMtO904LUPFRT1g3YT5haGE5ZeppEW+ldYZ21naHe6WCy4QA+aeTi5WAVaJbUVcB+bN8uX+1kShQu1NFXOhd" + "0mJuY9pk52QgbqxwW3ndjR6OAvl9kEWS+JJ+TvZOZVD+XfpeBmFXaXGBVIZHjnWTK5peTpFQcGdAaAlRjVKSUqJq////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////+8dxCS1J6rUi9g8o9IUKlh7WPKZDxohGrAb4iB" + "oYmUlgVYfXKscgR1eX1tfqmAi4l0i2OQUZ2JYnpsVG9QfTp/I4p8UUphnXsZi1eSjJOsTtNPHlC+UAZRwVLNUn9TcFeDWJpe" + "kV92YaxhzmRsZW9mu2b0Zpdoh22FcPFwn3SldMp02XVseOx433r2ekV9k30VgD+AG4GWg2aLFY8VkOGTA5g4mFqa6JvCT1NV" + "OlhRWWNbRly4YBJiQmiwaP//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////6Giqbkx1" + "eHbOeD16+3xrfnx+CIqhij+MjpbEneRT6VNKVHFU+lbRWWRbO1yrXvdiN2VFZXJloGavZ8FpvWz8dZB2fnc/epR/A4ChgI+B" + "5oL9gvCDwYUxiLSIpYoD+ZyPLpPHlmeY2JoTn+1Um2XyZo9oQHo3jGCd8FZkVxFdBmaxaM1o/m4odJ6I5JtobAT5qJqbT2xR" + "cVGfUlRb5V1QYG1g8WKnYztl2XN6eqOGooyPlzJO4VsIYpxn3HT/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////9F504OHirKK6I1OkEuTRpjTXuhp/4XtkAX5oFGYW+xbY2H6aD5rTHAvdNh0oXtQf8WDwImrjNyV" + "KJkuUl1g7GICkIpPSVEhU9lY417gZjhtmnDCctZzUHvxgFuUZlObY2t/Vk6AUEpY3lgqYCdh0GLQaUGbj1sYfbGAX4+kTtFQ" + "rFSsVQxboF3nXSplTmUhaEtq4XKOdu93Xn35f6CBToXfhgOPTo/KkAOZVZqrmxhORU5dTsdO8U93Uf5S////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////9AU+NT5VOOVBRWdVeiV8dbh13QXvxh2GJRZbhn6WfLaVBr" + "xmvsa0JsnW54cNdylnMDdL936Xd2en99CYD8gQWCCoLfgmKIM4v8jMCOEZCxkGSStpLSmUWa6ZzXnZyfC1dAXMqDoJerl7Se" + "G1SYeqR/2YjNjuGQAFhIXJhjn3quWxNfeXqueo6CrI4mUDhS+FJ3UwhX82JyYwprw203d6VTV3NohXaO1ZU6Z8NqcG9tisyO" + "S5kG+XdmeGu0jP//////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////PJsH+etTLVdOWcZj" + "+2nqc0V4unrFev58dYSPiXONNZColftSR1dHdWB7zIMekgj5WGpLUUtSh1IfYthodWmZlsVQpFLkUsNhpGU5aP9pfnRLe7mC" + "64OyiTmL0Y9JmQn5yk6XWdJkEWaOajR0gXm9eamCfoh/iF+JCvkmkwtPylMlYHFicmwafWZ9mE5iUdx3r4ABTw5PdlGAUdxV" + "aFY7V/pX/FcUWUdZk1nEW5BcDl3xXX5ezF+AYtdl42X/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////x5nH2deZ8toxGhfajprI2x9bIJsx22YcyZ0KnSCdKN0eHV/dYF473hBeUd5SHl6eZV7AH26fYh/BoAtgIyA" + "GIpPi0iMd40hkyST4phRmQ6aD5plmpKeyn12TwlU7mJUaNGRq1U6UQv5DPkcWuZhDfnPYv9iDvkP+RD5EfkS+RP5o5AU+RX5" + "FvkX+Rj5/ooZ+Rr5G/kc+ZZmHflWcR75H/njliD5T2N6Y1dTIfmPZ2Bpc24i+Td1I/kk+SX5////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////8NfSb5J/lyiMpWGFoo+Sn5Kvkr+Sz5Q04t+WdRSFnwZxCALvlzWXRe" + "mmTKefVfbGDIYntj51vXW6pSL/l0WSlfEmAw+TH5MvlZdDP5NPk1+Tb5N/k4+dGZOfk6+Tv5PPk9+T75P/lA+UH5QvlD+cNv" + "RPlF+b+Bso/xYEb5R/lmgUj5Sfk/XEr5S/lM+U35TvlP+VD5UfnpWiWKe2cQfVL5U/lU+VX5VvlX+f2AWPlZ+Txc5Ww/U7pu" + "Glk2g///////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////OU62TkZPrlUYV8dYVl+3ZeZl" + "gGq1a01u7Xfveh583n3LhpKIMpFbk7tkvm96c7h1VJBWVU1XumHUZMdm4W1bbm1vuW/wdUOAvYFBhYOJx4paix+Tk2xTdVR7" + "D45dkBBVAlhYWGJeB2KeZOBodnXWfLOH6J7jTohXblcnWQ1csVw2XoVfNGLhZLNz+oGLiLiMipbbnoVbt1+zYBJQAFIwUhZX" + "NVhXWA5cYFz2XItdpl6SX7xgEWOJYxdkQ2j/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////lowmrYbSFu1G7kb/5x3HZ5d7F5O3oEhKmJ7YzzjUiOA5AUkFOQ/ZBNk3aW3JfSawZwWHKicmhzY3e/eeR7m36Ai6lY" + "x2BmZf1lvmaMbB5xyXFajBOYbU6Bet1OrFHNUdVSDFSnYXFnUGjfaB5tfG+8dbN35Xr0gGOEhZJcUZdlXGeTZ9h1x3pzg1r5" + "RowXkC2Yb1zAgZqCQZBvkA2Sl1+dXVlqyHF7dkl75IUEiyeRMJqHVfZhW/lpdoV/////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////8/hrqH+IiPkFz5G23ZcN5zYX09hF35apHxmV75gk51UwRrEms+cBtyLYYenkxS" + "o49QXeVkLGUWa+tvQ3ycfs2FZIm9icli2IEfiMpeF2dqbfxyBXRvdIKH3pCGTw1doF8KhLdRoGNlda5OBlBpUclRgWgRaq58" + "sXznfG+C0oobj8+Rtk83UfVSQlTsXm5hPmLFZdpq/m8qedyFI4itlWKaapqXns6em1LGZndrHXAreWKPQpeQYQBiI2Ujb///" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////SXGJdPR9b4DuhCaPI5BKk71RF1KjUgxt" + "yHDCiMlegmWua8JvPnx1c+RONk/5Vl/5uly6XRxgsnMte5p/zn9GgB6QNJL2lkiXGJhhn4tPp2+uebSRt5beUmD5iGTEZNNq" + "Xm8YcBBy53YBgAaGXIbvjQWPMpdvm/qddZ6MeH95oH3JgwSTf56TntaK31gEXydnJ3DPdGB8foAhUShwYnLKeMKM2oz0jPeW" + "hk7aUO5b1l6ZZc5xQnatd0qA/IT/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////3yQ" + "J5uNn9hYQVpiXBNq2m0Pbzt2L303fh6FOInkk0uWiVLSZfNntGlBbZxuD3AJdGB0WXUkdmt4LItemG1RLmJ4lpZPK1AZXept" + "uH0qj4tfRGEXaGH5hpbSUouA3FHMUV5pHHq+ffGDdZbaTylSmFMPVA5VZVynYE5nqGhsbYFy+HIGdIN0YvnidWx8eX+4f4mD" + "z4jhiMyR0JHilsmbHVR+b9BxmHT6haqOo5ZXnJ+el2fLbTN06IEWlyx4////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////LeiB7knxpZGp08nW8eOh4rJlUm7ue3ltVXiBvnIGrg4iQB05NUyla0l1OX2JhPWNpZvxm" + "/24rb2NwnncshBOFO4gTj0WZO5wcVbliK2erbAmDaol6l6FOhFnYX9lfG2eyfVR/koIrg72DHo+ZkMtXuVmSWtBbJ2aaZ4Vo" + "z2tkcXV/t4zjjIGQRZsIgYqMTJZAmqWeX1sTbBtz8nbfdgyEqlGTiU1RlVHJUslolGwEdyB3v33sfWKXtZ7Fbv//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////EYWlUQ1UfVQOZp1mJ2mfbr92kXcXg8KEn4dpkZiS" + "9JyCiK5PklHfUsZZPV5VYXhkeWSuZtBnIWrNa9trX3JhckF0OHfbdxeAvIIFgwCLKIuMjChnkGxncu52ZndGeqmdf2uSbCJZ" + "JmeZhG9Tk1iZWd9ez2M0ZnNnOm4rc9d614Iok9lS612uYcthCmLHYqtk4GVZaWZry2shcfdzXXVGfh6CAoNqhaOKv4wnl2Gd" + "qFjYnhFQDlI7VE9Vh2X/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////3ZsCn0LfV6A" + "ioaAle+W/1KVbGlyc1SaWj5cS11MX65fKme2aGNpPG5Ebgl3c3yOf4eFDov3j2GX9J63XLZgDWGrYU9l+2X8ZRFs72yfc8lz" + "4X2UlcZbHIcQi11SWlPNYg9ksmQ0ZzhqymzAc550lHuVfBt+ioE2goSF64/5lsGZNE9KU81T21PMYixkAGWRZcNp7mxYb+1z" + "VHUiduR2/HbQePt4LHlGfSyC4IfUjxKY75jDUtRipWQkblFv////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////98dsuNsZFiku6aQ5sjUI1QSleoWShcR153Xz9iPmW5ZcFlCWaLZ5xpwm7FeCF9qoCAgSuCs4KhhIyG" + "KooXi6aQMpaQnw1Q809j+flXmF/cYpJjb2dDbhlxw3bMgNqA9Ij1iBmJ4Iwpj02RapYvT3BPG17PZyJofXZ+dkSbYV4Kamlx" + "1HFqdWT5QX5DhemF3JgQT097cH+lleFRBl61aD5sTmzbbK9yxHsDg9VsOnT7UIhSwVjYZJdqp3RWdv//////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////p3gXhuKVOZdl+V5TAV+Ki6iPr4+KkCVSpXdJnAifGU4CUHVR" + "W1x3Xh5mOmbEZ8Vos3ABdcV1yXndeiePIJkImt1PIVgxWPZbbmZlaxFtem59b+RzK3Xpg9yIE4lcixSPD0/VUBBTXFOTW6lf" + "DWePeXmBL4MUhQeJhok5jzuPpZkSnCxndk74T0lZAVzvXPBcZ2PSaP1wonErdCt+7IQChyKQ0pLznA1O2E7vT4VQVlJvUiZU" + "kFTgVytZZlr/////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////1pbdVvMW5xeZvl2Yndl" + "p2VubaVuNnImez98Nn9QgVGBmoFAgpmCqYMDiqCM5oz7jHSNuo3okNyRHJZEltmZ55wXUwZSKVR0VrNYVFluWf9fpGFuYhBm" + "fmwaccZ2iXzefBt9rILBjPCWZ/lbTxdff1/CYildC2faaHx4Q35snRVOmVAVUypTUVODWWJah16yYIphSWJ5YpBlh2enadRr" + "1mvXa9hruGxo+TV0+nUSeJF41XnYeYN8y33hf6WA////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////8+gcKB8oMah+iIuYpsi7uMGZFel9uYO5+sVipbbF+MZbNqr2tcbfFvFXBdcq1zp4zTjDuYkWE3bFiAAZpNTotO" + "m07VTjpPPE9/T99P/1DyU/hTBlXjVdtW61hiWRFa61v6WwRc810rXplfHWBoY5xlr2X2Z/tnrWh7a5ls12wjbglwRXMCeD55" + "QHlgecF56XsXfXJ9hoANgo6D0YTHht+IUIpeih2L3Ixmja2PqpD8mN+ZnZ5KUmn5FGdq+f//////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////mFAqUnFcY2VVbMpzI3WddZd7nIR4kTCXd06SZLprXnGphQlOa/lJZ+5o" + "F26fghiFa4j3Y4FvEpKvmApOt1DPUB9RRlWqVRdWQFsZXOBcOF6KXqBewl7zYFFoYWpYbj1yQHLAcvh2ZXmxe9R/84j0iXOK" + "YYzejByXXli9dP2Mx1Vs+WF6In1ygnJyH3UldW35GXuFWPtYvF2PXrZekF9VYJJif2NNZZFm2Wb4ZhZo8miAcl50bntufdZ9" + "cn//////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////+WAEoKvhX+Jk4odkOSSzZ4gnxVZ" + "bVktXtxgFGZzZpBnUGzFbV9v83epeMaEy5Erk9lOylBIUYRVC1ujW0difmXLZTJufXEBdER0h3S/dGx2qnnafVV+qH96gbOB" + "OYIahuyHdYrjjXiQkZIllE2ZrptoU1FcVGnEbCltK24MgpuFO4ktiqqK6pZnn2FSuWaya5Z+/ocNjYOVXZYdZYlt7nFu+c5X" + "01msWydg+mAQYh9mX2Ypc/lz23YBd2x7////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//9WgHKAZYGgipKRFk7iUnJrF20Fejl7MH1v+bCM7FMvVlFYtVsPXBFc4l1AYoNjFGQtZrNovGyIba9uH3CkcNJxJnWPdY51" + "GXYRe+B7K3wgfTl9LIVthQeGNIoNkGGQtZC3kvaXN5rXT2xcX2eRbZ98jH4WixaNH5BrW/1dDWTAhFyQ4ZiHc4tbmmB+Z95t" + "H4qmigGQDJg3UnD5UXCOeJaTcIjXke5P11P9VdpWglf9WMJaiFurXMBcJV4BYf//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////DWJLYohjHGQ2ZXhlOWqKazRsGW0xb+dx6XJ4cwd0snQmdmF3wHlXeup6uXyPfax9" + "YX6efymBMYOQhNqE6oWWiLCKkIs4j0KQg5BskZaSuZKLlqeWqJbWlgCXCJiWmdOaGpvUU35YGVlwW79b0W1ab59xIXS5dIWA" + "/YPhXYdfql9CYOxlEmhvaVNqiWs1bfNt43P+dqx3TXsUfSOBHIJAg/SEY4ViisSKh5EekwaYtJkMYlOI8I9lkgddJ13/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////2ldX3SdgWiH1W/+YtJ/NolyiR5OWE7nUN1S" + "R1N/YgdmaX4FiF6WjU8ZUzZWy1mkWjhcTlxNXAJeEV9DYL1lL2ZCZr5n9Gccc+J3OnnFf5SEzYSWiWaKaYrhilWMeoz0V9Rb" + "D19vYO1iDWmWa1xuhHHSe1WHWIv+jt+Y/pg4T4FP4U97VCBauFs8YbBlaGb8cTN1XnkzfU6B44GYg6qFzoUDhwqKq46bj3H5" + "xY8xWaRb5luJYOlbC1zDX4Fs////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////////////9y+fFt" + "C3Aada+C9orATkFTc/nZlg9snk7ET1JRXlUlWuhcEWJZcr2CqoP+hlmIHYo/lsWWE5kJnV2dClizXL1dRF7hYBVh4WMCaiVu" + "ApFUk06YEJx3n4lbuFwJY09mSGg8d8GWjZdUmJ+boWUBi8uOvJU1Valc1l21XpdmTHb0g8eV01i8Ys5yKJ3wTi5ZD2A7ZoNr" + "53kmnZNTwFTDVxZdG2HWZq9tjXh+gpiWRJeEU3xilmOybQp+S4FNmP//////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////+2pMf6+dGp5fTjtQtlEcWflg9mMwaTpyNoB0+c6RMV91+Xb5BH3lgm+Eu4TlhY2Od/lvT3j5" + "efnkWENbWWDaYxhlbWWYZnr5SmkjagttAXBscdJ1DXazeXB6e/mKf3z5RIl9+ZOLwJF9ln75CpkEV6FfvGUBbwB2pnmeiq2Z" + "WptsnwRRtmGRYo1qxoFDUDBYZl8JcQCK+op8WxaG+k88UbRWRFmpY/ltql1taYZRiE5ZT3/5gPmB+YJZgvn/////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////4P5X2tdbIT5tXQWeYX5B4JFgjmDP49dj4b5GJmH+Yj5" + "ifmmTor531d5XxNmi/mM+at1eX5vi435BpBbmqVWJ1j4WR9atFuO+fZej/mQ+VBjO2OR+T1ph2y/bI5tk231bRRvkvnfcDZx" + "WXGT+cNx1XGU+U94b3iV+XV7432W+S9+l/lNiN+OmPmZ+Zr5W5Kb+facnPmd+Z75hWCFbZ/5sXGg+aH5sZWtU6L5o/mk+dNn" + "pfmOcDBxMHR2gtKC////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////+m+buV5Zp9nsRm" + "p/nBcUmEqPmp+UtYqvmr+bhdcV+s+SBmjmZ5aa5pOGzzbDZuQW/abxtwL3BQcd9xcHOt+Vt0rvnUdMh2TnqTfq/5sPnxgmCK" + "zo+x+UiTsvkZl7P5tPlCTipQtfkIUuFT82ZtbMpvCnN/d2J6roLdhQKGtvnUiGOKfYtrjLf5s5K4+ROXEJiUTg1PyU+yUEhT" + "PlQzVNpVYli6WGdZG1rkW59gufnKYVZl/2VkZqdoWmyzb///////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////z3CscVJzfXsIh6SKMpwHn0tcg2xEc4lzOpKrbmV0H3ZpehV+CoZAUcVYwWTudBV1cHbBf5WQzZZUmSZu" + "5nSpeqp65YHZhniHG4pJWoxbm1uhaABpY22pcxN0LHSXeOl9638YgVWBnoNMjC6WEZjwZoBf+mWJZ2psi3MtUANaamvudxZZ" + "bF3NXSVzT3W6+bv55VD5US9YLVmWWdpZ5Vu8+b35ol3XYhZkk2T+ZL753Ga/+UhqwPn/cWR0wfn/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////4h6r3pHfl5+AIBwgcL574eBiSCLWZDD+YCQUpl+YTJrdG0ffiWJ" + "sY/RT61Ql1HHUsdXiVi5W7heQmGVaYxtZ262bpRxYnQodSx1c4A4g8mECo6Uk96TxPmOTlFPdlAqUchTy1PzU4db01skXBph" + "gmH0ZVtyl3NAdMJ2UHmRebl5Bn29f4uC1YVehsKPR5D1kOqRhZbolumW1lJnX+1lMWYvaFxxNnrBkAqYkU7F+VJqnmuQb4lx" + "GIC4glOF////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9LkJWW8pb7lxqFMZuQTopx" + "xJZDUZ9T4VQTVxJXo1ebWsRaw1soYD9h9GOFbDltcm6QbjByP3NXdNGCgYhFj2CQxvlilliYG50IZ4qNXpJNT0lQ3lBxUw1X" + "1FkBWglccGGQZi1uMnJLdO99w4AOhGaEP4Vfh1uIGIkCi1WQy5dPm3NOkU8SUWpRx/kvValVelulW3xefV6+XqBg32AIYQlh" + "xGM4ZQlnyPnUZ9pnyflhaWJpuWwnbcr5OG7L+f//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////4W82czdzzPlcdDF1zflSds75z/mtff6BOITViJiK24rtijCOQo5KkD6QepBJkcmRbpPQ+dH5CVjS+dNriYCygNP5" + "1PlBUWtZOVzV+db5ZG+nc+SAB43X+ReSj5XY+dn52vnb+X+ADmIccGh9jYfc+aBXaWBHYbdrvoqAkrGWWU4fVOttLYVwlvOX" + "7pjWY+NskZDdUclhuoH5nZ1PGlAAUZxbD2H/YexkBWnFa5F143epf2SCj4X7h2OIvIr/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////3CLq5GMTuVOCk/d+d75N1noWd/58l0bX1tfIWDg+eH54vnj+T5y5XPk+XB1" + "zXXl+ft55vkMgDOAhIDhglGD5/no+b2Ms4yHkOn56vn0mAyZ6/ns+TdwynbKf8x//H8ai7pOwU4DUnBT7fm9VOBW+1nFWxVf" + "zV9ubu757/lqfTWD8PmTho2K8fltl3eX8vnz+QBOWk9+T/lY5WWibjiQsJO5mftO7FiKWdlZQWD0+fX5FHr2+U+Dw4xlUURT" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////////////3+fj5+fnNTmlSVVu/gtROOlKoVMlZ" + "/1lQW1dbXFtjYEhhy26ZcG5xhnP3dLV1wXgrfQWA6oEogxeFyYXuiseMzJZcT/pSvFarZShmfHC4cDVyvX2NgkyRwJZynXFb" + "52iYa3pv3naRXKtmW2+0eyp8NojclghO104gUzRYu1jvWGxZB1wzXoReNV+MY7JmVmcfaqNqDGs/b0Zy+vlQc4t04HqnfHiB" + "34HngYqDbIQjhZSFz4XdiBONrJF3lf//////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "nJaNUclUKFewW01iUGc9aJNoPW7Tbn1wIX7BiKGMCY9Ln06fLXKPe82KGpNHT05PMlGAVNBZlV61YnVnbmkXaq5sGm7Zcipz" + "vXW4ezV954L5g1eE94Vbiq+Mh44ZkLiQzpZfn+NSClThWsJbWGR1ZfRuxHL7+YR2TXobe018Pn7ff3uDK4vKjGSN4Y1fjuqP" + "+Y9pkNGTQ096T7NQaFF4UU1SalJhWHxYYFkIXFVc216bYDBiE2i/awhssW//////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////05xIHQwdTh1UXVydkx7i3ute8Z7j35uij6PSY8/kpOSIpMrlPuWWphrmB6ZB1IqYphi" + "WW1kdsp6wHt2fWBTvlyXXjhvuXCYfBGXjpvenqVjemR2hwFOlU6tTlxQdVBIVMNZmltAXq1e916BX8VgOmM/ZXRlzGV2Znhm" + "/mdoaYlqY2tAbMBt6G0fbl5uHnChcI5z/XM6dVt3h3iOeQt6fXq+fI59R4ICiuqKnowtkUqR2JFmksySIJMGl1aX////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////9clwKYDp82UpFSfFUkWB1eH1+MYNBjr2jfb215" + "LHvNgbqF/Yj4ikSOjZFklpuWPZdMmEqfzk9GUctRqVIyVhRfa1+qY81k6WVBZvpm+WYdZ51o12j9aRVvbm9nceVxKnKqdDp3" + "Vnlaed95IHqVepd833xEfXB+h4D7haSGVIq/ipmNgY4gkG2Q45E7ltWW5ZzPZQd8s43Dk1hbClxSU9liHXMnUJdbnl+wYGth" + "1WjZbS50LnpCfZx9MX5rgf//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////Ko41jn6T" + "GJRQT1BX5l2nXitjan87Tk9Pj09aUN1ZxIBqVGhU/lVPWZlb3l3aXl1mMWfxZypo6GwybUpujW+3cOBzh3VMfAJ9LH2ifR+C" + "24Y7ioWKcI2KjjOPMZBOkVKRRJTQmfl6pXzKTwFRxlHIV+9b+1xZZj1qWm2WbuxvDHFvdeN6IoghkHWQy5b/mQGDLU7yTkaI" + "zZF9U9tqa2lBbHqEnliOYf5m72LdcBF1x3VSfriESYsIjUtO6lP/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////6tUMFdAV9dfAWMHY29kL2XoZXpmnWezZ2JrYGyabCxv5XcleEl5V3kZfaKAAoHzgZ2Ct4IYh4yK" + "/PkEjb6NcpD0dhl6N3pUfneAB1XUVXVYL2MiZElmS2ZtaJtphGslbbFuzXNodKF0W3W5deF2HneLd+Z5CX4dfvuBL4WXiDqK" + "0YzrjrCPMpCtk2OWc5YHl4RP8VPqWclaGV5OaMZ0vnXpeZJ6o4HthuqMzI3tj59lFWf9+fdXV2/dfS+P////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////2k8aWtV/yYYRvFE6YTx9QyVPfVW9d7l0ha2Rry3iae/75" + "SY7Kjm6QSWM+ZEB3hHovk3+Uap+wZK9v5nGodNp0xHoSfIJ+snyYfpqLCo19lBCZTJk5Ut9b5mQtZy597VDDU3lYWGFZYfph" + "rGXZepKLlosJUCFQdVIxVTxa4F5wXzRhXmUMZjZmombNacRuMm8WcyF2k3o5gVmC1oO8hLVQ8FfAW+hbaV+hYyZ4tX3cgyGF" + "x5H1kYpR9WdWe///////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////rIzEUbtZvWBVhhxQ" + "//lUUjpcfWEaYtNi8mSlZcxuIHYKgWCOX5a7lt9OQ1OYVSlZ3V3FZMls+m2Uc396G4KmheSMEI53kOeR4ZUhlsaX+FHyVIZV" + "uV+kZIhvtH0fj02PNZTJUBZcvmz7bRt1u3c9fGR8eYrCih5YvlkWXndjUnKKdWt33Iq8jBKP8150ZvhtfYDBg8uKUZfWmwD6" + "Q1L/ZpVt727gfeaKLpBekNSaHVJ/UuhUlGGEYttiomj/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////xJpWmk1apJwJnFdeAF5DnnSeQ16loB4gtWCSYNJhYKMhY1ikYuRrpHDT9FW7XHXdwCH+In4W9ZfUWeokOJT" + "Wlj1W6RggWFgZD1+cIAlhYOSrmSsUBRdAGecWL1iqGMOaXhpHmprbrp2y3m7gimEz4qojf2PEpFLkZyREJMYk5qT25Y2mg2c" + "EU5cdV15+npRe8l7Ln7EhFmOdI74jhCQJWY/aUN0+lEuZ9yeRVHgX5Zs8oddiHeItGC1gQOE////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////8FjdZTOVQ0VjZaMVyKcOB/WoAGge2Bo42JkV+a8p10UMROoFP7YCxu" + "ZFyITyRQ5FXZXF9eZWCUaLtsxG2+cdR19HVhdhp6SXrHfft9bn/0gamGHI/JlrOZUp9HUsVS7ZiqiQNO0mcGb7VP4luVZ4hs" + "eG0bdCd43ZF8k8SH5Hkxeutf1k6kVD5VrlilWfBgU2LWYjZnVWk1gkCWsZndmSxQU1NEVXxXAfpYYgL64mRrZt1nwW/vbyJ0" + "OHQXiv//////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////OJRRVAZWZldIX5phTmtYcK1w" + "u32VimpZK4GiYwh3PYCqjFRYLWS7aZVbEV5vbgP6aYVMUfBTKlkgYEthhmtwbPBsHnvOgNSCxo2wkLGYBPrHZKRvkWQEZU5R" + "EFQfVw6KX2F2aAX623VSe3F9GpAGWMxpf4EqiQCQOZh4UFdZrFmVYg+QKptdYXly1pVhV0Za9F2KYq1k+mR3Z+JsPm0scjZ0" + "NHh3f62C240XmCRSQld/Z0hy43SpjKaPEZL/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////yqWa1HtU0xjaU8EVZZgV2WbbH9tTHL9chd6h4mdjG1fjm/5cKiBDmG/T09QQWJHcsd76H3pf02QrZcZmraMaldzXrBn" + "DYRViiBUFltjXuJeCl+DZbqAPYWJlVuWSE8FUw1TD1OGVPpUA1cDXhZgm2KxYlVjBvrhbGZtsXUyeN6AL4HegmGEsoSNiBKJ" + "C5Dqkv2YkZtFXrRm3WYRcAZyB/r1T31Sal9TYVNnGWoCb+J0aHloiHmMx5jEmEOa////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////BVB96U2n3ikqMqJiumXxfq2Kyda52q4h/kEKWOVM8X8VfzGzMc2J1i3VGe/6C" + "nZlPTjyQC05VT6ZTD1nIXjBms2xVdHeDZofAjFCQHpcVnNFYeFtQhhSLtJ3SW2hgjWDxZVdsIm+jbxpwVX/wf5GVkpVQltOX" + "clJEj/1RK1S4VGNVilW7arVt2H1mgpySd5Z5nghUyFTSduSGpJXUlVyWok4JT+5Z5lr3XVJgl2JtZ0Fohmwvbjh/m4Aqgv//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////CPoJ+gWYpU5VULNUk1daWWlbs1vIYXdp" + "d20jcPmH44lyiueKgpDtmbiavlI4aBZQeF5PZ0eDTIirThFUrlbmcxWR/5cJmVeZmZlTVp9YW4YxirJh9mp7c9KOR2uqllea" + "VVkAcmuNaZfUT/RcJl/4YVtm62yrcIRzuXP+cyl3TXdDfWJ9I343glKICvrijEmSb5hRW3R6QIgBmMxa4E9UUz5Z/Vw+Y3lt" + "+XIFgQeBooPPkjCYqE5EURFSi1f/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////2Jf" + "wmzObgVwUHCvcJJx6XNpdEqDoodhiAiQopCjk6iZblFXX+BgZ2GzZlmFSo6vkYuXTk6STnxU1Vj6WH1ZtVwnXzZiSGIKZmdm" + "62tpbc9tVm74bpRv4G/pb11w0HIldFp04HSTdlx5ynwefuGApoJrhL+EToZfhnSHd4tqjKyTAJhlmNFgFmJ3kVpaD2b3bT5u" + "P3RCm/1f2mAPe8RUGF9ebNNsKm3YcAV9eYYMijudFlOMVAVbOmprcHV1////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////+Neb55sYLvg3GKQYuojHSXC/r0ZCtluni7eGt6OE6aVVBZplt7XqNg22Nha2VmU2gZbmVx" + "sHQIfYSQaZolnDtt0W4+c0GMypXwUUxeqF9NYPZgMGFMYUNmRGalacFsX27JbmJvTHGcdId2wXsnfFKDV4dRkI2Ww54vU95W" + "+16KX2JglGD3YWZmA2ecau5trm9wcGpzan6+gTSD1IaoisSMg1Jyc5Zba2oElO5UhlZdW0hlhWXJZp9ojW3Gbf//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////O3K0gHWRTZqvTxlQmlMOVDxUiVXFVT9ejF89Z2Zx" + "3XMFkNtS81JkWM5YBHGPcftxsIUTiohmqIWnVYRmSnExhElTmVXBa1lfvV/uY4lmR3Hxih2Pvp4RTzpky3BmdWeGZGBOi/id" + "R1H2UQhTNm34gNGeFWYja5hw1XUDVHlcB30WiiBrPWtGazhUcGA9bdV/CILWUN5RnFVrVs1W7FkJWwxemWGYYTFiXmbmZplx" + "uXG6cadyp3kAerJ/cIr/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +CP949_ENC_EXC = {} +CP949_ENC_REJECT = frozenset() + +# ---- euc_jp ---- +EUC_JP_DEC = _g( + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////Yf9i/2P/ZP9l/2b/Z/9o/2n/av9r/2z/" + "bf9u/2//cP9x/3L/c/90/3X/dv93/3j/ef96/3v/fP99/37/f/+A/4H/gv+D/4T/hf+G/4f/iP+J/4r/i/+M/43/jv+P/5D/" + "kf+S/5P/lP+V/5b/l/+Y/5n/mv+b/5z/nf+e/5//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////wAwATACMAz/Dv/7MBr/G/8f/wH/mzCcMLQAQP+oAD7/4/8///0w" + "/jCdMJ4wAzDdTgUwBjAHMPwwFSAQIA//PP8cMBYgXP8mICUgGCAZIBwgHSAI/wn/FDAVMDv/Pf9b/13/CDAJMAowCzAMMA0w" + "DjAPMBAwETAL/xIisQDXAPcAHf9gIhz/Hv9mImciHiI0IkImQCawADIgMyADIeX/BP+iAKMABf8D/wb/Cv8g/6cABiYFJssl" + "zyXOJccl////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////////////////////GJaEloCWzJbIlvSW8JTsg" + "EjCSIZAhkSGTIRMw/////////////////////////////wgiCyKGIocigiKDIioiKSL/////////////////////JyIoIqwA" + "0iHUIQAiAyL/////////////////////////////ICKlIhIjAiIHImEiUiJqImsiGiI9Ih0iNSIrIiwi////////////////" + "//8rITAgbyZtJmomICAhILYA///////////vJf//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////EP8R/xL/E/8U/xX/Fv8X/xj/Gf///////////////////yH/" + "Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov////////////////9B/0L/Q/9E/0X/" + "Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////0EwQjBDMEQwRTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYw" + "VzBYMFkwWjBbMFwwXTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgwaTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHow" + "ezB8MH0wfjB/MIAwgTCCMIMwhDCFMIYwhzCIMIkwijCLMIwwjTCOMI8wkDCRMJIwkzD/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////+hMKIwozCkMKUwpjCnMKgwqTCqMKsw" + "rDCtMK4wrzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w" + "0DDRMNIw0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw4jDjMOQw5TDmMOcw6DDpMOow6zDsMO0w7jDvMPAw8TDyMPMw" + "9DD1MPYw////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MDpAOlA6YDpwOoA6kD/////////////////////7EDsgOzA7QD" + "tQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QDxQPGA8cDyAPJA///////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////xAEEQQSBBMEFAQVBAEEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcE" + "KAQpBCoEKwQsBC0ELgQvBP///////////////////////////////////////zAEMQQyBDMENAQ1BFEENgQ3BDgEOQQ6BDsE" + "PAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBP//////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////8AJQIlDCUQJRglFCUcJSwlJCU0JTwlASUDJQ8l" + "EyUbJRclIyUzJSslOyVLJSAlLyUoJTclPyUdJTAlJSU4JUIl////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////5xOFlUDWj+WwFQbYShj9lkikHWEHINQeqpg4WMlbu1lZoSmgvWbk2gnV6FlcWKbW9BZe4b0mGJ9vn2OmxZin3y3iIlb" + "tV4JY5dmSGjHlY2XT2flTgpPTU+dT0lQ8lY3WdRZAVoJXN9gD2FwYRNmBWm6cE91cHX7ea19733DgA6EY4gCi1WQepA7U5VO" + "pU7fV7KAwZDveABO8ViibjiQMnoog4uCL5xBUXBTvVThVOBW+1kVX/KY623kgC2F////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////9ilnCWoJb7lwtU81OHW89wvX/Cj+iWb1Ncnbp6EU6TePyBJm4YVgRVHWsahTuc" + "5VmpU2Zt3HSPlUJWkU5LkPKWT4MMmeFTtlUwW3FfIGbzZgRoOGzzbCltW3TIdk56NJjxgluIYIrtkrJtq3XKdsWZpmABi4qN" + "spWOaa1ThlESVzBYRFm0W/ZeKGCpY/Rjv2wUb45wFHFZcdVxP3MBfnaC0YKXhWCQW5IbnWlYvGVabCV1+VEuWWVZgF/cX///" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////vGL6ZSpqJ2u0a4tzwX9WiSydDp3EnqFc" + "lmx7gwRRS1y2YcaBdmhhcllO+k94U2lgKW5PevOXC04WU+5OVU89T6FPc0+gUu9TCVYPWcFatlvhW9F5h2acZ7ZnTGuzbGtw" + "wnONeb55PHqHe7GC24IEg3eD74PTg2aHsoopVqiM5o9OkB6XiobET+hcEWJZcjt15YG9gv6GwIzFlhOZ1ZnLThpP44neVkpY" + "ylj7XutfKmCUYGJg0GESYtBiOWX/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////0Gb" + "ZmawaHdtcHBMdYZ2dX2lgvmHi5WOlp2M8VG+UhZZs1SzWxZdaGGCaa9tjXjLhFeIcoqnk7iabG2omdmGo1f/Z86GDpKDUodW" + "BFTTXuFiuWQ8aDhou2tyc7p4a3qaidKJa40Dj+2Qo5WUlmmXZluzXH1pTZhOmJtjIHsran9qtmgNnF9vclKdVXBg7GI7bQdu" + "0W5bhBCJRI8UTjmc9lMbaTpqhJcqaFxRw3qyhNyRjJNbViidImgFgzGE////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////+lfAhSxYLmdH5Og0+gUdJbClLYUudS+12aVSpY5lmMW5hb21tyXnleo2AfYWNhvmHbY2Jl" + "0WdTaPpoPmtTa1dsIm+Xb0VvsHQYdeN2C3f/eqF7IXzpfTZ/8H+dgGaCnoOzicyKq4yEkFGUk5WRlaKVZZbTlyiZGII4TitU" + "uFzMXalzTHY8d6lc638LjcGWEZhUmFiYAU8OT3FTnFVoVvpXR1kJW8RbkFwMXn5ezF/uYzpn12XiZR9ny2jEaP//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////X2owXsVrF2x9bH91SHljWwB6AH29X4+JGIq0jHeN" + "zI4dj+KYDpo8m4BOfVAAUZNZnFsvYoBi7GQ6a6BykXVHeal/+4e8inCLrGPKg6CXCVQDVKtVVGhYanCKJ3h1Z82edFOiWxqB" + "UIYGkBhORU7HThFPylM4VK5bE18lYFFlPWdCbHJs42x4cAN0dnquegh7Gn3+fGZ952VbcrtTRVzoXdJi4GIZYyBuWoYxit2N" + "+JIBb6Z5WpuoTqtOrE7/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////5tPoE/RUEdR" + "9npxUfZRVFMhU39T61OsVYNY4Vw3X0pfL2BQYG1gH2NZZUtqwWzCcu1y73f4gAWBCIJOhfeQ4ZP/l1eZWprwTt1RLVyBZm1p" + "QFzyZnVpiXNQaIF8xVDkUkdX/l0mk6RlI2s9azR0gXm9eUt7yn25gsyDf4hfiTmL0Y/RkR9UgJJdTjZQ5VM6U9dylnPpd+aC" + "r47GmciZ0pl3URphXoawVXp6dlDTW0eQhZYyTttq55FRXEhc////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////+YY596k2x0l2GPqnqKcYiWgnwXaHB+UWhsk/JSG1SrhROKpH/NjuGQZlOIiEF5wk++UBFSRFFTVS1X" + "6nOLV1FZYl+EX3VgdmFnYalhsmM6ZGxlb2ZCaBNuZnU9evt8TH2ZfUt+a38Og0qDzYYIimOKZov9jhqYj524gs6P6JuHUh9i" + "g2TAb5mWQWiRUCBremxUb3R6UH1AiCOKCGf2TjlQJlBlUHxROFJjUqdVD1cFWMxa+l6yYfhh82JyY///////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////HGkpan1yrHIucxR4b3h5fQx3qYCLiRmL4ozSjmOQdZN6llWY" + "E5p4nkNRn1OzU3teJl8bbpBuhHP+c0N9N4IAivqKUJZOTgtQ5FN8VPpW0VlkW/Fdq14nXzhiRWWvZ1Zu0HLKfLSIoYDhgPCD" + "ToaHiuiNN5LHlmeYE5+UTpJODU9IU0lUPlQvWoxfoV+fYKdojmpadIF4noqkineLkJFeTsmbpE58T69PGVAWUElRbFGfUrlS" + "/lKaU+NTEVT/////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////w5UiVVRV6JXfVlUW11b" + "j1vlXedd9114XoNeml63XhhfUmBMYZdi2GKnYztlAmZDZvRmbWchaJdoy2lfbCptaW0vbp1uMnWHdmx4P3rgfAV9GH1efbF9" + "FYADgK+AsYBUgY+BKoJSg0yIYYgbi6KM/IzKkHWRcZI/ePySpJVNlgWYmZnYmjudW1KrUvdTCFTVWPdi4G9qjF+PuZ5LUTtS" + "SlT9VkB6d5FgndKeRHMJb3CBEXX9X9pgqJrbcryP////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////9kawOYyk7wVmRXvlhaWmhgx2EPZgZmOWixaPdt1XU6fW6CQpubTlBPyVMGVW9d5l3uXftnmWxzdAJ4UIqWk9+I" + "UFenXitjtVCsUI1RAGfJVF5Yu1mwW2lfTWKhYz1oc2sIbn1wx5GAchV4JnhteY5lMH3cg8GICY+blmRSKFdQZ2p/oYy0UUJX" + "KpY6WIpptICyVA5d/FeVePqdXE9KUotUPmQoZhRn9WeEelZ7In0vk1xorZs5exlTilE3Uv//////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////31v2Yq5k5mQtZ7prqYXRlpB21ptMYwaTq5u/dlJmCU6YUMJTcVzoYJJk" + "Y2VfaOZxynMjdZd7gn6VhoOL24x4kRCZrGWrZotr1U7UTjpPf086UvhT8lPjVdtW61jLWclZ/1lQW01cAl4rXtdfHWAHYy9l" + "XFuvZb1l6GWdZ2Jre2sPbEVzSXnBefh8GX0rfaKAAoHzgZaJXoppimaKjIruiseM3IzMlvyYb2uLTjxPjU9QUVdb+ltIYQFj" + "Qmb/////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////yFry267bD5yvXTUdcF4OnkMgDOA" + "6oGUhJ6PUGx/ng9fWIsrnfp6+I6NW+uWA07xU/dXMVnJWqRbiWB/bgZvvnXqjJ9bAIXge3JQ9GedgmFcSoUefg6CmVEEXGhj" + "Zo2cZW5xPnkXfQWAHYvKjm6Qx4aqkB9Q+lI6XFNnfHA1ckyRyJErk+WCwlsxX/lgO07WU4hbS2IxZ4pr6XLgcy56a4GjjVKR" + "lpkSUddTalT/W4hjOWqsfQCX2lbOU2hU////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//+XWzFc3l3uTwFh/mIybcB5y3lCfU1+0n/tgR+CkIRGiHKJkIt0ji+PMZBLkWyRxpackcBOT09FUUFTk18OYtRnQWwLbmNz" + "Jn7NkYOS1FMZWb9b0W1deS5+m3x+WJ9x+lFTiPCPyk/7XCVmrHfjehyC/5nGUapf7GVvaYlr822WbmRv/nYUfeFddZCHkQaY" + "5lEdUkBikWbZZhputl7SfXJ/+GavhfeF+IqpUtlTc1mPXpBfVWDkkmSWt1AfUf//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////3VIgU0dT7FPoVEZVMVUXVmhZvlk8WrVbBlwPXBFcGlyEXope4F5wX39ihGLbYoxj" + "d2MHZgxmLWZ2Zn5nomgfajVqvGyIbQluWG48cSZxZ3HHdQF3XXgBeWV58HngehF7p3w5fZaA1oOLhEmFXYjziB+KPIpUinOK" + "YYzejKSRZpJ+kxiUnJaYlwpOCE4eTldOl1FwUs5XNFjMWCJbOF7FYP5kYWdWZ0RttnJzdWN6uIRyi7iRIJMxVvRX/pj/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////+1iDWmWa+1xVH53gHKC5onfmFWHsY87XDhP" + "4U+1TwdVIFrdW+lbw19OYS9jsGVLZu5om2l4bfFtM3W5dR93XnnmeTN944GvgqqFqok6iquOm48ykN2RB5e6TsFOA1J1WOxY" + "C1wadT1cToEKisWPY5ZtlyV7z4oImGKR81aoUxeQOVSCVyVeqGM0bIpwYXeLfOB/cIhCkFSREJMYk4+WXnTEmgddaV1wZaJn" + "qI3blm5jSWcZacWDF5jAlv6I////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////////////+Eb3pk" + "+FsWTixwXXUvZsRRNlLiUtNZgV8nYBBiP2V0ZR9mdGbyaBZoY2sFbnJyH3Xbdr58VoDwWP2If4mgipOKy4odkJKRUpdZl4ll" + "DnoGgbuWLV7cYBpipWUUZpBn83dNek18Pn4KgayMZI3hjV+OqXgHUtlipWNCZJhiLYqDesB7rIrqlnZ9DIJJh9lOSFFDU2BT" + "o1sCXBZc3V0mYkdisGQTaDRoyWxFbRdt02dcb05xfXHLZX96rXvaff//////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////Sn6of3qBG4I5gqaFborOjPWNeJB3kK2SkZKDla6bTVKEVThvNnFoUYV5VX6zgc58TFZRWKhc" + "qmP+Zv1mWmnZco91jnUOeVZ533mXfCB9RH0HhjSKO5ZhkCCf51B1UsxT4lMJUKpV7lhPWT1yi1tkXB1T42DzYFxjg2M/Y7tj" + "zWTpZflm413Naf1pFW/lcYlO6XX4dpN633zPfZx9YYBJg1iDbIS8hPuFxYhwjQGQbZCXkxyXEprPUJdYjmH/////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////9OBNYUIjSCQw090UEdSc1NvYEljX2csbrONH5DXT15c" + "yozPZZp9UlOWiHZRw2NYW2tbClwNZFFnXJDWThpZKllwbFGKPlUVWKVZ8GBTYsFnNYJVaUCWxJkomlNPBlj+WxCAsVwvXoVf" + "IGBLYTRi/2bwbN5uzoB/gdSCi4i4jACQLpCKltue25vjTvBTJ1kse42RTJj5nd1uJ3BTU0RVhVtYYp5i02KibO9vInQXijiU" + "wW/+ijiD51H4hupT////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////////////////////////////////////pU0ZPVJCwj2pZ" + "MYH9Xep6v4/aaDeM+HJInD1qsIo5TlhTBlZmV8ViomPmZU5r4W1bbq1w7Xfveqp7u309gMaAy4aViluT41bHWD5frWWWZoBq" + "tWs3dceKJFDldzBXG19lYHpmYGz0dRp6bn/0gRiHRZCzmcl7XHX5elF7xIQQkOl5kno2g+FaQHctTvJOmVvgX71iPGbxZ+hs" + "a4Z3iDuKTpHzktCZF2omcCpz54JXhK+MAU5GUctRi1X1W///////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////Fl4zXoFeFF81X2tftF/yYRFjomYdZ25vUnI6dTp3dIA5gXiBdoe/ityKhY3zjZqSd5UCmOWcxVJXY/R2" + "FWeIbM1zw4yuk3OWJW2cWA5pzGn9j5qT23UakFpYAmi0Y/tpQ08sb9hnu48mhbR9VJM/aXBvalf3WCxbLH0qcgpU45G0na1O" + "Tk9cUHVQQ1KejEhUJFiaWx1elV6tXvdeH1+MYLViOmPQY69oQGyHeI55C3rgfUeCAormikSOE5D/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////7iQLZHYkQ6f5WxYZOJkdWX0boR2G3tpkNGTum7yVLlfpGRNj+2P" + "RJJ4UWtYKVlVXJde+22Pfhx1vIzijluYuXAdT79rsW8wdfuWTlEQVDVYV1isWWBckl+XZVxnIW57dt+D7YwUkP2QTZMleDp4" + "qlKmXh9XdFkSYBJQWlGsUc1RAFIQVVRYWFhXWZVb9lyLXbxglWItZHFnQ2i8aN9o13bYbW9um21vcMhxU1/YdXd5SXtUe1J7" + "1nxxfTBS////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9jhGmF5IUOigSLRowPjgOQ" + "D5AZlHaWLZgwmtiVzVDVUgxUAlgOXKdhnmQebbN35Xr0gASEU5CFkuBcB50/U5dfs1+cbXlyY3e/eeR70mvscq2KA2hhavhR" + "gXo0aUpc9pzrgsVbSZEecHhWb1zHYGZljGxajEGQE5hRVMdmDZJIWaOQhVFNTupRmYUOi1hwemNLk2JptJkEfnd1V1Ngad+O" + "45ZdbIxOPFwQX+mPAlPRjImAeYb/XuVlc05lUf//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////glk/XO6X+06KWc1fjYrhb7B5YnnnW3GEK3OxcXRe9V97Y5pkw3GYfENO/F5LTtxXolapYMNvDX39gDOBv4Gyj5eJ" + "pIb0XYpirWSHiXdn4mw+bTZ0NHhGWnV/rYKsmfNPw17dYpJjV2VvZ8N2THLMgLqAKY9NkQ1Q+VeSWoVoc2lkcf1yt4zyWOCM" + "apYZkH+H5HnndymEL09lUlpTzWLPZ8psfXaUe5V8NoKEheuP3WYgbwZyG36rg8GZpp7/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////1RsXtyeLh7h4BIe+hqYV6MgFF1YHVrUWKSjG56dpeR6poQT3B/nGJPe6WV" + "6Zx6VllY5Ia8ljRPJFJKU81T21MGXixkkWV/Zz5sTmxIcq9y7XNUdUF+LILphamMxHvGkWlxEpjvmD1jaWZqdeR20HhDhe6G" + "KlNRUyZUg1mHXnxfsmBJYnliq2KQZdRrzGyyda52kXjYect9d3+lgKuIuYq7jH+QXpfbmAtqOHyZUD5crl+HZ9hrNXQJd45/" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////87n8pnF3o5U4t17ZpmX52B8YOYgDxf" + "xV9idUZ7PJBnaOtZm1oQfX52LIv1T2pfGWo3bAJv4nRoeWiIVYp5jN9ez2PFddJ514Iok/KSnITthi2cwVRsX4xlXG0VcKeM" + "04w7mE9l9nQNTthO4FcrWWZazFuoUQNenF4WYHZid2WnZW5mbm02ciZ7UIGagZmCXIugjOaMdI0clkSWrk+rZGZrHoJhhGqF" + "6JABXFNpqJh6hFeFD09vUqlfRV4NZ///////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "j3l5gQeJhon1bRdfVWK4bM9OaXKSmwZSO1R0VrNYpGFuYhpxblmJfN58G33wlodlXoAZTnVPdVFAWGNec14KX8RnJk49hYmV" + "W5ZzfAGY+1DBWFZ2p3glUqV3EYWGe09QCVlHcsd76H26j9SPTZC/T8lSKVoBX62X3U8XguqSA1dVY2lrK3XciBSPQnrfUpNY" + "VWEKYq5mzWs/fOmDI1D4TwVTRlQxWElZnVvwXO9cKV2WXrFiZ2M+ZbllC2f/////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////9Vs4Wz5cDJ4K37egLOCDITshAKHEokqikqMppDSkv2Y85xsnU9OoU6NUFZSSleoWT1e" + "2F/ZXz9itGYbZ9Bn0miSUSF9qoCogQCLjIy/jH6SMpYgVCyYF1PVUFxTqFiyZDRnZ3Jmd0Z65pHDUqFshmsAWExeVFksZ/t/" + "4VHGdmlk6HhUm7uey1e5WSdmmmfOa+lU2WlVXpyBlWeqm/5nUpxdaKZO40/IU7liK2erbMSPrU9tfr+eB05iYYBu////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////8rbxOFc1QqZ0Wb812Ve6xcxlsch0pu0YQUegiB" + "mVmNfBFsIHfZUiJZIXFfctt3J5dhnQtpf1oYWqVRDVR9VA5m33b3j5iS9JzqWV1yxW5NUclov33sfWKXup54ZCFqAoOEWV9b" + "22sbc/J2sn0XgJmEMlEoZ9me7nZiZ/9SBZkkXDtifnywjE9VtmALfYCVAVNfTrZRHFk6cjaAzpElX+J3hFN5XwR9rIUzio2O" + "VpfzZ66FU5QJYQhhuWxSdv//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////7Yo4jy9V" + "UU8qUcdSy1OlW31eoGCCYdZjCWfaZ2dujG02czdzMXVQedWImIpKkJGQ9ZDElo2HFVmITllPDk6Jij+PEJitUHxellm5W7he" + "2mP6Y8Fk3GZKadhpC222bpRxKHWveop/AIBJhMmEgYkhiwqOZZB9lgqZfmGRYjJrg2x0bcx//H/AbYV/uof4iGVnsYM8mPeW" + "G21hfT2EapFxTnVTUF0Ea+tvzYUthqeJKVIPVGVcTmeoaAZ0g3T/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////+J1z4jhiMyR4pZ4lotfh3PLek6EoGNldYlSQW2cbgl0WXVreJJ8hpbceo2ftk9uYcVlXIaGTq5O" + "2lAhTsxR7luZZYFovG0fc0J2rXcceud8b4LSinyQz5F1lhiYm1LRfStQmFOXZ8tt0HEzdOiBKo+jllecn55gdEFYmW0vfV6Y" + "5E42T4tPt1GxUrpdHGCyczx504I0kreW9pYKl5eeYp+mZnRrF1KjUshwwojJXktgkGEjb0lxPnz0fW+A////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////uhCOQLJNCVG+b02qJcMKM740yl7RSQVrKXgRfF2d8aZRp" + "am0Pb2Jy/HLtewGAfoBLh86QbVGTnoR5i4Ayk9aKLVCMVHGKamvEjAeB0WCgZ/KdmU6YThCca4rBhWiFAGl+bpd4VYH/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////DF8QThVOKk4xTjZO" + "PE4/TkJOVk5YToJOhU5rjIpOEoINX45Onk6fTqBOok6wTrNOtk7OTs1OxE7GTsJO107eTu1O3073TglPWk8wT1tPXU9XT0dP" + "dk+IT49PmE97T2lPcE+RT29Phk+WTxhR1E/fT85P2E/bT9FP2k/QT+RP5U8aUChQFFAqUCVQBVAcT/ZPIVApUCxQ/k/vTxFQ" + "BlBDUEdQA2dVUFBQSFBaUFZQbFB4UIBQmlCFULRQslD/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////8lQylCzUMJQ1lDeUOVQ7VDjUO5Q+VD1UAlRAVECURZRFVEUURpRIVE6UTdRPFE7UT9RQFFSUUxRVFFiUfh6" + "aVFqUW5RgFGCUdhWjFGJUY9RkVGTUZVRllGkUaZRolGpUapRq1GzUbFRslGwUbVRvVHFUclR21HgUVWG6VHtUfBR9VH+UQRS" + "C1IUUg5SJ1IqUi5SM1I5Uk9SRFJLUkxSXlJUUmpSdFJpUnNSf1J9Uo1SlFKSUnFSiFKRUqiP////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////+nj6xSrVK8UrVSwVLNUtdS3lLjUuZS7ZjgUvNS9VL4UvlSBlMIUzh1" + "DVMQUw9TFVMaUyNTL1MxUzNTOFNAU0ZTRVMXTklTTVPWUV5TaVNuUxhZe1N3U4JTllOgU6ZTpVOuU7BTtlPDUxJ82ZbfU/xm" + "7nHuU+hT7VP6UwFUPVRAVCxULVQ8VC5UNlQpVB1UTlSPVHVUjlRfVHFUd1RwVJJUe1SAVHZUhFSQVIZUx1SiVLhUpVSsVMRU" + "yFSoVP//////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////q1TCVKRUvlS8VNhU5VTmVA9V" + "FFX9VO5U7VT6VOJUOVVAVWNVTFUuVVxVRVVWVVdVOFUzVV1VmVWAVa9UilWfVXtVflWYVZ5VrlV8VYNVqVWHVahV2lXFVd9V" + "xFXcVeRV1FUUVvdVFlb+Vf1VG1b5VU5WUFbfcTRWNlYyVjhWa1ZkVi9WbFZqVoZWgFaKVqBWlFaPVqVWrla2VrRWwla8VsFW" + "w1bAVshWzlbRVtNW11buVvlWAFf/VgRXCVf/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////whXC1cNVxNXGFcWV8dVHFcmVzdXOFdOVztXQFdPV2lXwFeIV2FXf1eJV5NXoFezV6RXqlewV8NXxlfUV9JX01cKWNZX" + "41cLWBlYHVhyWCFYYlhLWHBYwGtSWD1YeViFWLlYn1irWLpY3li7WLhYrljFWNNY0VjXWNlY2FjlWNxY5FjfWO9Y+lj5WPtY" + "/Fj9WAJZClkQWRtZpmglWSxZLVkyWThZPlnSelVZUFlOWVpZWFliWWBZZ1lsWWlZ////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////94WYFZnVleT6tPo1myWcZZ6FncWY1Z2VnaWSVaH1oRWhxaCVoaWkBabFpJWjVa" + "NlpiWmpamlq8Wr5ay1rCWr1a41rXWuZa6VrWWvpa+1oMWwtbFlsyW9BaKls2Wz5bQ1tFW0BbUVtVW1pbW1tlW2lbcFtzW3Vb" + "eFuIZXpbgFuDW6ZbuFvDW8dbyVvUW9Bb5FvmW+Jb3lvlW+tb8Fv2W/NbBVwHXAhcDVwTXCBcIlwoXDhcOVxBXEZcTlxTXP//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////UFxPXHFbbFxuXGJOdlx5XIxckVyUXJtZ" + "q1y7XLZcvFy3XMVcvlzHXNlc6Vz9XPpc7VyMXepcC10VXRddXF0fXRtdEV0UXSJdGl0ZXRhdTF1SXU5dS11sXXNddl2HXYRd" + "gl2iXZ1drF2uXb1dkF23XbxdyV3NXdNd0l3WXdtd613yXfVdC14aXhleEV4bXjZeN15EXkNeQF5OXldeVF5fXmJeZF5HXnVe" + "dl56Xryef16gXsFewl7IXtBez17/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////9Ze" + "417dXtpe217iXuFe6F7pXuxe8V7zXvBe9F74Xv5eA18JX11fXF8LXxFfFl8pXy1fOF9BX0hfTF9OXy9fUV9WX1dfWV9hX21f" + "c193X4Nfgl9/X4pfiF+RX4dfnl+ZX5hfoF+oX61fvF/WX/tf5F/4X/Ff3V+zYP9fIWBgYBlgEGApYA5gMWAbYBVgK2AmYA9g" + "OmBaYEFgamB3YF9gSmBGYE1gY2BDYGRgQmBsYGtgWWCBYI1g52CDYJpg////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////+EYJtglmCXYJJgp2CLYOFguGDgYNNgtGDwX71gxmC1YNhgTWEVYQZh9mD3YABh9GD6YANh" + "IWH7YPFgDWEOYUdhPmEoYSdhSmE/YTxhLGE0YT1hQmFEYXNhd2FYYVlhWmFrYXRhb2FlYXFhX2FdYVNhdWGZYZZhh2GsYZRh" + "mmGKYZFhq2GuYcxhymHJYfdhyGHDYcZhumHLYXl/zWHmYeNh9mH6YfRh/2H9Yfxh/mEAYghiCWINYgxiFGIbYv//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////HmIhYipiLmIwYjJiM2JBYk5iXmJjYltiYGJoYnxi" + "gmKJYn5ikmKTYpZi1GKDYpRi12LRYrtiz2L/YsZi1GTIYtxizGLKYsJix2KbYsliDGPuYvFiJ2MCYwhj72L1YlBjPmNNYxxk" + "T2OWY45jgGOrY3Zjo2OPY4ljn2O1Y2tjaWO+Y+ljwGPGY+NjyWPSY/ZjxGMWZDRkBmQTZCZkNmQdZRdkKGQPZGdkb2R2ZE5k" + "KmWVZJNkpWSpZIhkvGT/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////9pk0mTFZMdk" + "u2TYZMJk8WTnZAmC4GThZKxi42TvZCxl9mT0ZPJk+mQAZf1kGGUcZQVlJGUjZStlNGU1ZTdlNmU4ZUt1SGVWZVVlTWVYZV5l" + "XWVyZXhlgmWDZYqLm2WfZatlt2XDZcZlwWXEZcxl0mXbZdll4GXhZfFlcmcKZgNm+2VzZzVmNmY0ZhxmT2ZEZklmQWZeZl1m" + "ZGZnZmhmX2ZiZnBmg2aIZo5miWaEZphmnWbBZrlmyWa+Zrxm////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////EZrhm1mbaZuBmP2bmZulm8Gb1ZvdmD2cWZx5nJmcnZziXLmc/ZzZnQWc4ZzdnRmdeZ2BnWWdjZ2Rn" + "iWdwZ6lnfGdqZ4xni2emZ6FnhWe3Z+9ntGfsZ7Nn6We4Z+Rn3mfdZ+Jn7me5Z85nxmfnZ5xqHmhGaCloQGhNaDJoTmizaCto" + "WWhjaHdof2ifaI9orWiUaJ1om2iDaK5quWh0aLVooGi6aA9pjWh+aAFpymgIadhoImkmaeFoDGnNaP//////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////1GjnaNVoNmkSaQRp12jjaCVp+WjgaO9oKGkqaRppI2khacZo" + "eWl3aVxpeGlraVRpfmluaTlpdGk9aVlpMGlhaV5pXWmBaWppsmmuadBpv2nBadNpvmnOaehbymndabtpw2mnaS5qkWmgaZxp" + "lWm0ad5p6GkCahtq/2kKa/lp8mnnaQVqsWkeau1pFGrraQpqEmrBaiNqE2pEagxqcmo2anhqR2piallqZmpIajhqImqQao1q" + "oGqEaqJqo2r/////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////5dqF4a7asNqwmq4arNq" + "rGreatFq32qqatpq6mr7agVrFob6ahJrFmsxmx9rOGs3a9x2OWvumEdrQ2tJa1BrWWtUa1trX2tha3hreWt/a4BrhGuDa41r" + "mGuVa55rpGuqa6trr2uya7Frs2u3a7xrxmvLa9Nr32vsa+tr82vva76eCGwTbBRsG2wkbCNsXmxVbGJsamyCbI1smmyBbJts" + "fmxobHNskmyQbMRs8WzTbL1s12zFbN1srmyxbL5s////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////+6bNts72zZbOpsH21NiDZtK209bThtGW01bTNtEm0MbWNtk21kbVpteW1ZbY5tlW3kb4Vt+W0VbgputW3HbeZt" + "uG3Gbext3m3Mbeht0m3Fbfpt2W3kbdVt6m3ubS1ubm4ubhlucm5fbj5uI25rbitudm5Nbh9uQ246bk5uJG7/bh1uOG6Cbqpu" + "mG7Jbrdu0269bq9uxG6ybtRu1W6PbqVuwm6fbkFvEW9McOxu+G7+bj9v8m4xb+9uMm/Mbv//////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////Pm8Tb/duhm96b3hvgW+Ab29vW2/zb21vgm98b1hvjm+Rb8JvZm+zb6Nv" + "oW+kb7lvxm+qb99v1W/sb9Rv2G/xb+5v228JcAtw+m8RcAFwD3D+bxtwGnB0bx1wGHAfcDBwPnAycFFwY3CZcJJwr3DxcKxw" + "uHCzcK5w33DLcN1w2XAJcf1wHHEZcWVxVXGIcWZxYnFMcVZxbHGPcftxhHGVcahxrHHXcblxvnHScclx1HHOceBx7HHncfVx" + "/HH/////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////lx/3ENchByG3Ioci1yLHIwcjJy" + "O3I8cj9yQHJGcktyWHJ0cn5ygnKBcodyknKWcqJyp3K5crJyw3LGcsRyznLScuJy4HLhcvly93IPUBdzCnMccxZzHXM0cy9z" + "KXMlcz5zTnNPc9ieV3Nqc2hzcHN4c3Vze3N6c8hzs3POc7tzwHPlc+5z3nOidAV0b3QldPhzMnQ6dFV0P3RfdFl0QXRcdGl0" + "cHRjdGp0dnR+dIt0nnSndMp0z3TUdPFz////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///gdON053TpdO508nTwdPF0+HT3dAR1A3UFdQx1DnUNdRV1E3UedSZ1LHU8dUR1TXVKdUl1W3VGdVp1aXVkdWd1a3VtdXh1" + "dnWGdYd1dHWKdYl1gnWUdZp1nXWldaN1wnWzdcN1tXW9dbh1vHWxdc11ynXSddl143Xedf51/3X8dQF28HX6dfJ183ULdg12" + "CXYfdid2IHYhdiJ2JHY0djB2O3ZHdkh2RnZcdlh2YXZidmh2aXZqdmd2bHZwdv//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////cnZ2dnh2fHaAdoN2iHaLdo52lnaTdpl2mnawdrR2uHa5drp2wnbNdtZ20nbeduF2" + "5Xbndup2L4b7dgh3B3cEdyl3JHcedyV3Jncbdzd3OHdHd1p3aHdrd1t3ZXd/d353eXeOd4t3kXegd553sHe2d7l3v3e8d713" + "u3fHd81313fad9x343fud/x3DHgSeCZ5IHgqeUV4jnh0eIZ4fHiaeIx4o3i1eKp4r3jReMZ4y3jUeL54vHjFeMp47Hj/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////+d42nj9ePR4B3kSeRF5GXkseSt5QHlgeVd5" + "X3laeVV5U3l6eX95inmdead5S5+qea55s3m5ebp5yXnVeed57HnheeN5CHoNehh6GXogeh96gHkxejt6Pno3ekN6V3pJemF6" + "Ynppep2fcHp5en16iHqXepV6mHqWeql6yHqwerZ6xXrEer96g5DHesp6zXrPetV603rZetp63XrheuJ65nrtevB6AnsPewp7" + "Bnszexh7GXseezV7KHs2e1B7////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////////////96ewR7" + "TXsLe0x7RXt1e2V7dHtne3B7cXtse257nXuYe597jXuce5p7i3uSe497XXuZe8t7wXvMe897tHvGe9176XsRfBR85nvle2B8" + "AHwHfBN883v3exd8DXz2eyN8J3wqfB98N3wrfD18THxDfFR8T3xAfFB8WHxffGR8VnxlfGx8dXyDfJB8pHytfKJ8q3yhfKh8" + "s3yyfLF8rny5fL18wHzFfMJ82HzSfNx84nw7m+988nz0fPZ8+nwGff//////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////An0cfRV9Cn1FfUt9Ln0yfT99NX1GfXN9Vn1OfXJ9aH1ufU99Y32TfYl9W32PfX19m326fa59" + "o321fcd9vX2rfT1+on2vfdx9uH2ffbB92H3dfeR93n37ffJ94X0Ffgp+I34hfhJ+MX4ffgl+C34ifkZ+Zn47fjV+OX5Dfjd+" + "Mn46fmd+XX5Wfl5+WX5afnl+an5pfnx+e36DftV9fX6uj39+iH6Jfox+kn6QfpN+lH6Wfo5+m36cfjh/On//////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////0V/TH9Nf05/UH9Rf1V/VH9Yf19/YH9of2l/Z394f4J/" + "hn+Df4h/h3+Mf5R/nn+df5p/o3+vf7J/uX+uf7Z/uH9xi8V/xn/Kf9V/1H/hf+Z/6X/zf/l/3JgGgASAC4ASgBiAGYAcgCGA" + "KIA/gDuASoBGgFKAWIBagF+AYoBogHOAcoBwgHaAeYB9gH+AhICGgIWAm4CTgJqArYCQUayA24DlgNmA3YDEgNqA1oAJge+A" + "8YAbgSmBI4EvgUuB////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////+LlkaBPoFTgVGB" + "/IBxgW6BZYFmgXSBg4GIgYqBgIGCgaCBlYGkgaOBX4GTgamBsIG1gb6BuIG9gcCBwoG6gcmBzYHRgdmB2IHIgdqB34HggeeB" + "+oH7gf6BAYICggWCB4IKgg2CEIIWgimCK4I4gjOCQIJZgliCXYJagl+CZIJigmiCaoJrgi6CcYJ3gniCfoKNgpKCq4KfgruC" + "rILhguOC34LSgvSC84L6gpODA4P7gvmC3oIGg9yCCYPZgv//////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////NYM0gxaDMoMxg0CDOYNQg0WDL4MrgxeDGIOFg5qDqoOfg6KDloMjg46Dh4OKg3yDtYNzg3WDoIOJg6iD" + "9IMThOuDzoP9gwOE2IMLhMGD94MHhOCD8oMNhCKEIIS9gziEBoX7g22EKoQ8hFqFhIR3hGuErYRuhIKEaYRGhCyEb4R5hDWE" + "yoRihLmEv4SfhNmEzYS7hNqE0ITBhMaE1oShhCGF/4T0hBeFGIUshR+FFYUUhfyEQIVjhViFSIX/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////0GFAoZLhVWFgIWkhYiFkYWKhaiFbYWUhZuF6oWHhZyFd4V+hZCF" + "yYW6hc+FuYXQhdWF3YXlhdyF+YUKhhOGC4b+hfqFBoYihhqGMIY/hk2GVU5Uhl+GZ4ZxhpOGo4aphqqGi4aMhraGr4bEhsaG" + "sIbJhiOIq4bUht6G6Ybsht+G24bvhhKHBocIhwCHA4f7hhGHCYcNh/mGCoc0hz+HN4c7hyWHKYcah2CHX4d4h0yHTod0h1eH" + "aIduh1mH////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9Th2OHaocFiKKHn4eCh6+H" + "y4e9h8CH0IfWlquHxIezh8eHxoe7h++H8ofghw+IDYj+h/aH94cOiNKHEYgWiBWIIoghiDGINog5iCeIO4hEiEKIUohZiF6I" + "YohriIGIfoieiHWIfYi1iHKIgoiXiJKIroiZiKKIjYikiLCIv4ixiMOIxIjUiNiI2YjdiPmIAon8iPSI6IjyiASJDIkKiROJ" + "Q4keiSWJKokriUGJRIk7iTaJOIlMiR2JYIleif//////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////ZolkiW2JaolviXSJd4l+iYOJiImKiZOJmImhiamJpomsia+Jsom6ib2Jv4nAidqJ3IndieeJ9In4iQOKFooQigyK" + "G4odiiWKNopBiluKUopGikiKfIptimyKYoqFioKKhIqoiqGKkYqliqaKmoqjisSKzYrCitqK64rziueK5IrxihSL4IriiveK" + "3orbigyLB4sai+GKFosQixeLIIszi6uXJosriz6LKItBi0yLT4tOi0mLVotbi1qLa4v/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////1+LbItvi3SLfYuAi4yLjouSi5OLlouZi5qLOoxBjD+MSIxMjE6MUIxVjGKM" + "bIx4jHqMgoyJjIWMioyNjI6MlIx8jJiMHWKtjKqMvYyyjLOMroy2jMiMwYzkjOOM2oz9jPqM+4wEjQWNCo0HjQ+NDY0QjU6f" + "E43NjBSNFo1njW2NcY1zjYGNmY3Cjb6Nuo3PjdqN1o3MjduNy43qjeuN343jjfyNCI4Jjv+NHY4ejhCOH45CjjWOMI40jkqO" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////9HjkmOTI5QjkiOWY5kjmCOKo5jjlWO" + "do5yjnyOgY6HjoWOhI6LjoqOk46RjpSOmY6qjqGOrI6wjsaOsY6+jsWOyI7LjtuO4478jvuO647+jgqPBY8VjxKPGY8TjxyP" + "H48bjwyPJo8zjzuPOY9Fj0KPPo9Mj0mPRo9Oj1ePXI9ij2OPZI+cj5+Po4+tj6+Pt4/aj+WP4o/qj++Ph5D0jwWQ+Y/6jxGQ" + "FZAhkA2QHpAWkAuQJ5A2kDWQOZD4j///////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "T5BQkFGQUpAOkEmQPpBWkFiQXpBokG+QdpColnKQgpB9kIGQgJCKkImQj5CokK+QsZC1kOKQ5JBIYtuQApESkRmRMpEwkUqR" + "VpFYkWORZZFpkXORcpGLkYmRgpGikauRr5GqkbWRtJG6kcCRwZHJkcuR0JHWkd+R4ZHbkfyR9ZH2kR6S/5EUkiySFZIRkl6S" + "V5JFkkmSZJJIkpWSP5JLklCSnJKWkpOSm5Jaks+SuZK3kumSD5P6kkSTLpP/////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////xmTIpMakyOTOpM1kzuTXJNgk3yTbpNWk7CTrJOtk5STuZPWk9eT6JPlk9iTw5Pdk9CT" + "yJPkkxqUFJQTlAOUB5QQlDaUK5Q1lCGUOpRBlFKURJRblGCUYpRelGqUKZJwlHWUd5R9lFqUfJR+lIGUf5SClYeVipWUlZaV" + "mJWZlaCVqJWnla2VvJW7lbmVvpXKlfZvw5XNlcyV1ZXUldaV3JXhleWV4pUhliiWLpYvlkKWTJZPlkuWd5Zcll6W////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////9dll+WZpZylmyWjZaYlpWWl5aqlqeWsZaylrCW" + "tJa2lriWuZbOlsuWyZbNlk2J3JYNl9WW+ZYElwaXCJcTlw6XEZcPlxaXGZcklyqXMJc5lz2XPpdEl0aXSJdCl0mXXJdgl2SX" + "Zpdol9JSa5dxl3mXhZd8l4GXepeGl4uXj5eQl5yXqJeml6OXs5e0l8OXxpfIl8uX3Jftl0+f8pffevaX9ZcPmAyYOJgkmCGY" + "N5g9mEaYT5hLmGuYb5hwmP//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////cZh0mHOY" + "qpivmLGYtpjEmMOYxpjpmOuYA5kJmRKZFJkYmSGZHZkemSSZIJksmS6ZPZk+mUKZSZlFmVCZS5lRmVKZTJlVmZeZmJmlma2Z" + "rpm8md+Z25ndmdiZ0Zntme6Z8ZnymfuZ+JkBmg+aBZrimRmaK5o3mkWaQppAmkOaPppVmk2aW5pXml+aYpplmmSaaZprmmqa" + "rZqwmryawJrPmtGa05rUmt6a35rimuOa5prvmuua7pr0mvGa95r/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////uaBpsYmxqbH5simyObJZsnmyibKZsqmy6bL5sym0SbQ5tPm02bTptRm1ibdJuTm4ObkZuWm5eb" + "n5ugm6ibtJvAm8qbuZvGm8+b0ZvSm+Ob4pvkm9Sb4Zs6nPKb8ZvwmxWcFJwJnBOcDJwGnAicEpwKnAScLpwbnCWcJJwhnDCc" + "R5wynEacPpxanGCcZ5x2nHic55zsnPCcCZ0IneucA50GnSqdJp2vnSOdH51EnRWdEp1BnT+dPp1GnUid////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////9dnV6dZJ1RnVCdWZ1ynYmdh52rnW+dep2anaSdqZ2yncSd" + "wZ27nbidup3Gnc+dwp3ZndOd+J3mne2d7539nRqeG54ennWeeZ59noGeiJ6Lnoyekp6VnpGenZ6lnqmeuJ6qnq2eYZfMns6e" + "z57QntSe3J7ent2e4J7lnuie7570nvae9575nvue/J79ngefCJ+3dhWfIZ8snz6fSp9Sn1SfY59fn2CfYZ9mn2efbJ9qn3ef" + "cp92n5WfnJ+gn///////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////L1jHaVmQZHTcUZlx" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +EUC_JP_DEC_SS3 = _g( + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "2ALHArgA2QLdAq8A2wLaAn4AhAOFA/////////////////////+hAKYAvwD/////////////////////////////////////" + "////////////////////////////////////////////////////////////////ugCqAKkArgAiIaQAFiH/////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////hgOIA4kDigOqA///" + "jAP//44DqwP//48D//////////+sA60DrgOvA8oDkAPMA8IDzQPLA7ADzgP/////////////////////////////////////" + "////////////////////////////////////////////////////////AgQDBAQEBQQGBAcECAQJBAoECwQMBA4EDwT/////" + "////////////////////////////////////////////////////////////////////////////////////////UgRTBFQE" + "VQRWBFcEWARZBFoEWwRcBF4EXwT/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////8YAEAH//yYB" + "//8yAf//QQE/Af//SgHYAFIB//9mAd4A///////////////////////////////////////////mABEB8AAnATEBMwE4AUIB" + "QAFJAUsB+ABTAd8AZwH+AP//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////wQDAAMQAwgACAc0BAAEEAcUAwwAGAQgBDAHHAAoBDgHJAMgA" + "ywDKABoBFgESARgB//8cAR4BIgEgASQBzQDMAM8AzgDPATABKgEuASgBNAE2ATkBPQE7AUMBRwFFAdEA0wDSANYA1ADRAVAB" + "TAHVAFQBWAFWAVoBXAFgAV4BZAFiAdoA2QDcANsAbAHTAXABagFyAW4BaAHXAdsB2QHVAXQB3QB4AXYBeQF9AXsB////////" + "///////////hAOAA5ADiAAMBzgEBAQUB5QDjAAcBCQENAecACwEPAekA6ADrAOoAGwEXARMBGQH1AR0BHwH//yEBJQHtAOwA" + "7wDuANAB//8rAS8BKQE1ATcBOgE+ATwBRAFIAUYB8QDzAPIA9gD0ANIBUQFNAfUAVQFZAVcBWwFdAWEBXwFlAWMB+gD5APwA" + "+wBtAdQBcQFrAXMBbwFpAdgB3AHaAdYBdQH9AP8AdwF6AX4BfAH/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////Ak4ETgVODE4STh9OI04kTihOK04uTi9OME41TkBOQU5ETkdOUU5aTlxOY05oTmlOdE51TnlOf06NTpZO" + "l06dTq9OuU7DTtBO2k7bTuBO4U7iTuhO707xTvNO9U79Tv5O/04ATwJPA08ITwtPDE8STxVPFk8XTxlPLk8xT2BPM081TzdP" + "OU87Tz5PQE9CT0hPSU9LT0xPUk9UT1ZPWE9fT2NPak9sT25PcU93T3hPeU96T31Pfk+BT4JPhE+FT4lPik+MT45PkE+ST5NP" + "lE+XT5lPmk+eT59Psk+3T7lPu0+8T71Pvk/AT8FPxU/GT8hPyU/LT8xPzU/PT9JP3E/gT+JP8E/yT/xP/U//TwBQAVAEUAdQ" + "ClAMUA5QEFATUBdQGFAbUBxQHVAeUCJQJ1AuUDBQMlAzUDVQQFBBUEJQRVBGUEpQTFBOUFFQUlBTUFdQWVBfUGBQYlBjUGZQ" + "Z1BqUG1QcFBxUDtQgVCDUIRQhlCKUI5Qj1CQUJJQk1CUUJZQm1CcUJ5Qn1CgUKFQolCqUK9QsFC5ULpQvVDAUMNQxFDHUMxQ" + "zlDQUNNQ1FDYUNxQ3VDfUOJQ5FDmUOhQ6VDvUPFQ9lD6UP5QA1EGUQdRCFELUQxRDVEOUfJQEFEXURlRG1EcUR1RHlEjUSdR" + "KFEsUS1RL1ExUTNRNFE1UThROVFCUUpRT1FTUVVRV1FYUV9RZFFmUX5Rg1GEUYtRjlGYUZ1RoVGjUa1RuFG6UbxRvlG/UcJR" + "yFHPUdFR0lHTUdVR2FHeUeJR5VHuUfJR81H0UfdRAVICUgVSElITUhVSFlIYUiJSKFIxUjJSNVI8UkVSSVJVUldSWFJaUlxS" + "X1JgUmFSZlJuUndSeFJ5UoBSglKFUopSjFKTUpVSllKXUphSmlKcUqRSpVKmUqdSr1KwUrZSt1K4UrpSu1K9UsBSxFLGUshS" + "zFLPUtFS1FLWUttS3FLhUuVS6FLpUupS7FLwUvFS9FL2UvdSAFMDUwpTC1MMUxFTE1MYUxtTHFMeUx9TJVMnUyhTKVMrUyxT" + "LVMwUzJTNVM8Uz1TPlNCU0xTS1NZU1tTYVNjU2VTbFNtU3JTeVN+U4NTh1OIU45Tk1OUU5lTnVOhU6RTqlOrU69TslO0U7VT" + "t1O4U7pTvVPAU8VTz1PSU9NT1VPaU91T3lPgU+ZT51P1UwJUE1QaVCFUJ1QoVCpUL1QxVDRUNVRDVERUR1RNVE9UXlRiVGRU" + "ZlRnVGlUa1RtVG5UdFR/VIFUg1SFVIhUiVSNVJFUlVSWVJxUn1ShVKZUp1SpVKpUrVSuVLFUt1S5VLpUu1S/VMZUylTNVM5U" + "4FTqVOxU71T2VPxU/lT/VABVAVUFVQhVCVUMVQ1VDlUVVSpVK1UyVTVVNlU7VTxVPVVBVUdVSVVKVU1VUFVRVVhVWlVbVV5V" + "YFVhVWRVZlV/VYFVglWGVYhVjlWPVZFVklWTVZRVl1WjVaRVrVWyVb9VwVXDVcZVyVXLVcxVzlXRVdJV01XXVdhV21XeVeJV" + "6VX2Vf9VBVYIVgpWDVYOVg9WEFYRVhJWGVYsVjBWM1Y1VjdWOVY7VjxWPVY/VkBWQVZDVkRWRlZJVktWTVZPVlRWXlZgVmFW" + "YlZjVmZWaVZtVm9WcVZyVnVWhFaFVohWi1aMVpVWmVaaVp1WnlafVqZWp1aoVqlWq1asVq1WsVazVrdWvlbFVslWylbLVs9W" + "0FbMVs1W2VbcVt1W31bhVuRW5VbmVudW6FbxVutW7Vb2VvdWAVcCVwdXClcMVxFXFVcaVxtXHVcgVyJXI1ckVyVXKVcqVyxX" + "LlcvVzNXNFc9Vz5XP1dFV0ZXTFdNV1JXYldlV2dXaFdrV21XbldvV3BXcVdzV3RXdVd3V3lXeld7V3xXfleBV4NXjFeUV5dX" + "mVeaV5xXnVeeV59XoVeVV6dXqFepV6xXuFe9V8dXyFfMV89X1VfdV95X5FfmV+dX6VftV/BX9Vf2V/hX/Vf+V/9XA1gEWAhY" + "CVjhVwxYDVgbWB5YH1ggWCZYJ1gtWDJYOVg/WElYTFhNWE9YUFhVWF9YYVhkWGdYaFh4WHxYf1iAWIFYh1iIWIlYiliMWI1Y" + "j1iQWJRYllidWKBYoViiWKZYqVixWLJYxFi8WMJYyFjNWM5Y0FjSWNRY1ljaWN1Y4VjiWOlY81gFWQZZC1kMWRJZE1kUWUGG" + "HVkhWSNZJFkoWS9ZMFkzWTVZNlk/WUNZRllSWVNZWVlbWV1ZXllfWWFZY1lrWW1Zb1lyWXVZdll5WXtZfFmLWYxZjlmSWZVZ" + "l1mfWaRZp1mtWa5Zr1mwWbNZt1m6WbxZwVnDWcRZyFnKWc1Z0lndWd5Z31njWeRZ51nuWe9Z8VnyWfRZ91kAWgRaDFoNWg5a" + "EloTWh5aI1okWidaKFoqWi1aMFpEWkVaR1pIWkxaUFpVWl5aY1plWmdabVp3Wnpae1p+WotakFqTWpZamVqcWp5an1qgWqJa" + "p1qsWrFaslqzWrVauFq6Wrtav1rEWsZayFrPWtpa3FrgWuVa6lruWvVa9lr9WgBbAVsIWxdbNFsZWxtbHVshWyVbLVs4W0Fb" + "S1tMW1JbVlteW2hbbltvW3xbfVt+W39bgVuEW4ZbiluOW5BbkVuTW5RblluoW6lbrFutW69bsVuyW7dbulu8W8BbwVvNW89b" + "1lvXW9hb2VvaW+Bb71vxW/Rb/VsMXBdcHlwfXCNcJlwpXCtcLFwuXDBcMlw1XDZcWVxaXFxcYlxjXGdcaFxpXG1ccFx0XHVc" + "elx7XHxcfVyHXIhcilyPXJJcnVyfXKBcolyjXKZcqlyyXLRctVy6XMlcy1zSXN1c11zuXPFc8lz0XAFdBl0NXRJdK10jXSRd" + "Jl0nXTFdNF05XT1dP11CXUNdRl1IXVVdUV1ZXUpdX11gXWFdYl1kXWpdbV1wXXldel1+XX9dgV2DXYhdil2SXZNdlF2VXZld" + "m12fXaBdp12rXbBdtF24Xbldw13HXctd0F3OXdhd2V3gXeRd6V34XfldAF4HXg1eEl4UXhVeGF4fXiBeLl4oXjJeNV4+Xkte" + "UF5JXlFeVl5YXlteXF5eXmheal5rXmxebV5uXnBegF6LXo5eol6kXqVeqF6qXqxesV6zXr1evl6/XsZezF7LXs5e0V7SXtRe" + "1V7cXt5e5V7rXgJfBl8HXwhfDl8ZXxxfHV8hXyJfI18kXyhfK18sXy5fMF80XzZfO189Xz9fQF9EX0VfR19NX1BfVF9YX1tf" + "YF9jX2RfZ19vX3JfdF91X3hfel99X35fiV+NX49fll+cX51fol+nX6tfpF+sX69fsF+xX7hfxF/HX8hfyV/LX9Bf0V/SX9Nf" + "1F/eX+Ff4l/oX+lf6l/sX+1f7l/vX/Jf81/2X/pf/F8HYApgDWATYBRgF2AYYBpgH2AkYC1gM2A1YEBgR2BIYElgTGBRYFRg" + "VmBXYF1gYWBnYHFgfmB/YIJghmCIYIpgjmCRYJNglWCYYJ1gnmCiYKRgpWCoYLBgsWC3YLtgvmDCYMRgyGDJYMpgy2DOYM9g" + "1GDVYNlg22DdYN5g4mDlYPJg9WD4YPxg/WACYQdhCmEMYRBhEWESYRNhFGEWYRdhGWEcYR5hImEqYSthMGExYTVhNmE3YTlh" + "QWFFYUZhSWFeYWBhbGFyYXhhe2F8YX9hgGGBYYNhhGGLYY1hkmGTYZdhmGGcYZ1hn2GgYaVhqGGqYa1huGG5YbxhwGHBYcJh" + "zmHPYdVh3GHdYd5h32HhYeJh52HpYeVh7GHtYe9hAWIDYgRiB2ITYhViHGIgYiJiI2InYiliK2I5Yj1iQmJDYkRiRmJMYlBi" + "UWJSYlRiVmJaYlxiZGJtYm9ic2J6Yn1ijWKOYo9ikGKmYqhis2K2YrdiumK+Yr9ixGLOYtVi1mLaYupi8mL0Yvxi/WIDYwRj" + "CmMLYw1jEGMTYxZjGGMpYypjLWM1YzZjOWM8Y0FjQmNDY0RjRmNKY0tjTmNSY1NjVGNYY1tjZWNmY2xjbWNxY3RjdWN4Y3xj" + "fWN/Y4JjhGOHY4pjkGOUY5VjmWOaY55jpGOmY61jrmOvY71jwWPFY8hjzmPRY9Nj1GPVY9xj4GPlY+pj7GPyY/Nj9WP4Y/lj" + "CWQKZBBkEmQUZBhkHmQgZCJkJGQlZClkKmQvZDBkNWQ9ZD9kS2RPZFFkUmRTZFRkWmRbZFxkXWRfZGBkYWRjZG1kc2R0ZHtk" + "fWSFZIdkj2SQZJFkmGSZZJtknWSfZKFko2SmZKhkrGSzZL1kvmS/ZMRkyWTKZMtkzGTOZNBk0WTVZNdk5GTlZOlk6mTtZPBk" + "9WT3ZPtk/2QBZQRlCGUJZQplD2UTZRRlFmUZZRtlHmUfZSJlJmUpZS5lMWU6ZTxlPWVDZUdlSWVQZVJlVGVfZWBlZ2VrZXpl" + "fWWBZYVlimWSZZVlmGWdZaBlo2WmZa5lsmWzZbRlv2XCZchlyWXOZdBl1GXWZdhl32XwZfJl9GX1Zfll/mX/ZQBmBGYIZglm" + "DWYRZhJmFWYWZh1mHmYhZiJmI2YkZiZmKWYqZitmLGYuZjBmMWYzZjlmN2ZAZkVmRmZKZkxmUWZOZldmWGZZZltmXGZgZmFm" + "+2ZqZmtmbGZ+ZnNmdWZ/ZndmeGZ5ZntmgGZ8ZotmjGaNZpBmkmaZZppmm2acZp9moGakZq1msWayZrVmu2a/ZsBmwmbDZshm" + "zGbOZs9m1GbbZt9m6GbrZuxm7mb6ZgVnB2cOZxNnGWccZyBnImczZz5nRWdHZ0hnTGdUZ1VnXWdmZ2xnbmd0Z3Zne2eBZ4Rn" + "jmePZ5Fnk2eWZ5hnmWebZ7BnsWeyZ7Vnu2e8Z71n+WfAZ8Jnw2fFZ8hnyWfSZ9dn2WfcZ+Fn5mfwZ/Jn9mf3Z1JoFGgZaB1o" + "H2goaCdoLGgtaC9oMGgxaDNoO2g/aERoRWhKaExoVWhXaFhoW2hraG5ob2hwaHFocmh1aHloemh7aHxogmiEaIZoiGiWaJho" + "mmicaKFoo2ilaKloqmiuaLJou2jFaMhozGjPaNBo0WjTaNZo2WjcaN1o5WjoaOpo62jsaO1o8GjxaPVo9mj7aPxo/WgGaQlp" + "CmkQaRFpE2kWaRdpMWkzaTVpOGk7aUJpRWlJaU5pV2lbaWNpZGllaWZpaGlpaWxpcGlxaXJpeml7aX9pgGmNaZJplmmYaaFp" + "pWmmaahpq2mtaa9pt2m4abppvGnFachp0WnWaddp4mnlae5p72nxafNp9Wn+aQBqAWoDag9qEWoVahpqHWogaiRqKGowajJq" + "NGo3ajtqPmo/akVqRmpJakpqTmpQalFqUmpValZqW2pkamdqampxanNqfmqBaoNqhmqHaolqi2qRaptqnWqeap9qpWqraq9q" + "sGqxarRqvWq+ar9qxmrJashqzGrQatRq1WrWatxq3Wrkaudq7GrwavFq8mr8av1qAmsDawZrB2sJaw9rEGsRaxdrG2seayRr" + "KGsrayxrL2s1azZrO2s/a0ZrSmtNa1JrVmtYa11rYGtna2trbmtwa3VrfWt+a4JrhWuXa5trn2uga6Jro2uoa6lrrGuta65r" + "sGu4a7lrvWu+a8NrxGvJa8xr1mvaa+Fr42vma+dr7mvxa/dr+Wv/awJsBGwFbAlsDWwObBBsEmwZbB9sJmwnbChsLGwubDNs" + "NWw2bDpsO2w/bEpsS2xNbE9sUmxUbFlsW2xcbGtsbWxvbHRsdmx4bHlse2yFbIZsh2yJbJRslWyXbJhsnGyfbLBssmy0bMJs" + "xmzNbM9s0GzRbNJs1GzWbNps3GzgbOds6WzrbOxs7mzybPRsBG0HbQptDm0PbRFtE20abSZtJ20obWdsLm0vbTFtOW08bT9t" + "V21ebV9tYW1lbWdtb21wbXxtgm2HbZFtkm2UbZZtl22YbaptrG20bbdtuW29bb9txG3Ibcptzm3PbdZt223dbd9t4G3ibeVt" + "6W3vbfBt9G32bfxtAG4Ebh5uIm4nbjJuNm45bjtuPG5EbkVuSG5JbktuT25RblJuU25UblduXG5dbl5uYm5jbmhuc257bn1u" + "jW6TbpluoG6nbq1urm6xbrNuu26/bsBuwW7DbsduyG7Kbs1uzm7Pbutu7W7ubvlu+279bgRvCG8KbwxvDW8WbxhvGm8bbyZv" + "KW8qby9vMG8zbzZvO288by1vT29Rb1JvU29Xb1lvWm9db15vYW9ib2hvbG99b35vg2+Hb4hvi2+Mb41vkG+Sb5NvlG+Wb5pv" + "n2+gb6Vvpm+nb6hvrm+vb7BvtW+2b7xvxW/Hb8hvym/ab95v6G/pb/Bv9W/5b/xv/W8AcAVwBnAHcA1wF3AgcCNwL3A0cDdw" + "OXA8cENwRHBIcElwSnBLcFRwVXBdcF5wTnBkcGVwbHBucHVwdnB+cIFwhXCGcJRwlXCWcJdwmHCbcKRwq3CwcLFwtHC3cMpw" + "0XDTcNRw1XDWcNhw3HDkcPpwA3EEcQVxBnEHcQtxDHEPcR5xIHErcS1xL3EwcTFxOHFBcUVxRnFHcUpxS3FQcVJxV3FacVxx" + "XnFgcWhxeXGAcYVxh3GMcZJxmnGbcaBxonGvcbBxsnGzcbpxv3HAccFxxHHLccxx03HWcdlx2nHccfhx/nEAcgdyCHIJchNy" + "F3Iach1yH3IkcityL3I0cjhyOXJBckJyQ3JFck5yT3JQclNyVXJWclpyXHJecmByY3JocmtybnJvcnFyd3J4cntyfHJ/coRy" + "iXKNco5yk3KbcqhyrXKucrFytHK+csFyx3LJcsxy1XLWcthy33LlcvNy9HL6cvty/nICcwRzBXMHcwtzDXMScxNzGHMZcx5z" + "InMkcydzKHMsczFzMnM1czpzO3M9c0NzTXNQc1JzVnNYc11zXnNfc2BzZnNnc2lza3Nsc25zb3Nxc3dzeXN8c4BzgXODc4Vz" + "hnOOc5Bzk3OVc5dzmHOcc55zn3Ogc6JzpXOmc6pzq3Otc7Vzt3O5c7xzvXO/c8VzxnPJc8tzzHPPc9Jz03PWc9lz3XPhc+Nz" + "5nPnc+lz9HP1c/dz+XP6c/tz/XP/cwB0AXQEdAd0CnQRdBp0G3QkdCZ0KHQpdCp0K3QsdC10LnQvdDB0MXQ5dEB0Q3REdEZ0" + "R3RLdE10UXRSdFd0XXRidGZ0Z3RodGt0bXRudHF0cnSAdIF0hXSGdId0iXSPdJB0kXSSdJh0mXSadJx0n3SgdKF0o3SmdKh0" + "qXSqdKt0rnSvdLF0snS1dLl0u3S/dMh0yXTMdNB003TYdNp023TedN905HTodOp063TvdPR0+nT7dPx0/3QGdRJ1FnUXdSB1" + "IXUkdSd1KXUqdS91NnU5dT11PnU/dUB1Q3VHdUh1TnVQdVJ1V3VedV91YXVvdXF1eXV6dXt1fHV9dX51gXWFdZB1knWTdZV1" + "mXWcdaJ1pHW0dbp1v3XAdcF1xHXGdcx1znXPddd13HXfdeB14XXkded17HXude918XX5dQB2AnYDdgR2B3YIdgp2DHYPdhJ2" + "E3YVdhZ2GXYbdhx2HXYediN2JXYmdil2LXYydjN2NXY4djl2OnY8dkp2QHZBdkN2RHZFdkl2S3ZVdll2X3ZkdmV2bXZudm92" + "cXZ0doF2hXaMdo12lXabdpx2nXafdqB2onajdqR2pXamdqd2qHaqdq12vXbBdsV2yXbLdsx2znbUdtl24Hbmduh27HbwdvF2" + "9nb5dvx2AHcGdwp3DncSdxR3FXcXdxl3GnccdyJ3KHctdy53L3c0dzV3Nnc5dz13PndCd0V3RndKd013TndPd1J3VndXd1x3" + "Xndfd2B3Yndkd2d3andsd3B3cndzd3R3end9d4B3hHeMd413lHeVd5Z3mnefd6J3p3eqd653r3exd7V3vnfDd8l30XfSd9V3" + "2Xfed9934Hfkd+Z36nfsd/B38Xf0d/h3+3cFeAZ4CXgNeA54EXgdeCF4IngjeC14LngweDV4N3hDeER4R3hIeEx4TnhSeFx4" + "XnhgeGF4Y3hkeGh4anhueHp4fniKeI94lHiYeKF4nXieeJ94pHioeKx4rXiweLF4snizeLt4vXi/eMd4yHjJeMx4znjSeNN4" + "1XjWeOR423jfeOB44XjmeOp48njzeAB59nj3ePp4+3j/eAZ5DHkQeRp5HHkeeR95IHkleSd5KXkteTF5NHk1eTt5PXk/eUR5" + "RXlGeUp5S3lPeVF5VHlYeVt5XHlneWl5a3lyeXl5e3l8eX55i3mMeZF5k3mUeZV5lnmYeZt5nHmheah5qXmrea95sXm0ebh5" + "u3nCecR5x3nIecp5z3nUedZ52nnded554HnieeV56nnree158Xn4efx5AnoDegd6CXoKegx6EXoVeht6Hnoheid6K3otei96" + "MHo0ejV6OHo5ejp6RHpFekd6SHpMelV6VnpZelx6XXpfemB6ZXpnemp6bXp1enh6fnqAeoJ6hXqGeop6i3qQepF6lHqeeqB6" + "o3qserN6tXq5ert6vHrGesl6zHrOetF623roeul663rsevF69Hr7ev16/noHexR7H3sjeyd7KXsqeyt7LXsuey97MHsxezR7" + "PXs/e0B7QXtHe057VXtge2R7Zntpe2p7bXtve3J7c3t3e4R7iXuOe5B7kXuWe5t7nnuge6V7rHuve7B7snu1e7Z7unu7e7x7" + "vXvCe8V7yHvKe9R71nvXe9l72nvbe+h76nvye/R79Xv4e/l7+nv8e/57AXwCfAN8BHwGfAl8C3wMfA58D3wZfBt8IHwlfCZ8" + "KHwsfDF8M3w0fDZ8OXw6fEZ8SnxVfFF8UnxTfFl8WnxbfFx8XXxefGF8Y3xnfGl8bXxufHB8cnx5fHx8fXyGfId8j3yUfJ58" + "oHymfLB8tny3fLp8u3y8fL98xHzHfMh8yXzNfM9803zUfNV813zZfNp83XzmfOl863z1fAN9B30IfQl9D30RfRJ9E30WfR19" + "Hn0jfSZ9Kn0tfTF9PH09fT59QH1BfUd9SH1NfVF9U31XfVl9Wn1cfV19ZX1nfWp9cH14fXp9e31/fYF9gn2DfYV9hn2IfYt9" + "jH2NfZF9ln2XfZ19nn2mfad9qn2zfbZ9t325fcJ9w33EfcV9xn3Mfc19zn3Xfdl9AH7ifeV95n3qfet97X3xffV99n35ffp9" + "CH4QfhF+FX4Xfhx+HX4gfid+KH4sfi1+L34zfjZ+P35EfkV+R35OflB+Un5Yfl9+YX5ifmV+a35ufm9+c354fn5+gX6Gfod+" + "in6NfpF+lX6Yfpp+nX6efjx/O389fz5/P39Df0R/R39Pf1J/U39bf1x/XX9hf2N/ZH9lf2Z/bX9xf31/fn9/f4B/i3+Nf49/" + "kH+Rf5Z/l3+cf6F/on+mf6p/rX+0f7x/v3/Af8N/yH/Of89/23/ff+N/5X/of+x/7n/vf/J/+n/9f/5//38HgAiACoANgA6A" + "D4ARgBOAFIAWgB2AHoAfgCCAJIAmgCyALoAwgDSANYA3gDmAOoA8gD6AQIBEgGCAZIBmgG2AcYB1gIGAiICOgJyAnoCmgKeA" + "q4C4gLmAyIDNgM+A0oDUgNWA14DYgOCA7YDugPCA8oDzgPaA+YD6gP6AA4ELgRaBF4EYgRyBHoEggSSBJ4EsgTCBNYE6gTyB" + "RYFHgUqBTIFSgVeBYIFhgWeBaIFpgW2Bb4F3gYGBkIGEgYWBhoGLgY6BloGYgZuBnoGiga6BsoG0gbuBy4HDgcWByoHOgc+B" + "1YHXgduB3YHegeGB5IHrgeyB8IHxgfKB9YH2gfiB+YH9gf+BAIIDgg+CE4IUghmCGoIdgiGCIoIogjKCNII6gkOCRIJFgkaC" + "S4JOgk+CUYJWglyCYIJjgmeCbYJ0gnuCfYJ/goCCgYKDgoSCh4KJgoqCjoKRgpSCloKYgpqCm4KggqGCo4KkgqeCqIKpgqqC" + "roKwgrKCtIK3grqCvIK+gr+CxoLQgtWC2oLgguKC5ILoguqC7YLvgvaC94L9gv6CAIMBgweDCIMKgwuDVIMbgx2DHoMfgyGD" + "IoMsgy2DLoMwgzODN4M6gzyDPYNCg0ODRINHg02DToNRg1WDVoNXg3CDeIN9g3+DgIOCg4SDhoONg5KDlIOVg5iDmYObg5yD" + "nYOmg6eDqYOsg76Dv4PAg8eDyYPPg9CD0YPUg92DU4Pog+qD9oP4g/mD/IMBhAaECoQPhBGEFYQZhK2DL4Q5hEWER4RIhEqE" + "TYRPhFGEUoRWhFiEWYRahFyEYIRkhGWEZ4RqhHCEc4R0hHaEeIR8hH2EgYSFhJKEk4SVhJ6EpoSohKmEqoSvhLGEtIS6hL2E" + "voTAhMKEx4TIhMyEz4TThNyE54TqhO+E8ITxhPKE94QyhfqE+4T9hAKFA4UHhQyFDoUQhRyFHoUihSOFJIUlhSeFKoUrhS+F" + "M4U0hTaFP4VGhU+FUIVRhVKFU4VWhVmFXIVdhV6FX4VghWGFYoVkhWuFb4V5hXqFe4V9hX+FgYWFhYaFiYWLhYyFj4WThZiF" + "nYWfhaCFooWlhaeFtIW2hbeFuIW8hb2FvoW/hcKFx4XKhcuFzoWthdiF2oXfheCF5oXohe2F84X2hfyF/4UAhgSGBYYNhg6G" + "EIYRhhKGGIYZhhuGHoYhhieGKYY2hjiGOoY8hj2GQIZChkaGUoZThlaGV4ZYhlmGXYZghmGGYoZjhmSGaYZshm+GdYZ2hneG" + "eoaNhpGGloaYhpqGnIahhqaGp4aohq2GsYazhrSGtYa3hriGuYa/hsCGwYbDhsWG0YbShtWG14bahtyG4IbjhuWG54aIhvqG" + "/Ib9hgSHBYcHhwuHDocPhxCHE4cUhxmHHocfhyGHI4cohy6HL4cxhzKHOYc6hzyHPYc+h0CHQ4dFh02HWIddh2GHZIdlh2+H" + "cYdyh3uHg4eEh4WHhoeHh4iHiYeLh4yHkIeTh5WHl4eYh5mHnoegh6OHp4esh62Hroexh7WHvoe/h8GHyIfJh8qHzofVh9aH" + "2Yfah9yH34fih+OH5Ifqh+uH7Yfxh/OH+If6h/+HAYgDiAaICYgKiAuIEIgZiBKIE4gUiBiIGogbiByIHogfiCiILYguiDCI" + "Mog1iDqIPIhBiEOIRYhIiEmISohLiE6IUYhViFaIWIhaiFyIX4hgiGSIaYhxiHmIe4iAiJiImoibiJyIn4igiKiIqoi6iL2I" + "vojAiMqIy4jMiM2IzojRiNKI04jbiN6I54jviPCI8Yj1iPeIAYkGiQ2JDokPiRWJFokYiRmJGokciSCJJokniSiJMIkxiTKJ" + "NYk5iTqJPolAiUKJRYlGiUmJT4lSiVeJWolbiVyJYYliiWOJa4luiXCJc4l1iXqJe4l8iX2JiYmNiZCJlImViZuJnImfiaCJ" + "pYmwibSJtYm2ibeJvInUidWJ1onXidiJ5YnpieuJ7YnxifOJ9on5if2J/4kEigWKB4oPihGKEooUihWKHoogiiKKJIomiiuK" + "LIovijWKN4o9ij6KQIpDikWKR4pJik2KTopTilaKV4pYilyKXYphimWKZ4p1inaKd4p5inqKe4p+in+KgIqDioaKi4qPipCK" + "koqWipeKmYqfiqeKqYquiq+Ks4q2ireKu4q+isOKxorIismKyorRitOK1IrViteK3YrfiuyK8Ir0ivWK9or8iv+KBYsGiwuL" + "EYscix6LH4sKiy2LMIs3izyLQotDi0SLRYtGi0iLUotTi1SLWYtNi16LY4tti3aLeIt5i3yLfouBi4SLhYuLi42Lj4uUi5WL" + "nIuei5+LOIw5jD2MPoxFjEeMSYxLjE+MUYxTjFSMV4xYjFuMXYxZjGOMZIxmjGiMaYxtjHOMdYx2jHuMfoyGjIeMi4yQjJKM" + "k4yZjJuMnIykjLmMuozFjMaMyYzLjM+M1ozVjNmM3YzhjOiM7IzvjPCM8oz1jPeM+Iz+jP+MAY0DjQmNEo0XjRuNZY1pjWyN" + "bo1/jYKNhI2IjY2NkI2RjZWNno2fjaCNpo2rjayNr42yjbWNt425jbuNwI3FjcaNx43IjcqNzo3RjdSN1Y3XjdmN5I3ljeeN" + "7I3wjbyN8Y3yjfSN/Y0BjgSOBY4GjguOEY4UjhaOII4hjiKOI44mjieOMY4zjjaON444jjmOPY5AjkGOS45Njk6OT45UjluO" + "XI5djl6OYY5ijmmObI5tjm+OcI5xjnmOeo57joKOg46JjpCOko6VjpqOm46djp6Ooo6njqmOrY6ujrOOtY66jruOwI7BjsOO" + "xI7Hjs+O0Y7UjtyO6I7ujvCO8Y73jvmO+o7tjgCPAo8HjwiPD48QjxaPF48Yjx6PII8hjyOPJY8njyiPLI8tjy6PNI81jzaP" + "N486j0CPQY9Dj0ePT49Rj1KPU49Uj1WPWI9dj16PZY+dj6CPoY+kj6WPpo+1j7aPuI++j8CPwY/Gj8qPy4/Nj9CP0o/Tj9WP" + "4I/jj+SP6I/uj/GP9Y/2j/uP/o8CkASQCJAMkBiQG5AokCmQL5AqkCyQLZAzkDSQN5A/kEOQRJBMkFuQXZBikGaQZ5BskHCQ" + "dJB5kIWQiJCLkIyQjpCQkJWQl5CYkJmQm5CgkKGQopClkLCQspCzkLSQtpC9kMyQvpDDkMSQxZDHkMiQ1ZDXkNiQ2ZDckN2Q" + "35DlkNKQ9pDrkO+Q8JD0kP6Q/5AAkQSRBZEGkQiRDZEQkRSRFpEXkRiRGpEckR6RIJElkSKRI5EnkSmRLpEvkTGRNJE2kTeR" + "OZE6kTyRPZFDkUeRSJFPkVORV5FZkVqRW5FhkWSRZ5FtkXSReZF6kXuRgZGDkYWRhpGKkY6RkZGTkZSRlZGYkZ6RoZGmkaiR" + "rJGtka6RsJGxkbKRs5G2kbuRvJG9kb+RwpHDkcWR05HUkdeR2ZHakd6R5JHlkemR6pHske2R7pHvkfCR8ZH3kfmR+5H9kQCS" + "AZIEkgWSBpIHkgmSCpIMkhCSEpITkhaSGJIckh2SI5IkkiWSJpIoki6SL5IwkjOSNZI2kjiSOZI6kjySPpJAkkKSQ5JGkkeS" + "SpJNkk6ST5JRkliSWZJckl2SYJJhkmWSZ5JokmmSbpJvknCSdZJ2kneSeJJ5knuSfJJ9kn+SiJKJkoqSjZKOkpKSl5KZkp+S" + "oJKkkqWSp5KokquSr5KykraSuJK6kruSvJK9kr+SwJLBksKSw5LFksaSx5LIksuSzJLNks6S0JLTktWS15LYktmS3JLdkt+S" + "4JLhkuOS5ZLnkuiS7JLukvCS+ZL7kv+SAJMCkwiTDZMRkxSTFZMckx2THpMfkyGTJJMlkyeTKZMqkzOTNJM2kzeTR5NIk0mT" + "UJNRk1KTVZNXk1iTWpNek2STZZNnk2mTapNtk2+TcJNxk3OTdJN2k3qTfZN/k4CTgZOCk4iTipOLk42Tj5OSk5WTmJObk56T" + "oZOjk6STppOok6uTtJO1k7aTupOpk8GTxJPFk8aTx5PJk8qTy5PMk82T05PZk9yT3pPfk+KT5pPnk/mT95P4k/qT+5P9kwGU" + "ApQElAiUCZQNlA6UD5QVlBaUF5QflC6UL5QxlDKUM5Q0lDuUP5Q9lEOURZRIlEqUTJRVlFmUXJRflGGUY5RolGuUbZRulG+U" + "cZRylISUg5R4lXmVfpWElYiVjJWNlY6VnZWelZ+VoZWmlamVq5WslbSVtpW6lb2Vv5XGlciVyZXLldCV0ZXSldOV2ZXald2V" + "3pXfleCV5JXmlR2WHpYiliSWJZYmliyWMZYzljeWOJY5ljqWPJY9lkGWUpZUllaWV5ZYlmGWbpZ0lnuWfJZ+ln+WgZaCloOW" + "hJaJlpGWlpaalp2Wn5aklqWWppaplq6Wr5azlrqWypbSlrJd2Jbalt2W3pbflumW75bxlvqWApcDlwWXCZcalxuXHZchlyKX" + "I5colzGXM5dBl0OXSpdOl0+XVZdXl1iXWpdbl2OXZ5dql26Xc5d2l3eXeJd7l32Xf5eAl4mXlZeWl5eXmZeal56Xn5eil6yX" + "rpexl7KXtZe2l7iXuZe6l7yXvpe/l8GXxJfFl8eXyZfKl8yXzZfOl9CX0ZfUl9eX2JfZl92X3pfgl9uX4Zfkl++X8Zf0l/eX" + "+Jf6lweYCpgZmA2YDpgUmBaYHJgemCCYI5gmmCuYLpgvmDCYMpgzmDWYJZg+mESYR5hKmFGYUphTmFaYV5hZmFqYYphjmGWY" + "ZphqmGyYq5itmK6YsJi0mLeYuJi6mLuYv5jCmMWYyJjMmOGY45jlmOaY55jqmPOY9pgCmQeZCJkRmRWZFpkXmRqZG5kcmR+Z" + "IpkmmSeZK5kxmTKZM5k0mTWZOZk6mTuZPJlAmUGZRplHmUiZTZlOmVSZWJlZmVuZXJlemV+ZYJmbmZ2Zn5mmmbCZsZmymbWZ" + "uZm6mb2Zv5nDmcmZ05nUmdmZ2pncmd6Z55nqmeuZ7JnwmfSZ9Zn5mf2Z/pkCmgOaBJoLmgyaEJoRmhaaHpogmiKaI5okmiea" + "LZoumjOaNZo2mjiaR5pBmkSaSppLmkyaTppRmlSaVppdmqqarJqumq+aspq0mrWatpq5mruavpq/msGaw5rGmsiazprQmtKa" + "1ZrWmtea25rcmuCa5Jrlmuea6ZrsmvKa85r1mvma+pr9mv+aAJsBmwKbA5sEmwWbCJsJmwubDJsNmw6bEJsSmxabGZsbmxyb" + "IJsmmyubLZszmzSbNZs3mzmbOps9m0ibS5tMm1WbVptXm1ubXpthm2ObZZtmm2ibaptrm2ybbZtum3ObdZt3m3ibeZt/m4Cb" + "hJuFm4abh5uJm4qbi5uNm4+bkJuUm5qbnZuem6abp5upm6ybsJuxm7Kbt5u4m7ubvJu+m7+bwZvHm8ibzpvQm9eb2Jvdm9+b" + "5Zvnm+qb65vvm/Ob95v4m/mb+pv9m/+bAJwCnAucD5wRnBacGJwZnBqcHJwenCKcI5wmnCecKJwpnCqcMZw1nDacN5w9nEGc" + "Q5xEnEWcSZxKnE6cT5xQnFOcVJxWnFicW5xdnF6cX5xjnGmcapxcnGucaJxunHCccpx1nHece5zmnPKc95z5nAudAp0RnRed" + "GJ0cnR2dHp0vnTCdMp0znTSdOp08nUWdPZ1CnUOdR51KnVOdVJ1fnWOdYp1lnWmdap1rnXCddp13nXudfJ1+nYOdhJ2GnYqd" + "jZ2OnZKdk52VnZadl52YnaGdqp2sna6dsZ21nbmdvJ2/ncOdx53Jncqd1J3Vndad153and6d353gneWd553pneud7p3wnfOd" + "9J3+nQqeAp4Hng6eEJ4RnhKeFZ4WnhmeHJ4dnnqee558noCegp6DnoSehZ6Hno6ej56Wnpiem56enqSeqJ6snq6er56wnrOe" + "tJ61nsaeyJ7LntWe357knuee7J7tnu6e8J7xnvKe9Z74nv+eAp8DnwmfD58QnxGfEp8UnxafF58ZnxqfG58fnyKfJp8qnyuf" + "L58xnzKfNJ83nzmfOp88nz2fP59Bn0OfRJ9Fn0afR59Tn1WfVp9Xn1ifWp9dn16faJ9pn22fbp9vn3CfcZ9zn3Wfep99n4+f" + "kJ+Rn5KflJ+Wn5efnp+hn6Kfo5+ln///////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////8=" +) +EUC_JP_ENC_EXC = {0xA5: b'\\', 0x203E: b'~'} +EUC_JP_ENC_REJECT = frozenset() + +# ---- shift_jis ---- +SHIFT_JIS_DEC = _g( + "ADABMAIwDP8O//swGv8b/x//Af+bMJwwtABA/6gAPv/j/z///TD+MJ0wnjADMN1OBTAGMAcw/DAVIBAgD/88/xwwFiBc/yYg" + "JSAYIBkgHCAdIAj/Cf8UMBUwO/89/1v/Xf8IMAkwCjALMAwwDTAOMA8wEDARMAv/EiKxANcA///3AB3/YCIc/x7/ZiJnIh4i" + "NCJCJkAmsAAyIDMgAyHl/wT/ogCjAAX/A/8G/wr/IP+nAAYmBSbLJc8lziXHJcYloSWgJbMlsiW9JbwlOyASMJIhkCGRIZMh" + "EzD/////////////////////////////CCILIoYihyKCIoMiKiIpIv////////////////////8nIigirADSIdQhACIDIv//" + "//////////////////////////8gIqUiEiMCIgciYSJSImoiayIaIj0iHSI1IisiLCL//////////////////yshMCBvJm0m" + "aiYgICEgtgD//////////+8l/////////////////////////////////////////////xD/Ef8S/xP/FP8V/xb/F/8Y/xn/" + "//////////////////8h/yL/I/8k/yX/Jv8n/yj/Kf8q/yv/LP8t/y7/L/8w/zH/Mv8z/zT/Nf82/zf/OP85/zr/////////" + "//////////9B/0L/Q/9E/0X/Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r///////////9BMEIw" + "QzBEMEUwRjBHMEgwSTBKMEswTDBNME4wTzBQMFEwUjBTMFQwVTBWMFcwWDBZMFowWzBcMF0wXjBfMGAwYTBiMGMwZDBlMGYw" + "ZzBoMGkwajBrMGwwbTBuMG8wcDBxMHIwczB0MHUwdjB3MHgweTB6MHswfDB9MH4wfzCAMIEwgjCDMIQwhTCGMIcwiDCJMIow" + "izCMMI0wjjCPMJAwkTCSMJMw//////////////////////////////////+hMKIwozCkMKUwpjCnMKgwqTCqMKswrDCtMK4w" + "rzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w0DDRMNIw" + "0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zD//+Aw4TDiMOMw5DDlMOYw5zDoMOkw6jDrMOww7TDuMO8w8DDxMPIw8zD0MPUw" + "9jD/////////////////////kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MDpAOlA6YDpwOoA6kD////////" + "/////////////7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QDxQPGA8cDyAPJA///////////////////" + "////////////////////////////////////////////////////////////////////////////////////////EAQRBBIE" + "EwQUBBUEAQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8E////////////////" + "////////////////////////MAQxBDIEMwQ0BDUEUQQ2BDcEOAQ5BDoEOwQ8BD0E//8+BD8EQARBBEIEQwREBEUERgRHBEgE" + "SQRKBEsETARNBE4ETwT//////////////////////////////////wAlAiUMJRAlGCUUJRwlLCUkJTQlPCUBJQMlDyUTJRsl" + "FyUjJTMlKyU7JUslICUvJSglNyU/JR0lMCUlJTglQiX/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////+cThZVA1o/lsBUG2EoY/ZZ" + "IpB1hByDUHqqYOFjJW7tZWaEpoL1m5NoJ1ehZXFim1vQWXuG9Jhifb59jpsWYp98t4iJW7VeCWOXZkhox5WNl09n5U4KT01P" + "nU9JUPJWN1nUWQFaCVzfYA9hcGETZgVpunBPdXB1+3mtfe99w4AOhGOIAotVkHqQO1OVTqVO31eygMGQ73gATvFYom44kDJ6" + "KIOLgi+cQVFwU71U4VTgVvtZFV/ymOtt5IAthf////9ilnCWoJb7lwtU81OHW89wvX/Cj+iWb1Ncnbp6EU6TePyBJm4YVgRV" + "HWsahTuc5VmpU2Zt3HSPlUJWkU5LkPKWT4MMmeFTtlUwW3FfIGbzZgRoOGzzbCltW3TIdk56NJjxgluIYIrtkrJtq3XKdsWZ" + "pmABi4qNspWOaa1ThlH//xJXMFhEWbRb9l4oYKlj9GO/bBRvjnAUcVlx1XE/cwF+doLRgpeFYJBbkhudaVi8ZVpsJXX5US5Z" + "ZVmAX9xfvGL6ZSpqJ2u0a4tzwX9WiSydDp3EnqFclmx7gwRRS1y2YcaBdmhhcllO+k94U2lgKW5PevOXC04WU+5OVU89T6FP" + "c0+gUu9TCVYPWcFatlvhW9F5h2acZ7ZnTGuzbGtwwnONeb55PHqHe7GC24IEg3eD74PTg2aHsoopVqiM5o9OkB6XiobET+hc" + "EWJZcjt15YG9gv6GwIzFlhOZ1ZnLThpP44neVkpYylj7XutfKmCUYGJg0GESYtBiOWX/////QZtmZrBod21wcEx1hnZ1faWC" + "+YeLlY6WnYzxUb5SFlmzVLNbFl1oYYJpr22NeMuEV4hyiqeTuJpsbaiZ2YajV/9nzoYOkoNSh1YEVNNe4WK5ZDxoOGi7a3Jz" + "unhrepqJ0olrjQOP7ZCjlZSWaZdmW7NcfWlNmE6Ym2Mgeytq//9/arZoDZxfb3JSnVVwYOxiO20HbtFuW4QQiUSPFE45nPZT" + "G2k6aoSXKmhcUcN6soTckYyTW1YonSJoBYMxhKV8CFLFguZ0fk6DT6BR0lsKUthS51L7XZpVKljmWYxbmFvbW3JeeV6jYB9h" + "Y2G+YdtjYmXRZ1No+mg+a1NrV2wib5dvRW+wdBh143YLd/96oXshfOl9Nn/wf52AZoKeg7OJzIqrjISQUZSTlZGVopVlltOX" + "KJkYgjhOK1S4XMxdqXNMdjx3qVzrfwuNwZYRmFSYWJgBTw5PcVOcVWhW+ldHWQlbxFuQXAxefl7MX+5jOmfXZeJlH2fLaMRo" + "/////19qMF7FaxdsfWx/dUh5Y1sAegB9vV+PiRiKtIx3jcyOHY/imA6aPJuATn1QAFGTWZxbL2KAYuxkOmugcpF1R3mpf/uH" + "vIpwi6xjyoOglwlUA1SrVVRoWGpwiid4dWfNnnRTolsagVCGBpAYTkVOx04RT8pTOFSuWxNfJWBRZf//PWdCbHJs42x4cAN0" + "dnquegh7Gn3+fGZ952VbcrtTRVzoXdJi4GIZYyBuWoYxit2N+JIBb6Z5WpuoTqtOrE6bT6BP0VBHUfZ6cVH2UVRTIVN/U+tT" + "rFWDWOFcN19KXy9gUGBtYB9jWWVLasFswnLtcu93+IAFgQiCToX3kOGT/5dXmVqa8E7dUS1cgWZtaUBc8mZ1aYlzUGiBfMVQ" + "5FJHV/5dJpOkZSNrPWs0dIF5vXlLe8p9uYLMg3+IX4k5i9GP0ZEfVICSXU42UOVTOlPXcpZz6Xfmgq+OxpnImdKZd1EaYV6G" + "sFV6enZQ01tHkIWWMk7baueRUVxIXP////+YY596k2x0l2GPqnqKcYiWgnwXaHB+UWhsk/JSG1SrhROKpH/NjuGQZlOIiEF5" + "wk++UBFSRFFTVS1X6nOLV1FZYl+EX3VgdmFnYalhsmM6ZGxlb2ZCaBNuZnU9evt8TH2ZfUt+a38Og0qDzYYIimOKZov9jhqY" + "j524gs6P6Jv//4dSH2KDZMBvmZZBaJFQIGt6bFRvdHpQfUCII4oIZ/ZOOVAmUGVQfFE4UmNSp1UPVwVYzFr6XrJh+GHzYnJj" + "HGkpan1yrHIucxR4b3h5fQx3qYCLiRmL4ozSjmOQdZN6llWYE5p4nkNRn1OzU3teJl8bbpBuhHP+c0N9N4IAivqKUJZOTgtQ" + "5FN8VPpW0VlkW/Fdq14nXzhiRWWvZ1Zu0HLKfLSIoYDhgPCDToaHiuiNN5LHlmeYE5+UTpJODU9IU0lUPlQvWoxfoV+fYKdo" + "jmpadIF4noqkineLkJFeTsmbpE58T69PGVAWUElRbFGfUrlS/lKaU+NTEVT/////DlSJVVFXold9WVRbXVuPW+Vd5133XXhe" + "g16aXrdeGF9SYExhl2LYYqdjO2UCZkNm9GZtZyFol2jLaV9sKm1pbS9unW4ydYd2bHg/euB8BX0YfV59sX0VgAOAr4CxgFSB" + "j4EqglKDTIhhiBuLooz8jMqQdZFxkj94/JKklU2W//8FmJmZ2Jo7nVtSq1L3UwhU1Vj3YuBvaoxfj7meS1E7UkpU/VZAeneR" + "YJ3SnkRzCW9wgRF1/V/aYKia23K8j2RrA5jKTvBWZFe+WFpaaGDHYQ9mBmY5aLFo923VdTp9boJCm5tOUE/JUwZVb13mXe5d" + "+2eZbHN0AnhQipaT34hQV6deK2O1UKxQjVEAZ8lUXli7WbBbaV9NYqFjPWhzawhufXDHkYByFXgmeG15jmUwfdyDwYgJj5uW" + "ZFIoV1Bnan+hjLRRQlcqljpYimm0gLJUDl38V5V4+p1cT0pSi1Q+ZChmFGf1Z4R6VnsifS+TXGitmzl7GVOKUTdS/////99b" + "9mKuZOZkLWe6a6mF0ZaQdtabTGMGk6ubv3ZSZglOmFDCU3Fc6GCSZGNlX2jmccpzI3WXe4J+lYaDi9uMeJEQmaxlq2aLa9VO" + "1E46T39POlL4U/JT41XbVutYy1nJWf9ZUFtNXAJeK17XXx1gB2MvZVxbr2W9ZehlnWdia///e2sPbEVzSXnBefh8GX0rfaKA" + "AoHzgZaJXoppimaKjIruiseM3IzMlvyYb2uLTjxPjU9QUVdb+ltIYQFjQmYha8tuu2w+cr101HXBeDp5DIAzgOqBlISej1Bs" + "f54PX1iLK536eviOjVvrlgNO8VP3VzFZyVqkW4lgf24Gb7516oyfWwCF4HtyUPRnnYJhXEqFHn4OgplRBFxoY2aNnGVucT55" + "F30FgB2Lyo5ukMeGqpAfUPpSOlxTZ3xwNXJMkciRK5PlgsJbMV/5YDtO1lOIW0tiMWeKa+ly4HMuemuBo41SkZaZElHXU2pU" + "/1uIYzlqrH0Al9pWzlNoVP////+XWzFc3l3uTwFh/mIybcB5y3lCfU1+0n/tgR+CkIRGiHKJkIt0ji+PMZBLkWyRxpackcBO" + "T09FUUFTk18OYtRnQWwLbmNzJn7NkYOS1FMZWb9b0W1deS5+m3x+WJ9x+lFTiPCPyk/7XCVmrHfjehyC/5nGUapf7GVvaYlr" + "823//5ZuZG/+dhR94V11kIeRBpjmUR1SQGKRZtlmGm62XtJ9cn/4Zq+F94X4iqlS2VNzWY9ekF9VYOSSZJa3UB9R3VIgU0dT" + "7FPoVEZVMVUXVmhZvlk8WrVbBlwPXBFcGlyEXope4F5wX39ihGLbYoxjd2MHZgxmLWZ2Zn5nomgfajVqvGyIbQluWG48cSZx" + "Z3HHdQF3XXgBeWV58HngehF7p3w5fZaA1oOLhEmFXYjziB+KPIpUinOKYYzejKSRZpJ+kxiUnJaYlwpOCE4eTldOl1FwUs5X" + "NFjMWCJbOF7FYP5kYWdWZ0RttnJzdWN6uIRyi7iRIJMxVvRX/pj/////7WINaZZr7XFUfneAcoLmid+YVYexjztcOE/hT7VP" + "B1UgWt1b6VvDX05hL2OwZUtm7mibaXht8W0zdbl1H3deeeZ5M33jga+CqoWqiTqKq46bjzKQ3ZEHl7pOwU4DUnVY7FgLXBp1" + "PVxOgQqKxY9jlm2XJXvPigiYYpHzVqhT//8XkDlUglclXqhjNGyKcGF3i3zgf3CIQpBUkRCTGJOPll50xJoHXWldcGWiZ6iN" + "25ZuY0lnGWnFgxeYwJb+iIRvemT4WxZOLHBddS9mxFE2UuJS01mBXydgEGI/ZXRlH2Z0ZvJoFmhjawVucnIfddt2vnxWgPBY" + "/Yh/iaCKk4rLih2QkpFSl1mXiWUOegaBu5YtXtxgGmKlZRRmkGfzd016TXw+fgqBrIxkjeGNX46peAdS2WKlY0JkmGItioN6" + "wHusiuqWdn0MgkmH2U5IUUNTYFOjWwJcFlzdXSZiR2KwZBNoNGjJbEVtF23TZ1xvTnF9cctlf3qte9p9/////0p+qH96gRuC" + "OYKmhW6Kzoz1jXiQd5CtkpGSg5Wum01ShFU4bzZxaFGFeVV+s4HOfExWUVioXKpj/mb9Zlpp2XKPdY51DnlWed95l3wgfUR9" + "B4Y0ijuWYZAgn+dQdVLMU+JTCVCqVe5YT1k9cotbZFwdU+Ng82BcY4NjP2O7Y///zWTpZflm413Naf1pFW/lcYlO6XX4dpN6" + "33zPfZx9YYBJg1iDbIS8hPuFxYhwjQGQbZCXkxyXEprPUJdYjmHTgTWFCI0gkMNPdFBHUnNTb2BJY19nLG6zjR+Q109eXMqM" + "z2WafVJTloh2UcNjWFtrWwpcDWRRZ1yQ1k4aWSpZcGxRij5VFVilWfBgU2LBZzWCVWlAlsSZKJpTTwZY/lsQgLFcL16FXyBg" + "S2E0Yv9m8Gzebs6Af4HUgouIuIwAkC6Qipbbntub407wUydZLHuNkUyY+Z3dbidwU1NEVYVbWGKeYtNiomzvbyJ0F4o4lMFv" + "/oo4g+dR+IbqU//////pU0ZPVJCwj2pZMYH9Xep6v4/aaDeM+HJInD1qsIo5TlhTBlZmV8ViomPmZU5r4W1bbq1w7Xfveqp7" + "u309gMaAy4aViluT41bHWD5frWWWZoBqtWs3dceKJFDldzBXG19lYHpmYGz0dRp6bn/0gRiHRZCzmcl7XHX5elF7xIT//xCQ" + "6XmSejaD4VpAdy1O8k6ZW+BfvWI8ZvFn6GxrhneIO4pOkfOS0JkXaiZwKnPngleEr4wBTkZRy1GLVfVbFl4zXoFeFF81X2tf" + "tF/yYRFjomYdZ25vUnI6dTp3dIA5gXiBdoe/ityKhY3zjZqSd5UCmOWcxVJXY/R2FWeIbM1zw4yuk3OWJW2cWA5pzGn9j5qT" + "23UakFpYAmi0Y/tpQ08sb9hnu48mhbR9VJM/aXBvalf3WCxbLH0qcgpU45G0na1OTk9cUHVQQ1KejEhUJFiaWx1elV6tXvde" + "H1+MYLViOmPQY69oQGyHeI55C3rgfUeCAormikSOE5D/////uJAtkdiRDp/lbFhk4mR1ZfRuhHYbe2mQ0ZO6bvJUuV+kZE2P" + "7Y9EknhRa1gpWVVcl177bY9+HHW8jOKOW5i5cB1Pv2uxbzB1+5ZOURBUNVhXWKxZYFySX5dlXGchbnt234PtjBSQ/ZBNkyV4" + "OniqUqZeH1d0WRJgElBaUaxR///NUQBSEFVUWFhYV1mVW/Zci128YJViLWRxZ0NovGjfaNd22G1vbpttb3DIcVNf2HV3eUl7" + "VHtSe9Z8cX0wUmOEaYXkhQ6KBItGjA+OA5APkBmUdpYtmDCa2JXNUNVSDFQCWA5cp2GeZB5ts3flevSABIRTkIWS4FwHnT9T" + "l1+zX5xteXJjd7955HvSa+xyrYoDaGFq+FGBejRpSlz2nOuCxVtJkR5weFZvXMdgZmWMbFqMQZATmFFUx2YNkkhZo5CFUU1O" + "6lGZhQ6LWHB6Y0uTYmm0mQR+d3VXU2Bp347jll1sjE48XBBf6Y8CU9GMiYB5hv9e5WVzTmVR/////4JZP1zul/tOilnNX42K" + "4W+weWJ551txhCtzsXF0XvVfe2OaZMNxmHxDTvxeS07cV6JWqWDDbw19/YAzgb+Bso+XiaSG9F2KYq1kh4l3Z+JsPm02dDR4" + "Rlp1f62CrJnzT8Ne3WKSY1dlb2fDdkxyzIC6gCmPTZENUPlXklqFaP//c2lkcf1yt4zyWOCMapYZkH+H5HnndymEL09lUlpT" + "zWLPZ8psfXaUe5V8NoKEheuP3WYgbwZyG36rg8GZpp79UbF7cni4e4eASHvoamFejIBRdWB1a1FikoxuenaXkeqaEE9wf5xi" + "T3ullemcelZZWOSGvJY0TyRSSlPNU9tTBl4sZJFlf2c+bE5sSHKvcu1zVHVBfiyC6YWpjMR7xpFpcRKY75g9Y2lmanXkdtB4" + "Q4XuhipTUVMmVINZh158X7JgSWJ5YqtikGXUa8xssnWudpF42HnLfXd/pYCriLmKu4x/kF6X25gLajh8mVA+XK5fh2fYazV0" + "CXeOf/////87n8pnF3o5U4t17ZpmX52B8YOYgDxfxV9idUZ7PJBnaOtZm1oQfX52LIv1T2pfGWo3bAJv4nRoeWiIVYp5jN9e" + "z2PFddJ514Iok/KSnITthi2cwVRsX4xlXG0VcKeM04w7mE9l9nQNTthO4FcrWWZazFuoUQNenF4WYHZid2X//6dlbmZubTZy" + "JntQgZqBmYJci6CM5ox0jRyWRJauT6tkZmsegmGEaoXokAFcU2momHqEV4UPT29SqV9FXg1nj3l5gQeJhon1bRdfVWK4bM9O" + "aXKSmwZSO1R0VrNYpGFuYhpxblmJfN58G33wlodlXoAZTnVPdVFAWGNec14KX8RnJk49hYmVW5ZzfAGY+1DBWFZ2p3glUqV3" + "EYWGe09QCVlHcsd76H26j9SPTZC/T8lSKVoBX62X3U8XguqSA1dVY2lrK3XciBSPQnrfUpNYVWEKYq5mzWs/fOmDI1D4TwVT" + "RlQxWElZnVvwXO9cKV2WXrFiZ2M+ZbllC2f/////1WzhbPlwMngrft6As4IMhOyEAocSiSqKSoymkNKS/ZjznGydT06hTo1Q" + "VlJKV6hZPV7YX9lfP2K0Zhtn0GfSaJJRIX2qgKiBAIuMjL+MfpIyliBULJgXU9VQXFOoWLJkNGdncmZ3RnrmkcNSoWyGawBY" + "TF5UWSxn+3/hUcZ2//9pZOh4VJu7nstXuVknZppnzmvpVNlpVV6cgZVnqpv+Z1KcXWimTuNPyFO5Yitnq2zEj61PbX6/ngdO" + "YmGAbitvE4VzVCpnRZvzXZV7rFzGWxyHSm7RhBR6CIGZWY18EWwgd9lSIlkhcV9y23cnl2GdC2l/WhhapVENVH1UDmbfdveP" + "mJL0nOpZXXLFbk1RyWi/fex9Ype6nnhkIWoCg4RZX1vbaxtz8nayfReAmYQyUShn2Z7udmJn/1IFmSRcO2J+fLCMT1W2YAt9" + "gJUBU19OtlEcWTpyNoDOkSVf4neEU3lfBH2shTOKjY5Wl/NnroVTlAlhCGG5bFJ2/////+2KOI8vVVFPKlHHUstTpVt9XqBg" + "gmHWYwln2mdnboxtNnM3czF1UHnViJiKSpCRkPWQxJaNhxVZiE5ZTw5OiYo/jxCYrVB8XpZZuVu4Xtpj+mPBZNxmSmnYaQtt" + "tm6UcSh1r3qKfwCASYTJhIGJIYsKjmWQfZYKmX5hkWIya///g2x0bcx//H/AbYV/uof4iGVnsYM8mPeWG21hfT2EapFxTnVT" + "UF0Ea+tvzYUthqeJKVIPVGVcTmeoaAZ0g3Tidc+I4YjMkeKWeJaLX4dzy3pOhKBjZXWJUkFtnG4JdFl1a3iSfIaW3HqNn7ZP" + "bmHFZVyGhk6uTtpQIU7MUe5bmWWBaLxtH3NCdq13HHrnfG+C0op8kM+RdZYYmJtS0X0rUJhTl2fLbdBxM3TogSqPo5ZXnJ+e" + "YHRBWJltL31emORONk+LT7dRsVK6XRxgsnM8edOCNJK3lvaWCpeXnmKfpmZ0axdSo1LIcMKIyV5LYJBhI29JcT589H1vgP//" + "///uhCOQLJNCVG+b02qJcMKM740yl7RSQVrKXgRfF2d8aZRpam0Pb2Jy/HLtewGAfoBLh86QbVGTnoR5i4Ayk9aKLVCMVHGK" + "amvEjAeB0WCgZ/KdmU6YThCca4rBhWiFAGl+bpd4VYH/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////DF8QThVOKk4xTjZOPE4/TkJOVk5YToJO" + "hU5rjIpOEoINX45Onk6fTqBOok6wTrNOtk7OTs1OxE7GTsJO107eTu1O3073TglPWk8wT1tPXU9XT0dPdk+IT49PmE97T2lP" + "cE+RT29Phk+WTxhR1E/fT85P2E/bT9FP2k/QT+RP5U8aUChQFFAqUCVQBVAcT/ZPIVApUCxQ/k/vTxFQBlBDUEdQA2dVUFBQ" + "SFBaUFZQbFB4UIBQmlCFULRQslD/////yVDKULNQwlDWUN5Q5VDtUONQ7lD5UPVQCVEBUQJRFlEVURRRGlEhUTpRN1E8UTtR" + "P1FAUVJRTFFUUWJR+HppUWpRblGAUYJR2FaMUYlRj1GRUZNRlVGWUaRRplGiUalRqlGrUbNRsVGyUbBRtVG9UcVRyVHbUeBR" + "VYbpUe1R///wUfVR/lEEUgtSFFIOUidSKlIuUjNSOVJPUkRSS1JMUl5SVFJqUnRSaVJzUn9SfVKNUpRSklJxUohSkVKoj6eP" + "rFKtUrxStVLBUs1S11LeUuNS5lLtmOBS81L1UvhS+VIGUwhTOHUNUxBTD1MVUxpTI1MvUzFTM1M4U0BTRlNFUxdOSVNNU9ZR" + "XlNpU25TGFl7U3dTglOWU6BTplOlU65TsFO2U8NTEnzZlt9T/Gbuce5T6FPtU/pTAVQ9VEBULFQtVDxULlQ2VClUHVROVI9U" + "dVSOVF9UcVR3VHBUklR7VIBUdlSEVJBUhlTHVKJUuFSlVKxUxFTIVKhU/////6tUwlSkVL5UvFTYVOVU5lQPVRRV/VTuVO1U" + "+lTiVDlVQFVjVUxVLlVcVUVVVlVXVThVM1VdVZlVgFWvVIpVn1V7VX5VmFWeVa5VfFWDValVh1WoVdpVxVXfVcRV3FXkVdRV" + "FFb3VRZW/lX9VRtW+VVOVlBW33E0VjZWMlY4Vv//a1ZkVi9WbFZqVoZWgFaKVqBWlFaPVqVWrla2VrRWwla8VsFWw1bAVshW" + "zlbRVtNW11buVvlWAFf/VgRXCVcIVwtXDVcTVxhXFlfHVRxXJlc3VzhXTlc7V0BXT1dpV8BXiFdhV39XiVeTV6BXs1ekV6pX" + "sFfDV8ZX1FfSV9NXCljWV+NXC1gZWB1YclghWGJYS1hwWMBrUlg9WHlYhVi5WJ9Yq1i6WN5Yu1i4WK5YxVjTWNFY11jZWNhY" + "5VjcWORY31jvWPpY+Vj7WPxY/VgCWQpZEFkbWaZoJVksWS1ZMlk4WT5Z0npVWVBZTllaWVhZYllgWWdZbFlpWf////94WYFZ" + "nVleT6tPo1myWcZZ6FncWY1Z2VnaWSVaH1oRWhxaCVoaWkBabFpJWjVaNlpiWmpamlq8Wr5ay1rCWr1a41rXWuZa6VrWWvpa" + "+1oMWwtbFlsyW9BaKls2Wz5bQ1tFW0BbUVtVW1pbW1tlW2lbcFtzW3VbeFuIZXpbgFv//4Nbplu4W8Nbx1vJW9Rb0FvkW+Zb" + "4lveW+Vb61vwW/Zb81sFXAdcCFwNXBNcIFwiXChcOFw5XEFcRlxOXFNcUFxPXHFbbFxuXGJOdlx5XIxckVyUXJtZq1y7XLZc" + "vFy3XMVcvlzHXNlc6Vz9XPpc7VyMXepcC10VXRddXF0fXRtdEV0UXSJdGl0ZXRhdTF1SXU5dS11sXXNddl2HXYRdgl2iXZ1d" + "rF2uXb1dkF23XbxdyV3NXdNd0l3WXdtd613yXfVdC14aXhleEV4bXjZeN15EXkNeQF5OXldeVF5fXmJeZF5HXnVedl56Xrye" + "f16gXsFewl7IXtBez17/////1l7jXt1e2l7bXuJe4V7oXule7F7xXvNe8F70Xvhe/l4DXwlfXV9cXwtfEV8WXylfLV84X0Ff" + "SF9MX05fL19RX1ZfV19ZX2FfbV9zX3dfg1+CX39fil+IX5Ffh1+eX5lfmF+gX6hfrV+8X9Zf+1/kX/hf8V/dX7Ng/18hYGBg" + "//8ZYBBgKWAOYDFgG2AVYCtgJmAPYDpgWmBBYGpgd2BfYEpgRmBNYGNgQ2BkYEJgbGBrYFlggWCNYOdgg2CaYIRgm2CWYJdg" + "kmCnYItg4WC4YOBg02C0YPBfvWDGYLVg2GBNYRVhBmH2YPdgAGH0YPpgA2EhYftg8WANYQ5hR2E+YShhJ2FKYT9hPGEsYTRh" + "PWFCYURhc2F3YVhhWWFaYWthdGFvYWVhcWFfYV1hU2F1YZlhlmGHYaxhlGGaYYphkWGrYa5hzGHKYclh92HIYcNhxmG6Ycth" + "eX/NYeZh42H2Yfph9GH/Yf1h/GH+YQBiCGIJYg1iDGIUYhti/////x5iIWIqYi5iMGIyYjNiQWJOYl5iY2JbYmBiaGJ8YoJi" + "iWJ+YpJik2KWYtRig2KUYtdi0WK7Ys9i/2LGYtRkyGLcYsxiymLCYsdim2LJYgxj7mLxYidjAmMIY+9i9WJQYz5jTWMcZE9j" + "lmOOY4Bjq2N2Y6Njj2OJY59jtWNrY///aWO+Y+ljwGPGY+NjyWPSY/ZjxGMWZDRkBmQTZCZkNmQdZRdkKGQPZGdkb2R2ZE5k" + "KmWVZJNkpWSpZIhkvGTaZNJkxWTHZLtk2GTCZPFk52QJguBk4WSsYuNk72QsZfZk9GTyZPpkAGX9ZBhlHGUFZSRlI2UrZTRl" + "NWU3ZTZlOGVLdUhlVmVVZU1lWGVeZV1lcmV4ZYJlg2WKi5tln2WrZbdlw2XGZcFlxGXMZdJl22XZZeBl4WXxZXJnCmYDZvtl" + "c2c1ZjZmNGYcZk9mRGZJZkFmXmZdZmRmZ2ZoZl9mYmZwZoNmiGaOZolmhGaYZp1mwWa5Zslmvma8Zv/////EZrhm1mbaZuBm" + "P2bmZulm8Gb1ZvdmD2cWZx5nJmcnZziXLmc/ZzZnQWc4ZzdnRmdeZ2BnWWdjZ2RniWdwZ6lnfGdqZ4xni2emZ6FnhWe3Z+9n" + "tGfsZ7Nn6We4Z+Rn3mfdZ+Jn7me5Z85nxmfnZ5xqHmhGaCloQGhNaDJoTmj//7NoK2hZaGNod2h/aJ9oj2itaJRonWibaINo" + "rmq5aHRotWigaLpoD2mNaH5oAWnKaAhp2GgiaSZp4WgMac1o1GjnaNVoNmkSaQRp12jjaCVp+WjgaO9oKGkqaRppI2khacZo" + "eWl3aVxpeGlraVRpfmluaTlpdGk9aVlpMGlhaV5pXWmBaWppsmmuadBpv2nBadNpvmnOaehbymndabtpw2mnaS5qkWmgaZxp" + "lWm0ad5p6GkCahtq/2kKa/lp8mnnaQVqsWkeau1pFGrraQpqEmrBaiNqE2pEagxqcmo2anhqR2piallqZmpIajhqImqQao1q" + "oGqEaqJqo2r/////l2oXhrtqw2rCarhqs2qsat5q0Wrfaqpq2mrqavtqBWsWhvpqEmsWazGbH2s4azdr3HY5a+6YR2tDa0lr" + "UGtZa1RrW2tfa2FreGt5a39rgGuEa4NrjWuYa5Vrnmuka6prq2uva7JrsWuza7drvGvGa8tr02vfa+xr62vza+9r//++nghs" + "E2wUbBtsJGwjbF5sVWxibGpsgmyNbJpsgWybbH5saGxzbJJskGzEbPFs02y9bNdsxWzdbK5ssWy+bLps22zvbNls6mwfbU2I" + "Nm0rbT1tOG0ZbTVtM20SbQxtY22TbWRtWm15bVltjm2VbeRvhW35bRVuCm61bcdt5m24bcZt7G3ebcxt6G3SbcVt+m3ZbeRt" + "1W3qbe5tLW5ubi5uGW5ybl9uPm4jbmtuK252bk1uH25DbjpuTm4kbv9uHW44boJuqm6Ybslut27Tbr1ur27EbrJu1G7Vbo9u" + "pW7Cbp9uQW8Rb0xw7G74bv5uP2/ybjFv724yb8xu////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//8+bxNv926Gb3pveG+Bb4Bvb29bb/NvbW+Cb3xvWG+Ob5Fvwm9mb7Nvo2+hb6RvuW/Gb6pv32/Vb+xv1G/Yb/Fv7m/bbwlw" + "C3D6bxFwAXAPcP5vG3AacHRvHXAYcB9wMHA+cDJwUXBjcJlwknCvcPFwrHC4cLNwrnDfcMtw3XD//9lwCXH9cBxxGXFlcVVx" + "iHFmcWJxTHFWcWxxj3H7cYRxlXGocaxx13G5cb5x0nHJcdRxznHgcexx53H1cfxx+XH/cQ1yEHIbcihyLXIscjByMnI7cjxy" + "P3JAckZyS3JYcnRyfnKCcoFyh3KScpZyonKncrlysnLDcsZyxHLOctJy4nLgcuFy+XL3cg9QF3MKcxxzFnMdczRzL3MpcyVz" + "PnNOc09z2J5Xc2pzaHNwc3hzdXN7c3pzyHOzc85zu3PAc+Vz7nPec6J0BXRvdCV0+HMydDp0VXQ/dF90WXRBdFx0aXRwdGN0" + "anR2dH50i3SedKd0ynTPdNR08XP/////4HTjdOd06XTudPJ08HTxdPh093QEdQN1BXUMdQ51DXUVdRN1HnUmdSx1PHVEdU11" + "SnVJdVt1RnVadWl1ZHVndWt1bXV4dXZ1hnWHdXR1inWJdYJ1lHWadZ11pXWjdcJ1s3XDdbV1vXW4dbx1sXXNdcp10nXZdeN1" + "3nX+df91///8dQF28HX6dfJ183ULdg12CXYfdid2IHYhdiJ2JHY0djB2O3ZHdkh2RnZcdlh2YXZidmh2aXZqdmd2bHZwdnJ2" + "dnZ4dnx2gHaDdoh2i3aOdpZ2k3aZdpp2sHa0drh2uXa6dsJ2zXbWdtJ23nbhduV253bqdi+G+3YIdwd3BHcpdyR3HncldyZ3" + "G3c3dzh3R3dad2h3a3dbd2V3f3d+d3l3jneLd5F3oHeed7B3tne5d793vHe9d7t3x3fNd9d32nfcd+N37nf8dwx4EngmeSB4" + "KnlFeI54dHiGeHx4mniMeKN4tXiqeK940XjGeMt41Hi+eLx4xXjKeOx4/////+d42nj9ePR4B3kSeRF5GXkseSt5QHlgeVd5" + "X3laeVV5U3l6eX95inmdead5S5+qea55s3m5ebp5yXnVeed57HnheeN5CHoNehh6GXogeh96gHkxejt6Pno3ekN6V3pJemF6" + "Ynppep2fcHp5en16iHqXepV6mHqWeql6yHqwev//tnrFesR6v3qDkMd6ynrNes961XrTetl62nrdeuF64nrmeu168HoCew97" + "CnsGezN7GHsZex57NXsoezZ7UHt6ewR7TXsLe0x7RXt1e2V7dHtne3B7cXtse257nXuYe597jXuce5p7i3uSe497XXuZe8t7" + "wXvMe897tHvGe9176XsRfBR85nvle2B8AHwHfBN883v3exd8DXz2eyN8J3wqfB98N3wrfD18THxDfFR8T3xAfFB8WHxffGR8" + "VnxlfGx8dXyDfJB8pHytfKJ8q3yhfKh8s3yyfLF8rny5fL18wHzFfMJ82HzSfNx84nw7m+988nz0fPZ8+nwGff////8CfRx9" + "FX0KfUV9S30ufTJ9P301fUZ9c31WfU59cn1ofW59T31jfZN9iX1bfY99fX2bfbp9rn2jfbV9x329fat9PX6ifa993H24fZ99" + "sH3Yfd195H3efft98n3hfQV+Cn4jfiF+En4xfh9+CX4LfiJ+Rn5mfjt+NX45fkN+N37//zJ+On5nfl1+Vn5efll+Wn55fmp+" + "aX58fnt+g37VfX1+ro9/foh+iX6MfpJ+kH6TfpR+ln6Ofpt+nH44fzp/RX9Mf01/Tn9Qf1F/VX9Uf1h/X39gf2h/aX9nf3h/" + "gn+Gf4N/iH+Hf4x/lH+ef51/mn+jf69/sn+5f65/tn+4f3GLxX/Gf8p/1X/Uf+F/5n/pf/N/+X/cmAaABIALgBKAGIAZgByA" + "IYAogD+AO4BKgEaAUoBYgFqAX4BigGiAc4BygHCAdoB5gH2Af4CEgIaAhYCbgJOAmoCtgJBRrIDbgOWA2YDdgMSA2oDWgAmB" + "74DxgBuBKYEjgS+BS4H/////i5ZGgT6BU4FRgfyAcYFugWWBZoF0gYOBiIGKgYCBgoGggZWBpIGjgV+Bk4GpgbCBtYG+gbiB" + "vYHAgcKBuoHJgc2B0YHZgdiByIHagd+B4IHngfqB+4H+gQGCAoIFggeCCoINghCCFoIpgiuCOIIzgkCCWYJYgl2CWoJfgmSC" + "//9igmiCaoJrgi6CcYJ3gniCfoKNgpKCq4KfgruCrILhguOC34LSgvSC84L6gpODA4P7gvmC3oIGg9yCCYPZgjWDNIMWgzKD" + "MYNAgzmDUINFgy+DK4MXgxiDhYOag6qDn4Oig5aDI4OOg4eDioN8g7WDc4N1g6CDiYOog/SDE4Trg86D/YMDhNiDC4TBg/eD" + "B4Tgg/KDDYQihCCEvYM4hAaF+4NthCqEPIRahYSEd4RrhK2EboSChGmERoQshG+EeYQ1hMqEYoS5hL+En4TZhM2Eu4TahNCE" + "wYTGhNaEoYQhhf+E9IQXhRiFLIUfhRWFFIX8hECFY4VYhUiF/////0GFAoZLhVWFgIWkhYiFkYWKhaiFbYWUhZuF6oWHhZyF" + "d4V+hZCFyYW6hc+FuYXQhdWF3YXlhdyF+YUKhhOGC4b+hfqFBoYihhqGMIY/hk2GVU5Uhl+GZ4ZxhpOGo4aphqqGi4aMhraG" + "r4bEhsaGsIbJhiOIq4bUht6G6Ybshv//34bbhu+GEocGhwiHAIcDh/uGEYcJhw2H+YYKhzSHP4c3hzuHJYcphxqHYIdfh3iH" + "TIdOh3SHV4doh26HWYdTh2OHaocFiKKHn4eCh6+Hy4e9h8CH0IfWlquHxIezh8eHxoe7h++H8ofghw+IDYj+h/aH94cOiNKH" + "EYgWiBWIIoghiDGINog5iCeIO4hEiEKIUohZiF6IYohriIGIfoieiHWIfYi1iHKIgoiXiJKIroiZiKKIjYikiLCIv4ixiMOI" + "xIjUiNiI2YjdiPmIAon8iPSI6IjyiASJDIkKiROJQ4keiSWJKokriUGJRIk7iTaJOIlMiR2JYIleif////9miWSJbYlqiW+J" + "dIl3iX6Jg4mIiYqJk4mYiaGJqYmmiayJr4myibqJvYm/icCJ2oncid2J54n0ifiJA4oWihCKDIobih2KJYo2ikGKW4pSikaK" + "SIp8im2KbIpiioWKgoqEiqiKoYqRiqWKpoqaiqOKxIrNisKK2orrivOK54r//+SK8YoUi+CK4or3it6K24oMiweLGovhihaL" + "EIsXiyCLM4urlyaLK4s+iyiLQYtMi0+LTotJi1aLW4tai2uLX4tsi2+LdIt9i4CLjIuOi5KLk4uWi5mLmos6jEGMP4xIjEyM" + "ToxQjFWMYoxsjHiMeoyCjImMhYyKjI2MjoyUjHyMmIwdYq2Mqoy9jLKMs4yujLaMyIzBjOSM44zajP2M+oz7jASNBY0KjQeN" + "D40NjRCNTp8Tjc2MFI0WjWeNbY1xjXONgY2ZjcKNvo26jc+N2o3WjcyN243LjeqN643fjeON/I0IjgmO/40djh6OEI4fjkKO" + "NY4wjjSOSo7/////R45JjkyOUI5IjlmOZI5gjiqOY45VjnaOco58joGOh46FjoSOi46KjpOOkY6UjpmOqo6hjqyOsI7GjrGO" + "vo7FjsiOy47bjuOO/I77juuO/o4KjwWPFY8SjxmPE48cjx+PG48MjyaPM487jzmPRY9Cjz6PTI9Jj0aPTo9Xj1yP//9ij2OP" + "ZI+cj5+Po4+tj6+Pt4/aj+WP4o/qj++Ph5D0jwWQ+Y/6jxGQFZAhkA2QHpAWkAuQJ5A2kDWQOZD4j0+QUJBRkFKQDpBJkD6Q" + "VpBYkF6QaJBvkHaQqJZykIKQfZCBkICQipCJkI+QqJCvkLGQtZDikOSQSGLbkAKREpEZkTKRMJFKkVaRWJFjkWWRaZFzkXKR" + "i5GJkYKRopGrka+RqpG1kbSRupHAkcGRyZHLkdCR1pHfkeGR25H8kfWR9pEekv+RFJIskhWSEZJekleSRZJJkmSSSJKVkj+S" + "S5JQkpySlpKTkpuSWpLPkrmSt5Lpkg+T+pJEky6T/////xmTIpMakyOTOpM1kzuTXJNgk3yTbpNWk7CTrJOtk5STuZPWk9eT" + "6JPlk9iTw5Pdk9CTyJPkkxqUFJQTlAOUB5QQlDaUK5Q1lCGUOpRBlFKURJRblGCUYpRelGqUKZJwlHWUd5R9lFqUfJR+lIGU" + "f5SClYeVipWUlZaVmJWZlf//oJWolaeVrZW8lbuVuZW+lcqV9m/Dlc2VzJXVldSV1pXcleGV5ZXilSGWKJYuli+WQpZMlk+W" + "S5Z3llyWXpZdll+WZpZylmyWjZaYlpWWl5aqlqeWsZaylrCWtJa2lriWuZbOlsuWyZbNlk2J3JYNl9WW+ZYElwaXCJcTlw6X" + "EZcPlxaXGZcklyqXMJc5lz2XPpdEl0aXSJdCl0mXXJdgl2SXZpdol9JSa5dxl3mXhZd8l4GXepeGl4uXj5eQl5yXqJeml6OX" + "s5e0l8OXxpfIl8uX3Jftl0+f8pffevaX9ZcPmAyYOJgkmCGYN5g9mEaYT5hLmGuYb5hwmP////9xmHSYc5iqmK+YsZi2mMSY" + "w5jGmOmY65gDmQmZEpkUmRiZIZkdmR6ZJJkgmSyZLpk9mT6ZQplJmUWZUJlLmVGZUplMmVWZl5mYmaWZrZmumbyZ35nbmd2Z" + "2JnRme2Z7pnxmfKZ+5n4mQGaD5oFmuKZGZormjeaRZpCmkCaQ5r//z6aVZpNmluaV5pfmmKaZZpkmmmaa5pqmq2asJq8msCa" + "z5rRmtOa1Jremt+a4prjmuaa75rrmu6a9Jrxmvea+5oGmxibGpsfmyKbI5slmyebKJspmyqbLpsvmzKbRJtDm0+bTZtOm1Gb" + "WJt0m5Obg5uRm5abl5ufm6CbqJu0m8Cbypu5m8abz5vRm9Kb45vim+Sb1Jvhmzqc8pvxm/CbFZwUnAmcE5wMnAacCJwSnAqc" + "BJwunBucJZwknCGcMJxHnDKcRpw+nFqcYJxnnHaceJznnOyc8JwJnQid65wDnQadKp0mna+dI50fnUSdFZ0SnUGdP50+nUad" + "SJ3/////XZ1enWSdUZ1QnVmdcp2JnYedq51vnXqdmp2knamdsp3EncGdu524nbqdxp3PncKd2Z3Tnfid5p3tne+d/Z0anhue" + "Hp51nnmefZ6Bnoiei56MnpKelZ6Rnp2epZ6pnrieqp6tnmGXzJ7Ons+e0J7Untye3p7dnuCe5Z7onu+e///0nvae9575nvue" + "/J79ngefCJ+3dhWfIZ8snz6fSp9Sn1SfY59fn2CfYZ9mn2efbJ9qn3efcp92n5WfnJ+gny9Yx2lZkGR03FGZcf//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +SHIFT_JIS_ENC_EXC = {0xA5: b'\\', 0x203E: b'~'} +SHIFT_JIS_ENC_REJECT = frozenset() + +# ---- cp932 ---- +CP932_DEC = _g( + "ADABMAIwDP8O//swGv8b/x//Af+bMJwwtABA/6gAPv/j/z///TD+MJ0wnjADMN1OBTAGMAcw/DAVIBAgD/88/17/JSJc/yYg" + "JSAYIBkgHCAdIAj/Cf8UMBUwO/89/1v/Xf8IMAkwCjALMAwwDTAOMA8wEDARMAv/Df+xANcA///3AB3/YCIc/x7/ZiJnIh4i" + "NCJCJkAmsAAyIDMgAyHl/wT/4P/h/wX/A/8G/wr/IP+nAAYmBSbLJc8lziXHJcYloSWgJbMlsiW9JbwlOyASMJIhkCGRIZMh" + "EzD/////////////////////////////CCILIoYihyKCIoMiKiIpIv////////////////////8nIigi4v/SIdQhACIDIv//" + "//////////////////////////8gIqUiEiMCIgciYSJSImoiayIaIj0iHSI1IisiLCL//////////////////yshMCBvJm0m" + "aiYgICEgtgD//////////+8l/////////////////////////////////////////////xD/Ef8S/xP/FP8V/xb/F/8Y/xn/" + "//////////////////8h/yL/I/8k/yX/Jv8n/yj/Kf8q/yv/LP8t/y7/L/8w/zH/Mv8z/zT/Nf82/zf/OP85/zr/////////" + "//////////9B/0L/Q/9E/0X/Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r///////////9BMEIw" + "QzBEMEUwRjBHMEgwSTBKMEswTDBNME4wTzBQMFEwUjBTMFQwVTBWMFcwWDBZMFowWzBcMF0wXjBfMGAwYTBiMGMwZDBlMGYw" + "ZzBoMGkwajBrMGwwbTBuMG8wcDBxMHIwczB0MHUwdjB3MHgweTB6MHswfDB9MH4wfzCAMIEwgjCDMIQwhTCGMIcwiDCJMIow" + "izCMMI0wjjCPMJAwkTCSMJMw//////////////////////////////////+hMKIwozCkMKUwpjCnMKgwqTCqMKswrDCtMK4w" + "rzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w0DDRMNIw" + "0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zD//+Aw4TDiMOMw5DDlMOYw5zDoMOkw6jDrMOww7TDuMO8w8DDxMPIw8zD0MPUw" + "9jD/////////////////////kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MDpAOlA6YDpwOoA6kD////////" + "/////////////7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QDxQPGA8cDyAPJA///////////////////" + "////////////////////////////////////////////////////////////////////////////////////////EAQRBBIE" + "EwQUBBUEAQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8E////////////////" + "////////////////////////MAQxBDIEMwQ0BDUEUQQ2BDcEOAQ5BDoEOwQ8BD0E//8+BD8EQARBBEIEQwREBEUERgRHBEgE" + "SQRKBEsETARNBE4ETwT//////////////////////////////////wAlAiUMJRAlGCUUJRwlLCUkJTQlPCUBJQMlDyUTJRsl" + "FyUjJTMlKyU7JUslICUvJSglNyU/JR0lMCUlJTglQiX/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////YCRhJGIkYyRkJGUk" + "ZiRnJGgkaSRqJGskbCRtJG4kbyRwJHEkciRzJGAhYSFiIWMhZCFlIWYhZyFoIWkh//9JMxQzIjNNMxgzJzMDMzYzUTNXMw0z" + "JjMjMyszSjM7M5wznTOeM44zjzPEM6Ez/////////////////////3sz//8dMB8wFiHNMyEhpDKlMqYypzKoMjEyMjI5Mn4z" + "fTN8M1IiYSIrIi4iESIaIqUiICIfIr8iNSIpIioi////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////+cThZVA1o/lsBUG2EoY/ZZ" + "IpB1hByDUHqqYOFjJW7tZWaEpoL1m5NoJ1ehZXFim1vQWXuG9Jhifb59jpsWYp98t4iJW7VeCWOXZkhox5WNl09n5U4KT01P" + "nU9JUPJWN1nUWQFaCVzfYA9hcGETZgVpunBPdXB1+3mtfe99w4AOhGOIAotVkHqQO1OVTqVO31eygMGQ73gATvFYom44kDJ6" + "KIOLgi+cQVFwU71U4VTgVvtZFV/ymOtt5IAthf////9ilnCWoJb7lwtU81OHW89wvX/Cj+iWb1Ncnbp6EU6TePyBJm4YVgRV" + "HWsahTuc5VmpU2Zt3HSPlUJWkU5LkPKWT4MMmeFTtlUwW3FfIGbzZgRoOGzzbCltW3TIdk56NJjxgluIYIrtkrJtq3XKdsWZ" + "pmABi4qNspWOaa1ThlH//xJXMFhEWbRb9l4oYKlj9GO/bBRvjnAUcVlx1XE/cwF+doLRgpeFYJBbkhudaVi8ZVpsJXX5US5Z" + "ZVmAX9xfvGL6ZSpqJ2u0a4tzwX9WiSydDp3EnqFclmx7gwRRS1y2YcaBdmhhcllO+k94U2lgKW5PevOXC04WU+5OVU89T6FP" + "c0+gUu9TCVYPWcFatlvhW9F5h2acZ7ZnTGuzbGtwwnONeb55PHqHe7GC24IEg3eD74PTg2aHsoopVqiM5o9OkB6XiobET+hc" + "EWJZcjt15YG9gv6GwIzFlhOZ1ZnLThpP44neVkpYylj7XutfKmCUYGJg0GESYtBiOWX/////QZtmZrBod21wcEx1hnZ1faWC" + "+YeLlY6WnYzxUb5SFlmzVLNbFl1oYYJpr22NeMuEV4hyiqeTuJpsbaiZ2YajV/9nzoYOkoNSh1YEVNNe4WK5ZDxoOGi7a3Jz" + "unhrepqJ0olrjQOP7ZCjlZSWaZdmW7NcfWlNmE6Ym2Mgeytq//9/arZoDZxfb3JSnVVwYOxiO20HbtFuW4QQiUSPFE45nPZT" + "G2k6aoSXKmhcUcN6soTckYyTW1YonSJoBYMxhKV8CFLFguZ0fk6DT6BR0lsKUthS51L7XZpVKljmWYxbmFvbW3JeeV6jYB9h" + "Y2G+YdtjYmXRZ1No+mg+a1NrV2wib5dvRW+wdBh143YLd/96oXshfOl9Nn/wf52AZoKeg7OJzIqrjISQUZSTlZGVopVlltOX" + "KJkYgjhOK1S4XMxdqXNMdjx3qVzrfwuNwZYRmFSYWJgBTw5PcVOcVWhW+ldHWQlbxFuQXAxefl7MX+5jOmfXZeJlH2fLaMRo" + "/////19qMF7FaxdsfWx/dUh5Y1sAegB9vV+PiRiKtIx3jcyOHY/imA6aPJuATn1QAFGTWZxbL2KAYuxkOmugcpF1R3mpf/uH" + "vIpwi6xjyoOglwlUA1SrVVRoWGpwiid4dWfNnnRTolsagVCGBpAYTkVOx04RT8pTOFSuWxNfJWBRZf//PWdCbHJs42x4cAN0" + "dnquegh7Gn3+fGZ952VbcrtTRVzoXdJi4GIZYyBuWoYxit2N+JIBb6Z5WpuoTqtOrE6bT6BP0VBHUfZ6cVH2UVRTIVN/U+tT" + "rFWDWOFcN19KXy9gUGBtYB9jWWVLasFswnLtcu93+IAFgQiCToX3kOGT/5dXmVqa8E7dUS1cgWZtaUBc8mZ1aYlzUGiBfMVQ" + "5FJHV/5dJpOkZSNrPWs0dIF5vXlLe8p9uYLMg3+IX4k5i9GP0ZEfVICSXU42UOVTOlPXcpZz6Xfmgq+OxpnImdKZd1EaYV6G" + "sFV6enZQ01tHkIWWMk7baueRUVxIXP////+YY596k2x0l2GPqnqKcYiWgnwXaHB+UWhsk/JSG1SrhROKpH/NjuGQZlOIiEF5" + "wk++UBFSRFFTVS1X6nOLV1FZYl+EX3VgdmFnYalhsmM6ZGxlb2ZCaBNuZnU9evt8TH2ZfUt+a38Og0qDzYYIimOKZov9jhqY" + "j524gs6P6Jv//4dSH2KDZMBvmZZBaJFQIGt6bFRvdHpQfUCII4oIZ/ZOOVAmUGVQfFE4UmNSp1UPVwVYzFr6XrJh+GHzYnJj" + "HGkpan1yrHIucxR4b3h5fQx3qYCLiRmL4ozSjmOQdZN6llWYE5p4nkNRn1OzU3teJl8bbpBuhHP+c0N9N4IAivqKUJZOTgtQ" + "5FN8VPpW0VlkW/Fdq14nXzhiRWWvZ1Zu0HLKfLSIoYDhgPCDToaHiuiNN5LHlmeYE5+UTpJODU9IU0lUPlQvWoxfoV+fYKdo" + "jmpadIF4noqkineLkJFeTsmbpE58T69PGVAWUElRbFGfUrlS/lKaU+NTEVT/////DlSJVVFXold9WVRbXVuPW+Vd5133XXhe" + "g16aXrdeGF9SYExhl2LYYqdjO2UCZkNm9GZtZyFol2jLaV9sKm1pbS9unW4ydYd2bHg/euB8BX0YfV59sX0VgAOAr4CxgFSB" + "j4EqglKDTIhhiBuLooz8jMqQdZFxkj94/JKklU2W//8FmJmZ2Jo7nVtSq1L3UwhU1Vj3YuBvaoxfj7meS1E7UkpU/VZAeneR" + "YJ3SnkRzCW9wgRF1/V/aYKia23K8j2RrA5jKTvBWZFe+WFpaaGDHYQ9mBmY5aLFo923VdTp9boJCm5tOUE/JUwZVb13mXe5d" + "+2eZbHN0AnhQipaT34hQV6deK2O1UKxQjVEAZ8lUXli7WbBbaV9NYqFjPWhzawhufXDHkYByFXgmeG15jmUwfdyDwYgJj5uW" + "ZFIoV1Bnan+hjLRRQlcqljpYimm0gLJUDl38V5V4+p1cT0pSi1Q+ZChmFGf1Z4R6VnsifS+TXGitmzl7GVOKUTdS/////99b" + "9mKuZOZkLWe6a6mF0ZaQdtabTGMGk6ubv3ZSZglOmFDCU3Fc6GCSZGNlX2jmccpzI3WXe4J+lYaDi9uMeJEQmaxlq2aLa9VO" + "1E46T39POlL4U/JT41XbVutYy1nJWf9ZUFtNXAJeK17XXx1gB2MvZVxbr2W9ZehlnWdia///e2sPbEVzSXnBefh8GX0rfaKA" + "AoHzgZaJXoppimaKjIruiseM3IzMlvyYb2uLTjxPjU9QUVdb+ltIYQFjQmYha8tuu2w+cr101HXBeDp5DIAzgOqBlISej1Bs" + "f54PX1iLK536eviOjVvrlgNO8VP3VzFZyVqkW4lgf24Gb7516oyfWwCF4HtyUPRnnYJhXEqFHn4OgplRBFxoY2aNnGVucT55" + "F30FgB2Lyo5ukMeGqpAfUPpSOlxTZ3xwNXJMkciRK5PlgsJbMV/5YDtO1lOIW0tiMWeKa+ly4HMuemuBo41SkZaZElHXU2pU" + "/1uIYzlqrH0Al9pWzlNoVP////+XWzFc3l3uTwFh/mIybcB5y3lCfU1+0n/tgR+CkIRGiHKJkIt0ji+PMZBLkWyRxpackcBO" + "T09FUUFTk18OYtRnQWwLbmNzJn7NkYOS1FMZWb9b0W1deS5+m3x+WJ9x+lFTiPCPyk/7XCVmrHfjehyC/5nGUapf7GVvaYlr" + "823//5ZuZG/+dhR94V11kIeRBpjmUR1SQGKRZtlmGm62XtJ9cn/4Zq+F94X4iqlS2VNzWY9ekF9VYOSSZJa3UB9R3VIgU0dT" + "7FPoVEZVMVUXVmhZvlk8WrVbBlwPXBFcGlyEXope4F5wX39ihGLbYoxjd2MHZgxmLWZ2Zn5nomgfajVqvGyIbQluWG48cSZx" + "Z3HHdQF3XXgBeWV58HngehF7p3w5fZaA1oOLhEmFXYjziB+KPIpUinOKYYzejKSRZpJ+kxiUnJaYlwpOCE4eTldOl1FwUs5X" + "NFjMWCJbOF7FYP5kYWdWZ0RttnJzdWN6uIRyi7iRIJMxVvRX/pj/////7WINaZZr7XFUfneAcoLmid+YVYexjztcOE/hT7VP" + "B1UgWt1b6VvDX05hL2OwZUtm7mibaXht8W0zdbl1H3deeeZ5M33jga+CqoWqiTqKq46bjzKQ3ZEHl7pOwU4DUnVY7FgLXBp1" + "PVxOgQqKxY9jlm2XJXvPigiYYpHzVqhT//8XkDlUglclXqhjNGyKcGF3i3zgf3CIQpBUkRCTGJOPll50xJoHXWldcGWiZ6iN" + "25ZuY0lnGWnFgxeYwJb+iIRvemT4WxZOLHBddS9mxFE2UuJS01mBXydgEGI/ZXRlH2Z0ZvJoFmhjawVucnIfddt2vnxWgPBY" + "/Yh/iaCKk4rLih2QkpFSl1mXiWUOegaBu5YtXtxgGmKlZRRmkGfzd016TXw+fgqBrIxkjeGNX46peAdS2WKlY0JkmGItioN6" + "wHusiuqWdn0MgkmH2U5IUUNTYFOjWwJcFlzdXSZiR2KwZBNoNGjJbEVtF23TZ1xvTnF9cctlf3qte9p9/////0p+qH96gRuC" + "OYKmhW6Kzoz1jXiQd5CtkpGSg5Wum01ShFU4bzZxaFGFeVV+s4HOfExWUVioXKpj/mb9Zlpp2XKPdY51DnlWed95l3wgfUR9" + "B4Y0ijuWYZAgn+dQdVLMU+JTCVCqVe5YT1k9cotbZFwdU+Ng82BcY4NjP2O7Y///zWTpZflm413Naf1pFW/lcYlO6XX4dpN6" + "33zPfZx9YYBJg1iDbIS8hPuFxYhwjQGQbZCXkxyXEprPUJdYjmHTgTWFCI0gkMNPdFBHUnNTb2BJY19nLG6zjR+Q109eXMqM" + "z2WafVJTloh2UcNjWFtrWwpcDWRRZ1yQ1k4aWSpZcGxRij5VFVilWfBgU2LBZzWCVWlAlsSZKJpTTwZY/lsQgLFcL16FXyBg" + "S2E0Yv9m8Gzebs6Af4HUgouIuIwAkC6Qipbbntub407wUydZLHuNkUyY+Z3dbidwU1NEVYVbWGKeYtNiomzvbyJ0F4o4lMFv" + "/oo4g+dR+IbqU//////pU0ZPVJCwj2pZMYH9Xep6v4/aaDeM+HJInD1qsIo5TlhTBlZmV8ViomPmZU5r4W1bbq1w7Xfveqp7" + "u309gMaAy4aViluT41bHWD5frWWWZoBqtWs3dceKJFDldzBXG19lYHpmYGz0dRp6bn/0gRiHRZCzmcl7XHX5elF7xIT//xCQ" + "6XmSejaD4VpAdy1O8k6ZW+BfvWI8ZvFn6GxrhneIO4pOkfOS0JkXaiZwKnPngleEr4wBTkZRy1GLVfVbFl4zXoFeFF81X2tf" + "tF/yYRFjomYdZ25vUnI6dTp3dIA5gXiBdoe/ityKhY3zjZqSd5UCmOWcxVJXY/R2FWeIbM1zw4yuk3OWJW2cWA5pzGn9j5qT" + "23UakFpYAmi0Y/tpQ08sb9hnu48mhbR9VJM/aXBvalf3WCxbLH0qcgpU45G0na1OTk9cUHVQQ1KejEhUJFiaWx1elV6tXvde" + "H1+MYLViOmPQY69oQGyHeI55C3rgfUeCAormikSOE5D/////uJAtkdiRDp/lbFhk4mR1ZfRuhHYbe2mQ0ZO6bvJUuV+kZE2P" + "7Y9EknhRa1gpWVVcl177bY9+HHW8jOKOW5i5cB1Pv2uxbzB1+5ZOURBUNVhXWKxZYFySX5dlXGchbnt234PtjBSQ/ZBNkyV4" + "OniqUqZeH1d0WRJgElBaUaxR///NUQBSEFVUWFhYV1mVW/Zci128YJViLWRxZ0NovGjfaNd22G1vbpttb3DIcVNf2HV3eUl7" + "VHtSe9Z8cX0wUmOEaYXkhQ6KBItGjA+OA5APkBmUdpYtmDCa2JXNUNVSDFQCWA5cp2GeZB5ts3flevSABIRTkIWS4FwHnT9T" + "l1+zX5xteXJjd7955HvSa+xyrYoDaGFq+FGBejRpSlz2nOuCxVtJkR5weFZvXMdgZmWMbFqMQZATmFFUx2YNkkhZo5CFUU1O" + "6lGZhQ6LWHB6Y0uTYmm0mQR+d3VXU2Bp347jll1sjE48XBBf6Y8CU9GMiYB5hv9e5WVzTmVR/////4JZP1zul/tOilnNX42K" + "4W+weWJ551txhCtzsXF0XvVfe2OaZMNxmHxDTvxeS07cV6JWqWDDbw19/YAzgb+Bso+XiaSG9F2KYq1kh4l3Z+JsPm02dDR4" + "Rlp1f62CrJnzT8Ne3WKSY1dlb2fDdkxyzIC6gCmPTZENUPlXklqFaP//c2lkcf1yt4zyWOCMapYZkH+H5HnndymEL09lUlpT" + "zWLPZ8psfXaUe5V8NoKEheuP3WYgbwZyG36rg8GZpp79UbF7cni4e4eASHvoamFejIBRdWB1a1FikoxuenaXkeqaEE9wf5xi" + "T3ullemcelZZWOSGvJY0TyRSSlPNU9tTBl4sZJFlf2c+bE5sSHKvcu1zVHVBfiyC6YWpjMR7xpFpcRKY75g9Y2lmanXkdtB4" + "Q4XuhipTUVMmVINZh158X7JgSWJ5YqtikGXUa8xssnWudpF42HnLfXd/pYCriLmKu4x/kF6X25gLajh8mVA+XK5fh2fYazV0" + "CXeOf/////87n8pnF3o5U4t17ZpmX52B8YOYgDxfxV9idUZ7PJBnaOtZm1oQfX52LIv1T2pfGWo3bAJv4nRoeWiIVYp5jN9e" + "z2PFddJ514Iok/KSnITthi2cwVRsX4xlXG0VcKeM04w7mE9l9nQNTthO4FcrWWZazFuoUQNenF4WYHZid2X//6dlbmZubTZy" + "JntQgZqBmYJci6CM5ox0jRyWRJauT6tkZmsegmGEaoXokAFcU2momHqEV4UPT29SqV9FXg1nj3l5gQeJhon1bRdfVWK4bM9O" + "aXKSmwZSO1R0VrNYpGFuYhpxblmJfN58G33wlodlXoAZTnVPdVFAWGNec14KX8RnJk49hYmVW5ZzfAGY+1DBWFZ2p3glUqV3" + "EYWGe09QCVlHcsd76H26j9SPTZC/T8lSKVoBX62X3U8XguqSA1dVY2lrK3XciBSPQnrfUpNYVWEKYq5mzWs/fOmDI1D4TwVT" + "RlQxWElZnVvwXO9cKV2WXrFiZ2M+ZbllC2f/////1WzhbPlwMngrft6As4IMhOyEAocSiSqKSoymkNKS/ZjznGydT06hTo1Q" + "VlJKV6hZPV7YX9lfP2K0Zhtn0GfSaJJRIX2qgKiBAIuMjL+MfpIyliBULJgXU9VQXFOoWLJkNGdncmZ3RnrmkcNSoWyGawBY" + "TF5UWSxn+3/hUcZ2//9pZOh4VJu7nstXuVknZppnzmvpVNlpVV6cgZVnqpv+Z1KcXWimTuNPyFO5Yitnq2zEj61PbX6/ngdO" + "YmGAbitvE4VzVCpnRZvzXZV7rFzGWxyHSm7RhBR6CIGZWY18EWwgd9lSIlkhcV9y23cnl2GdC2l/WhhapVENVH1UDmbfdveP" + "mJL0nOpZXXLFbk1RyWi/fex9Ype6nnhkIWoCg4RZX1vbaxtz8nayfReAmYQyUShn2Z7udmJn/1IFmSRcO2J+fLCMT1W2YAt9" + "gJUBU19OtlEcWTpyNoDOkSVf4neEU3lfBH2shTOKjY5Wl/NnroVTlAlhCGG5bFJ2/////+2KOI8vVVFPKlHHUstTpVt9XqBg" + "gmHWYwln2mdnboxtNnM3czF1UHnViJiKSpCRkPWQxJaNhxVZiE5ZTw5OiYo/jxCYrVB8XpZZuVu4Xtpj+mPBZNxmSmnYaQtt" + "tm6UcSh1r3qKfwCASYTJhIGJIYsKjmWQfZYKmX5hkWIya///g2x0bcx//H/AbYV/uof4iGVnsYM8mPeWG21hfT2EapFxTnVT" + "UF0Ea+tvzYUthqeJKVIPVGVcTmeoaAZ0g3Tidc+I4YjMkeKWeJaLX4dzy3pOhKBjZXWJUkFtnG4JdFl1a3iSfIaW3HqNn7ZP" + "bmHFZVyGhk6uTtpQIU7MUe5bmWWBaLxtH3NCdq13HHrnfG+C0op8kM+RdZYYmJtS0X0rUJhTl2fLbdBxM3TogSqPo5ZXnJ+e" + "YHRBWJltL31emORONk+LT7dRsVK6XRxgsnM8edOCNJK3lvaWCpeXnmKfpmZ0axdSo1LIcMKIyV5LYJBhI29JcT589H1vgP//" + "///uhCOQLJNCVG+b02qJcMKM740yl7RSQVrKXgRfF2d8aZRpam0Pb2Jy/HLtewGAfoBLh86QbVGTnoR5i4Ayk9aKLVCMVHGK" + "amvEjAeB0WCgZ/KdmU6YThCca4rBhWiFAGl+bpd4VYH/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////DF8QThVOKk4xTjZOPE4/TkJOVk5YToJO" + "hU5rjIpOEoINX45Onk6fTqBOok6wTrNOtk7OTs1OxE7GTsJO107eTu1O3073TglPWk8wT1tPXU9XT0dPdk+IT49PmE97T2lP" + "cE+RT29Phk+WTxhR1E/fT85P2E/bT9FP2k/QT+RP5U8aUChQFFAqUCVQBVAcT/ZPIVApUCxQ/k/vTxFQBlBDUEdQA2dVUFBQ" + "SFBaUFZQbFB4UIBQmlCFULRQslD/////yVDKULNQwlDWUN5Q5VDtUONQ7lD5UPVQCVEBUQJRFlEVURRRGlEhUTpRN1E8UTtR" + "P1FAUVJRTFFUUWJR+HppUWpRblGAUYJR2FaMUYlRj1GRUZNRlVGWUaRRplGiUalRqlGrUbNRsVGyUbBRtVG9UcVRyVHbUeBR" + "VYbpUe1R///wUfVR/lEEUgtSFFIOUidSKlIuUjNSOVJPUkRSS1JMUl5SVFJqUnRSaVJzUn9SfVKNUpRSklJxUohSkVKoj6eP" + "rFKtUrxStVLBUs1S11LeUuNS5lLtmOBS81L1UvhS+VIGUwhTOHUNUxBTD1MVUxpTI1MvUzFTM1M4U0BTRlNFUxdOSVNNU9ZR" + "XlNpU25TGFl7U3dTglOWU6BTplOlU65TsFO2U8NTEnzZlt9T/Gbuce5T6FPtU/pTAVQ9VEBULFQtVDxULlQ2VClUHVROVI9U" + "dVSOVF9UcVR3VHBUklR7VIBUdlSEVJBUhlTHVKJUuFSlVKxUxFTIVKhU/////6tUwlSkVL5UvFTYVOVU5lQPVRRV/VTuVO1U" + "+lTiVDlVQFVjVUxVLlVcVUVVVlVXVThVM1VdVZlVgFWvVIpVn1V7VX5VmFWeVa5VfFWDValVh1WoVdpVxVXfVcRV3FXkVdRV" + "FFb3VRZW/lX9VRtW+VVOVlBW33E0VjZWMlY4Vv//a1ZkVi9WbFZqVoZWgFaKVqBWlFaPVqVWrla2VrRWwla8VsFWw1bAVshW" + "zlbRVtNW11buVvlWAFf/VgRXCVcIVwtXDVcTVxhXFlfHVRxXJlc3VzhXTlc7V0BXT1dpV8BXiFdhV39XiVeTV6BXs1ekV6pX" + "sFfDV8ZX1FfSV9NXCljWV+NXC1gZWB1YclghWGJYS1hwWMBrUlg9WHlYhVi5WJ9Yq1i6WN5Yu1i4WK5YxVjTWNFY11jZWNhY" + "5VjcWORY31jvWPpY+Vj7WPxY/VgCWQpZEFkbWaZoJVksWS1ZMlk4WT5Z0npVWVBZTllaWVhZYllgWWdZbFlpWf////94WYFZ" + "nVleT6tPo1myWcZZ6FncWY1Z2VnaWSVaH1oRWhxaCVoaWkBabFpJWjVaNlpiWmpamlq8Wr5ay1rCWr1a41rXWuZa6VrWWvpa" + "+1oMWwtbFlsyW9BaKls2Wz5bQ1tFW0BbUVtVW1pbW1tlW2lbcFtzW3VbeFuIZXpbgFv//4Nbplu4W8Nbx1vJW9Rb0FvkW+Zb" + "4lveW+Vb61vwW/Zb81sFXAdcCFwNXBNcIFwiXChcOFw5XEFcRlxOXFNcUFxPXHFbbFxuXGJOdlx5XIxckVyUXJtZq1y7XLZc" + "vFy3XMVcvlzHXNlc6Vz9XPpc7VyMXepcC10VXRddXF0fXRtdEV0UXSJdGl0ZXRhdTF1SXU5dS11sXXNddl2HXYRdgl2iXZ1d" + "rF2uXb1dkF23XbxdyV3NXdNd0l3WXdtd613yXfVdC14aXhleEV4bXjZeN15EXkNeQF5OXldeVF5fXmJeZF5HXnVedl56Xrye" + "f16gXsFewl7IXtBez17/////1l7jXt1e2l7bXuJe4V7oXule7F7xXvNe8F70Xvhe/l4DXwlfXV9cXwtfEV8WXylfLV84X0Ff" + "SF9MX05fL19RX1ZfV19ZX2FfbV9zX3dfg1+CX39fil+IX5Ffh1+eX5lfmF+gX6hfrV+8X9Zf+1/kX/hf8V/dX7Ng/18hYGBg" + "//8ZYBBgKWAOYDFgG2AVYCtgJmAPYDpgWmBBYGpgd2BfYEpgRmBNYGNgQ2BkYEJgbGBrYFlggWCNYOdgg2CaYIRgm2CWYJdg" + "kmCnYItg4WC4YOBg02C0YPBfvWDGYLVg2GBNYRVhBmH2YPdgAGH0YPpgA2EhYftg8WANYQ5hR2E+YShhJ2FKYT9hPGEsYTRh" + "PWFCYURhc2F3YVhhWWFaYWthdGFvYWVhcWFfYV1hU2F1YZlhlmGHYaxhlGGaYYphkWGrYa5hzGHKYclh92HIYcNhxmG6Ycth" + "eX/NYeZh42H2Yfph9GH/Yf1h/GH+YQBiCGIJYg1iDGIUYhti/////x5iIWIqYi5iMGIyYjNiQWJOYl5iY2JbYmBiaGJ8YoJi" + "iWJ+YpJik2KWYtRig2KUYtdi0WK7Ys9i/2LGYtRkyGLcYsxiymLCYsdim2LJYgxj7mLxYidjAmMIY+9i9WJQYz5jTWMcZE9j" + "lmOOY4Bjq2N2Y6Njj2OJY59jtWNrY///aWO+Y+ljwGPGY+NjyWPSY/ZjxGMWZDRkBmQTZCZkNmQdZRdkKGQPZGdkb2R2ZE5k" + "KmWVZJNkpWSpZIhkvGTaZNJkxWTHZLtk2GTCZPFk52QJguBk4WSsYuNk72QsZfZk9GTyZPpkAGX9ZBhlHGUFZSRlI2UrZTRl" + "NWU3ZTZlOGVLdUhlVmVVZU1lWGVeZV1lcmV4ZYJlg2WKi5tln2WrZbdlw2XGZcFlxGXMZdJl22XZZeBl4WXxZXJnCmYDZvtl" + "c2c1ZjZmNGYcZk9mRGZJZkFmXmZdZmRmZ2ZoZl9mYmZwZoNmiGaOZolmhGaYZp1mwWa5Zslmvma8Zv/////EZrhm1mbaZuBm" + "P2bmZulm8Gb1ZvdmD2cWZx5nJmcnZziXLmc/ZzZnQWc4ZzdnRmdeZ2BnWWdjZ2RniWdwZ6lnfGdqZ4xni2emZ6FnhWe3Z+9n" + "tGfsZ7Nn6We4Z+Rn3mfdZ+Jn7me5Z85nxmfnZ5xqHmhGaCloQGhNaDJoTmj//7NoK2hZaGNod2h/aJ9oj2itaJRonWibaINo" + "rmq5aHRotWigaLpoD2mNaH5oAWnKaAhp2GgiaSZp4WgMac1o1GjnaNVoNmkSaQRp12jjaCVp+WjgaO9oKGkqaRppI2khacZo" + "eWl3aVxpeGlraVRpfmluaTlpdGk9aVlpMGlhaV5pXWmBaWppsmmuadBpv2nBadNpvmnOaehbymndabtpw2mnaS5qkWmgaZxp" + "lWm0ad5p6GkCahtq/2kKa/lp8mnnaQVqsWkeau1pFGrraQpqEmrBaiNqE2pEagxqcmo2anhqR2piallqZmpIajhqImqQao1q" + "oGqEaqJqo2r/////l2oXhrtqw2rCarhqs2qsat5q0Wrfaqpq2mrqavtqBWsWhvpqEmsWazGbH2s4azdr3HY5a+6YR2tDa0lr" + "UGtZa1RrW2tfa2FreGt5a39rgGuEa4NrjWuYa5Vrnmuka6prq2uva7JrsWuza7drvGvGa8tr02vfa+xr62vza+9r//++nghs" + "E2wUbBtsJGwjbF5sVWxibGpsgmyNbJpsgWybbH5saGxzbJJskGzEbPFs02y9bNdsxWzdbK5ssWy+bLps22zvbNls6mwfbU2I" + "Nm0rbT1tOG0ZbTVtM20SbQxtY22TbWRtWm15bVltjm2VbeRvhW35bRVuCm61bcdt5m24bcZt7G3ebcxt6G3SbcVt+m3ZbeRt" + "1W3qbe5tLW5ubi5uGW5ybl9uPm4jbmtuK252bk1uH25DbjpuTm4kbv9uHW44boJuqm6Ybslut27Tbr1ur27EbrJu1G7Vbo9u" + "pW7Cbp9uQW8Rb0xw7G74bv5uP2/ybjFv724yb8xu////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//8+bxNv926Gb3pveG+Bb4Bvb29bb/NvbW+Cb3xvWG+Ob5Fvwm9mb7Nvo2+hb6RvuW/Gb6pv32/Vb+xv1G/Yb/Fv7m/bbwlw" + "C3D6bxFwAXAPcP5vG3AacHRvHXAYcB9wMHA+cDJwUXBjcJlwknCvcPFwrHC4cLNwrnDfcMtw3XD//9lwCXH9cBxxGXFlcVVx" + "iHFmcWJxTHFWcWxxj3H7cYRxlXGocaxx13G5cb5x0nHJcdRxznHgcexx53H1cfxx+XH/cQ1yEHIbcihyLXIscjByMnI7cjxy" + "P3JAckZyS3JYcnRyfnKCcoFyh3KScpZyonKncrlysnLDcsZyxHLOctJy4nLgcuFy+XL3cg9QF3MKcxxzFnMdczRzL3MpcyVz" + "PnNOc09z2J5Xc2pzaHNwc3hzdXN7c3pzyHOzc85zu3PAc+Vz7nPec6J0BXRvdCV0+HMydDp0VXQ/dF90WXRBdFx0aXRwdGN0" + "anR2dH50i3SedKd0ynTPdNR08XP/////4HTjdOd06XTudPJ08HTxdPh093QEdQN1BXUMdQ51DXUVdRN1HnUmdSx1PHVEdU11" + "SnVJdVt1RnVadWl1ZHVndWt1bXV4dXZ1hnWHdXR1inWJdYJ1lHWadZ11pXWjdcJ1s3XDdbV1vXW4dbx1sXXNdcp10nXZdeN1" + "3nX+df91///8dQF28HX6dfJ183ULdg12CXYfdid2IHYhdiJ2JHY0djB2O3ZHdkh2RnZcdlh2YXZidmh2aXZqdmd2bHZwdnJ2" + "dnZ4dnx2gHaDdoh2i3aOdpZ2k3aZdpp2sHa0drh2uXa6dsJ2zXbWdtJ23nbhduV253bqdi+G+3YIdwd3BHcpdyR3HncldyZ3" + "G3c3dzh3R3dad2h3a3dbd2V3f3d+d3l3jneLd5F3oHeed7B3tne5d793vHe9d7t3x3fNd9d32nfcd+N37nf8dwx4EngmeSB4" + "KnlFeI54dHiGeHx4mniMeKN4tXiqeK940XjGeMt41Hi+eLx4xXjKeOx4/////+d42nj9ePR4B3kSeRF5GXkseSt5QHlgeVd5" + "X3laeVV5U3l6eX95inmdead5S5+qea55s3m5ebp5yXnVeed57HnheeN5CHoNehh6GXogeh96gHkxejt6Pno3ekN6V3pJemF6" + "Ynppep2fcHp5en16iHqXepV6mHqWeql6yHqwev//tnrFesR6v3qDkMd6ynrNes961XrTetl62nrdeuF64nrmeu168HoCew97" + "CnsGezN7GHsZex57NXsoezZ7UHt6ewR7TXsLe0x7RXt1e2V7dHtne3B7cXtse257nXuYe597jXuce5p7i3uSe497XXuZe8t7" + "wXvMe897tHvGe9176XsRfBR85nvle2B8AHwHfBN883v3exd8DXz2eyN8J3wqfB98N3wrfD18THxDfFR8T3xAfFB8WHxffGR8" + "VnxlfGx8dXyDfJB8pHytfKJ8q3yhfKh8s3yyfLF8rny5fL18wHzFfMJ82HzSfNx84nw7m+988nz0fPZ8+nwGff////8CfRx9" + "FX0KfUV9S30ufTJ9P301fUZ9c31WfU59cn1ofW59T31jfZN9iX1bfY99fX2bfbp9rn2jfbV9x329fat9PX6ifa993H24fZ99" + "sH3Yfd195H3efft98n3hfQV+Cn4jfiF+En4xfh9+CX4LfiJ+Rn5mfjt+NX45fkN+N37//zJ+On5nfl1+Vn5efll+Wn55fmp+" + "aX58fnt+g37VfX1+ro9/foh+iX6MfpJ+kH6TfpR+ln6Ofpt+nH44fzp/RX9Mf01/Tn9Qf1F/VX9Uf1h/X39gf2h/aX9nf3h/" + "gn+Gf4N/iH+Hf4x/lH+ef51/mn+jf69/sn+5f65/tn+4f3GLxX/Gf8p/1X/Uf+F/5n/pf/N/+X/cmAaABIALgBKAGIAZgByA" + "IYAogD+AO4BKgEaAUoBYgFqAX4BigGiAc4BygHCAdoB5gH2Af4CEgIaAhYCbgJOAmoCtgJBRrIDbgOWA2YDdgMSA2oDWgAmB" + "74DxgBuBKYEjgS+BS4H/////i5ZGgT6BU4FRgfyAcYFugWWBZoF0gYOBiIGKgYCBgoGggZWBpIGjgV+Bk4GpgbCBtYG+gbiB" + "vYHAgcKBuoHJgc2B0YHZgdiByIHagd+B4IHngfqB+4H+gQGCAoIFggeCCoINghCCFoIpgiuCOIIzgkCCWYJYgl2CWoJfgmSC" + "//9igmiCaoJrgi6CcYJ3gniCfoKNgpKCq4KfgruCrILhguOC34LSgvSC84L6gpODA4P7gvmC3oIGg9yCCYPZgjWDNIMWgzKD" + "MYNAgzmDUINFgy+DK4MXgxiDhYOag6qDn4Oig5aDI4OOg4eDioN8g7WDc4N1g6CDiYOog/SDE4Trg86D/YMDhNiDC4TBg/eD" + "B4Tgg/KDDYQihCCEvYM4hAaF+4NthCqEPIRahYSEd4RrhK2EboSChGmERoQshG+EeYQ1hMqEYoS5hL+En4TZhM2Eu4TahNCE" + "wYTGhNaEoYQhhf+E9IQXhRiFLIUfhRWFFIX8hECFY4VYhUiF/////0GFAoZLhVWFgIWkhYiFkYWKhaiFbYWUhZuF6oWHhZyF" + "d4V+hZCFyYW6hc+FuYXQhdWF3YXlhdyF+YUKhhOGC4b+hfqFBoYihhqGMIY/hk2GVU5Uhl+GZ4ZxhpOGo4aphqqGi4aMhraG" + "r4bEhsaGsIbJhiOIq4bUht6G6Ybshv//34bbhu+GEocGhwiHAIcDh/uGEYcJhw2H+YYKhzSHP4c3hzuHJYcphxqHYIdfh3iH" + "TIdOh3SHV4doh26HWYdTh2OHaocFiKKHn4eCh6+Hy4e9h8CH0IfWlquHxIezh8eHxoe7h++H8ofghw+IDYj+h/aH94cOiNKH" + "EYgWiBWIIoghiDGINog5iCeIO4hEiEKIUohZiF6IYohriIGIfoieiHWIfYi1iHKIgoiXiJKIroiZiKKIjYikiLCIv4ixiMOI" + "xIjUiNiI2YjdiPmIAon8iPSI6IjyiASJDIkKiROJQ4keiSWJKokriUGJRIk7iTaJOIlMiR2JYIleif////9miWSJbYlqiW+J" + "dIl3iX6Jg4mIiYqJk4mYiaGJqYmmiayJr4myibqJvYm/icCJ2oncid2J54n0ifiJA4oWihCKDIobih2KJYo2ikGKW4pSikaK" + "SIp8im2KbIpiioWKgoqEiqiKoYqRiqWKpoqaiqOKxIrNisKK2orrivOK54r//+SK8YoUi+CK4or3it6K24oMiweLGovhihaL" + "EIsXiyCLM4urlyaLK4s+iyiLQYtMi0+LTotJi1aLW4tai2uLX4tsi2+LdIt9i4CLjIuOi5KLk4uWi5mLmos6jEGMP4xIjEyM" + "ToxQjFWMYoxsjHiMeoyCjImMhYyKjI2MjoyUjHyMmIwdYq2Mqoy9jLKMs4yujLaMyIzBjOSM44zajP2M+oz7jASNBY0KjQeN" + "D40NjRCNTp8Tjc2MFI0WjWeNbY1xjXONgY2ZjcKNvo26jc+N2o3WjcyN243LjeqN643fjeON/I0IjgmO/40djh6OEI4fjkKO" + "NY4wjjSOSo7/////R45JjkyOUI5IjlmOZI5gjiqOY45VjnaOco58joGOh46FjoSOi46KjpOOkY6UjpmOqo6hjqyOsI7GjrGO" + "vo7FjsiOy47bjuOO/I77juuO/o4KjwWPFY8SjxmPE48cjx+PG48MjyaPM487jzmPRY9Cjz6PTI9Jj0aPTo9Xj1yP//9ij2OP" + "ZI+cj5+Po4+tj6+Pt4/aj+WP4o/qj++Ph5D0jwWQ+Y/6jxGQFZAhkA2QHpAWkAuQJ5A2kDWQOZD4j0+QUJBRkFKQDpBJkD6Q" + "VpBYkF6QaJBvkHaQqJZykIKQfZCBkICQipCJkI+QqJCvkLGQtZDikOSQSGLbkAKREpEZkTKRMJFKkVaRWJFjkWWRaZFzkXKR" + "i5GJkYKRopGrka+RqpG1kbSRupHAkcGRyZHLkdCR1pHfkeGR25H8kfWR9pEekv+RFJIskhWSEZJekleSRZJJkmSSSJKVkj+S" + "S5JQkpySlpKTkpuSWpLPkrmSt5Lpkg+T+pJEky6T/////xmTIpMakyOTOpM1kzuTXJNgk3yTbpNWk7CTrJOtk5STuZPWk9eT" + "6JPlk9iTw5Pdk9CTyJPkkxqUFJQTlAOUB5QQlDaUK5Q1lCGUOpRBlFKURJRblGCUYpRelGqUKZJwlHWUd5R9lFqUfJR+lIGU" + "f5SClYeVipWUlZaVmJWZlf//oJWolaeVrZW8lbuVuZW+lcqV9m/Dlc2VzJXVldSV1pXcleGV5ZXilSGWKJYuli+WQpZMlk+W" + "S5Z3llyWXpZdll+WZpZylmyWjZaYlpWWl5aqlqeWsZaylrCWtJa2lriWuZbOlsuWyZbNlk2J3JYNl9WW+ZYElwaXCJcTlw6X" + "EZcPlxaXGZcklyqXMJc5lz2XPpdEl0aXSJdCl0mXXJdgl2SXZpdol9JSa5dxl3mXhZd8l4GXepeGl4uXj5eQl5yXqJeml6OX" + "s5e0l8OXxpfIl8uX3Jftl0+f8pffevaX9ZcPmAyYOJgkmCGYN5g9mEaYT5hLmGuYb5hwmP////9xmHSYc5iqmK+YsZi2mMSY" + "w5jGmOmY65gDmQmZEpkUmRiZIZkdmR6ZJJkgmSyZLpk9mT6ZQplJmUWZUJlLmVGZUplMmVWZl5mYmaWZrZmumbyZ35nbmd2Z" + "2JnRme2Z7pnxmfKZ+5n4mQGaD5oFmuKZGZormjeaRZpCmkCaQ5r//z6aVZpNmluaV5pfmmKaZZpkmmmaa5pqmq2asJq8msCa" + "z5rRmtOa1Jremt+a4prjmuaa75rrmu6a9Jrxmvea+5oGmxibGpsfmyKbI5slmyebKJspmyqbLpsvmzKbRJtDm0+bTZtOm1Gb" + "WJt0m5Obg5uRm5abl5ufm6CbqJu0m8Cbypu5m8abz5vRm9Kb45vim+Sb1Jvhmzqc8pvxm/CbFZwUnAmcE5wMnAacCJwSnAqc" + "BJwunBucJZwknCGcMJxHnDKcRpw+nFqcYJxnnHaceJznnOyc8JwJnQid65wDnQadKp0mna+dI50fnUSdFZ0SnUGdP50+nUad" + "SJ3/////XZ1enWSdUZ1QnVmdcp2JnYedq51vnXqdmp2knamdsp3EncGdu524nbqdxp3PncKd2Z3Tnfid5p3tne+d/Z0anhue" + "Hp51nnmefZ6Bnoiei56MnpKelZ6Rnp2epZ6pnrieqp6tnmGXzJ7Ons+e0J7Untye3p7dnuCe5Z7onu+e///0nvae9575nvue" + "/J79ngefCJ+3dhWfIZ8snz6fSp9Sn1SfY59fn2CfYZ9mn2efbJ9qn3efcp92n5WfnJ+gny9Yx2lZkGR03FGZcf//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "in4ciUiTiJLchMlPu3AxZsho+ZL7ZkVfKE7hTvxOAE8DTzlPVk+ST4pPmk+UT81PQFAiUP9PHlBGUHBQQlCUUPRQ2FBKUWRR" + "nVG+UexRFVKcUqZSwFLbUgBTB1MkU3JTk1OyU91TDvqcVIpUqVT/VIZVWVdlV6xXyFfHVw/6//8Q+p5YslgLWVNZW1ldWWNZ" + "pFm6WVZbwFsvddhb7FseXKZculz1XCddU10R+kJdbV24Xbld0F0hXzRfZ1+3X95fXWCFYIpg3mDVYCBh8mARYTdhMGGYYRNi" + "pmL1Y2BknWTOZE5lAGYVZjtmCWYuZh5mJGZlZldmWWYS+nNmmWagZrJmv2b6Zg5nKflmZ7tnUmjAZwFoRGjPaBP6aGkU+php" + "4mkwamtqRmpzan5q4mrkatZrP2xcbIZsb2zabARth21vbZZtrG3Pbfht8m38bTluXG4nbjxuv26Ib7Vv9W8FcAdwKHCFcKtw" + "D3EEcVxxRnFHcRX6wXH+cbFy/////75yJHMW+ndzvXPJc9Zz43PScwd09XMmdCp0KXQudGJ0iXSfdAF1b3WCdpx2nnabdqZ2" + "F/pGd69SIXhOeGR4engweRj6Gfoa+pR5G/qbedF653oc+ut6nnsd+kh9XH23faB91n1Sfkd/oX8e+gGDYoN/g8eD9oNIhLSE" + "U4VZhf//a4Uf+rCFIPoh+geI9YgSijeKeYqnir6K34oi+vaKU4t/i/CM9IwSjXaNI/rPjiT6JfpnkN6QJvoVkSeR2pHXkd6R" + "7ZHukeSR5ZEGkhCSCpI6kkCSPJJOklmSUZI5kmeSp5J3kniS55LXktmS0JIn+tWS4JLTkiWTIZP7kij6HpP/kh2TApNwk1eT" + "pJPGk96T+JMxlEWUSJSSldz5Kfqdlq+WM5c7l0OXTZdPl1GXVZdXmGWYKvor+ieZLPqemU6a2ZrcmnWbcpuPm7Gbu5sAnHCd" + "a50t+hme0Z7/////cCFxIXIhcyF0IXUhdiF3IXgheSHi/+T/B/8C////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////AOAB4ALg" + "A+AE4AXgBuAH4AjgCeAK4AvgDOAN4A7gD+AQ4BHgEuAT4BTgFeAW4BfgGOAZ4BrgG+Ac4B3gHuAf4CDgIeAi4CPgJOAl4Cbg" + "J+Ao4CngKuAr4CzgLeAu4C/gMOAx4DLgM+A04DXgNuA34DjgOeA64DvgPOA94D7g//8/4EDgQeBC4EPgROBF4EbgR+BI4Eng" + "SuBL4EzgTeBO4E/gUOBR4FLgU+BU4FXgVuBX4FjgWeBa4FvgXOBd4F7gX+Bg4GHgYuBj4GTgZeBm4GfgaOBp4Grga+Bs4G3g" + "buBv4HDgceBy4HPgdOB14Hbgd+B44HngeuB74HzgfeB+4H/ggOCB4ILgg+CE4IXghuCH4IjgieCK4IvgjOCN4I7gj+CQ4JHg" + "kuCT4JTgleCW4JfgmOCZ4Jrgm+Cc4J3gnuCf4KDgoeCi4KPgpOCl4Kbgp+Co4KngquCr4KzgreCu4K/gsOCx4LLgs+C04LXg" + "tuC34LjgueC64Lvg/////7zgveC+4L/gwODB4MLgw+DE4MXgxuDH4MjgyeDK4MvgzODN4M7gz+DQ4NHg0uDT4NTg1eDW4Nfg" + "2ODZ4Nrg2+Dc4N3g3uDf4ODg4eDi4OPg5ODl4Obg5+Do4Ong6uDr4Ozg7eDu4O/g8ODx4PLg8+D04PXg9uD34Pjg+eD64P//" + "++D84P3g/uD/4ADhAeEC4QPhBOEF4QbhB+EI4QnhCuEL4QzhDeEO4Q/hEOER4RLhE+EU4RXhFuEX4RjhGeEa4RvhHOEd4R7h" + "H+Eg4SHhIuEj4SThJeEm4SfhKOEp4SrhK+Es4S3hLuEv4TDhMeEy4TPhNOE14TbhN+E44TnhOuE74TzhPeE+4T/hQOFB4ULh" + "Q+FE4UXhRuFH4UjhSeFK4UvhTOFN4U7hT+FQ4VHhUuFT4VThVeFW4VfhWOFZ4VrhW+Fc4V3hXuFf4WDhYeFi4WPhZOFl4Wbh" + "Z+Fo4WnhauFr4WzhbeFu4W/hcOFx4XLhc+F04XXhduF34f////944XnheuF74XzhfeF+4X/hgOGB4YLhg+GE4YXhhuGH4Yjh" + "ieGK4YvhjOGN4Y7hj+GQ4ZHhkuGT4ZThleGW4ZfhmOGZ4Zrhm+Gc4Z3hnuGf4aDhoeGi4aPhpOGl4abhp+Go4anhquGr4azh" + "reGu4a/hsOGx4bLhs+G04bXhtuH//7fhuOG54brhu+G84b3hvuG/4cDhweHC4cPhxOHF4cbhx+HI4cnhyuHL4czhzeHO4c/h" + "0OHR4dLh0+HU4dXh1uHX4djh2eHa4dvh3OHd4d7h3+Hg4eHh4uHj4eTh5eHm4efh6OHp4erh6+Hs4e3h7uHv4fDh8eHy4fPh" + "9OH14fbh9+H44fnh+uH74fzh/eH+4f/hAOIB4gLiA+IE4gXiBuIH4gjiCeIK4gviDOIN4g7iD+IQ4hHiEuIT4hTiFeIW4hfi" + "GOIZ4hriG+Ic4h3iHuIf4iDiIeIi4iPiJOIl4ibiJ+Io4iniKuIr4iziLeIu4i/iMOIx4jLiM+L/////NOI14jbiN+I44jni" + "OuI74jziPeI+4j/iQOJB4kLiQ+JE4kXiRuJH4kjiSeJK4kviTOJN4k7iT+JQ4lHiUuJT4lTiVeJW4lfiWOJZ4lriW+Jc4l3i" + "XuJf4mDiYeJi4mPiZOJl4mbiZ+Jo4mniauJr4mzibeJu4m/icOJx4nLi//9z4nTideJ24nfieOJ54nrie+J84n3ifuJ/4oDi" + "geKC4oPihOKF4obih+KI4oniiuKL4ozijeKO4o/ikOKR4pLik+KU4pXiluKX4pjimeKa4pvinOKd4p7in+Kg4qHiouKj4qTi" + "peKm4qfiqOKp4qriq+Ks4q3iruKv4rDiseKy4rPitOK14rbit+K44rniuuK74rziveK+4r/iwOLB4sLiw+LE4sXixuLH4sji" + "yeLK4svizOLN4s7iz+LQ4tHi0uLT4tTi1eLW4tfi2OLZ4tri2+Lc4t3i3uLf4uDi4eLi4uPi5OLl4ubi5+Lo4uni6uLr4uzi" + "7eLu4u/i//////Di8eLy4vPi9OL14vbi9+L44vni+uL74vzi/eL+4v/iAOMB4wLjA+ME4wXjBuMH4wjjCeMK4wvjDOMN4w7j" + "D+MQ4xHjEuMT4xTjFeMW4xfjGOMZ4xrjG+Mc4x3jHuMf4yDjIeMi4yPjJOMl4ybjJ+Mo4ynjKuMr4yzjLeMu4///L+Mw4zHj" + "MuMz4zTjNeM24zfjOOM54zrjO+M84z3jPuM/40DjQeNC40PjRONF40bjR+NI40njSuNL40zjTeNO40/jUONR41LjU+NU41Xj" + "VuNX41jjWeNa41vjXONd417jX+Ng42HjYuNj42TjZeNm42fjaONp42rja+Ns423jbuNv43DjceNy43PjdON143bjd+N443nj" + "euN743zjfeN+43/jgOOB44Ljg+OE44XjhuOH44jjieOK44vjjOON447jj+OQ45HjkuOT45TjleOW45fjmOOZ45rjm+Oc453j" + "nuOf46DjoeOi46PjpOOl46bjp+Oo46njquOr4/////+s463jruOv47DjseOy47PjtOO147bjt+O447njuuO747zjveO+47/j" + "wOPB48Ljw+PE48XjxuPH48jjyePK48vjzOPN487jz+PQ49Hj0uPT49Tj1ePW49fj2OPZ49rj2+Pc493j3uPf4+Dj4ePi4+Pj" + "5OPl4+bj5+Po4+nj6uP//+vj7OPt4+7j7+Pw4/Hj8uPz4/Tj9eP24/fj+OP54/rj++P84/3j/uP/4wDkAeQC5APkBOQF5Abk" + "B+QI5AnkCuQL5AzkDeQO5A/kEOQR5BLkE+QU5BXkFuQX5BjkGeQa5BvkHOQd5B7kH+Qg5CHkIuQj5CTkJeQm5CfkKOQp5Crk" + "K+Qs5C3kLuQv5DDkMeQy5DPkNOQ15DbkN+Q45DnkOuQ75DzkPeQ+5D/kQORB5ELkQ+RE5EXkRuRH5EjkSeRK5EvkTORN5E7k" + "T+RQ5FHkUuRT5FTkVeRW5FfkWORZ5FrkW+Rc5F3kXuRf5GDkYeRi5GPkZORl5GbkZ+T/////aORp5Grka+Rs5G3kbuRv5HDk" + "ceRy5HPkdOR15Hbkd+R45HnkeuR75HzkfeR+5H/kgOSB5ILkg+SE5IXkhuSH5IjkieSK5IvkjOSN5I7kj+SQ5JHkkuST5JTk" + "leSW5JfkmOSZ5Jrkm+Sc5J3knuSf5KDkoeSi5KPkpOSl5Kbk//+n5KjkqeSq5KvkrOSt5K7kr+Sw5LHksuSz5LTkteS25Lfk" + "uOS55Lrku+S85L3kvuS/5MDkweTC5MPkxOTF5Mbkx+TI5MnkyuTL5MzkzeTO5M/k0OTR5NLk0+TU5NXk1uTX5Njk2eTa5Nvk" + "3OTd5N7k3+Tg5OHk4uTj5OTk5eTm5Ofk6OTp5Ork6+Ts5O3k7uTv5PDk8eTy5PPk9OT15Pbk9+T45Pnk+uT75Pzk/eT+5P/k" + "AOUB5QLlA+UE5QXlBuUH5QjlCeUK5QvlDOUN5Q7lD+UQ5RHlEuUT5RTlFeUW5RflGOUZ5RrlG+Uc5R3lHuUf5SDlIeUi5SPl" + "/////yTlJeUm5SflKOUp5SrlK+Us5S3lLuUv5TDlMeUy5TPlNOU15TblN+U45TnlOuU75TzlPeU+5T/lQOVB5ULlQ+VE5UXl" + "RuVH5UjlSeVK5UvlTOVN5U7lT+VQ5VHlUuVT5VTlVeVW5VflWOVZ5VrlW+Vc5V3lXuVf5WDlYeVi5f//Y+Vk5WXlZuVn5Wjl" + "aeVq5WvlbOVt5W7lb+Vw5XHlcuVz5XTldeV25XfleOV55Xrle+V85X3lfuV/5YDlgeWC5YPlhOWF5Yblh+WI5YnliuWL5Yzl" + "jeWO5Y/lkOWR5ZLlk+WU5ZXlluWX5ZjlmeWa5ZvlnOWd5Z7ln+Wg5aHlouWj5aTlpeWm5aflqOWp5arlq+Ws5a3lruWv5bDl" + "seWy5bPltOW15bblt+W45bnluuW75bzlveW+5b/lwOXB5cLlw+XE5cXlxuXH5cjlyeXK5cvlzOXN5c7lz+XQ5dHl0uXT5dTl" + "1eXW5dfl2OXZ5drl2+Xc5d3l3uXf5f/////g5eHl4uXj5eTl5eXm5efl6OXp5erl6+Xs5e3l7uXv5fDl8eXy5fPl9OX15fbl" + "9+X45fnl+uX75fzl/eX+5f/lAOYB5gLmA+YE5gXmBuYH5gjmCeYK5gvmDOYN5g7mD+YQ5hHmEuYT5hTmFeYW5hfmGOYZ5hrm" + "G+Yc5h3mHub//x/mIOYh5iLmI+Yk5iXmJuYn5ijmKeYq5ivmLOYt5i7mL+Yw5jHmMuYz5jTmNeY25jfmOOY55jrmO+Y85j3m" + "PuY/5kDmQeZC5kPmROZF5kbmR+ZI5knmSuZL5kzmTeZO5k/mUOZR5lLmU+ZU5lXmVuZX5ljmWeZa5lvmXOZd5l7mX+Zg5mHm" + "YuZj5mTmZeZm5mfmaOZp5mrma+Zs5m3mbuZv5nDmceZy5nPmdOZ15nbmd+Z45nnmeuZ75nzmfeZ+5n/mgOaB5oLmg+aE5oXm" + "huaH5ojmieaK5ovmjOaN5o7mj+aQ5pHmkuaT5pTmleaW5pfmmOaZ5prmm+b/////nOad5p7mn+ag5qHmouaj5qTmpeam5qfm" + "qOap5qrmq+as5q3mruav5rDmseay5rPmtOa15rbmt+a45rnmuua75rzmvea+5r/mwObB5sLmw+bE5sXmxubH5sjmyebK5svm" + "zObN5s7mz+bQ5tHm0ubT5tTm1ebW5tfm2ObZ5trm///b5tzm3ebe5t/m4Obh5uLm4+bk5uXm5ubn5ujm6ebq5uvm7Obt5u7m" + "7+bw5vHm8ubz5vTm9eb25vfm+Ob55vrm++b85v3m/ub/5gDnAecC5wPnBOcF5wbnB+cI5wnnCucL5wznDecO5w/nEOcR5xLn" + "E+cU5xXnFucX5xjnGeca5xvnHOcd5x7nH+cg5yHnIucj5yTnJecm5yfnKOcp5yrnK+cs5y3nLucv5zDnMecy5zPnNOc15zbn" + "N+c45znnOuc75zznPec+5z/nQOdB50LnQ+dE50XnRudH50jnSedK50vnTOdN507nT+dQ51HnUudT51TnVedW51fn/////3Ah" + "cSFyIXMhdCF1IXYhdyF4IXkhYCFhIWIhYyFkIWUhZiFnIWghaSHi/+T/B/8C/zEyFiEhITUiin4ciUiTiJLchMlPu3AxZsho" + "+ZL7ZkVfKE7hTvxOAE8DTzlPVk+ST4pPmk+UT81PQFAiUP9PHlBGUHBQQlCUUPRQ2FBKUf//ZFGdUb5R7FEVUpxSplLAUttS" + "AFMHUyRTclOTU7JT3VMO+pxUilSpVP9UhlVZV2VXrFfIV8dXD/oQ+p5YslgLWVNZW1ldWWNZpFm6WVZbwFsvddhb7FseXKZc" + "ulz1XCddU10R+kJdbV24Xbld0F0hXzRfZ1+3X95fXWCFYIpg3mDVYCBh8mARYTdhMGGYYRNipmL1Y2BknWTOZE5lAGYVZjtm" + "CWYuZh5mJGZlZldmWWYS+nNmmWagZrJmv2b6Zg5nKflmZ7tnUmjAZwFoRGjPaBP6aGkU+php4mkwamtqRmpzan5q4mrkatZr" + "P2xcbIZsb2zabARth21vbf////+Wbaxtz234bfJt/G05blxuJ248br9uiG+1b/VvBXAHcChwhXCrcA9xBHFccUZxR3EV+sFx" + "/nGxcr5yJHMW+ndzvXPJc9Zz43PScwd09XMmdCp0KXQudGJ0iXSfdAF1b3WCdpx2nnabdqZ2F/pGd69SIXhOeGR4engweRj6" + "Gfr//xr6lHkb+pt50Xrnehz663qeex36SH1cfbd9oH3WfVJ+R3+hfx76AYNig3+Dx4P2g0iEtIRThVmFa4Uf+rCFIPoh+geI" + "9YgSijeKeYqnir6K34oi+vaKU4t/i/CM9IwSjXaNI/rPjiT6JfpnkN6QJvoVkSeR2pHXkd6R7ZHukeSR5ZEGkhCSCpI6kkCS" + "PJJOklmSUZI5kmeSp5J3kniS55LXktmS0JIn+tWS4JLTkiWTIZP7kij6HpP/kh2TApNwk1eTpJPGk96T+JMxlEWUSJSSldz5" + "Kfqdlq+WM5c7l0OXTZdPl1GXVZdXmGWYKvor+ieZLPqemU6a2Zr/////3Jp1m3Kbj5uxm7ubAJxwnWudLfoZntGe////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +CP932_ENC_EXC = {0x80: b'\x80', 0xA2: b'\x81\x91', 0xA3: b'\x81\x92', 0xAC: b'\x81\xca', 0x2016: b'\x81a', 0x2212: b'\x81|', 0x301C: b'\x81`'} +CP932_ENC_REJECT = frozenset() + +# ---- gb2312 ---- +GB2312_DEC = _g( + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////wAwATACMPswyQLHAqgAAzAFMBUgXv8WICYgGCAZIBwgHSAUMBUw" + "CDAJMAowCzAMMA0wDjAPMBYwFzAQMBEwsQDXAPcANiInIigiESIPIioiKSIIIjciGiKlIiUiICISI5kiKyIuImEiTCJIIj0i" + "HSJgIm4ibyJkImUiHiI1IjQiQiZAJrAAMiAzIAMhBP+kAOD/4f8wIKcAFiEGJgUmyyXPJc4lxyXGJaEloCWzJbIlOyCSIZAh" + "kSGTIRMw////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////4gkiSSKJIskjCSNJI4kjySQJJEkkiSTJJQklSSWJJckmCSZJJokmyR0JHUkdiR3JHgkeSR6JHsk" + "fCR9JH4kfySAJIEkgiSDJIQkhSSGJIckYCRhJGIkYyRkJGUkZiRnJGgkaST/////IDIhMiIyIzIkMiUyJjInMigyKTL/////" + "YCFhIWIhYyFkIWUhZiFnIWghaSFqIWsh////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////Af8C/wP/5f8F/wb/B/8I/wn/Cv8L/wz/Df8O/w//EP8R/xL/E/8U/xX/Fv8X/xj/Gf8a/xv/HP8d/x7/H/8g/yH/" + "Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov87/zz/Pf8+/z//QP9B/0L/Q/9E/0X/" + "Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/W/9c/13/4///////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////0EwQjBDMEQwRTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYw" + "VzBYMFkwWjBbMFwwXTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgwaTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHow" + "ezB8MH0wfjB/MIAwgTCCMIMwhDCFMIYwhzCIMIkwijCLMIwwjTCOMI8wkDCRMJIwkzD/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////+hMKIwozCkMKUwpjCnMKgwqTCqMKsw" + "rDCtMK4wrzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w" + "0DDRMNIw0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw4jDjMOQw5TDmMOcw6DDpMOow6zDsMO0w7jDvMPAw8TDyMPMw" + "9DD1MPYw////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MDpAOlA6YDpwOoA6kD/////////////////////7EDsgOzA7QD" + "tQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QDxQPGA8cDyAPJA///////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////xAEEQQSBBMEFAQVBAEEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcE" + "KAQpBCoEKwQsBC0ELgQvBP///////////////////////////////////////zAEMQQyBDMENAQ1BFEENgQ3BDgEOQQ6BDsE" + "PAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBP//////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////8BAeEAzgHgABMB6QAbAegAKwHtANAB7ABNAfMA" + "0gHyAGsB+gDUAfkA1gHYAdoB3AH8AOoA//////////////////////////8FMQYxBzEIMQkxCjELMQwxDTEOMQ8xEDERMRIx" + "EzEUMRUxFjEXMRgxGTEaMRsxHDEdMR4xHzEgMSExIjEjMSQxJTEmMScxKDEpMf//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "ACUBJQIlAyUEJQUlBiUHJQglCSUKJQslDCUNJQ4lDyUQJRElEiUTJRQlFSUWJRclGCUZJRolGyUcJR0lHiUfJSAlISUiJSMl" + "JCUlJSYlJyUoJSklKiUrJSwlLSUuJS8lMCUxJTIlMyU0JTUlNiU3JTglOSU6JTslPCU9JT4lPyVAJUElQiVDJUQlRSVGJUcl" + "SCVJJUolSyX/////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////0pVP5bDVyhjzlQJVcBUkXZMdjyF7nd+go14MXKYlo2XKGyJW/pPCWOXZrhc+oBIaK6AAmbOdvlRVmWscfF/hIiyUGVZ" + "ymGzb62CTGNSYu1TJ1QGe2tRpHX0XdRiy412l4piGYBdVziXYn84cn12z2d+dkZkcE8ljdxiF3qRZe1zLGRzYiyCgZh/Z0hy" + "bmLMYjRP43RKU55Syn6mkC5ehmicaYCB0X7SaMV4jIZRlY1QJIzegt6ABVMSiWVS////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////+EhfmW3U8hWHGZnVuxYqVitGZ5jI2cBnJvZ5F4smBRUxdTiI/MgB2NoZQNUMhy" + "B1nrYBlxq4hUWe+CLGcoeyld934tdfVsZo74jzyQO5/UaxmRFHt8X6d41oQ9hdVr2WvWawFeh175de2VXWUKX8Vfn4/BWMKB" + "f5Bblq2XuY8WfyyNQWK/T9hTXlOoj6mPq49NkAdoal+YgWiI1pyLYStSKnZsX4xl0m/obr5bSGR1UbBRxGcZTsl5fJmzcP//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////xXV2Xrtz4IOtZOhitZTibFpTw1IPZMKU" + "lHsvTxteNoIWgYqBJG7KbHOaVWNcU/pUZYjgVw1OA15laz986JAWYOZkHHPBiFBnTWIijWx3KY7HkWlf3IMhhRCZwlOVhotr" + "7WDoYH9wzYIxgtNOp2zPhc1k2Xz9aflmSYOVU1Z7p0+MUUttQlxtjtJjyVMsgzaD5We0eD1k31uUXO5d54vGYvRneowAZLpj" + "SYeLmReMIH/ylKdOEJakmAxmFnP/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////zpX" + "HVw4Xn+Vf1CggIJTXmVFdTFVIVCFjYRinpQdZzJWbm/iXTVUknBmj29ipGSjY3tfiG/0kOOBsI8YXGhm8V+JbEiWgY1siJFk" + "8HnOV1lqEGJIVFhOC3rpYIRv2ot/Yh6Qi5rkeQNU9HUBYxlTYGzfjxtfcJo7gH+fiE86XGSNxX+lZb1wRVGyUWuGB12gW71i" + "bJF0dQyOIHoBYXl7x074foV3EU7tgR1S+lFxaqhTh44Elc+WwW5kllpp////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////9AeKhQ13cQZOaJBFnjY91df3o9aSBPOYKYVTJOrnWXemJeil7vlRtSOVSKcHZjJJWCVyVm" + "P2mHkQdV822vfiKIM2LwfrV1KIPBeMyWno9IYfd0zYtkazpSUI0ha2qAcYTxVgZTzk4bTtFRl3yLkQd8w09/juF7nHpnZBRd" + "rFAGgQF2uXzsbeB/UWdYW/hby3iuZBNkqmMrYxmVLWS+j1R7KXZTYidZRlR5a6NQNGImXoZr4043jYuIhV8ukP//////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////IGA9gMViOU5VU/iQuGPGgOZlLmxGT+5g4W3eizlf" + "y4ZTXyFjWlFhg2NoAFJjY0iOElCbXHd5/FswUjt6vGBTkNd2t1+XX4R2bI5vcHt2SXuqd/NRk5AkWE5P9G7qj0xlG3vEcqRt" + "33/hWrVilV4wV4KELHsdXh9fEpAUf6CYgmPHbph4uXB4UVuXq1c1dUNPOHWXXuZgYFnAbb9riXj8U9WWy1EBUoljClSTlAOM" + "zI05cp94doftjw2M4FP/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////wFO73buU4mU" + "dpgOny2VmluiiyJOHE6sUWOEwmGoUgtol09rYLtRHm1cUZZil2VhlkaMF5DYdf2QY3fSa4py7HL7izVYeXdMjVxnQJWagKZe" + "IW6SWe967Xc7lbVrrWUOfwZYUVEflvlbqVgoVHKOZmV/mORWnZT+dkGQh2PGVBpZOlmbV7KONWf6jTWCQVLwYBVY/oboXEWe" + "xE+dmLmLJVp2YIRTfGJPkAKRf5lpYAyAP1EzgBRcdZkxbYxO////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////8wjdFTWn9PexBPT04AltVs0HPphQZeanX7fwpq/neSlEF+4VHmcM1T1I8DgymNr3JtmdtsSlezgrll" + "qoA/YjKWqFn/Tr+Lun4+ZfKDXpdhVd6YpYAqU/2LIFS6gJ9euGw5jayCWpEpVBtsBlK3fl9XGnF+bIl8S1n9Tv9fJGGqfDBO" + "AVyrZwKH8FwLlc6Yr3X9cCKQr1Edf72LSVnkUVtPJlQrWXdlpIB1W3ZiwmKQj0VeH2wmew9P2E8NZ///////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////bm2qbY95sYgXXyt1mmKFj+9P3JGnZS+BUYGcXlCBdI1vUoaJ" + "S40NWYVQ2E4cljZyeYEfjcxbo4tElodZGn+QVHZWDlblizllgmmZlNZ2iW5yXhh1RmfRZ/96nYB2jR9hxnliZWONiFEaUqKU" + "OH+bgLJ+l1wvbmBn2XuLdtiaj4GUf9V8HmRQlT96SlTlVExrAWQIYj2e84CZdXJSaZdbhDxo5IYBlpSW7JQqTgRU2X45aN+N" + "FYD0ZppeuX//////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////8JXP4CXaOVdO2WfUm1g" + "mp+bT6yObFGrWxNf6V1ebPFiIY1xUamU/lKfbN+C13KiV4RnLY0fWZyPx4OVVI17ME+9bGRb0VkTn+RTyoaomjeMoYBFZX6Y" + "+lbHli5S3HRQUuFbAmMCiVZO0GIqYPpoc1GYW6BRwomhe4aZUH/vYExwL41JUX9eG5BwdMSJLVdFeFJfn5/6lWiPPJvhi3h2" + "QmjcZ+qNNY09UoqP2m7NaAWV7ZD9Vpxn+YjHj8hU////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////+4mmlbd20mbKVOs1uHmmORqGGvkOmXK1S1bdJb/VGKVVV/8H+8ZE1j8WW+YY1gCnFXbElsL1ltZyqC1ViOVmqM" + "62vdkH1ZF4D3U2ltdVSdVXeDz4M4aL55jFRVTwhU0naJjAKWs2y4bWuNEIlknjqNP1bRntV1iF/gcmhg/FSoTipqYYhSYHCP" + "xFTYcHmGP54qbY9bGF+ifolVr080czxUmlMZUA5UfFROTv1fWnT2WGuE4YB0h9ByynxWbv//////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////J19OhixVpGKSTqpsN2KxgtdUTlM+c9FuO3USUhZT3YvQaYpfAGDubU9X" + "Imuvc1No2I8Tf2Jjo2AkVep1YowVcaNtplt7XlKDTGHEnvp4V4cnfId28FH2YExxQ2ZMXk1gDoxwcCVjiY+9X2Jg1IbeVsFr" + "lGBnYUlT4GBmZj+N/XkaT+lwR2yzi/KL2H5kgw9mWlpCm1Ft921BjDttGU9rcLeDFmLRYA2XJ414eftRPlf6VzpneHU9eu95" + "lXv/////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////4yAZZn5j8BvpYshnuxZ6X4JfwlU" + "gWfYaJGPTXzGlspTJWC+dXJsc1PJWqd+JGPgUQqB8V3fhIBigFFjWw5PbXlCUrhgTm3EW8JboYuwi+JlzF9FlpNZ536qfglW" + "t2c5WXNPtlugUlqDipg+jTJ1vpRHUDx69062Z36awVp8a9F2WlcWXDp79JVOcXxRqYBwgnhZBH8ng8Bo7GexeHd442JhY4B7" + "7U9qUs9RUIPbaXSS9Y0xjcGJLpWte/ZO////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//9lUDCCUVJvmRBuhW6nbfpe9VDcWQZcRm1fbIZ1i4RoaFZZsosgU3GRTZZJhRJpAXkmcfaApE7KkEdthJoHWrxWBWTwlOt3" + "pU8ageFy0ol6mTR/3n5/UllldZF/j4OP61OWeu1jpWOGdvh5V4g2lipiq1KCglRocGd3Y2t37XoBbdN+44nQWRJiyYWlgkx1" + "H1DLTqV164tKXP5dS3ukZdGRyk4lbV+JJ30mlcVOKIzbj3OXS2aBedGP7HB4bf//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////PVyyUkaDYlEOg1t3dma4nKxOymC+fLN8z36VTmaLb2aImFmXg1hsZVyVhF/JdVaX" + "33reesBRr3CYeupjdnqgfpZz7ZdFTnhwXU5SkalTUWXnZfyBBYKOVDFcmnWgl9hi2XK9dUVceZrKg0BcgFTpdz5OrmxagNJi" + "bmPoXXdR3Y0eji+V8U/lU+dgrHBnUlBjQ54fWiZQN3d3U+J+hWQrZYlimGMUUDVyyYmzUcCL3X5HV8yDp5SbURtU+1z/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////8pP43pabeGQj5qAVZZUYVOvVABf6WN3ae9R" + "aGEKUipY2FJOVw14C3e3Xndh4HxbYpdiok6VcAOA92LkcGCXd1fbgu9n9WjVeJeY0XnzWLNU71M0bktRO1KiW/6Lr4BDVaZX" + "c2BRVy1UenpQYFRbp2OgYuNTY2LHW69n7VSfeuaCd5GTXuSIOFmuVw5j6I3vgFdXd3upT+tfvVs+ayFTUHvCckZo/3c2d/dl" + "tVGPTtR2v1ylenWETllBm4BQ////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////////////+ImSdh" + "g25kVwZmRmPwVuxiaWLTXhSWg1fJYodVIYdKgaOPZlWxg2VnVo3dhGpaD2jmYu57EZZwUZxvMIz9Y8iJ0mEGf8Jw5W4FdJRp" + "/HLKXs6QF2dqbV5js1JicgGAbE/lWWqR2XCdbdJSUE73lm2VfoXKeC99IVGSV8Jki4B7fOps8WheabdRmFOoaIFyzp7xe/hy" + "u3kTbwZ0TmfMkaScPHmJg1SDD1QXaD1OiVOxUj54hlMpUohQi0/QT///////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////4nXLepJ8pWy2lptSg3TpVOlPVICyg96PcJXJXhxgn20YXltlOIH+lEtgvHDDfq58yVGBaLF8" + "b4IkToaPz5F+Zq5OBYypZEqA2lCXdc5x5Vu9j2Zvhk6CZGOV1l6ZZRdSwojIcKNSDnMzdJdn93gWlzROu5DenMtt21FBjR1U" + "zmKyc/GD9paEn8OUNk+af8xRdXB1lq1chpjmU+ROnG4JdLRpa3iPmVl1GFIkdkFt82dtUZmfS4CZVDx7v3r/////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////4aWhFfiYkeWfGkEWgJk03sPb0uWpoJiU4WYkF6JcLNj" + "ZFNPhoGck56MeDKX741CjX+eXm+EeVVfRpYuYnSaFVTdlKNPxWVlXGFcFX9Rhi9si1+Hc+Ru/37mXBtjalvmbnVTcU6gY2V1" + "oWJujyZP0U6mbLZ+uosdhLqHV387kCOVqXuhmviIPYQbbYaa3H6IWbuem3MBeIKGbJqCmhtWF1TLV3BOpp5WU8iPCYGSd5KZ" + "7obhbhOF/GZiYStv////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////8pjJKCK4PydhNs" + "2V+9gytzBYMaldtr23fGlG9TAoOSUT1ejIw4jUhOq3OaZ4VodpEJl2RxoWwJd5JaQZXPa45/J2bQW7lZmlrolfeV7E4MhJmE" + "rGrfdjCVG3OmaF9bL3eakWGX3Hz3jxyMJV9zfNh5xYnMbByHxltCXsloIHf1fpVRTVHJUilaBX9il9eCz2OEd9CF0nk6bple" + "mVkRhW1wEWy/Yr92T2WvYP2VDmafhyOe7ZQNVH1ULIx4ZP//////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////eWQRhiFqnIHoeGlkVJu5Yitnq4OoWNieq2wgb95bTJYLjF9y0GfHYmFyqU7GWc1rk1iuZlVe31JVYShn" + "7nZmd2dyRnr/YupUUFSglKOQHFqzfhZsQ052WRCASFlXUzd1vpbKViBjEYF8YPmV1m1iVIGZhVHpWv2ArlkTlypQ5Ww8XN9i" + "YE8/U3uBBpC6biuFyGJ0Xr54tWR7Y/VfGFp/kR+eP1xPY0KAfVtuVUqVTZWFbahg4Gfect1RgVv/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////+di3mxbcm1irpS9fhOBU22cUQRfdFmqUhJgc1mWZlCGn3UqY+Zh" + "73z6i+ZUJ2slnrRr1YVVVHZQpGxqVbSNLHIVXhVgNnTNYpJjTHKYX0NuPm0AZVhv2HbQePx2VHUkUttTU06eXsFlKoDWgJti" + "hlQoUq5wjYjRjeFseFTagPlX9IhUjWqWTZFpT5tst1XGdjB4qGL5cI5vbV/shNpofHj3e6iBC2dPnmdjsHhvVxJ4OZd5Yqti" + "iFI1dNdr////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9kVT6BsnWudjlT3nX7UEFc" + "bIvHe09QR3KXmtiYAm/idGh5h2Sld/xikZgrjcFUWIBSTmpX+YINhHNe7VH2dMSLT1xhV/xsh5hGWjR4RJvrj5V8VlJRYvqU" + "xk6Gg2GE6YOyhNRXNGcDV25mZm0xjN1mEXAfZzprFmgaYrtZA07EUQZv0mePbHZRy2hHWWdrZnUOXRCBUJ/XZUh5QXmRmneN" + "glxeTgFPL1RRWQx4aFYUbMSPA199bONsq4uQY///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////cGA9bXVyZmKOlMWUQ1PBj357304mjH5O1J6xlLOUTVJcb2OQRW00jBFYTF0ga0lrqmdbVFSBjH+ZWDeFOl+iYkdq" + "OZVyZYRgZWind1ROqE/nXZiXrGTYf+1cz0+NegdSBIMUTi9gg3qmlLVPsk7meTR05FK5gtJkvXndW4FsUpd7jyJsPlB/UwVu" + "zmR0ZjBsxWB3mPeLhl48dHd6y3kYTrGQA3RCbNpWS5HFbIuNOlPGhvJmr45IXHGaIG7/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////9ZTNlqLn6ONu1MIV6eYQ2ebkclsaFHKdfNirHI4Up1SOn+UcDh2dFNKnrdp" + "bnjAltmIpH82ccNxiVHTZ+R05FgYZbdWqYt2mXBi1X75YO1w7FjBTrpOzV/nl/tOpIsDUopZq35UYs1O5WUOYjiDyYRjg42H" + "lHG2brlb0n6XUclj1GeJgDmDFYgSUXpbglmxj3NOXWxlUSWJb48ulkqFXnQQlfCVpm3lgjFfkmQSbSiEboHDnF5YW40JTsFT" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////8eT2NlUWjTVSdOFGSammtiwlpfdHKC" + "qW3uaOdQjoMCeEBnOVKZbLF+u1BlVV5xW3tSZspz64JJZ3FcIFJ9cWuI6pVVlsVkYY2zgYRVVWxHYi5/klgkT0ZVT41MZgpO" + "GlzziKJoTmMNeudwjYL6UvaXEVzoVLWQzX5iWUqNx4YMgg2CZo1EZARcUWGJbT55vos3eDN1e1Q4T6uO8W0gWsV+XnmIbKFb" + "dloadb6ATmEXbvBYH3UldXJyR1Pzfv//////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "AXfbdmlS3IAjVwheMVnucr1lf27XizhccYZBU/N3/mL2ZcBO35iAhp5bxovyU+J3f09OXHaay1kPXzp561gWTv9ni07tYpOK" + "HZC/Ui9m3FVsVgKQ1U6NT8qRcJkPbAJeQ2CkW8aJ1Ys2ZUtilpmIW/9biGMuVddTJnZ9USyFomezaIprkmKTj9RTEoLRbY91" + "Zk5OjXBbn3GvhZFm2WZyfwCHzZ4gn15cL2fwjxFoX2cNYtZ6hVi2XnBlMW//////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////1VgN1INgFRkcIgpdQVeE2j0YhyXzFM9cgGMNGxhdw56LlSsd3qYHIL0i1V4FGfBcK9l" + "lWQ2Vh1gwXn4Ux1Oe2uGgPpb41XbVjpPPE9ymfNdfmc4gAJggpgBkItbvIv1ixxkWILeZP1Vz4JlkddPIH0fkJ9881BRWK9u" + "v1vJi4OAeJGchJd7fYaLlo+W5X7Tmo54gVxXekKQp5ZfeVlbX2MLe9GErWgGVSl/EHQifQGVQGJMWNZOg1t5WVRY////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////9tcx5jS44Pjs6A1IKsYvBT8GxekSpZAWBwbE1X" + "SmQqjSt26W5bV4Bq8HVtby2MCIxmV+9rkoizeKJj+VOtcGRsWFgqZAJY4GibgRBV1nwYULqOzG2fjetwj2ObbdRu5n4EhENo" + "A5DYbXaWqItXWXly5IV+gbx1ioqvaFRSIo4RldBjmJhEjnxVU0//Zo9W1WCVbUNSSVwpWftta1gwdRx1bGAUgkaBEWNhZ+KP" + "OnfzjTSNwZQWXoVTLFTDcP//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////QGz3XlxQ" + "rU6tXjpjR4IakFBobpGzdwxU3JRkX+V6dmhFY1J7337bdXdQlWI0WQ+Q+FHDeYF6/laSXxSQgm1gXB9XEFRUUU1u4laoY5OY" + "f4EVhyqJAJAeVG9cwIHWYlhiMYE1nkCWbpp8mi1ppVnTYj5VFmPHVNmGPG0DWuZ0nIhqaxZZTIwvX35uqXN9mDhO93CMW5d4" + "PWNaZpZ2y2CbW0laB05VgWpsi3OhTolnUX+AX/plG2fYX4RZAVr/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////81drl9xU+aX3Y9FaPRWL1XfYDpOTW/0fseCDoTUWR9PKk8+XKx+KmcahXNUT3XDgIJVT5tNTy1u" + "E4wJXHBha1MfdiluioaHZfuVuX47VDN6Cn3uleFVwX/udB1jF4ehbZ16EWKhZWdT4WODbOtdXFSolExOYWzsi0tc4GWcgqdo" + "PlQ0VMtrZmuUTkJjSFMegg1Prk9eVwpi/pZkZmly/1KhUp9g74sUZplxkGd/iVJ4/XdwZjtWOFQhlXpy////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////8Aem9gDF6JYJ2BFVncYIRx73CqblBsgHKEaq2ILV5gTrNa" + "nFXjlBdt+3yZlg9ixn6Od36GI1Mel5aPh2bhXKBP7XILTqZTD1kTVIBjKJVIUdlOnJykfrhUJI1UiDeC8pWObSZfzFo+ZmmW" + "sHMuc79TeoGFmaF/qlt3llCWv374dqJTdpWZmbF7RIlYbmFO1H9leeaL82DNVKtOeZj3XWFqz1ARVGGMJ4RdeASXSlLuVKNW" + "AJWIbbVbxm1TZv//////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////D1xdWyFoloB4VRF7" + "SGVUaZtOR2tOh4uXT1MfYzpkqpCcZcGAEIyZUbBoeFP5h8hhxGz7bCKMUVyqha+CDJUja5uPsGX7X8Nf4U9FiB9mZYEpc/pg" + "dFERUotXYl+ikEyIkpF4Xk9nJ2DTWURR9lH4gAhTeWzElopxEU/uT55/PWfFVQiVwHmWiON+n1gMYgCXWoYYVnuYkF+4i8SE" + "V5HZU+1lj15cdWRgbn1/Wup+7X5pj6dVo1usYMtlhHP/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////wmQY3Ypd9p+dJebhWZbdHrqlkCIy1KPcapf7GXii/tbb5rhXYlrW2yti6+LCpDFj4tTvGImni2eQFQrTr2C" + "WXKchhZdWYivbcWW0VSaTraLCXG9VAmW33D5bdB2JU4UeBKHqVz2XgCKnJgOlo5wv2xEWaljPHdNiBRvc4IwWNVxjFMaeMGW" + "AVVmXzBxtFsajIyag2suWS+e53loZ2xib0+hdYp/C20zlids8E7SdXtRN2g+b4CQcIGWWXZ0////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////9HZCdcZZCReiOM2lmsVACCb4OBiQCAMGlOVjaAN3LOkbZRX051mJZj" + "Gk72U/NmS4EcWbJtAE75WDtT1mPxlJ1PCk9jiJCYN1lXkPt56k7wgJF1gmycW+hZXV8FaYGGGlDyXVlO43flTnqCkWITZpGQ" + "eVy/TnlfxoE4kISAq3WmTtSID2HFa8ZfSU7KdqJu44uuiwqM0YsCX/x/zH/OfjWDa4PgVrdr85c0lvtZH1T2lOttxVtumTlc" + "FV+Qlv//////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////cFPxgjFqdFpwnpReKH+5gySE" + "JYRng0eHzo9ijch2cV+WmGx4IGbfVOViY0/Dgch1uF7NlgqO+YaPVPNsjG04bH9gx1IodX1eGE+gYOdfJFwxda6QwJS5crls" + "OG5JkQlny1PzU1FPyZHxi8hTfF7Cj+Rtjk7CdoZpXoYaYQaCWU/eTz6QfJwJYR1uFG6FlohOMVrolg5Of1y5eYdb7Yu9f4lz" + "31eLgsGQAVRHkLtV6lyhXwhhMmvxcrKAiYr/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////3Rt01vViISYa4xtmjOeCm6kUUNRo1eBiJ9T9GOVj+1WWFQGVz9zkG4Yf9yP0YI/YShgYpbwZqZ+io3DjaWUs1ykfAhn" + "pmAFlhiAkU7nkABTaJZBUdCPdIVdkVVm9ZdVWx1TOHhCZz1oyVR+cLBbfY+NUShXsVQSZYJmXo1DjQ+BbIRtkN98/1H7haNn" + "6WWhb6SGgY5qViCQgnZ2cOVxI43pYhlS/Ww8jQ5gnliOYf5mYI1OYrNVI24tZ2eP////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////hlPiVKHcFaKhpi1RNTrhwyItYZItlhVuEejpQ6Fu7d+FreYqYfL5sz3apZZeP" + "LV1VXDiGCGhgUxhi2Xpbbv1+H2rgenBfM28gX4xjqG1WZwhOEF4mjddOwIA0dpyW22ItZn5ivGx1jWdxaX9GUYeA7FNukJhi" + "8lTwhpmPBYAXlReF2Y9Zbc1zn2UfdwR1J3j7gR6NiJSmT5VnuXXKiweXL2NHlTWWuIQjY0F3gV/wcolOFGB0Ze9iY2s/Zf//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////J17HddGQwYudgp1nL2UxVBiH5XeigAKB" + "QWxLTsd+TID0dg1plmtnYjxQhE9AVwdjYmu+jepT6GW4ftdfGmO3Y/OB9IFufxxe2Vw2Unpm6XkaeiiNmXDUdd5uu2ySei1O" + "xXbgX5+Ud4jIfs15v4DNkfJOF08fgmhU3l0ybcyLpXx0j5iAGl6SVLF2mVs8ZqSa4HMqaNuGMWcqc/iL24sQkPl623BuccRi" + "qXcxVjtOV4TxZ6lSwIYujfiUUXv/////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////09P" + "6GxdeXuak2Iqcv1iE04WeGyPsGRajcZ7aWiEXsWIhlmeZO5YtnIOaSWV/Y9YjWBXAH8GjMZRSWPZYlNTTGgidAGDTJFEVUB3" + "fHBKbXlRqFREjf9Zy27EbVxbK33UTn18025QW+qBDW5XWwOb1Wgqjpdb/H47YLV+uZBwjU9ZzWPfebONUlPPZVZ5xYs7lsR+" + "u5SCfjRWiZEAZ2p/Clx1kChm5l1QT95nWlBcT1BXp17/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////+NTgxOQFEQTv9eRVMVTphOHk4ym2xbaVYoTrp5P04VU0dOLVk7cm5TEGzfVuSAl5nTa353" + "F582Tp9OEJ9cTmlOk06IgltbbFUPVsROjVOdU6NTpVOuU2WXXY0aU/VTJlMuUz5TXI1mU2NTAlIIUg5SLVIzUj9SQFJMUl5S" + "YVJcUq+EfVKCUoFSkFKTUoJRVH+7TsNOyU7CTuhO4U7rTt5OG0/zTiJPZE/1TiVPJ08JTytPXk9nTzhlWk9dT///////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////X09XTzJPPU92T3RPkU+JT4NPj09+T3tPqk98T6xP" + "lE/mT+hP6k/FT9pP40/cT9FP30/4TylQTFDzTyxQD1AuUC1Q/k8cUAxQJVAoUH5QQ1BVUEhQTlBsUHtQpVCnUKlQulDWUAZR" + "7VDsUOZQ7lAHUQtR3U49bFhPZU/OT6CfRmx0fG5R/V3JnpiZgVEUWflSDVMHihBT61EZWVVRoE5WUbNOboikiLVOFIHSiIB5" + "NFsDiLh/q1GxUb1RvFH/////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////8dRllGiUaVR" + "oIumi6eLqou0i7WLt4vCi8OLy4vPi86L0ovTi9SL1ovYi9mL3Ivfi+CL5Ivoi+mL7ovwi/OL9ov5i/yL/4sAjAKMBIwHjAyM" + "D4wRjBKMFIwVjBaMGYwbjBiMHYwfjCCMIYwljCeMKowrjC6ML4wyjDOMNYw2jGlTelMdliKWIZYxliqWPZY8lkKWSZZUll+W" + "Z5ZslnKWdJaIlo2Wl5awlpeQm5CdkJmQrJChkLSQs5C2kLqQ////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////+4kLCQz5DFkL6Q0JDEkMeQ05DmkOKQ3JDXkNuQ65DvkP6QBJEikR6RI5ExkS+ROZFDkUaRDVJCWaJS" + "rFKtUr5S/1TQUtZS8FLfU+5xzXf0XvVR/FEvm7ZTAV9ade9dTFepV6FXfli8WMVY0VgpVyxXKlczVzlXLlcvV1xXO1dCV2lX" + "hVdrV4ZXfFd7V2hXbVd2V3NXrVekV4xXslfPV6dXtFeTV6BX1VfYV9pX2VfSV7hX9FfvV/hX5FfdV///////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////C1gNWP1X7VcAWB5YGVhEWCBYZVhsWIFYiViaWIBYqJkZn/9h" + "eYJ9gn+Cj4KKgqiChIKOgpGCl4KZgquCuIK+grCCyILKguOCmIK3gq6Cy4LMgsGCqYK0gqGCqoKfgsSCzoKkguGCCYP3guSC" + "D4MHg9yC9ILSgtiCDIP7gtOCEYMagwaDFIMVg+CC1YIcg1GDW4NcgwiDkoM8gzSDMYObg16DL4NPg0eDQ4Nfg0CDF4Nggy2D" + "OoMzg2aDZYP/////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////2iDG4Npg2yDaoNtg26D" + "sIN4g7ODtIOgg6qDk4Ocg4WDfIO2g6mDfYO4g3uDmIOeg6iDuoO8g8GDAYTlg9iDB1gYhAuE3YP9g9aDHIQ4hBGEBoTUg9+D" + "D4QDhPiD+YPqg8WDwIMmhPCD4YNchFGEWoRZhHOEh4SIhHqEiYR4hDyERoRphHaEjISOhDGEbYTBhM2E0ITmhL2E04TKhL+E" + "uoTghKGEuYS0hJeE5YTjhAyFDXU4hfCEOYUfhTqF////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////9WhTuF/4T8hFmFSIVohWSFXoV6haJ3Q4VyhXuFpIWohYeFj4V5ha6FnIWFhbmFt4WwhdOFwYXchf+FJ4YFhimG" + "FoY8hv5eCF88WUFZN4BVWVpZWFkPUyJcJVwsXDRcTGJqYp9iu2LKYtpi12LuYiJj9mI5Y0tjQ2OtY/ZjcWN6Y45jtGNtY6xj" + "imNpY65jvGPyY/hj4GP/Y8Rj3mPOY1JkxmO+Y0VkQWQLZBtkIGQMZCZkIWReZIRkbWSWZP//////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////emS3ZLhkmWS6ZMBk0GTXZORk4mQJZSVlLmULX9JfGXURX19T8VP9U+lT" + "6FP7UxJUFlQGVEtUUlRTVFRUVlRDVCFUV1RZVCNUMlSCVJRUd1RxVGRUmlSbVIRUdlRmVJ1U0FStVMJUtFTSVKdUplTTVNRU" + "clSjVNVUu1S/VMxU2VTaVNxUqVSqVKRU3VTPVN5UG1XnVCBV/VQUVfNUIlUjVQ9VEVUnVSpVZ1WPVbVVSVVtVUFVVVU/VVBV" + "PFX/////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////zdVVlV1VXZVd1UzVTBVXFWLVdJV" + "g1WxVblViFWBVZ9VflXWVZFVe1XfVb1VvlWUVZlV6lX3VclVH1bRVetV7FXUVeZV3VXEVe9V5VXyVfNVzFXNVehV9VXkVZSP" + "HlYIVgxWAVYkViNW/lUAVidWLVZYVjlWV1YsVk1WYlZZVlxWTFZUVoZWZFZxVmtWe1Z8VoVWk1avVtRW11bdVuFW9VbrVvlW" + "/1YEVwpXCVccVw9eGV4UXhFeMV47Xjxe////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//83XkReVF5bXl5eYV6MXHpcjVyQXJZciFyYXJlckVyaXJxctVyiXL1crFyrXLFco1zBXLdcxFzSXORcy1zlXAJdA10nXSZd" + "Ll0kXR5dBl0bXVhdPl00XT1dbF1bXW9dXV1rXUtdSl1pXXRdgl2ZXZ1dc4y3XcVdc193X4Jfh1+JX4xflV+ZX5xfqF+tX7Vf" + "vF9iiGFfrXKwcrRyt3K4csNywXLOcs1y0nLocu9y6XLycvRy93IBc/NyA3P6cv//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////+3IXcxNzIXMKcx5zHXMVcyJzOXMlcyxzOHMxc1BzTXNXc2BzbHNvc35zG4IlWeeY" + "JFkCWWOZZ5lomWmZaplrmWyZdJl3mX2ZgJmEmYeZipmNmZCZkZmTmZSZlZmAXpFei16WXqVeoF65XrVevl6zXlON0l7RXtte" + "6F7qXrqBxF/JX9Zfz18DYO5fBGDhX+Rf/l8FYAZg6l/tX/hfGWA1YCZgG2APYA1gKWArYApgP2AhYHhgeWB7YHpgQmD/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////2pgfWCWYJpgrWCdYINgkmCMYJtg7GC7YLFg" + "3WDYYMZg2mC0YCBhJmEVYSNh9GAAYQ5hK2FKYXVhrGGUYadht2HUYfVh3V+zlumV65XxlfOV9ZX2lfyV/pUDlgSWBpYIlgqW" + "C5YMlg2WD5YSlhWWFpYXlhmWGpYsTj9yFWI1bFRsXGxKbKNshWyQbJRsjGxobGlsdGx2bIZsqWzQbNRsrWz3bPhs8WzXbLJs" + "4GzWbPps62zubLFs02zvbP5s////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////////////85bSdt" + "DG1DbUhtB20EbRltDm0rbU1tLm01bRptT21SbVRtM22RbW9tnm2gbV5tk22UbVxtYG18bWNtGm7HbcVt3m0Obr9t4G0RbuZt" + "3W3ZbRZuq20Mbq5tK25ubk5ua26ybl9uhm5TblRuMm4lbkRu326xbphu4G4tb+JupW6nbr1uu263btdutG7Pbo9uwm6fbmJv" + "Rm9HbyRvFW/5bi9vNm9Lb3RvKm8JbylviW+Nb4xveG9yb3xvem/Rb///////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////yW+nb7lvtm/Cb+Fv7m/eb+Bv728acCNwG3A5cDVwT3BecIBbhFuVW5NbpVu4Wy91npo0ZORb" + "7lswifBbR44Hi7aP04/Vj+WP7o/kj+mP5o/zj+iPBZAEkAuQJpARkA2QFpAhkDWQNpAtkC+QRJBRkFKQUJBokFiQYpBbkLlm" + "dJB9kIKQiJCDkIuQUF9XX1ZfWF87XKtUUFxZXHFbY1xmXLx/Kl8pXy1fdII8XzubblyBWYNZjVmpWapZo1n/////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////5dZylmrWZ5ZpFnSWbJZr1nXWb5ZBVoGWt1ZCFrjWdhZ" + "+VkMWglaMlo0WhFaI1oTWkBaZ1pKWlVaPFpiWnVa7ICqWptad1p6Wr5a61qyWtJa1Fq4WuBa41rxWtZa5lrYWtxaCVsXWxZb" + "Mls3W0BbFVwcXFpbZVtzW1FbU1tiW3Wad5p4mnqaf5p9moCagZqFmoiaipqQmpKak5qWmpiam5qcmp2an5qgmqKao5qlmqea" + "n36hfqN+pX6ofql+////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////////////+tfrB+vn7AfsF+" + "wn7Jfst+zH7QftR+137bfuB+4X7ofut+7n7vfvF+8n4Nf/Z++n77fv5+AX8CfwN/B38Ifwt/DH8PfxF/En8Xfxl/HH8bfx9/" + "IX8ifyN/JH8lfyZ/J38qfyt/LH8tfy9/MH8xfzJ/M381f3pef3XbXT51lZCOc5FzrnOic59zz3PCc9Fzt3Ozc8BzyXPIc+Vz" + "2XN8mAp06XPnc95zunPycw90KnRbdCZ0JXQodDB0LnQsdP//////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////G3QadEF0XHRXdFV0WXR3dG10fnScdI50gHSBdId0i3SedKh0qXSQdKd00nS6dOqX65fsl0xnU2deZ0hn" + "aWelZ4dnamdzZ5hnp2d1Z6hnnmetZ4tnd2d8Z/BnCWjYZwpo6WewZwxo2We1Z9pns2fdZwBow2e4Z+JnDmjBZ/1nMmgzaGBo" + "YWhOaGJoRGhkaINoHWhVaGZoQWhnaEBoPmhKaEloKWi1aI9odGh3aJNoa2jCaG5p/GgfaSBp+Wj/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////yRp8GgLaQFpV2njaBBpcWk5aWBpQmldaYRpa2mAaZhpeGk0acxp" + "h2mIac5piWlmaWNpeWmbaadpu2mraa1p1GmxacFpymnfaZVp4GmNaf9pL2rtaRdqGGplavJpRGo+aqBqUGpbajVqjmp5aj1q" + "KGpYanxqkWqQaqlql2qrajdzUnOBa4Jrh2uEa5Jrk2uNa5prm2uha6pra49tj3GPco9zj3WPdo94j3ePeY96j3yPfo+Bj4KP" + "hI+Hj4uP////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////+Nj46Pj4+Yj5qPzo4LYhdi" + "G2IfYiJiIWIlYiRiLGLnge909HT/dA91EXUTdTRl7mXvZfBlCmYZZnJnA2YVZgBmhXD3Zh1mNGYxZjZmNWYGgF9mVGZBZk9m" + "VmZhZldmd2aEZoxmp2adZr5m22bcZuZm6WYyjTONNo07jT2NQI1FjUaNSI1JjUeNTY1VjVmNx4nKicuJzInOic+J0InRiW5y" + "n3JdcmZyb3J+cn9yhHKLco1yj3KScghjMmOwY///////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////P2TYZASA6mvza/1r9Wv5awVsB2wGbA1sFWwYbBlsGmwhbClsJGwqbDJsNWVVZWtlTXJSclZyMHJihhZSn4CcgJOA" + "vIAKZ72AsYCrgK2AtIC3gOeA6IDpgOqA24DCgMSA2YDNgNeAEGfdgOuA8YD0gO2ADYEOgfKA/IAVZxKBWow2gR6BLIEYgTKB" + "SIFMgVOBdIFZgVqBcYFggWmBfIF9gW2BZ4FNWLVaiIGCgZGB1W6jgaqBzIEmZ8qBu4H/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////8GBpoEkazdrOWtDa0ZrWWvRmNKY05jVmNmY2piza0BfwmvziZBlUZ+TZbxl" + "xmXEZcNlzGXOZdJl1mWAcJxwlnCdcLtwwHC3cKtwsXDocMpwEHETcRZxL3ExcXNxXHFocUVxcnFKcXhxenGYcbNxtXGocaBx" + "4HHUcedx+XEdcihybHAYcWZxuXE+Yj1iQ2JIYkliO3lAeUZ5SXlbeVx5U3laeWJ5V3lgeW95Z3l6eYV5inmaead5s3nRX9Bf" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////88YF1gWmBnYEFgWWBjYKtgBmENYV1h" + "qWGdYcth0WEGYoCAf4CTbPZs/G32d/h3AHgJeBd4GHgReKtlLXgceB14OXg6eDt4H3g8eCV4LHgjeCl4TnhteFZ4V3gmeFB4" + "R3hMeGp4m3iTeJp4h3iceKF4o3iyeLl4pXjUeNl4yXjsePJ4BXn0eBN5JHkeeTR5m5/5nvue/J7xdgR3DXf5dgd3CHcadyJ3" + "GXctdyZ3NXc4d1B3UXdHd0N3Wndod///////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "Yndld393jXd9d4B3jHeRd593oHewd7V3vXc6dUB1TnVLdUh1W3VydXl1g3VYf2F/X39Iimh/dH9xf3l/gX9+f8125XYyiIWU" + "hpSHlIuUipSMlI2Uj5SQlJSUl5SVlJqUm5SclKOUpJSrlKqUrZSslK+UsJSylLSUtpS3lLiUuZS6lLyUvZS/lMSUyJTJlMqU" + "y5TMlM2UzpTQlNGU0pTVlNaU15TZlNiU25TelN+U4JTilOSU5ZTnlOiU6pT/////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////+mU65TulO+U85T0lPWU95T5lPyU/ZT/lAOVApUGlQeVCZUKlQ2VDpUPlRKVE5UUlRWV" + "FpUYlRuVHZUelR+VIpUqlSuVKZUslTGVMpU0lTaVN5U4lTyVPpU/lUKVNZVElUWVRpVJlUyVTpVPlVKVU5VUlVaVV5VYlVmV" + "W5VelV+VXZVhlWKVZJVllWaVZ5VolWmVapVrlWyVb5VxlXKVc5U6led37HfJltV57Xnjeet5BnpHXQN6AnoeehR6////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////85ejd6UXrPnqWZcHqIdo52k3aZdqR23nTgdCx1" + "IJ4iniieKZ4qniueLJ4ynjGeNp44njeeOZ46nj6eQZ5CnkSeRp5HnkieSZ5LnkyeTp5RnlWeV55anlueXJ5enmOeZp5nnmie" + "aZ5qnmuebJ5xnm2ec56SdZR1lnWgdZ11rHWjdbN1tHW4dcR1sXWwdcN1wnXWdc1143XodeZ15HXrded1A3bxdfx1/3UQdgB2" + "BXYMdhd2CnYldhh2FXYZdv//////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////G3Y8diJ2" + "IHZAdi12MHY/djV2Q3Y+djN2TXZedlR2XHZWdmt2b3bKf+Z6eHp5eoB6hnqIepV6pnqgeqx6qHqterN6ZIhpiHKIfYh/iIKI" + "oojGiLeIvIjJiOKIzojjiOWI8YgaifyI6Ij+iPCIIYkZiROJG4kKiTSJK4k2iUGJZol7iYt15YCydrR23HcSgBSAFoAcgCCA" + "IoAlgCaAJ4ApgCiAMYALgDWAQ4BGgE2AUoBpgHGAg4l4mICYg5j/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////4mYjJiNmI+YlJiamJuYnpifmKGYopilmKaYTYZUhmyGboZ/hnqGfIZ7hqiGjYaLhqyGnYanhqOG" + "qoaThqmGtobEhrWGzoawhrqGsYavhsmGz4a0humG8Ybyhu2G84bQhhOH3ob0ht+G2IbRhgOHB4f4hgiHCocNhwmHI4c7hx6H" + "JYcuhxqHPodIhzSHMYcphzeHP4eChyKHfYd+h3uHYIdwh0yHboeLh1OHY4d8h2SHWYdlh5OHr4eoh9KH////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////////////Gh4iHhYeth5eHg4erh+WHrIe1h7OHy4fTh72H0YfAh8qH" + "24fqh+CH7ocWiBOI/ocKiBuIIYg5iDyINn9Cf0R/RX8Qgvp6/XoIewN7BHsVewp7K3sPe0d7OHsqexl7LnsxeyB7JXskezN7" + "Pnsee1h7WntFe3V7THtde2B7bnt7e2J7cntxe5B7pnune7h7rHude6h7hXuqe5x7onure7R70XvBe8x73Xvae+V75nvqewx8" + "/nv8ew98FnwLfP//////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////H3wqfCZ8OHxBfEB8" + "/oEBggKCBILsgUSIIYIigiOCLYIvgiiCK4I4gjuCM4I0gj6CRIJJgkuCT4Jagl+CaIJ+iIWIiIjYiN+IXomdf59/p3+vf7B/" + "sn98fEllkXydfJx8nnyifLJ8vHy9fMF8x3zMfM18yHzFfNd86Hxugqhmv3/Of9V/5X/hf+Z/6X/uf/N/+Hx3faZ9rn1Hfpt+" + "uJ60nnONhI2UjZGNsY1njW2NR4xJjEqRUJFOkU+RZJH/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////2KRYZFwkWmRb5F9kX6RcpF0kXmRjJGFkZCRjZGRkaKRo5Gqka2RrpGvkbWRtJG6kVWMfp64jeuNBY5ZjmmO" + "tY2/jbyNuo3EjdaN143ajd6Nzo3PjduNxo3sjfeN+I3jjfmN+43kjQmO/Y0Ujh2OH44sji6OI44vjjqOQI45jjWOPY4xjkmO" + "QY5CjlGOUo5KjnCOdo58jm+OdI6Fjo+OlI6QjpyOno54jIKMioyFjJiMlIybZdaJ3onaidyJ////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "///////////////////////////////////////////lieuJ74k+iiaLU5fplvOW75YGlwGXCJcPlw6XKpctlzCXPpeAn4Of" + "hZ+Gn4efiJ+Jn4qfjJ/+ngufDZ+5lryWvZbOltKWv3fglo6SrpLIkj6TapPKk4+TPpRrlH+cgpyFnIach5yInCN6i5yOnJCc" + "kZySnJSclZyanJucnpyfnKCcoZyinKOcpZymnKecqJypnKucrZyunLCcsZyynLOctJy1nLact5y6nLucvJy9nMScxZzGnMec" + "ypzLnP//////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////zJzNnM6cz5zQnNOc1JzVnNec" + "2JzZnNyc3ZzfnOKcfJeFl5GXkpeUl6+Xq5ejl7KXtJexmrCat5pYnraaupq8msGawJrFmsKay5rMmtGaRZtDm0ebSZtIm02b" + "UZvomA2ZLplVmVSZ35rhmuaa75rrmvua7Zr5mgibD5sTmx+bI5u9nr6eO36CnoeeiJ6LnpKe1pOdnp+e257cnt2e4J7fnuKe" + "6Z7nnuWe6p7vniKfLJ8vnzmfN589nz6fRJ//////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +GB2312_ENC_EXC = {} +GB2312_ENC_REJECT = frozenset() + +# ---- gbk ---- +GBK_DEC = _g( + "Ak4ETgVOBk4PThJOF04fTiBOIU4jTiZOKU4uTi9OMU4zTjVON048TkBOQU5CTkRORk5KTlFOVU5XTlpOW05iTmNOZE5lTmdO" + "aE5qTmtObE5tTm5Ob05yTnROdU52TndOeE55TnpOe058Tn1Of06AToFOgk6DToROhU6HTopO//+QTpZOl06ZTpxOnU6eTqNO" + "qk6vTrBOsU60TrZOt064TrlOvE69Tr5OyE7MTs9O0E7STtpO207cTuBO4k7mTudO6U7tTu5O707xTvRO+E75TvpO/E7+TgBP" + "Ak8DTwRPBU8GTwdPCE8LTwxPEk8TTxRPFU8WTxxPHU8hTyNPKE8pTyxPLU8uTzFPM081TzdPOU87Tz5PP09AT0FPQk9ET0VP" + "R09IT0lPSk9LT0xPUk9UT1ZPYU9iT2ZPaE9qT2tPbU9uT3FPck91T3dPeE95T3pPfU+AT4FPgk+FT4ZPh0+KT4xPjk+QT5JP" + "k0+VT5ZPmE+ZT5pPnE+eT59PoU+iT6RPq0+tT7BPsU+yT7NPtE+2T7dPuE+5T7pPu0+8T71Pvk/AT8FPwk/GT8dPyE/JT8tP" + "zE/NT9JP00/UT9VP1k/ZT9tP4E/iT+RP5U/nT+tP7E/wT/JP9E/1T/ZP90/5T/tP/E/9T/9PAFABUAJQA1AEUAVQBlAHUAhQ" + "CVAKUP//C1AOUBBQEVATUBVQFlAXUBtQHVAeUCBQIlAjUCRQJ1ArUC9QMFAxUDJQM1A0UDVQNlA3UDhQOVA7UD1QP1BAUEFQ" + "QlBEUEVQRlBJUEpQS1BNUFBQUVBSUFNQVFBWUFdQWFBZUFtQXVBeUF9QYFBhUGJQY1BkUGZQZ1BoUGlQalBrUG1QblBvUHBQ" + "cVByUHNQdFB1UHhQeVB6UHxQfVCBUIJQg1CEUIZQh1CJUIpQi1CMUI5Qj1CQUJFQklCTUJRQlVCWUJdQmFCZUJpQm1CcUJ1Q" + "nlCfUKBQoVCiUKRQplCqUKtQrVCuUK9QsFCxULNQtFC1ULZQt1C4ULlQvFC9UL5Qv1DAUMFQwlDDUMRQxVDGUMdQyFDJUMpQ" + "y1DMUM1QzlDQUNFQ0lDTUNRQ1VDXUNhQ2VDbUNxQ3VDeUN9Q4FDhUOJQ41DkUOVQ6FDpUOpQ61DvUPBQ8VDyUPRQ9lD3UPhQ" + "+VD6UPxQ/VD+UP9QAFEBUQJRA1EEUQVRCFH//wlRClEMUQ1RDlEPURBREVETURRRFVEWURdRGFEZURpRG1EcUR1RHlEfUSBR" + "IlEjUSRRJVEmUSdRKFEpUSpRK1EsUS1RLlEvUTBRMVEyUTNRNFE1UTZRN1E4UTlROlE7UTxRPVE+UUJRR1FKUUxRTlFPUVBR" + "UlFTUVdRWFFZUVtRXVFeUV9RYFFhUWNRZFFmUWdRaVFqUW9RclF6UX5Rf1GDUYRRhlGHUYpRi1GOUY9RkFGRUZNRlFGYUZpR" + "nVGeUZ9RoVGjUaZRp1GoUalRqlGtUa5RtFG4UblRulG+Ub9RwVHCUcNRxVHIUcpRzVHOUdBR0lHTUdRR1VHWUddR2FHZUdpR" + "3FHeUd9R4lHjUeVR5lHnUehR6VHqUexR7lHxUfJR9FH3Uf5RBFIFUglSC1IMUg9SEFITUhRSFVIcUh5SH1IhUiJSI1IlUiZS" + "J1IqUixSL1IxUjJSNFI1UjxSPlJEUkVSRlJHUkhSSVJLUk5ST1JSUlNSVVJXUlhS//9ZUlpSW1JdUl9SYFJiUmNSZFJmUmhS" + "a1JsUm1SblJwUnFSc1J0UnVSdlJ3UnhSeVJ6UntSfFJ+UoBSg1KEUoVShlKHUolSilKLUoxSjVKOUo9SkVKSUpRSlVKWUpdS" + "mFKZUppSnFKkUqVSplKnUq5Sr1KwUrRStVK2UrdSuFK5UrpSu1K8Ur1SwFLBUsJSxFLFUsZSyFLKUsxSzVLOUs9S0VLTUtRS" + "1VLXUtlS2lLbUtxS3VLeUuBS4VLiUuNS5VLmUudS6FLpUupS61LsUu1S7lLvUvFS8lLzUvRS9VL2UvdS+FL7UvxS/VIBUwJT" + "A1MEUwdTCVMKUwtTDFMOUxFTElMTUxRTGFMbUxxTHlMfUyJTJFMlUydTKFMpUytTLFMtUy9TMFMxUzJTM1M0UzVTNlM3UzhT" + "PFM9U0BTQlNEU0ZTS1NMU01TUFNUU1hTWVNbU11TZVNoU2pTbFNtU3JTdlN5U3tTfFN9U35TgFOBU4NTh1OIU4pTjlOPU///" + "kFORU5JTk1OUU5ZTl1OZU5tTnFOeU6BToVOkU6dTqlOrU6xTrVOvU7BTsVOyU7NTtFO1U7dTuFO5U7pTvFO9U75TwFPDU8RT" + "xVPGU8dTzlPPU9BT0lPTU9VT2lPcU91T3lPhU+JT51P0U/pT/lP/UwBUAlQFVAdUC1QUVBhUGVQaVBxUIlQkVCVUKlQwVDNU" + "NlQ3VDpUPVQ/VEFUQlREVEVUR1RJVExUTVROVE9UUVRaVF1UXlRfVGBUYVRjVGVUZ1RpVGpUa1RsVG1UblRvVHBUdFR5VHpU" + "flR/VIFUg1SFVIdUiFSJVIpUjVSRVJNUl1SYVJxUnlSfVKBUoVSiVKVUrlSwVLJUtVS2VLdUuVS6VLxUvlTDVMVUylTLVNZU" + "2FTbVOBU4VTiVONU5FTrVOxU71TwVPFU9FT1VPZU91T4VPlU+1T+VABVAlUDVQRVBVUIVQpVC1UMVQ1VDlUSVRNVFVUWVRdV" + "GFUZVRpVHFUdVR5VH1UhVSVVJlX//yhVKVUrVS1VMlU0VTVVNlU4VTlVOlU7VT1VQFVCVUVVR1VIVUtVTFVNVU5VT1VRVVJV" + "U1VUVVdVWFVZVVpVW1VdVV5VX1VgVWJVY1VoVWlVa1VvVXBVcVVyVXNVdFV5VXpVfVV/VYVVhlWMVY1VjlWQVZJVk1WVVZZV" + "l1WaVZtVnlWgVaFVolWjVaRVpVWmVahVqVWqVatVrFWtVa5Vr1WwVbJVtFW2VbhVulW8Vb9VwFXBVcJVw1XGVcdVyFXKVctV" + "zlXPVdBV1VXXVdhV2VXaVdtV3lXgVeJV51XpVe1V7lXwVfFV9FX2VfhV+VX6VftV/FX/VQJWA1YEVgVWBlYHVgpWC1YNVhBW" + "EVYSVhNWFFYVVhZWF1YZVhpWHFYdViBWIVYiViVWJlYoVilWKlYrVi5WL1YwVjNWNVY3VjhWOlY8Vj1WPlZAVkFWQlZDVkRW" + "RVZGVkdWSFZJVkpWS1ZPVlBWUVZSVlNWVVZWVlpWW1ZdVl5WX1ZgVmFW//9jVmVWZlZnVm1WblZvVnBWclZzVnRWdVZ3VnhW" + "eVZ6Vn1WflZ/VoBWgVaCVoNWhFaHVohWiVaKVotWjFaNVpBWkVaSVpRWlVaWVpdWmFaZVppWm1acVp1WnlafVqBWoVaiVqRW" + "pVamVqdWqFapVqpWq1asVq1WrlawVrFWslazVrRWtVa2VrhWuVa6VrtWvVa+Vr9WwFbBVsJWw1bEVsVWxlbHVshWyVbLVsxW" + "zVbOVs9W0FbRVtJW01bVVtZW2FbZVtxW41blVuZW51boVulW6lbsVu5W71byVvNW9lb3VvhW+1b8VgBXAVcCVwVXB1cLVwxX" + "DVcOVw9XEFcRVxJXE1cUVxVXFlcXVxhXGVcaVxtXHVceVyBXIVciVyRXJVcmVydXK1cxVzJXNFc1VzZXN1c4VzxXPVc/V0FX" + "Q1dEV0VXRldIV0lXS1dSV1NXVFdVV1ZXWFdZV2JXY1dlV2dXbFduV3BXcVdyV3RXdVd4V3lXeld9V35Xf1eAV///gVeHV4hX" + "iVeKV41XjlePV5BXkVeUV5VXlleXV5hXmVeaV5xXnVeeV59XpVeoV6pXrFevV7BXsVezV7VXtle3V7lXule7V7xXvVe+V79X" + "wFfBV8RXxVfGV8dXyFfJV8pXzFfNV9BX0VfTV9ZX11fbV9xX3lfhV+JX41flV+ZX51foV+lX6lfrV+xX7lfwV/FX8lfzV/VX" + "9lf3V/tX/Ff+V/9XAVgDWARYBVgIWAlYClgMWA5YD1gQWBJYE1gUWBZYF1gYWBpYG1gcWB1YH1giWCNYJVgmWCdYKFgpWCtY" + "LFgtWC5YL1gxWDJYM1g0WDZYN1g4WDlYOlg7WDxYPVg+WD9YQFhBWEJYQ1hFWEZYR1hIWElYSlhLWE5YT1hQWFJYU1hVWFZY" + "V1hZWFpYW1hcWF1YX1hgWGFYYlhjWGRYZlhnWGhYaVhqWG1YblhvWHBYcVhyWHNYdFh1WHZYd1h4WHlYelh7WHxYfVh/WIJY" + "hFiGWIdYiFiKWItYjFj//41YjliPWJBYkViUWJVYlliXWJhYm1icWJ1YoFihWKJYo1ikWKVYplinWKpYq1isWK1YrlivWLBY" + "sViyWLNYtFi1WLZYt1i4WLlYuli7WL1Yvli/WMBYwljDWMRYxljHWMhYyVjKWMtYzFjNWM5Yz1jQWNJY01jUWNZY11jYWNlY" + "2ljbWNxY3VjeWN9Y4FjhWOJY41jlWOZY51joWOlY6ljtWO9Y8VjyWPRY9Vj3WPhY+lj7WPxY/Vj+WP9YAFkBWQNZBVkGWQhZ" + "CVkKWQtZDFkOWRBZEVkSWRNZF1kYWRtZHVkeWSBZIVkiWSNZJlkoWSxZMFkyWTNZNVk2WTtZPVk+WT9ZQFlDWUVZRllKWUxZ" + "TVlQWVJZU1lZWVtZXFldWV5ZX1lhWWNZZFlmWWdZaFlpWWpZa1lsWW1ZbllvWXBZcVlyWXVZd1l6WXtZfFl+WX9ZgFmFWYlZ" + "i1mMWY5Zj1mQWZFZlFmVWZhZmlmbWZxZnVmfWaBZoVmiWaZZ//+nWaxZrVmwWbFZs1m0WbVZtlm3WbhZulm8Wb1Zv1nAWcFZ" + "wlnDWcRZxVnHWchZyVnMWc1ZzlnPWdVZ1lnZWdtZ3lnfWeBZ4VniWeRZ5lnnWelZ6lnrWe1Z7lnvWfBZ8VnyWfNZ9Fn1WfZZ" + "91n4WfpZ/Fn9Wf5ZAFoCWgpaC1oNWg5aD1oQWhJaFFoVWhZaF1oZWhpaG1odWh5aIVoiWiRaJlonWihaKlorWixaLVouWi9a" + "MFozWjVaN1o4WjlaOlo7Wj1aPlo/WkFaQlpDWkRaRVpHWkhaS1pMWk1aTlpPWlBaUVpSWlNaVFpWWldaWFpZWltaXFpdWl5a" + "X1pgWmFaY1pkWmVaZlpoWmlaa1psWm1ablpvWnBacVpyWnNaeFp5WntafFp9Wn5agFqBWoJag1qEWoVahlqHWohaiVqKWota" + "jFqNWo5aj1qQWpFak1qUWpVallqXWphamVqcWp1anlqfWqBaoVqiWqNapFqlWqZap1qoWqlaq1qsWv//rVquWq9asFqxWrRa" + "tlq3Wrlaulq7WrxavVq/WsBaw1rEWsVaxlrHWshaylrLWs1azlrPWtBa0VrTWtVa11rZWtpa21rdWt5a31riWuRa5VrnWuha" + "6lrsWu1a7lrvWvBa8lrzWvRa9Vr2Wvda+Fr5Wvpa+1r8Wv1a/lr/WgBbAVsCWwNbBFsFWwZbB1sIWwpbC1sMWw1bDlsPWxBb" + "EVsSWxNbFFsVWxhbGVsaWxtbHFsdWx5bH1sgWyFbIlsjWyRbJVsmWydbKFspWypbK1ssWy1bLlsvWzBbMVszWzVbNls4Wzlb" + "Ols7WzxbPVs+Wz9bQVtCW0NbRFtFW0ZbR1tIW0lbSltLW0xbTVtOW09bUltWW15bYFthW2dbaFtrW21bbltvW3JbdFt2W3db" + "eFt5W3tbfFt+W39bgluGW4pbjVuOW5BbkVuSW5RbllufW6dbqFupW6xbrVuuW69bsVuyW7dbulu7W7xbwFvBW8NbyFvJW8pb" + "y1vNW85bz1v//9Fb1FvVW9Zb11vYW9lb2lvbW9xb4FviW+Nb5lvnW+lb6lvrW+xb7VvvW/Fb8lvzW/Rb9Vv2W/db/Vv+WwBc" + "AlwDXAVcB1wIXAtcDFwNXA5cEFwSXBNcF1wZXBtcHlwfXCBcIVwjXCZcKFwpXCpcK1wtXC5cL1wwXDJcM1w1XDZcN1xDXERc" + "RlxHXExcTVxSXFNcVFxWXFdcWFxaXFtcXFxdXF9cYlxkXGdcaFxpXGpca1xsXG1ccFxyXHNcdFx1XHZcd1x4XHtcfFx9XH5c" + "gFyDXIRchVyGXIdciVyKXItcjlyPXJJck1yVXJ1cnlyfXKBcoVykXKVcplynXKhcqlyuXK9csFyyXLRctly5XLpcu1y8XL5c" + "wFzCXMNcxVzGXMdcyFzJXMpczFzNXM5cz1zQXNFc01zUXNVc1lzXXNhc2lzbXNxc3VzeXN9c4FziXONc51zpXOtc7FzuXO9c" + "8VzyXPNc9Fz1XPZc91z4XPlc+lz8XP1c/lz/XABd//8BXQRdBV0IXQldCl0LXQxdDV0PXRBdEV0SXRNdFV0XXRhdGV0aXRxd" + "HV0fXSBdIV0iXSNdJV0oXSpdK10sXS9dMF0xXTJdM101XTZdN104XTldOl07XTxdP11AXUFdQl1DXURdRV1GXUhdSV1NXU5d" + "T11QXVFdUl1TXVRdVV1WXVddWV1aXVxdXl1fXWBdYV1iXWNdZF1lXWZdZ11oXWpdbV1uXXBdcV1yXXNddV12XXddeF15XXpd" + "e118XX1dfl1/XYBdgV2DXYRdhV2GXYddiF2JXYpdi12MXY1djl2PXZBdkV2SXZNdlF2VXZZdl12YXZpdm12cXZ5dn12gXaFd" + "ol2jXaRdpV2mXaddqF2pXapdq12sXa1drl2vXbBdsV2yXbNdtF21XbZduF25Xbpdu128Xb1dvl2/XcBdwV3CXcNdxF3GXcdd" + "yF3JXcpdy13MXc5dz13QXdFd0l3TXdRd1V3WXddd2F3ZXdpd3F3fXeBd413kXepd7F3tXf//8F31XfZd+F35Xfpd+138Xf9d" + "AF4EXgdeCV4KXgteDV4OXhJeE14XXh5eH14gXiFeIl4jXiReJV4oXileKl4rXixeL14wXjJeM140XjVeNl45XjpePl4/XkBe" + "QV5DXkZeR15IXkleSl5LXk1eTl5PXlBeUV5SXlNeVl5XXlheWV5aXlxeXV5fXmBeY15kXmVeZl5nXmheaV5qXmtebF5tXm5e" + "b15wXnFedV53Xnlefl6BXoJeg16FXoheiV6MXo1ejl6SXphem16dXqFeol6jXqReqF6pXqpeq16sXq5er16wXrFesl60Xrpe" + "u168Xr1ev17AXsFewl7DXsRexV7GXsdeyF7LXsxezV7OXs9e0F7UXtVe117YXtle2l7cXt1e3l7fXuBe4V7iXuNe5F7lXuZe" + "517pXute7F7tXu5e717wXvFe8l7zXvVe+F75Xvte/F79XgVfBl8HXwlfDF8NXw5fEF8SXxRfFl8ZXxpfHF8dXx5fIV8iXyNf" + "JF///yhfK18sXy5fMF8yXzNfNF81XzZfN184XztfPV8+Xz9fQV9CX0NfRF9FX0ZfR19IX0lfSl9LX0xfTV9OX09fUV9UX1lf" + "Wl9bX1xfXl9fX2BfY19lX2dfaF9rX25fb19yX3RfdV92X3hfel99X35ff1+DX4ZfjV+OX49fkV+TX5Rfll+aX5tfnV+eX59f" + "oF+iX6NfpF+lX6Zfp1+pX6tfrF+vX7BfsV+yX7NftF+2X7hfuV+6X7tfvl+/X8BfwV/CX8dfyF/KX8tfzl/TX9Rf1V/aX9tf" + "3F/eX99f4l/jX+Vf5l/oX+lf7F/vX/Bf8l/zX/Rf9l/3X/lf+l/8XwdgCGAJYAtgDGAQYBFgE2AXYBhgGmAeYB9gImAjYCRg" + "LGAtYC5gMGAxYDJgM2A0YDZgN2A4YDlgOmA9YD5gQGBEYEVgRmBHYEhgSWBKYExgTmBPYFFgU2BUYFZgV2BYYFtgXGBeYF9g" + "YGBhYGVgZmBuYHFgcmB0YHVgd2B+YIBg//+BYIJghWCGYIdgiGCKYItgjmCPYJBgkWCTYJVgl2CYYJlgnGCeYKFgomCkYKVg" + "p2CpYKpgrmCwYLNgtWC2YLdguWC6YL1gvmC/YMBgwWDCYMNgxGDHYMhgyWDMYM1gzmDPYNBg0mDTYNRg1mDXYNlg22DeYOFg" + "4mDjYORg5WDqYPFg8mD1YPdg+GD7YPxg/WD+YP9gAmEDYQRhBWEHYQphC2EMYRBhEWESYRNhFGEWYRdhGGEZYRthHGEdYR5h" + "IWEiYSVhKGEpYSphLGEtYS5hL2EwYTFhMmEzYTRhNWE2YTdhOGE5YTphO2E8YT1hPmFAYUFhQmFDYURhRWFGYUdhSWFLYU1h" + "T2FQYVJhU2FUYVZhV2FYYVlhWmFbYVxhXmFfYWBhYWFjYWRhZWFmYWlhamFrYWxhbWFuYW9hcWFyYXNhdGF2YXhheWF6YXth" + "fGF9YX5hf2GAYYFhgmGDYYRhhWGGYYdhiGGJYYphjGGNYY9hkGGRYZJhk2GVYf//lmGXYZhhmWGaYZthnGGeYZ9hoGGhYaJh" + "o2GkYaVhpmGqYathrWGuYa9hsGGxYbJhs2G0YbVhtmG4YblhumG7YbxhvWG/YcBhwWHDYcRhxWHGYcdhyWHMYc1hzmHPYdBh" + "02HVYdZh12HYYdlh2mHbYdxh3WHeYd9h4GHhYeJh42HkYeVh52HoYelh6mHrYexh7WHuYe9h8GHxYfJh82H0YfZh92H4Yflh" + "+mH7Yfxh/WH+YQBiAWICYgNiBGIFYgdiCWITYhRiGWIcYh1iHmIgYiNiJmInYihiKWIrYi1iL2IwYjFiMmI1YjZiOGI5Yjpi" + "O2I8YkJiRGJFYkZiSmJPYlBiVWJWYldiWWJaYlxiXWJeYl9iYGJhYmJiZGJlYmhicWJyYnRidWJ3YnhiemJ7Yn1igWKCYoNi" + "hWKGYodiiGKLYoxijWKOYo9ikGKUYplinGKdYp5io2KmYqdiqWKqYq1irmKvYrBismKzYrRitmK3YrhiumK+YsBiwWL//8Ni" + "y2LPYtFi1WLdYt5i4GLhYuRi6mLrYvBi8mL1Yvhi+WL6YvtiAGMDYwRjBWMGYwpjC2MMYw1jD2MQYxJjE2MUYxVjF2MYYxlj" + "HGMmYydjKWMsYy1jLmMwYzFjM2M0YzVjNmM3YzhjO2M8Yz5jP2NAY0FjRGNHY0hjSmNRY1JjU2NUY1ZjV2NYY1ljWmNbY1xj" + "XWNgY2RjZWNmY2hjamNrY2xjb2NwY3Jjc2N0Y3VjeGN5Y3xjfWN+Y39jgWODY4RjhWOGY4tjjWORY5NjlGOVY5djmWOaY5tj" + "nGOdY55jn2OhY6RjpmOrY69jsWOyY7VjtmO5Y7tjvWO/Y8BjwWPCY8NjxWPHY8hjymPLY8xj0WPTY9Rj1WPXY9hj2WPaY9tj" + "3GPdY99j4mPkY+Vj5mPnY+hj62PsY+5j72PwY/Fj82P1Y/dj+WP6Y/tj/GP+YwNkBGQGZAdkCGQJZApkDWQOZBFkEmQVZBZk" + "F2QYZBlkGmQdZB9kImQjZCRk//8lZCdkKGQpZCtkLmQvZDBkMWQyZDNkNWQ2ZDdkOGQ5ZDtkPGQ+ZEBkQmRDZElkS2RMZE1k" + "TmRPZFBkUWRTZFVkVmRXZFlkWmRbZFxkXWRfZGBkYWRiZGNkZGRlZGZkaGRqZGtkbGRuZG9kcGRxZHJkc2R0ZHVkdmR3ZHtk" + "fGR9ZH5kf2SAZIFkg2SGZIhkiWSKZItkjGSNZI5kj2SQZJNklGSXZJhkmmSbZJxknWSfZKBkoWSiZKNkpWSmZKdkqGSqZKtk" + "r2SxZLJks2S0ZLZkuWS7ZL1kvmS/ZMFkw2TEZMZkx2TIZMlkymTLZMxkz2TRZNNk1GTVZNZk2WTaZNtk3GTdZN9k4GThZONk" + "5WTnZOhk6WTqZOtk7GTtZO5k72TwZPFk8mTzZPRk9WT2ZPdk+GT5ZPpk+2T8ZP1k/mT/ZAFlAmUDZQRlBWUGZQdlCGUKZQtl" + "DGUNZQ5lD2UQZRFlE2UUZRVlFmUXZRllGmUbZRxlHWUeZR9lIGUhZf//ImUjZSRlJmUnZShlKWUqZSxlLWUwZTFlMmUzZTdl" + "OmU8ZT1lQGVBZUJlQ2VEZUZlR2VKZUtlTWVOZVBlUmVTZVRlV2VYZVplXGVfZWBlYWVkZWVlZ2VoZWllamVtZW5lb2VxZXNl" + "dWV2ZXhleWV6ZXtlfGV9ZX5lf2WAZYFlgmWDZYRlhWWGZYhliWWKZY1ljmWPZZJllGWVZZZlmGWaZZ1lnmWgZaJlo2WmZahl" + "qmWsZa5lsWWyZbNltGW1ZbZlt2W4Zbplu2W+Zb9lwGXCZcdlyGXJZcplzWXQZdFl02XUZdVl2GXZZdpl22XcZd1l3mXfZeFl" + "42XkZepl62XyZfNl9GX1Zfhl+WX7Zfxl/WX+Zf9lAWYEZgVmB2YIZglmC2YNZhBmEWYSZhZmF2YYZhpmG2YcZh5mIWYiZiNm" + "JGYmZilmKmYrZixmLmYwZjJmM2Y3ZjhmOWY6ZjtmPWY/ZkBmQmZEZkVmRmZHZkhmSWZKZk1mTmZQZlFmWGb//1lmW2ZcZl1m" + "XmZgZmJmY2ZlZmdmaWZqZmtmbGZtZnFmcmZzZnVmeGZ5ZntmfGZ9Zn9mgGaBZoNmhWaGZohmiWaKZotmjWaOZo9mkGaSZpNm" + "lGaVZphmmWaaZptmnGaeZp9moGahZqJmo2akZqVmpmapZqpmq2asZq1mr2awZrFmsmazZrVmtma3Zrhmuma7ZrxmvWa/ZsBm" + "wWbCZsNmxGbFZsZmx2bIZslmymbLZsxmzWbOZs9m0GbRZtJm02bUZtVm1mbXZthm2mbeZt9m4GbhZuJm42bkZuVm52boZupm" + "62bsZu1m7mbvZvFm9Wb2Zvhm+mb7Zv1mAWcCZwNnBGcFZwZnB2cMZw5nD2cRZxJnE2cWZxhnGWcaZxxnHmcgZyFnImcjZyRn" + "JWcnZylnLmcwZzJnM2c2ZzdnOGc5ZztnPGc+Zz9nQWdEZ0VnR2dKZ0tnTWdSZ1RnVWdXZ1hnWWdaZ1tnXWdiZ2NnZGdmZ2dn" + "a2dsZ25ncWd0Z3Zn//94Z3lnemd7Z31ngGeCZ4NnhWeGZ4hnimeMZ41njmePZ5FnkmeTZ5RnlmeZZ5tnn2egZ6FnpGemZ6ln" + "rGeuZ7Fnsme0Z7lnume7Z7xnvWe+Z79nwGfCZ8VnxmfHZ8hnyWfKZ8tnzGfNZ85n1WfWZ9dn22ffZ+Fn42fkZ+Zn52foZ+pn" + "62ftZ+5n8mf1Z/Zn92f4Z/ln+mf7Z/xn/mcBaAJoA2gEaAZoDWgQaBJoFGgVaBhoGWgaaBtoHGgeaB9oIGgiaCNoJGglaCZo" + "J2goaCtoLGgtaC5oL2gwaDFoNGg1aDZoOmg7aD9oR2hLaE1oT2hSaFZoV2hYaFloWmhbaFxoXWheaF9oamhsaG1obmhvaHBo" + "cWhyaHNodWh4aHloemh7aHxofWh+aH9ogGiCaIRoh2iIaIloimiLaIxojWiOaJBokWiSaJRolWiWaJhomWiaaJtonGidaJ5o" + "n2igaKFoo2ikaKVoqWiqaKtorGiuaLFosmi0aLZot2i4aP//uWi6aLtovGi9aL5ov2jBaMNoxGjFaMZox2jIaMpozGjOaM9o" + "0GjRaNNo1GjWaNdo2WjbaNxo3WjeaN9o4WjiaORo5WjmaOdo6GjpaOpo62jsaO1o72jyaPNo9Gj2aPdo+Gj7aP1o/mj/aABp" + "AmkDaQRpBmkHaQhpCWkKaQxpD2kRaRNpFGkVaRZpF2kYaRlpGmkbaRxpHWkeaSFpImkjaSVpJmknaShpKWkqaStpLGkuaS9p" + "MWkyaTNpNWk2aTdpOGk6aTtpPGk+aUBpQWlDaURpRWlGaUdpSGlJaUppS2lMaU1pTmlPaVBpUWlSaVNpVWlWaVhpWWlbaVxp" + "X2lhaWJpZGllaWdpaGlpaWppbGltaW9pcGlyaXNpdGl1aXZpeml7aX1pfml/aYFpg2mFaYppi2mMaY5pj2mQaZFpkmmTaZZp" + "l2mZaZppnWmeaZ9poGmhaaJpo2mkaaVppmmpaapprGmuaa9psGmyabNptWm2abhpuWm6abxpvWn//75pv2nAacJpw2nEacVp" + "xmnHachpyWnLac1pz2nRadJp02nVadZp12nYadlp2mncad1p3mnhaeJp42nkaeVp5mnnaehp6Wnqaetp7Gnuae9p8GnxafNp" + "9Gn1afZp92n4aflp+mn7afxp/mkAagFqAmoDagRqBWoGagdqCGoJagtqDGoNag5qD2oQahFqEmoTahRqFWoWahlqGmobahxq" + "HWoeaiBqImojaiRqJWomaidqKWoraixqLWouajBqMmozajRqNmo3ajhqOWo6ajtqPGo/akBqQWpCakNqRWpGakhqSWpKaktq" + "TGpNak5qT2pRalJqU2pUalVqVmpXalpqXGpdal5qX2pgamJqY2pkamZqZ2poamlqampramxqbWpuam9qcGpyanNqdGp1anZq" + "d2p4anpqe2p9an5qf2qBaoJqg2qFaoZqh2qIaolqimqLaoxqjWqPapJqk2qUapVqlmqYaplqmmqbapxqnWqeap9qoWqiaqNq" + "pGqlaqZq//+naqhqqmqtaq5qr2qwarFqsmqzarRqtWq2ardquGq5arpqu2q8ar1qvmq/asBqwWrCasNqxGrFasZqx2rIaslq" + "ymrLasxqzWrOas9q0GrRatJq02rUatVq1mrXathq2Wraattq3Grdat5q32rgauFq4mrjauRq5Wrmaudq6Grpaupq62rsau1q" + "7mrvavBq8WryavNq9Gr1avZq92r4avlq+mr7avxq/Wr+av9qAGsBawJrA2sEawVrBmsHawhrCWsKawtrDGsNaw5rD2sQaxFr" + "EmsTaxRrFWsWaxdrGGsZaxprG2scax1rHmsfayVrJmsoaylrKmsrayxrLWsuay9rMGsxazNrNGs1azZrOGs7azxrPWs/a0Br" + "QWtCa0RrRWtIa0prS2tNa05rT2tQa1FrUmtTa1RrVWtWa1drWGtaa1trXGtda15rX2tga2FraGtpa2trbGtta25rb2twa3Fr" + "cmtza3RrdWt2a3dreGt6a31rfmt/a4BrhWuIa///jGuOa49rkGuRa5RrlWuXa5hrmWuca51rnmufa6Bromuja6RrpWuma6dr" + "qGupa6trrGuta65rr2uwa7Frsmu2a7hruWu6a7trvGu9a75rwGvDa8RrxmvHa8hryWvKa8xrzmvQa9Fr2Gvaa9xr3Wvea99r" + "4Gvia+Nr5Gvla+Zr52voa+lr7Gvta+5r8Gvxa/Jr9Gv2a/dr+Gv6a/tr/Gv+a/9rAGwBbAJsA2wEbAhsCWwKbAtsDGwObBJs" + "F2wcbB1sHmwgbCNsJWwrbCxsLWwxbDNsNmw3bDlsOmw7bDxsPmw/bENsRGxFbEhsS2xMbE1sTmxPbFFsUmxTbFZsWGxZbFps" + "YmxjbGVsZmxnbGtsbGxtbG5sb2xxbHNsdWx3bHhsemx7bHxsf2yAbIRsh2yKbItsjWyObJFskmyVbJZsl2yYbJpsnGydbJ5s" + "oGyibKhsrGyvbLBstGy1bLZst2y6bMBswWzCbMNsxmzHbMhsy2zNbM5sz2zRbNJs2Gz//9ls2mzcbN1s32zkbOZs52zpbOxs" + "7WzybPRs+Wz/bABtAm0DbQVtBm0IbQltCm0NbQ9tEG0RbRNtFG0VbRZtGG0cbR1tH20gbSFtIm0jbSRtJm0obSltLG0tbS9t" + "MG00bTZtN204bTptP21AbUJtRG1JbUxtUG1VbVZtV21YbVttXW1fbWFtYm1kbWVtZ21obWttbG1tbXBtcW1ybXNtdW12bXlt" + "em17bX1tfm1/bYBtgW2DbYRthm2HbYpti22NbY9tkG2SbZZtl22YbZltmm2cbaJtpW2sba1tsG2xbbNttG22bbdtuW26bbtt" + "vG29bb5twW3CbcNtyG3JbcptzW3Obc9t0G3SbdNt1G3Vbddt2m3bbdxt323ibeNt5W3nbeht6W3qbe1t723wbfJt9G31bfZt" + "+G36bf1t/m3/bQBuAW4CbgNuBG4GbgduCG4JbgtuD24SbhNuFW4YbhluG24cbh5uH24ibiZuJ24obipuLG4ubjBuMW4zbjVu" + "//82bjduOW47bjxuPW4+bj9uQG5BbkJuRW5GbkduSG5JbkpuS25Mbk9uUG5RblJuVW5XblluWm5cbl1uXm5gbmFuYm5jbmRu" + "ZW5mbmduaG5pbmpubG5tbm9ucG5xbnJuc250bnVudm53bnhueW56bntufG59boBugW6CboRuh26Ibopui26Mbo1ujm6RbpJu" + "k26UbpVulm6Xbplumm6bbp1unm6gbqFuo26kbqZuqG6pbqturG6tbq5usG6zbrVuuG65brxuvm6/bsBuw27EbsVuxm7Ibslu" + "ym7Mbs1uzm7QbtJu1m7Ybtlu227cbt1u427nbupu627sbu1u7m7vbvBu8W7ybvNu9W72bvdu+G76bvtu/G79bv5u/24AbwFv" + "A28EbwVvB28IbwpvC28Mbw1vDm8QbxFvEm8WbxdvGG8ZbxpvG28cbx1vHm8fbyFvIm8jbyVvJm8nbyhvLG8ubzBvMm80bzVv" + "N284bzlvOm87bzxvPW8/b0BvQW9Cb///Q29Eb0VvSG9Jb0pvTG9Ob09vUG9Rb1JvU29Ub1VvVm9Xb1lvWm9bb11vX29gb2Fv" + "Y29kb2VvZ29ob2lvam9rb2xvb29wb3Fvc291b3Zvd295b3tvfW9+b39vgG+Bb4Jvg2+Fb4Zvh2+Kb4tvj2+Qb5Fvkm+Tb5Rv" + "lW+Wb5dvmG+Zb5pvm2+db55vn2+gb6Jvo2+kb6Vvpm+ob6lvqm+rb6xvrW+ub69vsG+xb7JvtG+1b7dvuG+6b7tvvG+9b75v" + "v2/Bb8NvxG/Fb8Zvx2/Ib8pvy2/Mb81vzm/Pb9Bv02/Ub9Vv1m/Xb9hv2W/ab9tv3G/db99v4m/jb+Rv5W/mb+dv6G/pb+pv" + "62/sb+1v8G/xb/Jv82/0b/Vv9m/3b/hv+W/6b/tv/G/9b/5v/28AcAFwAnADcARwBXAGcAdwCHAJcApwC3AMcA1wDnAPcBBw" + "EnATcBRwFXAWcBdwGHAZcBxwHXAecB9wIHAhcCJwJHAlcCZwJ3AocClwKnD//ytwLHAtcC5wL3AwcDFwMnAzcDRwNnA3cDhw" + "OnA7cDxwPXA+cD9wQHBBcEJwQ3BEcEVwRnBHcEhwSXBKcEtwTXBOcFBwUXBScFNwVHBVcFZwV3BYcFlwWnBbcFxwXXBfcGBw" + "YXBicGNwZHBlcGZwZ3BocGlwanBucHFwcnBzcHRwd3B5cHpwe3B9cIFwgnCDcIRwhnCHcIhwi3CMcI1wj3CQcJFwk3CXcJhw" + "mnCbcJ5wn3CgcKFwonCjcKRwpXCmcKdwqHCpcKpwsHCycLRwtXC2cLpwvnC/cMRwxXDGcMdwyXDLcMxwzXDOcM9w0HDRcNJw" + "03DUcNVw1nDXcNpw3HDdcN5w4HDhcOJw43DlcOpw7nDwcPFw8nDzcPRw9XD2cPhw+nD7cPxw/nD/cABxAXECcQNxBHEFcQZx" + "B3EIcQtxDHENcQ5xD3ERcRJxFHEXcRtxHHEdcR5xH3EgcSFxInEjcSRxJXEncShxKXEqcStxLHEtcS5xMnEzcTRx//81cTdx" + "OHE5cTpxO3E8cT1xPnE/cUBxQXFCcUNxRHFGcUdxSHFJcUtxTXFPcVBxUXFScVNxVHFVcVZxV3FYcVlxWnFbcV1xX3FgcWFx" + "YnFjcWVxaXFqcWtxbHFtcW9xcHFxcXRxdXF2cXdxeXF7cXxxfnF/cYBxgXGCcYNxhXGGcYdxiHGJcYtxjHGNcY5xkHGRcZJx" + "k3GVcZZxl3GacZtxnHGdcZ5xoXGicaNxpHGlcaZxp3Gpcapxq3Gtca5xr3GwcbFxsnG0cbZxt3G4cbpxu3G8cb1xvnG/ccBx" + "wXHCccRxxXHGccdxyHHJccpxy3HMcc1xz3HQcdFx0nHTcdZx13HYcdlx2nHbcdxx3XHecd9x4XHiceNx5HHmcehx6XHqcetx" + "7HHtce9x8HHxcfJx83H0cfVx9nH3cfhx+nH7cfxx/XH+cf9xAHIBcgJyA3IEcgVyB3IIcglyCnILcgxyDXIOcg9yEHIRchJy" + "E3IUchVyFnIXchhyGXIacv//G3Icch5yH3IgciFyInIjciRyJXImcidyKXIrci1yLnIvcjJyM3I0cjpyPHI+ckByQXJCckNy" + "RHJFckZySXJKcktyTnJPclByUXJTclRyVXJXclhyWnJccl5yYHJjcmRyZXJocmpya3Jscm1ycHJxcnNydHJ2cndyeHJ7cnxy" + "fXKCcoNyhXKGcodyiHKJcoxyjnKQcpFyk3KUcpVylnKXcphymXKacptynHKdcp5yoHKhcqJyo3KkcqVypnKncqhyqXKqcqty" + "rnKxcrJys3K1crpyu3K8cr1yvnK/csByxXLGcsdyyXLKcstyzHLPctFy03LUctVy1nLYctpy23L/////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////wAwATACMLcAyQLHAqgAAzAFMBQgXv8WICYgGCAZIBwgHSAUMBUw" + "CDAJMAowCzAMMA0wDjAPMBYwFzAQMBEwsQDXAPcANiInIigiESIPIioiKSIIIjciGiKlIiUiICISI5kiKyIuImEiTCJIIj0i" + "HSJgIm4ibyJkImUiHiI1IjQiQiZAJrAAMiAzIAMhBP+kAOD/4f8wIKcAFiEGJgUmyyXPJc4lxyXGJaEloCWzJbIlOyCSIZAh" + "kSGTIRMw////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////9wIXEhciFzIXQhdSF2IXch" + "eCF5If///////////////4gkiSSKJIskjCSNJI4kjySQJJEkkiSTJJQklSSWJJckmCSZJJokmyR0JHUkdiR3JHgkeSR6JHsk" + "fCR9JH4kfySAJIEkgiSDJIQkhSSGJIckYCRhJGIkYyRkJGUkZiRnJGgkaST/////IDIhMiIyIzIkMiUyJjInMigyKTL/////" + "YCFhIWIhYyFkIWUhZiFnIWghaSFqIWsh////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////Af8C/wP/5f8F/wb/B/8I/wn/Cv8L/wz/Df8O/w//EP8R/xL/E/8U/xX/Fv8X/xj/Gf8a/xv/HP8d/x7/H/8g/yH/" + "Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov87/zz/Pf8+/z//QP9B/0L/Q/9E/0X/" + "Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/W/9c/13/4///////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////0EwQjBDMEQwRTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYw" + "VzBYMFkwWjBbMFwwXTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgwaTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHow" + "ezB8MH0wfjB/MIAwgTCCMIMwhDCFMIYwhzCIMIkwijCLMIwwjTCOMI8wkDCRMJIwkzD/////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////+hMKIwozCkMKUwpjCnMKgwqTCqMKsw" + "rDCtMK4wrzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w" + "0DDRMNIw0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw4jDjMOQw5TDmMOcw6DDpMOow6zDsMO0w7jDvMPAw8TDyMPMw" + "9DD1MPYw////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MDpAOlA6YDpwOoA6kD/////////////////////7EDsgOzA7QD" + "tQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QDxQPGA8cDyAPJA///////////////////Nf42/jn+Ov4//kD+Pf4+/kH+" + "Qv5D/kT+/////zv+PP43/jj+Mf7//zP+NP7/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////xAEEQQSBBMEFAQVBAEEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcE" + "KAQpBCoEKwQsBC0ELgQvBP///////////////////////////////////////zAEMQQyBDMENAQ1BFEENgQ3BDgEOQQ6BDsE" + "PAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBP//////////////////////////////////ygLLAtkC" + "EyAVICUgNSAFIQkhliGXIZghmSEVIh8iIyJSImYiZyK/IlAlUSVSJVMlVCVVJVYlVyVYJVklWiVbJVwlXSVeJV8lYCVhJWIl" + "YyVkJWUlZiVnJWglaSVqJWslbCVtJW4lbyVwJXElciVzJYElgiWDJYQlhSWGJYcl//+IJYkliiWLJYwljSWOJY8lkyWUJZUl" + "vCW9JeIl4yXkJeUlCSaVIhIwHTAeMP////////////////////////////8BAeEAzgHgABMB6QAbAegAKwHtANAB7ABNAfMA" + "0gHyAGsB+gDUAfkA1gHYAdoB3AH8AOoAUQL//0QBSAH//2EC//////////8FMQYxBzEIMQkxCjELMQwxDTEOMQ8xEDERMRIx" + "EzEUMRUxFjEXMRgxGTEaMRsxHDEdMR4xHzEgMSExIjEjMSQxJTEmMScxKDEpMf//////////////////////////////////" + "/////////////////////yEwIjAjMCQwJTAmMCcwKDApMKMyjjOPM5wznTOeM6EzxDPOM9Ez0jPVMzD+4v/k////ISExMv//" + "ECD////////8MJswnDD9MP4wBjCdMJ4wSf5K/kv+TP5N/k7+T/5Q/lH+Uv5U/lX+Vv5X/ln+Wv5b/lz+Xf5e/l/+YP5h/v//" + "Yv5j/mT+Zf5m/mj+af5q/mv+//////////////////////////////////8HMP//////////////////////////////////" + "ACUBJQIlAyUEJQUlBiUHJQglCSUKJQslDCUNJQ4lDyUQJRElEiUTJRQlFSUWJRclGCUZJRolGyUcJR0lHiUfJSAlISUiJSMl" + "JCUlJSYlJyUoJSklKiUrJSwlLSUuJS8lMCUxJTIlMyU0JTUlNiU3JTglOSU6JTslPCU9JT4lPyVAJUElQiVDJUQlRSVGJUcl" + "SCVJJUolSyX////////////////////////////////////////cct1y33LicuNy5HLlcuZy53Lqcuty9XL2cvly/XL+cv9y" + "AHMCcwRzBXMGcwdzCHMJcwtzDHMNcw9zEHMRcxJzFHMYcxlzGnMfcyBzI3MkcyZzJ3Mocy1zL3MwczJzM3M1czZzOnM7czxz" + "PXNAc0FzQnNDc0RzRXNGc0dzSHP//0lzSnNLc0xzTnNPc1FzU3NUc1VzVnNYc1lzWnNbc1xzXXNec19zYXNic2NzZHNlc2Zz" + "Z3Noc2lzanNrc25zcHNxc///////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////cnNzc3RzdXN2c3dz" + "eHN5c3pze3N8c31zf3OAc4FzgnODc4VzhnOIc4pzjHONc49zkHOSc5NzlHOVc5dzmHOZc5pznHOdc55zoHOhc6NzpHOlc6Zz" + "p3Ooc6pzrHOtc7FztHO1c7ZzuHO5c7xzvXO+c79zwXPDc8RzxXPGc8dz///Lc8xzznPSc9Nz1HPVc9Zz13PYc9pz23Pcc91z" + "33Phc+Jz43Pkc+Zz6HPqc+tz7HPuc+9z8HPxc/Nz9HP1c/Zz93P/////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////hz+XP6c/tz/HP9c/5z/3MAdAF0AnQEdAd0CHQLdAx0DXQOdBF0EnQTdBR0FXQWdBd0GHQZdBx0HXQedB90" + "IHQhdCN0JHQndCl0K3QtdC90MXQydDd0OHQ5dDp0O3Q9dD50P3RAdEJ0Q3REdEV0RnRHdEh0SXRKdEt0THRNdP//TnRPdFB0" + "UXRSdFN0VHRWdFh0XXRgdGF0YnRjdGR0ZXRmdGd0aHRpdGp0a3RsdG50b3RxdHJ0c3R0dHV0eHR5dHp0////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////97dHx0fXR/dIJ0hHSFdIZ0iHSJdIp0jHSNdI90kXSSdJN0lHSVdJZ0" + "l3SYdJl0mnSbdJ10n3SgdKF0onSjdKR0pXSmdKp0q3SsdK10rnSvdLB0sXSydLN0tHS1dLZ0t3S4dLl0u3S8dL10vnS/dMB0" + "wXTCdMN0xHTFdMZ0x3T//8h0yXTKdMt0zHTNdM50z3TQdNF003TUdNV01nTXdNh02XTadNt03XTfdOF05XTndOh06XTqdOt0" + "7HTtdPB08XTydP//////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////83T1dPh0+XT6dPt0/HT9dP50" + "AHUBdQJ1A3UFdQZ1B3UIdQl1CnULdQx1DnUQdRJ1FHUVdRZ1F3UbdR11HnUgdSF1InUjdSR1JnUndSp1LnU0dTZ1OXU8dT11" + "P3VBdUJ1Q3VEdUZ1R3VJdUp1TXVQdVF1UnVTdVV1VnVXdVh1//9ddV51X3VgdWF1YnVjdWR1Z3VodWl1a3VsdW11bnVvdXB1" + "cXVzdXV1dnV3dXp1e3V8dX11fnWAdYF1gnWEdYV1h3X/////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////4h1iXWKdYx1jXWOdZB1k3WVdZh1m3WcdZ51onWmdad1qHWpdap1rXW2dbd1unW7db91wHXBdcZ1y3XMdc51z3XQddF1" + "03XXddl12nXcdd1133XgdeF15XXpdex17XXude918nXzdfV19nX3dfh1+nX7df11/nUCdgR2BnYHdv//CHYJdgt2DXYOdg92" + "EXYSdhN2FHYWdhp2HHYddh52IXYjdid2KHYsdi52L3YxdjJ2NnY3djl2OnY7dj12QXZCdkR2////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////9FdkZ2R3ZIdkl2SnZLdk52T3ZQdlF2UnZTdlV2V3ZYdll2WnZbdl12X3ZgdmF2" + "YnZkdmV2ZnZndmh2aXZqdmx2bXZudnB2cXZydnN2dHZ1dnZ2d3Z5dnp2fHZ/doB2gXaDdoV2iXaKdox2jXaPdpB2knaUdpV2" + "l3aYdpp2m3b//5x2nXaedp92oHahdqJ2o3aldqZ2p3aodql2qnardqx2rXavdrB2s3a1drZ2t3a4drl2una7drx2vXa+dsB2" + "wXbDdkpVP5bDVyhjzlQJVcBUkXZMdjyF7nd+go14MXKYlo2XKGyJW/pPCWOXZrhc+oBIaK6AAmbOdvlRVmWscfF/hIiyUGVZ" + "ymGzb62CTGNSYu1TJ1QGe2tRpHX0XdRiy412l4piGYBdVziXYn84cn12z2d+dkZkcE8ljdxiF3qRZe1zLGRzYiyCgZh/Z0hy" + "bmLMYjRP43RKU55Syn6mkC5ehmicaYCB0X7SaMV4jIZRlY1QJIzegt6ABVMSiWVSxHbHdsl2y3bMdtN21XbZdtp23Hbddt52" + "4HbhduJ243bkduZ253bodul26nbrdux27XbwdvN29Xb2dvd2+nb7dv12/3YAdwJ3A3cFdwZ3CncMdw53D3cQdxF3EncTdxR3" + "FXcWdxd3GHcbdxx3HXcedyF3I3ckdyV3J3cqdyt3//8sdy53MHcxdzJ3M3c0dzl3O3c9dz53P3dCd0R3RXdGd0h3SXdKd0t3" + "THdNd053T3dSd1N3VHdVd1Z3V3dYd1l3XHeEhfmW3U8hWHGZnVuxYqVitGZ5jI2cBnJvZ5F4smBRUxdTiI/MgB2NoZQNUMhy" + "B1nrYBlxq4hUWe+CLGcoeyld934tdfVsZo74jzyQO5/UaxmRFHt8X6d41oQ9hdVr2WvWawFeh175de2VXWUKX8Vfn4/BWMKB" + "f5Bblq2XuY8WfyyNQWK/T9hTXlOoj6mPq49NkAdoal+YgWiI1pyLYStSKnZsX4xl0m/obr5bSGR1UbBRxGcZTsl5fJmzcF13" + "Xndfd2B3ZHdnd2l3andtd253b3dwd3F3cndzd3R3dXd2d3d3eHd6d3t3fHeBd4J3g3eGd4d3iHeJd4p3i3ePd5B3k3eUd5V3" + "lneXd5h3mXead5t3nHedd553oXejd6R3pneod6t3rXeud693sXeyd7R3tne3d7h3uXe6d///vHe+d8B3wXfCd8N3xHfFd8Z3" + "x3fId8l3ynfLd8x3znfPd9B30XfSd9N31HfVd9Z32HfZd9p33Xfed9934Hfhd+R3xXV2Xrtz4IOtZOhitZTibFpTw1IPZMKU" + "lHsvTxteNoIWgYqBJG7KbHOaVWNcU/pUZYjgVw1OA15laz986JAWYOZkHHPBiFBnTWIijWx3KY7HkWlf3IMhhRCZwlOVhotr" + "7WDoYH9wzYIxgtNOp2zPhc1k2Xz9aflmSYOVU1Z7p0+MUUttQlxtjtJjyVMsgzaD5We0eD1k31uUXO5d54vGYvRneowAZLpj" + "SYeLmReMIH/ylKdOEJakmAxmFnPmd+h36nfvd/B38Xfyd/R39Xf3d/l3+nf7d/x3A3gEeAV4BngHeAh4CngLeA54D3gQeBN4" + "FXgZeBt4HnggeCF4IngkeCh4KngreC54L3gxeDJ4M3g1eDZ4PXg/eEF4QnhDeER4RnhIeEl4SnhLeE14T3hReFN4VHhYeFl4" + "Wnj//1t4XHheeF94YHhheGJ4Y3hkeGV4ZnhneGh4aXhveHB4cXhyeHN4dHh1eHZ4eHh5eHp4e3h9eH54f3iAeIF4gniDeDpX" + "HVw4Xn+Vf1CggIJTXmVFdTFVIVCFjYRinpQdZzJWbm/iXTVUknBmj29ipGSjY3tfiG/0kOOBsI8YXGhm8V+JbEiWgY1siJFk" + "8HnOV1lqEGJIVFhOC3rpYIRv2ot/Yh6Qi5rkeQNU9HUBYxlTYGzfjxtfcJo7gH+fiE86XGSNxX+lZb1wRVGyUWuGB12gW71i" + "bJF0dQyOIHoBYXl7x074foV3EU7tgR1S+lFxaqhTh44Elc+WwW5kllpphHiFeIZ4iHiKeIt4j3iQeJJ4lHiVeJZ4mXideJ54" + "oHiieKR4pnioeKl4qnireKx4rXiueK94tXi2eLd4uHi6eLt4vHi9eL94wHjCeMN4xHjGeMd4yHjMeM14znjPeNF40njTeNZ4" + "13jYeNp423jceN143njfeOB44XjieON4///keOV45njneOl46njreO147njvePB48XjzePV49nj4ePl4+3j8eP14/nj/eAB5" + "AnkDeQR5BnkHeQh5CXkKeQt5DHlAeKhQ13cQZOaJBFnjY91df3o9aSBPOYKYVTJOrnWXemJeil7vlRtSOVSKcHZjJJWCVyVm" + "P2mHkQdV822vfiKIM2LwfrV1KIPBeMyWno9IYfd0zYtkazpSUI0ha2qAcYTxVgZTzk4bTtFRl3yLkQd8w09/juF7nHpnZBRd" + "rFAGgQF2uXzsbeB/UWdYW/hby3iuZBNkqmMrYxmVLWS+j1R7KXZTYidZRlR5a6NQNGImXoZr4043jYuIhV8ukA15DnkPeRB5" + "EXkSeRR5FXkWeRd5GHkZeRp5G3kceR15H3kgeSF5InkjeSV5JnkneSh5KXkqeSt5LHkteS55L3kweTF5MnkzeTV5Nnk3eTh5" + "OXk9eT95QnlDeUR5RXlHeUp5S3lMeU15TnlPeVB5UXlSeVR5VXlYeVl5YXljef//ZHlmeWl5anlreWx5bnlweXF5cnlzeXR5" + "dXl2eXl5e3l8eX15fnl/eYJ5g3mGeYd5iHmJeYt5jHmNeY55kHmReZJ5IGA9gMViOU5VU/iQuGPGgOZlLmxGT+5g4W3eizlf" + "y4ZTXyFjWlFhg2NoAFJjY0iOElCbXHd5/FswUjt6vGBTkNd2t1+XX4R2bI5vcHt2SXuqd/NRk5AkWE5P9G7qj0xlG3vEcqRt" + "33/hWrVilV4wV4KELHsdXh9fEpAUf6CYgmPHbph4uXB4UVuXq1c1dUNPOHWXXuZgYFnAbb9riXj8U9WWy1EBUoljClSTlAOM" + "zI05cp94doftjw2M4FOTeZR5lXmWeZd5mHmZeZt5nHmdeZ55n3mgeaF5onmjeaR5pXmmeah5qXmqeat5rHmtea55r3mwebF5" + "snm0ebV5tnm3ebh5vHm/ecJ5xHnFecd5yHnKecx5znnPedB503nUedZ513nZedp523nced153nngeeF54nnleeh56nn//+x5" + "7nnxefJ583n0efV59nn3efl5+nn8ef55/3kBegR6BXoHegh6CXoKegx6D3oQehF6EnoTehV6FnoYehl6G3ocegFO73buU4mU" + "dpgOny2VmluiiyJOHE6sUWOEwmGoUgtol09rYLtRHm1cUZZil2VhlkaMF5DYdf2QY3fSa4py7HL7izVYeXdMjVxnQJWagKZe" + "IW6SWe967Xc7lbVrrWUOfwZYUVEflvlbqVgoVHKOZmV/mORWnZT+dkGQh2PGVBpZOlmbV7KONWf6jTWCQVLwYBVY/oboXEWe" + "xE+dmLmLJVp2YIRTfGJPkAKRf5lpYAyAP1EzgBRcdZkxbYxOHXofeiF6InokeiV6Jnoneih6KXoqeit6LHotei56L3owejF6" + "Mno0ejV6Nno4ejp6PnpAekF6QnpDekR6RXpHekh6SXpKekt6THpNek56T3pQelJ6U3pUelV6VnpYell6Wnpbelx6XXpeel96" + "YHphemJ6Y3pkemV6Znpnemh6//9pemp6a3psem16bnpvenF6cnpzenV6e3p8en16fnqCeoV6h3qJeop6i3qMeo56j3qQepN6" + "lHqZepp6m3qeeqF6onowjdFTWn9PexBPT04AltVs0HPphQZeanX7fwpq/neSlEF+4VHmcM1T1I8DgymNr3JtmdtsSlezgrll" + "qoA/YjKWqFn/Tr+Lun4+ZfKDXpdhVd6YpYAqU/2LIFS6gJ9euGw5jayCWpEpVBtsBlK3fl9XGnF+bIl8S1n9Tv9fJGGqfDBO" + "AVyrZwKH8FwLlc6Yr3X9cCKQr1Edf72LSVnkUVtPJlQrWXdlpIB1W3ZiwmKQj0VeH2wmew9P2E8NZ6N6pHqneql6qnqreq56" + "r3qwerF6snq0erV6tnq3erh6uXq6ert6vHq9er56wHrBesJ6w3rEesV6xnrHesh6yXrKesx6zXrOes960HrRetJ603rUetV6" + "13rYetp623rcet164XrieuR653roeul66nrreux67nrwevF68nrzev//9Hr1evZ693r4evt6/Hr+egB7AXsCewV7B3sJewx7" + "DXsOexB7EnsTexZ7F3sYexp7HHsdex97IXsieyN7J3spey17bm2qbY95sYgXXyt1mmKFj+9P3JGnZS+BUYGcXlCBdI1vUoaJ" + "S40NWYVQ2E4cljZyeYEfjcxbo4tElodZGn+QVHZWDlblizllgmmZlNZ2iW5yXhh1RmfRZ/96nYB2jR9hxnliZWONiFEaUqKU" + "OH+bgLJ+l1wvbmBn2XuLdtiaj4GUf9V8HmRQlT96SlTlVExrAWQIYj2e84CZdXJSaZdbhDxo5IYBlpSW7JQqTgRU2X45aN+N" + "FYD0ZppeuX8vezB7Mns0ezV7Nns3ezl7O3s9ez97QHtBe0J7Q3tEe0Z7SHtKe017TntTe1V7V3tZe1x7Xntfe2F7Y3tke2V7" + "Zntne2h7aXtqe2t7bHtte297cHtze3R7dnt4e3p7fHt9e397gXuCe4N7hHuGe4d7iHuJe4p7i3uMe457j3v//5F7knuTe5Z7" + "mHuZe5p7m3uee597oHuje6R7pXuue697sHuye7N7tXu2e7d7uXu6e7t7vHu9e757v3vAe8J7w3vEe8JXP4CXaOVdO2WfUm1g" + "mp+bT6yObFGrWxNf6V1ebPFiIY1xUamU/lKfbN+C13KiV4RnLY0fWZyPx4OVVI17ME+9bGRb0VkTn+RTyoaomjeMoYBFZX6Y" + "+lbHli5S3HRQUuFbAmMCiVZO0GIqYPpoc1GYW6BRwomhe4aZUH/vYExwL41JUX9eG5BwdMSJLVdFeFJfn5/6lWiPPJvhi3h2" + "QmjcZ+qNNY09UoqP2m7NaAWV7ZD9Vpxn+YjHj8hUxXvIe8l7ynvLe817znvPe9B70nvUe9V71nvXe9h723vce95733vge+J7" + "43vke+d76Hvpe+t77Hvte+978Hvye/N79Hv1e/Z7+Hv5e/p7+3v9e/97AHwBfAJ8A3wEfAV8BnwIfAl8CnwNfA58EHwRfBJ8" + "E3wUfBV8F3wYfBl8//8afBt8HHwdfB58IHwhfCJ8I3wkfCV8KHwpfCt8LHwtfC58L3wwfDF8MnwzfDR8NXw2fDd8OXw6fDt8" + "PHw9fD58Qny4mmlbd20mbKVOs1uHmmORqGGvkOmXK1S1bdJb/VGKVVV/8H+8ZE1j8WW+YY1gCnFXbElsL1ltZyqC1ViOVmqM" + "62vdkH1ZF4D3U2ltdVSdVXeDz4M4aL55jFRVTwhU0naJjAKWs2y4bWuNEIlknjqNP1bRntV1iF/gcmhg/FSoTipqYYhSYHCP" + "xFTYcHmGP54qbY9bGF+ifolVr080czxUmlMZUA5UfFROTv1fWnT2WGuE4YB0h9ByynxWbkN8RHxFfEZ8R3xIfEl8SnxLfEx8" + "TnxPfFB8UXxSfFN8VHxVfFZ8V3xYfFl8WnxbfFx8XXxefF98YHxhfGJ8Y3xkfGV8ZnxnfGh8aXxqfGt8bHxtfG58b3xwfHF8" + "cnx1fHZ8d3x4fHl8enx+fH98gHyBfIJ8g3yEfIV8hnyHfP//iHyKfIt8jHyNfI58j3yQfJN8lHyWfJl8mnybfKB8oXyjfKZ8" + "p3yofKl8q3ysfK18r3ywfLR8tXy2fLd8uHy6fLt8J19OhixVpGKSTqpsN2KxgtdUTlM+c9FuO3USUhZT3YvQaYpfAGDubU9X" + "Imuvc1No2I8Tf2Jjo2AkVep1YowVcaNtplt7XlKDTGHEnvp4V4cnfId28FH2YExxQ2ZMXk1gDoxwcCVjiY+9X2Jg1IbeVsFr" + "lGBnYUlT4GBmZj+N/XkaT+lwR2yzi/KL2H5kgw9mWlpCm1Ft921BjDttGU9rcLeDFmLRYA2XJ414eftRPlf6VzpneHU9eu95" + "lXu/fMB8wnzDfMR8xnzJfMt8znzPfNB80XzSfNN81HzYfNp823zdfN584XzifON85HzlfOZ853zpfOp863zsfO187nzwfPF8" + "8nzzfPR89Xz2fPd8+Xz6fPx8/Xz+fP98AH0BfQJ9A30EfQV9Bn0HfQh9CX0LfQx9DX0OfQ99EH3//xF9En0TfRR9FX0WfRd9" + "GH0ZfRp9G30cfR19Hn0ffSF9I30kfSV9Jn0ofSl9Kn0sfS19Ln0wfTF9Mn0zfTR9NX02fYyAZZn5j8BvpYshnuxZ6X4JfwlU" + "gWfYaJGPTXzGlspTJWC+dXJsc1PJWqd+JGPgUQqB8V3fhIBigFFjWw5PbXlCUrhgTm3EW8JboYuwi+JlzF9FlpNZ536qfglW" + "t2c5WXNPtlugUlqDipg+jTJ1vpRHUDx69062Z36awVp8a9F2WlcWXDp79JVOcXxRqYBwgnhZBH8ng8Bo7GexeHd442JhY4B7" + "7U9qUs9RUIPbaXSS9Y0xjcGJLpWte/ZON304fTl9On07fTx9PX0+fT99QH1BfUJ9Q31EfUV9Rn1HfUh9SX1KfUt9TH1NfU59" + "T31QfVF9Un1TfVR9VX1WfVd9WH1ZfVp9W31cfV19Xn1ffWB9YX1ifWN9ZH1lfWZ9Z31ofWl9an1rfWx9bX1vfXB9cX1yfXN9" + "dH11fXZ9//94fXl9en17fXx9fX1+fX99gH2BfYJ9g32EfYV9hn2HfYh9iX2KfYt9jH2NfY59j32QfZF9kn2TfZR9lX2WfZd9" + "mH1lUDCCUVJvmRBuhW6nbfpe9VDcWQZcRm1fbIZ1i4RoaFZZsosgU3GRTZZJhRJpAXkmcfaApE7KkEdthJoHWrxWBWTwlOt3" + "pU8ageFy0ol6mTR/3n5/UllldZF/j4OP61OWeu1jpWOGdvh5V4g2lipiq1KCglRocGd3Y2t37XoBbdN+44nQWRJiyYWlgkx1" + "H1DLTqV164tKXP5dS3ukZdGRyk4lbV+JJ30mlcVOKIzbj3OXS2aBedGP7HB4bZl9mn2bfZx9nX2efZ99oH2hfaJ9o32kfaV9" + "p32ofal9qn2rfax9rX2vfbB9sX2yfbN9tH21fbZ9t324fbl9un27fbx9vX2+fb99wH3BfcJ9w33EfcV9xn3Hfch9yX3Kfct9" + "zH3Nfc59z33QfdF90n3TfdR91X3Wfdd92H3Zff//2n3bfdx93X3efd994H3hfeJ9433kfeV95n3nfeh96X3qfet97H3tfe59" + "733wffF98n3zffR99X32ffd9+H35ffp9PVyyUkaDYlEOg1t3dma4nKxOymC+fLN8z36VTmaLb2aImFmXg1hsZVyVhF/JdVaX" + "33reesBRr3CYeupjdnqgfpZz7ZdFTnhwXU5SkalTUWXnZfyBBYKOVDFcmnWgl9hi2XK9dUVceZrKg0BcgFTpdz5OrmxagNJi" + "bmPoXXdR3Y0eji+V8U/lU+dgrHBnUlBjQ54fWiZQN3d3U+J+hWQrZYlimGMUUDVyyYmzUcCL3X5HV8yDp5SbURtU+1z7ffx9" + "/X3+ff99AH4BfgJ+A34EfgV+Bn4Hfgh+CX4Kfgt+DH4Nfg5+D34QfhF+En4TfhR+FX4Wfhd+GH4Zfhp+G34cfh1+Hn4ffiB+" + "IX4ifiN+JH4lfiZ+J34ofil+Kn4rfix+LX4ufi9+MH4xfjJ+M340fjV+Nn43fjh+OX7//zp+PH49fj5+P35AfkJ+Q35EfkV+" + "Rn5Ifkl+Sn5Lfkx+TX5Ofk9+UH5RflJ+U35UflV+Vn5Xflh+WX5aflt+XH5dfspP43pabeGQj5qAVZZUYVOvVABf6WN3ae9R" + "aGEKUipY2FJOVw14C3e3Xndh4HxbYpdiok6VcAOA92LkcGCXd1fbgu9n9WjVeJeY0XnzWLNU71M0bktRO1KiW/6Lr4BDVaZX" + "c2BRVy1UenpQYFRbp2OgYuNTY2LHW69n7VSfeuaCd5GTXuSIOFmuVw5j6I3vgFdXd3upT+tfvVs+ayFTUHvCckZo/3c2d/dl" + "tVGPTtR2v1ylenWETllBm4BQXn5ffmB+YX5ifmN+ZH5lfmZ+Z35ofml+an5rfmx+bX5ufm9+cH5xfnJ+c350fnV+dn53fnh+" + "eX56fnt+fH59fn5+f36AfoF+g36EfoV+hn6Hfoh+iX6Kfot+jH6Nfo5+j36QfpF+kn6TfpR+lX6Wfpd+mH6Zfpp+nH6dfp5+" + "//+ufrR+u368ftZ+5H7sfvl+Cn8Qfx5/N385fzt/PH89fz5/P39Af0F/Q39Gf0d/SH9Jf0p/S39Mf01/Tn9Pf1J/U3+ImSdh" + "g25kVwZmRmPwVuxiaWLTXhSWg1fJYodVIYdKgaOPZlWxg2VnVo3dhGpaD2jmYu57EZZwUZxvMIz9Y8iJ0mEGf8Jw5W4FdJRp" + "/HLKXs6QF2dqbV5js1JicgGAbE/lWWqR2XCdbdJSUE73lm2VfoXKeC99IVGSV8Jki4B7fOps8WheabdRmFOoaIFyzp7xe/hy" + "u3kTbwZ0TmfMkaScPHmJg1SDD1QXaD1OiVOxUj54hlMpUohQi0/QT1Z/WX9bf1x/XX9ef2B/Y39kf2V/Zn9nf2t/bH9tf29/" + "cH9zf3V/dn93f3h/en97f3x/fX9/f4B/gn+Df4R/hX+Gf4d/iH+Jf4t/jX+Pf5B/kX+Sf5N/lX+Wf5d/mH+Zf5t/nH+gf6J/" + "o3+lf6Z/qH+pf6p/q3+sf61/rn+xf///s3+0f7V/tn+3f7p/u3++f8B/wn/Df8R/xn/Hf8h/yX/Lf81/z3/Qf9F/0n/Tf9Z/" + "13/Zf9p/23/cf91/3n/if+N/4nXLepJ8pWy2lptSg3TpVOlPVICyg96PcJXJXhxgn20YXltlOIH+lEtgvHDDfq58yVGBaLF8" + "b4IkToaPz5F+Zq5OBYypZEqA2lCXdc5x5Vu9j2Zvhk6CZGOV1l6ZZRdSwojIcKNSDnMzdJdn93gWlzROu5DenMtt21FBjR1U" + "zmKyc/GD9paEn8OUNk+af8xRdXB1lq1chpjmU+ROnG4JdLRpa3iPmVl1GFIkdkFt82dtUZmfS4CZVDx7v3rkf+d/6H/qf+t/" + "7H/tf+9/8n/0f/V/9n/3f/h/+X/6f/1//n//fwKAB4AIgAmACoAOgA+AEYATgBqAG4AdgB6AH4AhgCOAJIArgCyALYAugC+A" + "MIAygDSAOYA6gDyAPoBAgEGARIBFgEeASIBJgE6AT4BQgFGAU4BVgFaAV4D//1mAW4BcgF2AXoBfgGCAYYBigGOAZIBlgGaA" + "Z4BogGuAbIBtgG6Ab4BwgHKAc4B0gHWAdoB3gHiAeYB6gHuAfIB9gIaWhFfiYkeWfGkEWgJk03sPb0uWpoJiU4WYkF6JcLNj" + "ZFNPhoGck56MeDKX741CjX+eXm+EeVVfRpYuYnSaFVTdlKNPxWVlXGFcFX9Rhi9si1+Hc+Ru/37mXBtjalvmbnVTcU6gY2V1" + "oWJujyZP0U6mbLZ+uosdhLqHV387kCOVqXuhmviIPYQbbYaa3H6IWbuem3MBeIKGbJqCmhtWF1TLV3BOpp5WU8iPCYGSd5KZ" + "7obhbhOF/GZiYStvfoCBgIKAhYCIgIqAjYCOgI+AkICRgJKAlICVgJeAmYCegKOApoCngKiArICwgLOAtYC2gLiAuYC7gMWA" + "x4DIgMmAyoDLgM+A0IDRgNKA04DUgNWA2IDfgOCA4oDjgOaA7oD1gPeA+YD7gP6A/4AAgQGBA4EEgQWBB4EIgQuB//8MgRWB" + "F4EZgRuBHIEdgR+BIIEhgSKBI4EkgSWBJoEngSiBKYEqgSuBLYEugTCBM4E0gTWBN4E5gTqBO4E8gT2BP4EpjJKCK4PydhNs" + "2V+9gytzBYMaldtr23fGlG9TAoOSUT1ejIw4jUhOq3OaZ4VodpEJl2RxoWwJd5JaQZXPa45/J2bQW7lZmlrolfeV7E4MhJmE" + "rGrfdjCVG3OmaF9bL3eakWGX3Hz3jxyMJV9zfNh5xYnMbByHxltCXsloIHf1fpVRTVHJUilaBX9il9eCz2OEd9CF0nk6bple" + "mVkRhW1wEWy/Yr92T2WvYP2VDmafhyOe7ZQNVH1ULIx4ZECBQYFCgUOBRIFFgUeBSYFNgU6BT4FSgVaBV4FYgVuBXIFdgV6B" + "X4FhgWKBY4FkgWaBaIFqgWuBbIFvgXKBc4F1gXaBd4F4gYGBg4GEgYWBhoGHgYmBi4GMgY2BjoGQgZKBk4GUgZWBloGXgZmB" + "moGegZ+BoIGhgaKBpIGlgf//p4GpgauBrIGtga6Br4GwgbGBsoG0gbWBtoG3gbiBuYG8gb2BvoG/gcSBxYHHgciByYHLgc2B" + "zoHPgdCB0YHSgdOBeWQRhiFqnIHoeGlkVJu5Yitnq4OoWNieq2wgb95bTJYLjF9y0GfHYmFyqU7GWc1rk1iuZlVe31JVYShn" + "7nZmd2dyRnr/YupUUFSglKOQHFqzfhZsQ052WRCASFlXUzd1vpbKViBjEYF8YPmV1m1iVIGZhVHpWv2ArlkTlypQ5Ww8XN9i" + "YE8/U3uBBpC6biuFyGJ0Xr54tWR7Y/VfGFp/kR+eP1xPY0KAfVtuVUqVTZWFbahg4Gfect1RgVvUgdWB1oHXgdiB2YHagduB" + "3IHdgd6B34HggeGB4oHkgeWB5oHogemB64Huge+B8IHxgfKB9YH2gfeB+IH5gfqB/YH/gQOCB4IIggmCCoILgg6CD4IRghOC" + "FYIWgheCGIIZghqCHYIggiSCJYImgieCKYIugjKCOoI8gj2CP4L//0CCQYJCgkOCRYJGgkiCSoJMgk2CToJQglGCUoJTglSC" + "VYJWgleCWYJbglyCXYJegmCCYYJigmOCZIJlgmaCZ4Jpgudi3mxbcm1irpS9fhOBU22cUQRfdFmqUhJgc1mWZlCGn3UqY+Zh" + "73z6i+ZUJ2slnrRr1YVVVHZQpGxqVbSNLHIVXhVgNnTNYpJjTHKYX0NuPm0AZVhv2HbQePx2VHUkUttTU06eXsFlKoDWgJti" + "hlQoUq5wjYjRjeFseFTagPlX9IhUjWqWTZFpT5tst1XGdjB4qGL5cI5vbV/shNpofHj3e6iBC2dPnmdjsHhvVxJ4OZd5Yqti" + "iFI1dNdraoJrgmyCbYJxgnWCdoJ3gniCe4J8goCCgYKDgoWChoKHgomCjIKQgpOClIKVgpaCmoKbgp6CoIKigqOCp4KygrWC" + "toK6gruCvIK/gsCCwoLDgsWCxoLJgtCC1oLZgtqC3YLigueC6ILpguqC7ILtgu6C8ILygvOC9YL2gviC///6gvyC/YL+gv+C" + "AIMKgwuDDYMQgxKDE4MWgxiDGYMdgx6DH4MggyGDIoMjgySDJYMmgymDKoMugzCDMoM3gzuDPYNkVT6BsnWudjlT3nX7UEFc" + "bIvHe09QR3KXmtiYAm/idGh5h2Sld/xikZgrjcFUWIBSTmpX+YINhHNe7VH2dMSLT1xhV/xsh5hGWjR4RJvrj5V8VlJRYvqU" + "xk6Gg2GE6YOyhNRXNGcDV25mZm0xjN1mEXAfZzprFmgaYrtZA07EUQZv0mePbHZRy2hHWWdrZnUOXRCBUJ/XZUh5QXmRmneN" + "glxeTgFPL1RRWQx4aFYUbMSPA199bONsq4uQYz6DP4NBg0KDRINFg0iDSoNLg0yDTYNOg1ODVYNWg1eDWINZg12DYoNwg3GD" + "coNzg3SDdYN2g3mDeoN+g3+DgIOBg4KDg4OEg4eDiIOKg4uDjIONg4+DkIORg5SDlYOWg5eDmYOag52Dn4Ohg6KDo4Okg6WD" + "poOng6yDrYOug///r4O1g7uDvoO/g8KDw4PEg8aDyIPJg8uDzYPOg9CD0YPSg9OD1YPXg9mD2oPbg96D4oPjg+SD5oPng+iD" + "64Psg+2DcGA9bXVyZmKOlMWUQ1PBj357304mjH5O1J6xlLOUTVJcb2OQRW00jBFYTF0ga0lrqmdbVFSBjH+ZWDeFOl+iYkdq" + "OZVyZYRgZWind1ROqE/nXZiXrGTYf+1cz0+NegdSBIMUTi9gg3qmlLVPsk7meTR05FK5gtJkvXndW4FsUpd7jyJsPlB/UwVu" + "zmR0ZjBsxWB3mPeLhl48dHd6y3kYTrGQA3RCbNpWS5HFbIuNOlPGhvJmr45IXHGaIG7ug++D84P0g/WD9oP3g/qD+4P8g/6D" + "/4MAhAKEBYQHhAiECYQKhBCEEoQThBSEFYQWhBeEGYQahBuEHoQfhCCEIYQihCOEKYQqhCuELIQthC6EL4QwhDKEM4Q0hDWE" + "NoQ3hDmEOoQ7hD6EP4RAhEGEQoRDhESERYRHhEiESYT//0qES4RMhE2EToRPhFCEUoRThFSEVYRWhFiEXYRehF+EYIRihGSE" + "ZYRmhGeEaIRqhG6Eb4RwhHKEdIR3hHmEe4R8hNZTNlqLn6ONu1MIV6eYQ2ebkclsaFHKdfNirHI4Up1SOn+UcDh2dFNKnrdp" + "bnjAltmIpH82ccNxiVHTZ+R05FgYZbdWqYt2mXBi1X75YO1w7FjBTrpOzV/nl/tOpIsDUopZq35UYs1O5WUOYjiDyYRjg42H" + "lHG2brlb0n6XUclj1GeJgDmDFYgSUXpbglmxj3NOXWxlUSWJb48ulkqFXnQQlfCVpm3lgjFfkmQSbSiEboHDnF5YW40JTsFT" + "fYR+hH+EgISBhIOEhISFhIaEioSNhI+EkISRhJKEk4SUhJWEloSYhJqEm4SdhJ6En4SghKKEo4SkhKWEpoSnhKiEqYSqhKuE" + "rISthK6EsISxhLOEtYS2hLeEu4S8hL6EwITChMOExYTGhMeEyITLhMyEzoTPhNKE1ITVhNeE///YhNmE2oTbhNyE3oThhOKE" + "5ITnhOiE6YTqhOuE7YTuhO+E8YTyhPOE9IT1hPaE94T4hPmE+oT7hP2E/oQAhQGFAoUeT2NlUWjTVSdOFGSammtiwlpfdHKC" + "qW3uaOdQjoMCeEBnOVKZbLF+u1BlVV5xW3tSZspz64JJZ3FcIFJ9cWuI6pVVlsVkYY2zgYRVVWxHYi5/klgkT0ZVT41MZgpO" + "GlzziKJoTmMNeudwjYL6UvaXEVzoVLWQzX5iWUqNx4YMgg2CZo1EZARcUWGJbT55vos3eDN1e1Q4T6uO8W0gWsV+XnmIbKFb" + "dloadb6ATmEXbvBYH3UldXJyR1PzfgOFBIUFhQaFB4UIhQmFCoULhQ2FDoUPhRCFEoUUhRWFFoUYhRmFG4UchR2FHoUghSKF" + "I4UkhSWFJoUnhSiFKYUqhS2FLoUvhTCFMYUyhTOFNIU1hTaFPoU/hUCFQYVChUSFRYVGhUeFS4VMhU2FToVPhVCFUYVShVOF" + "VIVVhf//V4VYhVqFW4VchV2FX4VghWGFYoVjhWWFZoVnhWmFaoVrhWyFbYVuhW+FcIVxhXOFdYV2hXeFeIV8hX2Ff4WAhYGF" + "AXfbdmlS3IAjVwheMVnucr1lf27XizhccYZBU/N3/mL2ZcBO35iAhp5bxovyU+J3f09OXHaay1kPXzp561gWTv9ni07tYpOK" + "HZC/Ui9m3FVsVgKQ1U6NT8qRcJkPbAJeQ2CkW8aJ1Ys2ZUtilpmIW/9biGMuVddTJnZ9USyFomezaIprkmKTj9RTEoLRbY91" + "Zk5OjXBbn3GvhZFm2WZyfwCHzZ4gn15cL2fwjxFoX2cNYtZ6hVi2XnBlMW+ChYOFhoWIhYmFioWLhYyFjYWOhZCFkYWShZOF" + "lIWVhZaFl4WYhZmFmoWdhZ6Fn4WghaGFooWjhaWFpoWnhamFq4Wsha2FsYWyhbOFtIW1hbaFuIW6hbuFvIW9hb6Fv4XAhcKF" + "w4XEhcWFxoXHhciFyoXLhcyFzYXOhdGF0oX//9SF1oXXhdiF2YXahduF3YXehd+F4IXhheKF44XlheaF54XoheqF64Xshe2F" + "7oXvhfCF8YXyhfOF9IX1hfaF94X4hVVgN1INgFRkcIgpdQVeE2j0YhyXzFM9cgGMNGxhdw56LlSsd3qYHIL0i1V4FGfBcK9l" + "lWQ2Vh1gwXn4Ux1Oe2uGgPpb41XbVjpPPE9ymfNdfmc4gAJggpgBkItbvIv1ixxkWILeZP1Vz4JlkddPIH0fkJ9881BRWK9u" + "v1vJi4OAeJGchJd7fYaLlo+W5X7Tmo54gVxXekKQp5ZfeVlbX2MLe9GErWgGVSl/EHQifQGVQGJMWNZOg1t5WVRY+YX6hfyF" + "/YX+hQCGAYYChgOGBIYGhgeGCIYJhgqGC4YMhg2GDoYPhhCGEoYThhSGFYYXhhiGGYYahhuGHIYdhh6GH4YghiGGIoYjhiSG" + "JYYmhiiGKoYrhiyGLYYuhi+GMIYxhjKGM4Y0hjWGNoY3hjmGOoY7hj2GPoY/hkCG//9BhkKGQ4ZEhkWGRoZHhkiGSYZKhkuG" + "TIZShlOGVYZWhleGWIZZhluGXIZdhl+GYIZhhmOGZIZlhmaGZ4ZohmmGaoZtcx5jS44Pjs6A1IKsYvBT8GxekSpZAWBwbE1X" + "SmQqjSt26W5bV4Bq8HVtby2MCIxmV+9rkoizeKJj+VOtcGRsWFgqZAJY4GibgRBV1nwYULqOzG2fjetwj2ObbdRu5n4EhENo" + "A5DYbXaWqItXWXly5IV+gbx1ioqvaFRSIo4RldBjmJhEjnxVU0//Zo9W1WCVbUNSSVwpWftta1gwdRx1bGAUgkaBEWNhZ+KP" + "OnfzjTSNwZQWXoVTLFTDcG2Gb4ZwhnKGc4Z0hnWGdoZ3hniGg4aEhoWGhoaHhoiGiYaOho+GkIaRhpKGlIaWhpeGmIaZhpqG" + "m4aehp+GoIahhqKGpYamhquGrYauhrKGs4a3hriGuYa7hryGvYa+hr+GwYbChsOGxYbIhsyGzYbShtOG1YbWhteG2obchv//" + "3YbghuGG4objhuWG5obnhuiG6obrhuyG74b1hvaG94b6hvuG/Ib9hv+GAYcEhwWHBocLhwyHDocPhxCHEYcUhxaHQGz3XlxQ" + "rU6tXjpjR4IakFBobpGzdwxU3JRkX+V6dmhFY1J7337bdXdQlWI0WQ+Q+FHDeYF6/laSXxSQgm1gXB9XEFRUUU1u4laoY5OY" + "f4EVhyqJAJAeVG9cwIHWYlhiMYE1nkCWbpp8mi1ppVnTYj5VFmPHVNmGPG0DWuZ0nIhqaxZZTIwvX35uqXN9mDhO93CMW5d4" + "PWNaZpZ2y2CbW0laB05VgWpsi3OhTolnUX+AX/plG2fYX4RZAVoZhxuHHYcfhyCHJIcmhyeHKIcqhyuHLIcthy+HMIcyhzOH" + "NYc2hziHOYc6hzyHPYdAh0GHQodDh0SHRYdGh0qHS4dNh0+HUIdRh1KHVIdVh1aHWIdah1uHXIddh16HX4dhh2KHZodnh2iH" + "aYdqh2uHbIdth2+HcYdyh3OHdYf//3eHeId5h3qHf4eAh4GHhIeGh4eHiYeKh4yHjoePh5CHkYeSh5SHlYeWh5iHmYeah5uH" + "nIedh56HoIehh6KHo4ekh81drl9xU+aX3Y9FaPRWL1XfYDpOTW/0fseCDoTUWR9PKk8+XKx+KmcahXNUT3XDgIJVT5tNTy1u" + "E4wJXHBha1MfdiluioaHZfuVuX47VDN6Cn3uleFVwX/udB1jF4ehbZ16EWKhZWdT4WODbOtdXFSolExOYWzsi0tc4GWcgqdo" + "PlQ0VMtrZmuUTkJjSFMegg1Prk9eVwpi/pZkZmly/1KhUp9g74sUZplxkGd/iVJ4/XdwZjtWOFQhlXpypYemh6eHqYeqh66H" + "sIexh7KHtIe2h7eHuIe5h7uHvIe+h7+HwYfCh8OHxIfFh8eHyIfJh8yHzYfOh8+H0IfUh9WH1ofXh9iH2Yfah9yH3Yfeh9+H" + "4Yfih+OH5Ifmh+eH6Ifph+uH7Ifth++H8Ifxh/KH84f0h/WH9of3h/iH///6h/uH/If9h/+HAIgBiAKIBIgFiAaIB4gIiAmI" + "C4gMiA2IDogPiBCIEYgSiBSIF4gYiBmIGogciB2IHogfiCCII4gAem9gDF6JYJ2BFVncYIRx73CqblBsgHKEaq2ILV5gTrNa" + "nFXjlBdt+3yZlg9ixn6Od36GI1Mel5aPh2bhXKBP7XILTqZTD1kTVIBjKJVIUdlOnJykfrhUJI1UiDeC8pWObSZfzFo+ZmmW" + "sHMuc79TeoGFmaF/qlt3llCWv374dqJTdpWZmbF7RIlYbmFO1H9leeaL82DNVKtOeZj3XWFqz1ARVGGMJ4RdeASXSlLuVKNW" + "AJWIbbVbxm1TZiSIJYgmiCeIKIgpiCqIK4gsiC2ILogviDCIMYgziDSINYg2iDeIOIg6iDuIPYg+iD+IQYhCiEOIRohHiEiI" + "SYhKiEuITohPiFCIUYhSiFOIVYhWiFiIWohbiFyIXYheiF+IYIhmiGeIaohtiG+IcYhziHSIdYh2iHiIeYh6iP//e4h8iICI" + "g4iGiIeIiYiKiIyIjoiPiJCIkYiTiJSIlYiXiJiImYiaiJuInYieiJ+IoIihiKOIpYimiKeIqIipiKqID1xdWyFoloB4VRF7" + "SGVUaZtOR2tOh4uXT1MfYzpkqpCcZcGAEIyZUbBoeFP5h8hhxGz7bCKMUVyqha+CDJUja5uPsGX7X8Nf4U9FiB9mZYEpc/pg" + "dFERUotXYl+ikEyIkpF4Xk9nJ2DTWURR9lH4gAhTeWzElopxEU/uT55/PWfFVQiVwHmWiON+n1gMYgCXWoYYVnuYkF+4i8SE" + "V5HZU+1lj15cdWRgbn1/Wup+7X5pj6dVo1usYMtlhHOsiK6Ir4iwiLKIs4i0iLWItoi4iLmIuoi7iL2Ivoi/iMCIw4jEiMeI" + "yIjKiMuIzIjNiM+I0IjRiNOI1ojXiNqI24jciN2I3ojgiOGI5ojniOmI6ojriOyI7YjuiO+I8oj1iPaI94j6iPuI/Yj/iACJ" + "AYkDiQSJBYkGiQeJCIn//wmJC4kMiQ2JDokPiRGJFIkViRaJF4kYiRyJHYkeiR+JIIkiiSOJJIkmiSeJKIkpiSyJLYkuiS+J" + "MYkyiTOJNYk3iQmQY3Ypd9p+dJebhWZbdHrqlkCIy1KPcapf7GXii/tbb5rhXYlrW2yti6+LCpDFj4tTvGImni2eQFQrTr2C" + "WXKchhZdWYivbcWW0VSaTraLCXG9VAmW33D5bdB2JU4UeBKHqVz2XgCKnJgOlo5wv2xEWaljPHdNiBRvc4IwWNVxjFMaeMGW" + "AVVmXzBxtFsajIyag2suWS+e53loZ2xib0+hdYp/C20zlids8E7SdXtRN2g+b4CQcIGWWXZ0OIk5iTqJO4k8iT2JPok/iUCJ" + "QolDiUWJRolHiUiJSYlKiUuJTIlNiU6JT4lQiVGJUolTiVSJVYlWiVeJWIlZiVqJW4lciV2JYIlhiWKJY4lkiWWJZ4loiWmJ" + "aolriWyJbYluiW+JcIlxiXKJc4l0iXWJdol3iXiJeYl6iXyJ//99iX6JgImCiYSJhYmHiYiJiYmKiYuJjImNiY6Jj4mQiZGJ" + "komTiZSJlYmWiZeJmImZiZqJm4mciZ2JnomfiaCJoYlHZCdcZZCReiOM2lmsVACCb4OBiQCAMGlOVjaAN3LOkbZRX051mJZj" + "Gk72U/NmS4EcWbJtAE75WDtT1mPxlJ1PCk9jiJCYN1lXkPt56k7wgJF1gmycW+hZXV8FaYGGGlDyXVlO43flTnqCkWITZpGQ" + "eVy/TnlfxoE4kISAq3WmTtSID2HFa8ZfSU7KdqJu44uuiwqM0YsCX/x/zH/OfjWDa4PgVrdr85c0lvtZH1T2lOttxVtumTlc" + "FV+QlqKJo4mkiaWJpomniaiJqYmqiauJrImtia6Jr4mwibGJsomzibSJtYm2ibeJuIm5ibqJu4m8ib2Jvom/icCJw4nNidOJ" + "1InVideJ2InZiduJ3YnfieCJ4YniieSJ54noiemJ6onsie2J7onwifGJ8on0ifWJ9on3ifiJ+Yn6if//+4n8if2J/on/iQGK" + "AooDigSKBYoGigiKCYoKiguKDIoNig6KD4oQihGKEooTihSKFYoWiheKGIoZihqKG4ocih2KcFPxgjFqdFpwnpReKH+5gySE" + "JYRng0eHzo9ijch2cV+WmGx4IGbfVOViY0/Dgch1uF7NlgqO+YaPVPNsjG04bH9gx1IodX1eGE+gYOdfJFwxda6QwJS5crls" + "OG5JkQlny1PzU1FPyZHxi8hTfF7Cj+Rtjk7CdoZpXoYaYQaCWU/eTz6QfJwJYR1uFG6FlohOMVrolg5Of1y5eYdb7Yu9f4lz" + "31eLgsGQAVRHkLtV6lyhXwhhMmvxcrKAiYoeih+KIIohiiKKI4okiiWKJooniiiKKYoqiiuKLIotii6KL4owijGKMoozijSK" + "NYo2ijeKOIo5ijqKO4o8ij2KP4pAikGKQopDikSKRYpGikeKSYpKikuKTIpNik6KT4pQilGKUopTilSKVYpWileKWIpZilqK" + "W4pcil2KXor//1+KYIphimKKY4pkimWKZopnimiKaYpqimuKbIptim6Kb4pwinGKcopzinSKdYp2ineKeIp6inuKfIp9in6K" + "f4qAinRt01vViISYa4xtmjOeCm6kUUNRo1eBiJ9T9GOVj+1WWFQGVz9zkG4Yf9yP0YI/YShgYpbwZqZ+io3DjaWUs1ykfAhn" + "pmAFlhiAkU7nkABTaJZBUdCPdIVdkVVm9ZdVWx1TOHhCZz1oyVR+cLBbfY+NUShXsVQSZYJmXo1DjQ+BbIRtkN98/1H7haNn" + "6WWhb6SGgY5qViCQgnZ2cOVxI43pYhlS/Ww8jQ5gnliOYf5mYI1OYrNVI24tZ2ePgYqCioOKhIqFioaKh4qIiouKjIqNio6K" + "j4qQipGKkoqUipWKloqXipiKmYqaipuKnIqdip6Kn4qgiqGKooqjiqSKpYqmiqeKqIqpiqqKq4qsiq2KroqvirCKsYqyirOK" + "tIq1iraKt4q4irmKuoq7iryKvYq+ir+KwIrBisKK///DisSKxYrGiseKyIrJisqKy4rMis2KzorPitCK0YrSitOK1IrVitaK" + "14rYitmK2orbityK3Yreit+K4IrhiuKK44rhlPiVKHcFaKhpi1RNTrhwyItYZItlhVuEejpQ6Fu7d+FreYqYfL5sz3apZZeP" + "LV1VXDiGCGhgUxhi2Xpbbv1+H2rgenBfM28gX4xjqG1WZwhOEF4mjddOwIA0dpyW22ItZn5ivGx1jWdxaX9GUYeA7FNukJhi" + "8lTwhpmPBYAXlReF2Y9Zbc1zn2UfdwR1J3j7gR6NiJSmT5VnuXXKiweXL2NHlTWWuIQjY0F3gV/wcolOFGB0Ze9iY2s/ZeSK" + "5YrmiueK6IrpiuqK64rsiu2K7orvivCK8YryivOK9Ir1ivaK94r4ivmK+or7ivyK/Yr+iv+KAIsBiwKLA4sEiwWLBosIiwmL" + "CosLiwyLDYsOiw+LEIsRixKLE4sUixWLFosXixiLGYsaixuLHIsdix6LH4sgiyGLIosji///JIsliyeLKIspiyqLK4ssiy2L" + "LosvizCLMYsyizOLNIs1izaLN4s4izmLOos7izyLPYs+iz+LQItBi0KLQ4tEi0WLJ17HddGQwYudgp1nL2UxVBiH5XeigAKB" + "QWxLTsd+TID0dg1plmtnYjxQhE9AVwdjYmu+jepT6GW4ftdfGmO3Y/OB9IFufxxe2Vw2Unpm6XkaeiiNmXDUdd5uu2ySei1O" + "xXbgX5+Ud4jIfs15v4DNkfJOF08fgmhU3l0ybcyLpXx0j5iAGl6SVLF2mVs8ZqSa4HMqaNuGMWcqc/iL24sQkPl623BuccRi" + "qXcxVjtOV4TxZ6lSwIYujfiUUXtGi0eLSItJi0qLS4tMi02LTotPi1CLUYtSi1OLVItVi1aLV4tYi1mLWotbi1yLXYtei1+L" + "YIthi2KLY4tki2WLZ4toi2mLaotri22Lbotvi3CLcYtyi3OLdIt1i3aLd4t4i3mLeot7i3yLfYt+i3+LgIuBi4KLg4uEi4WL" + "hov//4eLiIuJi4qLi4uMi42LjouPi5CLkYuSi5OLlIuVi5aLl4uYi5mLmoubi5yLnYuei5+LrIuxi7uLx4vQi+qLCYwejE9P" + "6GxdeXuak2Iqcv1iE04WeGyPsGRajcZ7aWiEXsWIhlmeZO5YtnIOaSWV/Y9YjWBXAH8GjMZRSWPZYlNTTGgidAGDTJFEVUB3" + "fHBKbXlRqFREjf9Zy27EbVxbK33UTn18025QW+qBDW5XWwOb1Wgqjpdb/H47YLV+uZBwjU9ZzWPfebONUlPPZVZ5xYs7lsR+" + "u5SCfjRWiZEAZ2p/Clx1kChm5l1QT95nWlBcT1BXp17/////////////OIw5jDqMO4w8jD2MPow/jECMQoxDjESMRYxIjEqM" + "S4xNjE6MT4xQjFGMUoxTjFSMVoxXjFiMWYxbjFyMXYxejF+MYIxjjGSMZYxmjGeMaIxpjGyMbYxujG+McIxxjHKMdIx1jHaM" + "d4x7jHyMfYx+jH+MgIyBjIOMhIyGjIeM//+IjIuMjYyOjI+MkIyRjJKMk4yVjJaMl4yZjJqMm4ycjJ2MnoyfjKCMoYyijKOM" + "pIyljKaMp4yojKmMqoyrjKyMrYyNTgxOQFEQTv9eRVMVTphOHk4ym2xbaVYoTrp5P04VU0dOLVk7cm5TEGzfVuSAl5nTa353" + "F582Tp9OEJ9cTmlOk06IgltbbFUPVsROjVOdU6NTpVOuU2WXXY0aU/VTJlMuUz5TXI1mU2NTAlIIUg5SLVIzUj9SQFJMUl5S" + "YVJcUq+EfVKCUoFSkFKTUoJRVH+7TsNOyU7CTuhO4U7rTt5OG0/zTiJPZE/1TiVPJ08JTytPXk9nTzhlWk9dT66Mr4ywjLGM" + "soyzjLSMtYy2jLeMuIy5jLqMu4y8jL2Mvoy/jMCMwYzCjMOMxIzFjMaMx4zIjMmMyozLjMyMzYzOjM+M0IzRjNKM04zUjNWM" + "1ozXjNiM2YzajNuM3IzdjN6M34zgjOGM4ozjjOSM5YzmjOeM6IzpjOqM64zsjP//7YzujO+M8IzxjPKM84z0jPWM9oz3jPiM" + "+Yz6jPuM/Iz9jP6M/4wAjQGNAo0DjQSNBY0GjQeNCI0JjQqNC40MjQ2NX09XTzJPPU92T3RPkU+JT4NPj09+T3tPqk98T6xP" + "lE/mT+hP6k/FT9pP40/cT9FP30/4TylQTFDzTyxQD1AuUC1Q/k8cUAxQJVAoUH5QQ1BVUEhQTlBsUHtQpVCnUKlQulDWUAZR" + "7VDsUOZQ7lAHUQtR3U49bFhPZU/OT6CfRmx0fG5R/V3JnpiZgVEUWflSDVMHihBT61EZWVVRoE5WUbNOboikiLVOFIHSiIB5" + "NFsDiLh/q1GxUb1RvFEOjQ+NEI0RjRKNE40UjRWNFo0XjRiNGY0ajRuNHI0gjVGNUo1XjV+NZY1ojWmNao1sjW6Nb41xjXKN" + "eI15jXqNe418jX2Nfo1/jYCNgo2DjYaNh42IjYmNjI2NjY6Nj42QjZKNk42VjZaNl42YjZmNmo2bjZyNnY2ejaCNoY3//6KN" + "pI2ljaaNp42ojamNqo2rjayNrY2uja+NsI2yjbaNt425jbuNvY3AjcGNwo3FjceNyI3JjcqNzY3QjdKN043UjcdRllGiUaVR" + "oIumi6eLqou0i7WLt4vCi8OLy4vPi86L0ovTi9SL1ovYi9mL3Ivfi+CL5Ivoi+mL7ovwi/OL9ov5i/yL/4sAjAKMBIwHjAyM" + "D4wRjBKMFIwVjBaMGYwbjBiMHYwfjCCMIYwljCeMKowrjC6ML4wyjDOMNYw2jGlTelMdliKWIZYxliqWPZY8lkKWSZZUll+W" + "Z5ZslnKWdJaIlo2Wl5awlpeQm5CdkJmQrJChkLSQs5C2kLqQ1Y3YjdmN3I3gjeGN4o3ljeaN543pje2N7o3wjfGN8o30jfaN" + "/I3+jf+NAI4BjgKOA44EjgaOB44IjguODY4OjhCOEY4SjhOOFY4WjheOGI4ZjhqOG44cjiCOIY4kjiWOJo4njiiOK44tjjCO" + "Mo4zjjSONo43jjiOO448jj6O//8/jkOORY5GjkyOTY5Ojk+OUI5TjlSOVY5WjleOWI5ajluOXI5djl6OX45gjmGOYo5jjmSO" + "ZY5njmiOao5rjm6OcY64kLCQz5DFkL6Q0JDEkMeQ05DmkOKQ3JDXkNuQ65DvkP6QBJEikR6RI5ExkS+ROZFDkUaRDVJCWaJS" + "rFKtUr5S/1TQUtZS8FLfU+5xzXf0XvVR/FEvm7ZTAV9ade9dTFepV6FXfli8WMVY0VgpVyxXKlczVzlXLlcvV1xXO1dCV2lX" + "hVdrV4ZXfFd7V2hXbVd2V3NXrVekV4xXslfPV6dXtFeTV6BX1VfYV9pX2VfSV7hX9FfvV/hX5FfdV3OOdY53jniOeY56jnuO" + "fY5+joCOgo6DjoSOho6IjomOio6LjoyOjY6OjpGOko6TjpWOlo6XjpiOmY6ajpuOnY6fjqCOoY6ijqOOpI6ljqaOp46ojqmO" + "qo6tjq6OsI6xjrOOtI61jraOt464jrmOu468jr2Ovo6/jsCOwY7Cjv//w47EjsWOxo7HjsiOyY7KjsuOzI7Njs+O0I7RjtKO" + "047UjtWO1o7XjtiO2Y7ajtuO3I7djt6O347gjuGO4o7jjuSOC1gNWP1X7VcAWB5YGVhEWCBYZVhsWIFYiViaWIBYqJkZn/9h" + "eYJ9gn+Cj4KKgqiChIKOgpGCl4KZgquCuIK+grCCyILKguOCmIK3gq6Cy4LMgsGCqYK0gqGCqoKfgsSCzoKkguGCCYP3guSC" + "D4MHg9yC9ILSgtiCDIP7gtOCEYMagwaDFIMVg+CC1YIcg1GDW4NcgwiDkoM8gzSDMYObg16DL4NPg0eDQ4Nfg0CDF4Nggy2D" + "OoMzg2aDZYPljuaO547ojumO6o7rjuyO7Y7uju+O8I7xjvKO8470jvWO9o73jviO+Y76jvuO/I79jv6O/44AjwGPAo8DjwSP" + "BY8GjwePCI8JjwqPC48Mjw2PDo8PjxCPEY8SjxOPFI8VjxaPF48YjxmPGo8bjxyPHY8ejx+PII8hjyKPI4///ySPJY8mjyeP" + "KI8pjyqPK48sjy2PLo8vjzCPMY8yjzOPNI81jzaPN484jzmPOo87jzyPPY8+jz+PQI9Bj0KPQ49Ej2iDG4Npg2yDaoNtg26D" + "sIN4g7ODtIOgg6qDk4Ocg4WDfIO2g6mDfYO4g3uDmIOeg6iDuoO8g8GDAYTlg9iDB1gYhAuE3YP9g9aDHIQ4hBGEBoTUg9+D" + "D4QDhPiD+YPqg8WDwIMmhPCD4YNchFGEWoRZhHOEh4SIhHqEiYR4hDyERoRphHaEjISOhDGEbYTBhM2E0ITmhL2E04TKhL+E" + "uoTghKGEuYS0hJeE5YTjhAyFDXU4hfCEOYUfhTqFRY9Gj0ePSI9Jj0qPS49Mj02PTo9Pj1CPUY9Sj1OPVI9Vj1aPV49Yj1mP" + "Wo9bj1yPXY9ej1+PYI9hj2KPY49kj2WPao+Aj4yPko+dj6CPoY+ij6SPpY+mj6ePqo+sj62Pro+vj7KPs4+0j7WPt4+4j7qP" + "u4+8j7+PwI/Dj8aP///Jj8qPy4/Mj82Pz4/Sj9aP14/aj+CP4Y/jj+eP7I/vj/GP8o/0j/WP9o/6j/uP/I/+j/+PB5AIkAyQ" + "DpATkBWQGJBWhTuF/4T8hFmFSIVohWSFXoV6haJ3Q4VyhXuFpIWohYeFj4V5ha6FnIWFhbmFt4WwhdOFwYXchf+FJ4YFhimG" + "FoY8hv5eCF88WUFZN4BVWVpZWFkPUyJcJVwsXDRcTGJqYp9iu2LKYtpi12LuYiJj9mI5Y0tjQ2OtY/ZjcWN6Y45jtGNtY6xj" + "imNpY65jvGPyY/hj4GP/Y8Rj3mPOY1JkxmO+Y0VkQWQLZBtkIGQMZCZkIWReZIRkbWSWZBmQHJAjkCSQJZAnkCiQKZAqkCuQ" + "LJAwkDGQMpAzkDSQN5A5kDqQPZA/kECQQ5BFkEaQSJBJkEqQS5BMkE6QVJBVkFaQWZBakFyQXZBekF+QYJBhkGSQZpBnkGmQ" + "apBrkGyQb5BwkHGQcpBzkHaQd5B4kHmQepB7kHyQfpCBkP//hJCFkIaQh5CJkIqQjJCNkI6Qj5CQkJKQlJCWkJiQmpCckJ6Q" + "n5CgkKSQpZCnkKiQqZCrkK2QspC3kLyQvZC/kMCQemS3ZLhkmWS6ZMBk0GTXZORk4mQJZSVlLmULX9JfGXURX19T8VP9U+lT" + "6FP7UxJUFlQGVEtUUlRTVFRUVlRDVCFUV1RZVCNUMlSCVJRUd1RxVGRUmlSbVIRUdlRmVJ1U0FStVMJUtFTSVKdUplTTVNRU" + "clSjVNVUu1S/VMxU2VTaVNxUqVSqVKRU3VTPVN5UG1XnVCBV/VQUVfNUIlUjVQ9VEVUnVSpVZ1WPVbVVSVVtVUFVVVU/VVBV" + "PFXCkMOQxpDIkMmQy5DMkM2Q0pDUkNWQ1pDYkNmQ2pDekN+Q4JDjkOSQ5ZDpkOqQ7JDukPCQ8ZDykPOQ9ZD2kPeQ+ZD6kPuQ" + "/JD/kACRAZEDkQWRBpEHkQiRCZEKkQuRDJENkQ6RD5EQkRGREpETkRSRFZEWkReRGJEakRuRHJH//x2RH5EgkSGRJJElkSaR" + "J5EokSmRKpErkSyRLZEukTCRMpEzkTSRNZE2kTeROJE6kTuRPJE9kT6RP5FAkUGRQpFEkTdVVlV1VXZVd1UzVTBVXFWLVdJV" + "g1WxVblViFWBVZ9VflXWVZFVe1XfVb1VvlWUVZlV6lX3VclVH1bRVetV7FXUVeZV3VXEVe9V5VXyVfNVzFXNVehV9VXkVZSP" + "HlYIVgxWAVYkViNW/lUAVidWLVZYVjlWV1YsVk1WYlZZVlxWTFZUVoZWZFZxVmtWe1Z8VoVWk1avVtRW11bdVuFW9VbrVvlW" + "/1YEVwpXCVccVw9eGV4UXhFeMV47XjxeRZFHkUiRUZFTkVSRVZFWkViRWZFbkVyRX5FgkWaRZ5FokWuRbZFzkXqRe5F8kYCR" + "gZGCkYORhJGGkYiRipGOkY+Rk5GUkZWRlpGXkZiRmZGckZ2RnpGfkaCRoZGkkaWRppGnkaiRqZGrkayRsJGxkbKRs5G2kbeR" + "uJG5kbuR//+8kb2RvpG/kcCRwZHCkcORxJHFkcaRyJHLkdCR0pHTkdSR1ZHWkdeR2JHZkdqR25Hdkd6R35HgkeGR4pHjkeSR" + "5ZE3XkReVF5bXl5eYV6MXHpcjVyQXJZciFyYXJlckVyaXJxctVyiXL1crFyrXLFco1zBXLdcxFzSXORcy1zlXAJdA10nXSZd" + "Ll0kXR5dBl0bXVhdPl00XT1dbF1bXW9dXV1rXUtdSl1pXXRdgl2ZXZ1dc4y3XcVdc193X4Jfh1+JX4xflV+ZX5xfqF+tX7Vf" + "vF9iiGFfrXKwcrRyt3K4csNywXLOcs1y0nLocu9y6XLycvRy93IBc/NyA3P6cuaR55HokemR6pHrkeyR7ZHuke+R8JHxkfKR" + "85H0kfWR9pH3kfiR+ZH6kfuR/JH9kf6R/5EAkgGSApIDkgSSBZIGkgeSCJIJkgqSC5IMkg2SDpIPkhCSEZISkhOSFJIVkhaS" + "F5IYkhmSGpIbkhySHZIekh+SIJIhkiKSI5Ikkv//JZImkieSKJIpkiqSK5Iski2SLpIvkjCSMZIykjOSNJI1kjaSN5I4kjmS" + "OpI7kjySPZI+kj+SQJJBkkKSQ5JEkkWS+3IXcxNzIXMKcx5zHXMVcyJzOXMlcyxzOHMxc1BzTXNXc2BzbHNvc35zG4IlWeeY" + "JFkCWWOZZ5lomWmZaplrmWyZdJl3mX2ZgJmEmYeZipmNmZCZkZmTmZSZlZmAXpFei16WXqVeoF65XrVevl6zXlON0l7RXtte" + "6F7qXrqBxF/JX9Zfz18DYO5fBGDhX+Rf/l8FYAZg6l/tX/hfGWA1YCZgG2APYA1gKWArYApgP2AhYHhgeWB7YHpgQmBGkkeS" + "SJJJkkqSS5JMkk2STpJPklCSUZJSklOSVJJVklaSV5JYklmSWpJbklySXZJekl+SYJJhkmKSY5JkkmWSZpJnkmiSaZJqkmuS" + "bJJtkm6Sb5JwknGScpJzknWSdpJ3kniSeZJ6knuSfJJ9kn6Sf5KAkoGSgpKDkoSShZL//4aSh5KIkomSipKLkoySjZKPkpCS" + "kZKSkpOSlJKVkpaSl5KYkpmSmpKbkpySnZKekp+SoJKhkqKSo5KkkqWSppKnkmpgfWCWYJpgrWCdYINgkmCMYJtg7GC7YLFg" + "3WDYYMZg2mC0YCBhJmEVYSNh9GAAYQ5hK2FKYXVhrGGUYadht2HUYfVh3V+zlumV65XxlfOV9ZX2lfyV/pUDlgSWBpYIlgqW" + "C5YMlg2WD5YSlhWWFpYXlhmWGpYsTj9yFWI1bFRsXGxKbKNshWyQbJRsjGxobGlsdGx2bIZsqWzQbNRsrWz3bPhs8WzXbLJs" + "4GzWbPps62zubLFs02zvbP5sqJKpkqqSq5Kskq2Sr5KwkrGSspKzkrSStZK2kreSuJK5krqSu5K8kr2SvpK/ksCSwZLCksOS" + "xJLFksaSx5LJksqSy5LMks2SzpLPktCS0ZLSktOS1JLVktaS15LYktmS2pLbktyS3ZLekt+S4JLhkuKS45LkkuWS5pLnkuiS" + "///pkuqS65Lsku2S7pLvkvCS8ZLykvOS9JL1kvaS95L4kvmS+pL7kvyS/ZL+kv+SAJMBkwKTA5MEkwWTBpMHkwiTCZM5bSdt" + "DG1DbUhtB20EbRltDm0rbU1tLm01bRptT21SbVRtM22RbW9tnm2gbV5tk22UbVxtYG18bWNtGm7HbcVt3m0Obr9t4G0RbuZt" + "3W3ZbRZuq20Mbq5tK25ubk5ua26ybl9uhm5TblRuMm4lbkRu326xbphu4G4tb+JupW6nbr1uu263btdutG7Pbo9uwm6fbmJv" + "Rm9HbyRvFW/5bi9vNm9Lb3RvKm8JbylviW+Nb4xveG9yb3xvem/RbwqTC5MMkw2TDpMPkxCTEZMSkxOTFJMVkxaTF5MYkxmT" + "GpMbkxyTHZMekx+TIJMhkyKTI5MkkyWTJpMnkyiTKZMqkyuTLJMtky6TL5MwkzGTMpMzkzSTNZM2kzeTOJM5kzqTO5M8kz2T" + "P5NAk0GTQpNDk0STRZNGk0eTSJNJk///SpNLk0yTTZNOk0+TUJNRk1KTU5NUk1WTVpNXk1iTWZNak1uTXJNdk16TX5Ngk2GT" + "YpNjk2STZZNmk2eTaJNpk2uTyW+nb7lvtm/Cb+Fv7m/eb+Bv728acCNwG3A5cDVwT3BecIBbhFuVW5NbpVu4Wy91npo0ZORb" + "7lswifBbR44Hi7aP04/Vj+WP7o/kj+mP5o/zj+iPBZAEkAuQJpARkA2QFpAhkDWQNpAtkC+QRJBRkFKQUJBokFiQYpBbkLlm" + "dJB9kIKQiJCDkIuQUF9XX1ZfWF87XKtUUFxZXHFbY1xmXLx/Kl8pXy1fdII8XzubblyBWYNZjVmpWapZo1lsk22TbpNvk3CT" + "cZNyk3OTdJN1k3aTd5N4k3mTepN7k3yTfZN+k3+TgJOBk4KTg5OEk4WThpOHk4iTiZOKk4uTjJONk46TkJORk5KTk5OUk5WT" + "lpOXk5iTmZOak5uTnJOdk56Tn5Ogk6GTopOjk6STpZOmk6eTqJOpk6qTq5P//6yTrZOuk6+TsJOxk7KTs5O0k7WTtpO3k7iT" + "uZO6k7uTvJO9k76Tv5PAk8GTwpPDk8STxZPGk8eTyJPJk8uTzJPNk5dZylmrWZ5ZpFnSWbJZr1nXWb5ZBVoGWt1ZCFrjWdhZ" + "+VkMWglaMlo0WhFaI1oTWkBaZ1pKWlVaPFpiWnVa7ICqWptad1p6Wr5a61qyWtJa1Fq4WuBa41rxWtZa5lrYWtxaCVsXWxZb" + "Mls3W0BbFVwcXFpbZVtzW1FbU1tiW3Wad5p4mnqaf5p9moCagZqFmoiaipqQmpKak5qWmpiam5qcmp2an5qgmqKao5qlmqea" + "n36hfqN+pX6ofql+zpPPk9CT0ZPSk9OT1JPVk9eT2JPZk9qT25Pck92T3pPfk+CT4ZPik+OT5JPlk+aT55Pok+mT6pPrk+yT" + "7ZPuk++T8JPxk/KT85P0k/WT9pP3k/iT+ZP6k/uT/JP9k/6T/5MAlAGUApQDlASUBZQGlAeUCJQJlAqUC5QMlA2U//8OlA+U" + "EJQRlBKUE5QUlBWUFpQXlBiUGZQalBuUHJQdlB6UH5QglCGUIpQjlCSUJZQmlCeUKJQplCqUK5QslC2ULpStfrB+vn7AfsF+" + "wn7Jfst+zH7QftR+137bfuB+4X7ofut+7n7vfvF+8n4Nf/Z++n77fv5+AX8CfwN/B38Ifwt/DH8PfxF/En8Xfxl/HH8bfx9/" + "IX8ifyN/JH8lfyZ/J38qfyt/LH8tfy9/MH8xfzJ/M381f3pef3XbXT51lZCOc5FzrnOic59zz3PCc9Fzt3Ozc8BzyXPIc+Vz" + "2XN8mAp06XPnc95zunPycw90KnRbdCZ0JXQodDB0LnQsdC+UMJQxlDKUM5Q0lDWUNpQ3lDiUOZQ6lDuUPJQ9lD+UQJRBlEKU" + "Q5RElEWURpRHlEiUSZRKlEuUTJRNlE6UT5RQlFGUUpRTlFSUVZRWlFeUWJRZlFqUW5RclF2UXpRflGCUYZRilGOUZJRllGaU" + "Z5RolGmUapRslG2UbpRvlP//cJRxlHKUc5R0lHWUdpR3lHiUeZR6lHuUfJR9lH6Uf5SAlIGUgpSDlISUkZSWlJiUx5TPlNOU" + "1JTalOaU+5QclSCVG3QadEF0XHRXdFV0WXR3dG10fnScdI50gHSBdId0i3SedKh0qXSQdKd00nS6dOqX65fsl0xnU2deZ0hn" + "aWelZ4dnamdzZ5hnp2d1Z6hnnmetZ4tnd2d8Z/BnCWjYZwpo6WewZwxo2We1Z9pns2fdZwBow2e4Z+JnDmjBZ/1nMmgzaGBo" + "YWhOaGJoRGhkaINoHWhVaGZoQWhnaEBoPmhKaEloKWi1aI9odGh3aJNoa2jCaG5p/GgfaSBp+WgnlTOVPZVDlUiVS5VVlVqV" + "YJVulXSVdZV3lXiVeZV6lXuVfJV9lX6VgJWBlYKVg5WElYWVhpWHlYiViZWKlYuVjJWNlY6Vj5WQlZGVkpWTlZSVlZWWlZeV" + "mJWZlZqVm5WclZ2VnpWflaCVoZWilaOVpJWllaaVp5WolamVqpX//6uVrJWtla6Vr5WwlbGVspWzlbSVtZW2lbeVuJW5lbqV" + "u5W8lb2VvpW/lcCVwZXClcOVxJXFlcaVx5XIlcmVypXLlSRp8GgLaQFpV2njaBBpcWk5aWBpQmldaYRpa2mAaZhpeGk0acxp" + "h2mIac5piWlmaWNpeWmbaadpu2mraa1p1GmxacFpymnfaZVp4GmNaf9pL2rtaRdqGGplavJpRGo+aqBqUGpbajVqjmp5aj1q" + "KGpYanxqkWqQaqlql2qrajdzUnOBa4Jrh2uEa5Jrk2uNa5prm2uha6pra49tj3GPco9zj3WPdo94j3ePeY96j3yPfo+Bj4KP" + "hI+Hj4uPzJXNlc6Vz5XQldGV0pXTldSV1ZXWldeV2JXZldqV25Xcld2V3pXfleCV4ZXileOV5JXlleaV55Xslf+VB5YTlhiW" + "G5YeliCWI5YkliWWJpYnliiWKZYrliyWLZYvljCWN5Y4ljmWOpY+lkGWQ5ZKlk6WT5ZRllKWU5ZWlleW//9YllmWWpZcll2W" + "XpZglmOWZZZmlmuWbZZulm+WcJZxlnOWeJZ5lnqWe5Z8ln2WfpZ/loCWgZaCloOWhJaHlomWipaNj46Pj4+Yj5qPzo4LYhdi" + "G2IfYiJiIWIlYiRiLGLnge909HT/dA91EXUTdTRl7mXvZfBlCmYZZnJnA2YVZgBmhXD3Zh1mNGYxZjZmNWYGgF9mVGZBZk9m" + "VmZhZldmd2aEZoxmp2adZr5m22bcZuZm6WYyjTONNo07jT2NQI1FjUaNSI1JjUeNTY1VjVmNx4nKicuJzInOic+J0InRiW5y" + "n3JdcmZyb3J+cn9yhHKLco1yj3KScghjMmOwY4yWjpaRlpKWk5aVlpaWmpablp2WnpaflqCWoZailqOWpJallqaWqJaplqqW" + "q5aslq2WrpavlrGWspa0lrWWt5a4lrqWu5a/lsKWw5bIlsqWy5bQltGW05bUltaW15bYltmW2pbbltyW3Zbelt+W4ZbiluOW" + "5JblluaW55brlv//7Jbtlu6W8JbxlvKW9Jb1lviW+pb7lvyW/Zb/lgKXA5cFlwqXC5cMlxCXEZcSlxSXFZcXlxiXGZcalxuX" + "HZcflyCXP2TYZASA6mvza/1r9Wv5awVsB2wGbA1sFWwYbBlsGmwhbClsJGwqbDJsNWVVZWtlTXJSclZyMHJihhZSn4CcgJOA" + "vIAKZ72AsYCrgK2AtIC3gOeA6IDpgOqA24DCgMSA2YDNgNeAEGfdgOuA8YD0gO2ADYEOgfKA/IAVZxKBWow2gR6BLIEYgTKB" + "SIFMgVOBdIFZgVqBcYFggWmBfIF9gW2BZ4FNWLVaiIGCgZGB1W6jgaqBzIEmZ8qBu4EhlyKXI5cklyWXJpcnlyiXKZcrlyyX" + "LpcvlzGXM5c0lzWXNpc3lzqXO5c8lz2XP5dAl0GXQpdDl0SXRZdGl0eXSJdJl0qXS5dMl02XTpdPl1CXUZdUl1WXV5dYl1qX" + "XJddl1+XY5dkl2aXZ5dol2qXa5dsl22Xbpdvl3CXcZf//3KXdZd3l3iXeZd6l3uXfZd+l3+XgJeBl4KXg5eEl4aXh5eIl4mX" + "ipeMl46Xj5eQl5OXlZeWl5eXmZeal5uXnJedl8GBpoEkazdrOWtDa0ZrWWvRmNKY05jVmNmY2piza0BfwmvziZBlUZ+TZbxl" + "xmXEZcNlzGXOZdJl1mWAcJxwlnCdcLtwwHC3cKtwsXDocMpwEHETcRZxL3ExcXNxXHFocUVxcnFKcXhxenGYcbNxtXGocaBx" + "4HHUcedx+XEdcihybHAYcWZxuXE+Yj1iQ2JIYkliO3lAeUZ5SXlbeVx5U3laeWJ5V3lgeW95Z3l6eYV5inmaead5s3nRX9Bf" + "npefl6GXopekl6WXppenl6iXqZeql6yXrpewl7GXs5e1l7aXt5e4l7mXupe7l7yXvZe+l7+XwJfBl8KXw5fEl8WXxpfHl8iX" + "yZfKl8uXzJfNl86Xz5fQl9GX0pfTl9SX1ZfWl9eX2JfZl9qX25fcl92X3pffl+CX4Zfil+OX///kl+WX6Jful++X8Jfxl/KX" + "9Jf3l/iX+Zf6l/uX/Jf9l/6X/5cAmAGYApgDmASYBZgGmAeYCJgJmAqYC5gMmA2YDpg8YF1gWmBnYEFgWWBjYKtgBmENYV1h" + "qWGdYcth0WEGYoCAf4CTbPZs/G32d/h3AHgJeBd4GHgReKtlLXgceB14OXg6eDt4H3g8eCV4LHgjeCl4TnhteFZ4V3gmeFB4" + "R3hMeGp4m3iTeJp4h3iceKF4o3iyeLl4pXjUeNl4yXjsePJ4BXn0eBN5JHkeeTR5m5/5nvue/J7xdgR3DXf5dgd3CHcadyJ3" + "GXctdyZ3NXc4d1B3UXdHd0N3Wndodw+YEJgRmBKYE5gUmBWYFpgXmBiYGZgamBuYHJgdmB6YH5ggmCGYIpgjmCSYJZgmmCeY" + "KJgpmCqYK5gsmC2YLpgvmDCYMZgymDOYNJg1mDaYN5g4mDmYOpg7mDyYPZg+mD+YQJhBmEKYQ5hEmEWYRphHmEiYSZhKmEuY" + "TJhNmP//TphPmFCYUZhSmFOYVJhVmFaYV5hYmFmYWphbmFyYXZhemF+YYJhhmGKYY5hkmGWYZphnmGiYaZhqmGuYbJhtmG6Y" + "Yndld393jXd9d4B3jHeRd593oHewd7V3vXc6dUB1TnVLdUh1W3VydXl1g3VYf2F/X39Iimh/dH9xf3l/gX9+f8125XYyiIWU" + "hpSHlIuUipSMlI2Uj5SQlJSUl5SVlJqUm5SclKOUpJSrlKqUrZSslK+UsJSylLSUtpS3lLiUuZS6lLyUvZS/lMSUyJTJlMqU" + "y5TMlM2UzpTQlNGU0pTVlNaU15TZlNiU25TelN+U4JTilOSU5ZTnlOiU6pRvmHCYcZhymHOYdJiLmI6YkpiVmJmYo5iomKmY" + "qpirmKyYrZiumK+YsJixmLKYs5i0mLWYtpi3mLiYuZi6mLuYvJi9mL6Yv5jAmMGYwpjDmMSYxZjGmMeYyJjJmMqYy5jMmM2Y" + "z5jQmNSY1pjXmNuY3JjdmOCY4ZjimOOY5Jj//+WY5pjpmOqY65jsmO2Y7pjvmPCY8ZjymPOY9Jj1mPaY95j4mPmY+pj7mPyY" + "/Zj+mP+YAJkBmQKZA5kEmQWZBpkHmemU65TulO+U85T0lPWU95T5lPyU/ZT/lAOVApUGlQeVCZUKlQ2VDpUPlRKVE5UUlRWV" + "FpUYlRuVHZUelR+VIpUqlSuVKZUslTGVMpU0lTaVN5U4lTyVPpU/lUKVNZVElUWVRpVJlUyVTpVPlVKVU5VUlVaVV5VYlVmV" + "W5VelV+VXZVhlWKVZJVllWaVZ5VolWmVapVrlWyVb5VxlXKVc5U6led37HfJltV57Xnjeet5BnpHXQN6AnoeehR6CJkJmQqZ" + "C5kMmQ6ZD5kRmRKZE5kUmRWZFpkXmRiZGZkamRuZHJkdmR6ZH5kgmSGZIpkjmSSZJZkmmSeZKJkpmSqZK5ksmS2ZL5kwmTGZ" + "MpkzmTSZNZk2mTeZOJk5mTqZO5k8mT2ZPpk/mUCZQZlCmUOZRJlFmUaZR5lImUmZ//9KmUuZTJlNmU6ZT5lQmVGZUplTmVaZ" + "V5lYmVmZWplbmVyZXZlemV+ZYJlhmWKZZJlmmXOZeJl5mXuZfpmCmYOZiZk5ejd6UXrPnqWZcHqIdo52k3aZdqR23nTgdCx1" + "IJ4iniieKZ4qniueLJ4ynjGeNp44njeeOZ46nj6eQZ5CnkSeRp5HnkieSZ5LnkyeTp5RnlWeV55anlueXJ5enmOeZp5nnmie" + "aZ5qnmuebJ5xnm2ec56SdZR1lnWgdZ11rHWjdbN1tHW4dcR1sXWwdcN1wnXWdc1143XodeZ15HXrded1A3bxdfx1/3UQdgB2" + "BXYMdhd2CnYldhh2FXYZdoyZjpmamZuZnJmdmZ6Zn5mgmaGZopmjmaSZppmnmamZqpmrmayZrZmuma+ZsJmxmbKZs5m0mbWZ" + "tpm3mbiZuZm6mbuZvJm9mb6Zv5nAmcGZwpnDmcSZxZnGmceZyJnJmcqZy5nMmc2ZzpnPmdCZ0ZnSmdOZ1JnVmdaZ15nYmf//" + "2ZnamduZ3Jndmd6Z35ngmeGZ4pnjmeSZ5ZnmmeeZ6JnpmeqZ65nsme2Z7pnvmfCZ8ZnymfOZ9Jn1mfaZ95n4mfmZG3Y8diJ2" + "IHZAdi12MHY/djV2Q3Y+djN2TXZedlR2XHZWdmt2b3bKf+Z6eHp5eoB6hnqIepV6pnqgeqx6qHqterN6ZIhpiHKIfYh/iIKI" + "oojGiLeIvIjJiOKIzojjiOWI8YgaifyI6Ij+iPCIIYkZiROJG4kKiTSJK4k2iUGJZol7iYt15YCydrR23HcSgBSAFoAcgCCA" + "IoAlgCaAJ4ApgCiAMYALgDWAQ4BGgE2AUoBpgHGAg4l4mICYg5j6mfuZ/Jn9mf6Z/5kAmgGaApoDmgSaBZoGmgeaCJoJmgqa" + "C5oMmg2aDpoPmhCaEZoSmhOaFJoVmhaaF5oYmhmaGpobmhyaHZoemh+aIJohmiKaI5okmiWaJponmiiaKZoqmiuaLJotmi6a" + "L5owmjGaMpozmjSaNZo2mjeaOJr//zmaOpo7mjyaPZo+mj+aQJpBmkKaQ5pEmkWaRppHmkiaSZpKmkuaTJpNmk6aT5pQmlGa" + "UppTmlSaVZpWmleaWJpZmomYjJiNmI+YlJiamJuYnpifmKGYopilmKaYTYZUhmyGboZ/hnqGfIZ7hqiGjYaLhqyGnYanhqOG" + "qoaThqmGtobEhrWGzoawhrqGsYavhsmGz4a0humG8Ybyhu2G84bQhhOH3ob0ht+G2IbRhgOHB4f4hgiHCocNhwmHI4c7hx6H" + "JYcuhxqHPodIhzSHMYcphzeHP4eChyKHfYd+h3uHYIdwh0yHboeLh1OHY4d8h2SHWYdlh5OHr4eoh9KHWppbmlyaXZpeml+a" + "YJphmmKaY5pkmmWaZppnmmiaaZpqmmuacpqDmomajZqOmpSalZqZmqaaqZqqmquarJqtmq6ar5qymrOatJq1mrmau5q9mr6a" + "v5rDmsSaxprHmsiayZrKms2azprPmtCa0prUmtWa1prXmtma2prbmtya///dmt6a4JrimuOa5Jrlmuea6Jrpmuqa7JrumvCa" + "8ZrymvOa9Jr1mvaa95r4mvqa/Jr9mv6a/5oAmwGbApsEmwWbBpvGh4iHhYeth5eHg4erh+WHrIe1h7OHy4fTh72H0YfAh8qH" + "24fqh+CH7ocWiBOI/ocKiBuIIYg5iDyINn9Cf0R/RX8Qgvp6/XoIewN7BHsVewp7K3sPe0d7OHsqexl7LnsxeyB7JXskezN7" + "Pnsee1h7WntFe3V7THtde2B7bnt7e2J7cntxe5B7pnune7h7rHude6h7hXuqe5x7onure7R70XvBe8x73Xvae+V75nvqewx8" + "/nv8ew98FnwLfAebCZsKmwubDJsNmw6bEJsRmxKbFJsVmxabF5sYmxmbGpsbmxybHZsemyCbIZsimySbJZsmmyebKJspmyqb" + "K5ssmy2bLpswmzGbM5s0mzWbNps3mzibOZs6mz2bPps/m0CbRptKm0ubTJtOm1CbUptTm1WbVptXm1ibWZtam///W5tcm12b" + "Xptfm2CbYZtim2ObZJtlm2abZ5tom2mbaptrm2ybbZtum2+bcJtxm3Kbc5t0m3Wbdpt3m3ibeZt6m3ubH3wqfCZ8OHxBfEB8" + "/oEBggKCBILsgUSIIYIigiOCLYIvgiiCK4I4gjuCM4I0gj6CRIJJgkuCT4Jagl+CaIJ+iIWIiIjYiN+IXomdf59/p3+vf7B/" + "sn98fEllkXydfJx8nnyifLJ8vHy9fMF8x3zMfM18yHzFfNd86Hxugqhmv3/Of9V/5X/hf+Z/6X/uf/N/+Hx3faZ9rn1Hfpt+" + "uJ60nnONhI2UjZGNsY1njW2NR4xJjEqRUJFOkU+RZJF8m32bfpt/m4CbgZuCm4ObhJuFm4abh5uIm4mbipuLm4ybjZuOm4+b" + "kJuRm5Kbk5uUm5WblpuXm5ibmZuam5ubnJudm56bn5ugm6Gbopujm6SbpZumm6ebqJupm6qbq5usm62brpuvm7CbsZuym7Ob" + "tJu1m7abt5u4m7mbupv//7ubvJu9m76bv5vAm8GbwpvDm8SbxZvGm8ebyJvJm8qby5vMm82bzpvPm9Cb0ZvSm9Ob1JvVm9ab" + "15vYm9mb2pvbm2KRYZFwkWmRb5F9kX6RcpF0kXmRjJGFkZCRjZGRkaKRo5Gqka2RrpGvkbWRtJG6kVWMfp64jeuNBY5ZjmmO" + "tY2/jbyNuo3EjdaN143ajd6Nzo3PjduNxo3sjfeN+I3jjfmN+43kjQmO/Y0Ujh2OH44sji6OI44vjjqOQI45jjWOPY4xjkmO" + "QY5CjlGOUo5KjnCOdo58jm+OdI6Fjo+OlI6QjpyOno54jIKMioyFjJiMlIybZdaJ3onaidyJ3Jvdm96b35vgm+Gb4pvjm+Sb" + "5Zvmm+eb6Jvpm+qb65vsm+2b7pvvm/Cb8Zvym/Ob9Jv1m/ab95v4m/mb+pv7m/yb/Zv+m/+bAJwBnAKcA5wEnAWcBpwHnAic" + "CZwKnAucDJwNnA6cD5wQnBGcEpwTnBScFZwWnBecGJwZnBqc//8bnBycHZwenB+cIJwhnCKcI5wknCWcJpwnnCicKZwqnCuc" + "LJwtnC6cL5wwnDGcMpwznDScNZw2nDecOJw5nDqcO5zlieuJ74k+iiaLU5fplvOW75YGlwGXCJcPlw6XKpctlzCXPpeAn4Of" + "hZ+Gn4efiJ+Jn4qfjJ/+ngufDZ+5lryWvZbOltKWv3fglo6SrpLIkj6TapPKk4+TPpRrlH+cgpyFnIach5yInCN6i5yOnJCc" + "kZySnJSclZyanJucnpyfnKCcoZyinKOcpZymnKecqJypnKucrZyunLCcsZyynLOctJy1nLact5y6nLucvJy9nMScxZzGnMec" + "ypzLnDycPZw+nD+cQJxBnEKcQ5xEnEWcRpxHnEicSZxKnEucTJxNnE6cT5xQnFGcUpxTnFScVZxWnFecWJxZnFqcW5xcnF2c" + "XpxfnGCcYZxinGOcZJxlnGacZ5xonGmcapxrnGycbZxunG+ccJxxnHKcc5x0nHWcdpx3nHiceZx6nP//e5x9nH6cgJyDnISc" + "iZyKnIycj5yTnJacl5yYnJmcnZyqnKycr5y5nL6cv5zAnMGcwpzInMmc0ZzSnNqc25zgnOGczJzNnM6cz5zQnNOc1JzVnNec" + "2JzZnNyc3ZzfnOKcfJeFl5GXkpeUl6+Xq5ejl7KXtJexmrCat5pYnraaupq8msGawJrFmsKay5rMmtGaRZtDm0ebSZtIm02b" + "UZvomA2ZLplVmVSZ35rhmuaa75rrmvua7Zr5mgibD5sTmx+bI5u9nr6eO36CnoeeiJ6LnpKe1pOdnp+e257cnt2e4J7fnuKe" + "6Z7nnuWe6p7vniKfLJ8vnzmfN589nz6fRJ/jnOSc5ZzmnOec6JzpnOqc65zsnO2c7pzvnPCc8ZzynPOc9Jz1nPac95z4nPmc" + "+pz7nPyc/Zz+nP+cAJ0BnQKdA50EnQWdBp0HnQidCZ0KnQudDJ0NnQ6dD50QnRGdEp0TnRSdFZ0WnRedGJ0ZnRqdG50cnR2d" + "Hp0fnSCdIZ3//yKdI50knSWdJp0nnSidKZ0qnSudLJ0tnS6dL50wnTGdMp0znTSdNZ02nTedOJ05nTqdO508nT2dPp0/nUCd" + "QZ1Cnf//////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////Q51EnUWdRp1HnUidSZ1KnUudTJ1NnU6d" + "T51QnVGdUp1TnVSdVZ1WnVedWJ1ZnVqdW51cnV2dXp1fnWCdYZ1inWOdZJ1lnWadZ51onWmdap1rnWydbZ1unW+dcJ1xnXKd" + "c510nXWddp13nXideZ16nXudfJ19nX6df52AnYGd//+CnYOdhJ2FnYadh52InYmdip2LnYydjZ2OnY+dkJ2RnZKdk52UnZWd" + "lp2XnZidmZ2anZudnJ2dnZ6dn52gnaGdop3/////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////////////6Od" + "pJ2lnaadp52onamdqp2rnaydrZ2una+dsJ2xnbKds520nbWdtp23nbiduZ26nbudvJ29nb6dv53AncGdwp3DncSdxZ3Gnced" + "yJ3Jncqdy53Mnc2dzp3PndCd0Z3SndOd1J3Vndad153Yndmd2p3bndyd3Z3end+d4J3hnf//4p3jneSd5Z3mneed6J3pneqd" + "653sne2d7p3vnfCd8Z3ynfOd9J31nfad9534nfmd+p37nfyd/Z3+nf+dAJ4BngKe////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////8DngSeBZ4GngeeCJ4JngqeC54Mng2eDp4PnhCeEZ4SnhOeFJ4VnhaeF54YnhmeGp4bnhye" + "HZ4eniSeJ54unjCeNJ47njyeQJ5NnlCeUp5TnlSeVp5Znl2eX55gnmGeYp5lnm6eb55ynnSedZ52nneeeJ55nnqee558nn2e" + "gJ7//4Geg56EnoWehp6JnoqejJ6Nno6ej56QnpGelJ6Vnpael56Ynpmemp6bnpyenp6gnqGeop6jnqSepZ6nnqieqZ6qnv//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////q56snq2erp6vnrCesZ6ynrOetZ62nreeuZ66nrye" + "v57AnsGewp7DnsWexp7Hnsieyp7Lnsye0J7SntOe1Z7Wntee2Z7ant6e4Z7jnuSe5p7onuue7J7tnu6e8J7xnvKe8570nvWe" + "9p73nvie+p79nv+eAJ8BnwKfA58EnwWf//8GnwefCJ8JnwqfDJ8PnxGfEp8UnxWfFp8YnxqfG58cnx2fHp8fnyGfI58knyWf" + "Jp8nnyifKZ8qnyufLZ8unzCfMZ//////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////////////////////zKfM580nzWf" + "Np84nzqfPJ8/n0CfQZ9Cn0OfRZ9Gn0efSJ9Jn0qfS59Mn02fTp9Pn1KfU59Un1WfVp9Xn1ifWZ9an1ufXJ9dn16fX59gn2Gf" + "Yp9jn2SfZZ9mn2efaJ9pn2qfa59sn22fbp9vn3CfcZ9yn3OfdJ91n3afd594n///eZ96n3uffJ99n36fgZ+Cn42fjp+Pn5Cf" + "kZ+Sn5OflJ+Vn5afl5+Yn5yfnZ+en6Gfop+jn6SfpZ8s+Xn5lfnn+fH5////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////8M+g36DvoP+hH6E/oU+hj6H/og+iH6I/ok+if6KPop+v//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +GBK_ENC_EXC = {} +GBK_ENC_REJECT = frozenset() + +# ---- gb18030 ---- +GB18030_DEC = _g( + "Ak4ETgVOBk4PThJOF04fTiBOIU4jTiZOKU4uTi9OMU4zTjVON048TkBOQU5CTkRORk5KTlFOVU5XTlpOW05iTmNOZE5lTmdO" + "aE5qTmtObE5tTm5Ob05yTnROdU52TndOeE55TnpOe058Tn1Of06AToFOgk6DToROhU6HTopO//+QTpZOl06ZTpxOnU6eTqNO" + "qk6vTrBOsU60TrZOt064TrlOvE69Tr5OyE7MTs9O0E7STtpO207cTuBO4k7mTudO6U7tTu5O707xTvRO+E75TvpO/E7+TgBP" + "Ak8DTwRPBU8GTwdPCE8LTwxPEk8TTxRPFU8WTxxPHU8hTyNPKE8pTyxPLU8uTzFPM081TzdPOU87Tz5PP09AT0FPQk9ET0VP" + "R09IT0lPSk9LT0xPUk9UT1ZPYU9iT2ZPaE9qT2tPbU9uT3FPck91T3dPeE95T3pPfU+AT4FPgk+FT4ZPh0+KT4xPjk+QT5JP" + "k0+VT5ZPmE+ZT5pPnE+eT59PoU+iT6RPq0+tT7BPsU+yT7NPtE+2T7dPuE+5T7pPu0+8T71Pvk/AT8FPwk/GT8dPyE/JT8tP" + "zE/NT9JP00/UT9VP1k/ZT9tP4E/iT+RP5U/nT+tP7E/wT/JP9E/1T/ZP90/5T/tP/E/9T/9PAFABUAJQA1AEUAVQBlAHUAhQ" + "CVAKUP//C1AOUBBQEVATUBVQFlAXUBtQHVAeUCBQIlAjUCRQJ1ArUC9QMFAxUDJQM1A0UDVQNlA3UDhQOVA7UD1QP1BAUEFQ" + "QlBEUEVQRlBJUEpQS1BNUFBQUVBSUFNQVFBWUFdQWFBZUFtQXVBeUF9QYFBhUGJQY1BkUGZQZ1BoUGlQalBrUG1QblBvUHBQ" + "cVByUHNQdFB1UHhQeVB6UHxQfVCBUIJQg1CEUIZQh1CJUIpQi1CMUI5Qj1CQUJFQklCTUJRQlVCWUJdQmFCZUJpQm1CcUJ1Q" + "nlCfUKBQoVCiUKRQplCqUKtQrVCuUK9QsFCxULNQtFC1ULZQt1C4ULlQvFC9UL5Qv1DAUMFQwlDDUMRQxVDGUMdQyFDJUMpQ" + "y1DMUM1QzlDQUNFQ0lDTUNRQ1VDXUNhQ2VDbUNxQ3VDeUN9Q4FDhUOJQ41DkUOVQ6FDpUOpQ61DvUPBQ8VDyUPRQ9lD3UPhQ" + "+VD6UPxQ/VD+UP9QAFEBUQJRA1EEUQVRCFH//wlRClEMUQ1RDlEPURBREVETURRRFVEWURdRGFEZURpRG1EcUR1RHlEfUSBR" + "IlEjUSRRJVEmUSdRKFEpUSpRK1EsUS1RLlEvUTBRMVEyUTNRNFE1UTZRN1E4UTlROlE7UTxRPVE+UUJRR1FKUUxRTlFPUVBR" + "UlFTUVdRWFFZUVtRXVFeUV9RYFFhUWNRZFFmUWdRaVFqUW9RclF6UX5Rf1GDUYRRhlGHUYpRi1GOUY9RkFGRUZNRlFGYUZpR" + "nVGeUZ9RoVGjUaZRp1GoUalRqlGtUa5RtFG4UblRulG+Ub9RwVHCUcNRxVHIUcpRzVHOUdBR0lHTUdRR1VHWUddR2FHZUdpR" + "3FHeUd9R4lHjUeVR5lHnUehR6VHqUexR7lHxUfJR9FH3Uf5RBFIFUglSC1IMUg9SEFITUhRSFVIcUh5SH1IhUiJSI1IlUiZS" + "J1IqUixSL1IxUjJSNFI1UjxSPlJEUkVSRlJHUkhSSVJLUk5ST1JSUlNSVVJXUlhS//9ZUlpSW1JdUl9SYFJiUmNSZFJmUmhS" + "a1JsUm1SblJwUnFSc1J0UnVSdlJ3UnhSeVJ6UntSfFJ+UoBSg1KEUoVShlKHUolSilKLUoxSjVKOUo9SkVKSUpRSlVKWUpdS" + "mFKZUppSnFKkUqVSplKnUq5Sr1KwUrRStVK2UrdSuFK5UrpSu1K8Ur1SwFLBUsJSxFLFUsZSyFLKUsxSzVLOUs9S0VLTUtRS" + "1VLXUtlS2lLbUtxS3VLeUuBS4VLiUuNS5VLmUudS6FLpUupS61LsUu1S7lLvUvFS8lLzUvRS9VL2UvdS+FL7UvxS/VIBUwJT" + "A1MEUwdTCVMKUwtTDFMOUxFTElMTUxRTGFMbUxxTHlMfUyJTJFMlUydTKFMpUytTLFMtUy9TMFMxUzJTM1M0UzVTNlM3UzhT" + "PFM9U0BTQlNEU0ZTS1NMU01TUFNUU1hTWVNbU11TZVNoU2pTbFNtU3JTdlN5U3tTfFN9U35TgFOBU4NTh1OIU4pTjlOPU///" + "kFORU5JTk1OUU5ZTl1OZU5tTnFOeU6BToVOkU6dTqlOrU6xTrVOvU7BTsVOyU7NTtFO1U7dTuFO5U7pTvFO9U75TwFPDU8RT" + "xVPGU8dTzlPPU9BT0lPTU9VT2lPcU91T3lPhU+JT51P0U/pT/lP/UwBUAlQFVAdUC1QUVBhUGVQaVBxUIlQkVCVUKlQwVDNU" + "NlQ3VDpUPVQ/VEFUQlREVEVUR1RJVExUTVROVE9UUVRaVF1UXlRfVGBUYVRjVGVUZ1RpVGpUa1RsVG1UblRvVHBUdFR5VHpU" + "flR/VIFUg1SFVIdUiFSJVIpUjVSRVJNUl1SYVJxUnlSfVKBUoVSiVKVUrlSwVLJUtVS2VLdUuVS6VLxUvlTDVMVUylTLVNZU" + "2FTbVOBU4VTiVONU5FTrVOxU71TwVPFU9FT1VPZU91T4VPlU+1T+VABVAlUDVQRVBVUIVQpVC1UMVQ1VDlUSVRNVFVUWVRdV" + "GFUZVRpVHFUdVR5VH1UhVSVVJlX//yhVKVUrVS1VMlU0VTVVNlU4VTlVOlU7VT1VQFVCVUVVR1VIVUtVTFVNVU5VT1VRVVJV" + "U1VUVVdVWFVZVVpVW1VdVV5VX1VgVWJVY1VoVWlVa1VvVXBVcVVyVXNVdFV5VXpVfVV/VYVVhlWMVY1VjlWQVZJVk1WVVZZV" + "l1WaVZtVnlWgVaFVolWjVaRVpVWmVahVqVWqVatVrFWtVa5Vr1WwVbJVtFW2VbhVulW8Vb9VwFXBVcJVw1XGVcdVyFXKVctV" + "zlXPVdBV1VXXVdhV2VXaVdtV3lXgVeJV51XpVe1V7lXwVfFV9FX2VfhV+VX6VftV/FX/VQJWA1YEVgVWBlYHVgpWC1YNVhBW" + "EVYSVhNWFFYVVhZWF1YZVhpWHFYdViBWIVYiViVWJlYoVilWKlYrVi5WL1YwVjNWNVY3VjhWOlY8Vj1WPlZAVkFWQlZDVkRW" + "RVZGVkdWSFZJVkpWS1ZPVlBWUVZSVlNWVVZWVlpWW1ZdVl5WX1ZgVmFW//9jVmVWZlZnVm1WblZvVnBWclZzVnRWdVZ3VnhW" + "eVZ6Vn1WflZ/VoBWgVaCVoNWhFaHVohWiVaKVotWjFaNVpBWkVaSVpRWlVaWVpdWmFaZVppWm1acVp1WnlafVqBWoVaiVqRW" + "pVamVqdWqFapVqpWq1asVq1WrlawVrFWslazVrRWtVa2VrhWuVa6VrtWvVa+Vr9WwFbBVsJWw1bEVsVWxlbHVshWyVbLVsxW" + "zVbOVs9W0FbRVtJW01bVVtZW2FbZVtxW41blVuZW51boVulW6lbsVu5W71byVvNW9lb3VvhW+1b8VgBXAVcCVwVXB1cLVwxX" + "DVcOVw9XEFcRVxJXE1cUVxVXFlcXVxhXGVcaVxtXHVceVyBXIVciVyRXJVcmVydXK1cxVzJXNFc1VzZXN1c4VzxXPVc/V0FX" + "Q1dEV0VXRldIV0lXS1dSV1NXVFdVV1ZXWFdZV2JXY1dlV2dXbFduV3BXcVdyV3RXdVd4V3lXeld9V35Xf1eAV///gVeHV4hX" + "iVeKV41XjlePV5BXkVeUV5VXlleXV5hXmVeaV5xXnVeeV59XpVeoV6pXrFevV7BXsVezV7VXtle3V7lXule7V7xXvVe+V79X" + "wFfBV8RXxVfGV8dXyFfJV8pXzFfNV9BX0VfTV9ZX11fbV9xX3lfhV+JX41flV+ZX51foV+lX6lfrV+xX7lfwV/FX8lfzV/VX" + "9lf3V/tX/Ff+V/9XAVgDWARYBVgIWAlYClgMWA5YD1gQWBJYE1gUWBZYF1gYWBpYG1gcWB1YH1giWCNYJVgmWCdYKFgpWCtY" + "LFgtWC5YL1gxWDJYM1g0WDZYN1g4WDlYOlg7WDxYPVg+WD9YQFhBWEJYQ1hFWEZYR1hIWElYSlhLWE5YT1hQWFJYU1hVWFZY" + "V1hZWFpYW1hcWF1YX1hgWGFYYlhjWGRYZlhnWGhYaVhqWG1YblhvWHBYcVhyWHNYdFh1WHZYd1h4WHlYelh7WHxYfVh/WIJY" + "hFiGWIdYiFiKWItYjFj//41YjliPWJBYkViUWJVYlliXWJhYm1icWJ1YoFihWKJYo1ikWKVYplinWKpYq1isWK1YrlivWLBY" + "sViyWLNYtFi1WLZYt1i4WLlYuli7WL1Yvli/WMBYwljDWMRYxljHWMhYyVjKWMtYzFjNWM5Yz1jQWNJY01jUWNZY11jYWNlY" + "2ljbWNxY3VjeWN9Y4FjhWOJY41jlWOZY51joWOlY6ljtWO9Y8VjyWPRY9Vj3WPhY+lj7WPxY/Vj+WP9YAFkBWQNZBVkGWQhZ" + "CVkKWQtZDFkOWRBZEVkSWRNZF1kYWRtZHVkeWSBZIVkiWSNZJlkoWSxZMFkyWTNZNVk2WTtZPVk+WT9ZQFlDWUVZRllKWUxZ" + "TVlQWVJZU1lZWVtZXFldWV5ZX1lhWWNZZFlmWWdZaFlpWWpZa1lsWW1ZbllvWXBZcVlyWXVZd1l6WXtZfFl+WX9ZgFmFWYlZ" + "i1mMWY5Zj1mQWZFZlFmVWZhZmlmbWZxZnVmfWaBZoVmiWaZZ//+nWaxZrVmwWbFZs1m0WbVZtlm3WbhZulm8Wb1Zv1nAWcFZ" + "wlnDWcRZxVnHWchZyVnMWc1ZzlnPWdVZ1lnZWdtZ3lnfWeBZ4VniWeRZ5lnnWelZ6lnrWe1Z7lnvWfBZ8VnyWfNZ9Fn1WfZZ" + "91n4WfpZ/Fn9Wf5ZAFoCWgpaC1oNWg5aD1oQWhJaFFoVWhZaF1oZWhpaG1odWh5aIVoiWiRaJlonWihaKlorWixaLVouWi9a" + "MFozWjVaN1o4WjlaOlo7Wj1aPlo/WkFaQlpDWkRaRVpHWkhaS1pMWk1aTlpPWlBaUVpSWlNaVFpWWldaWFpZWltaXFpdWl5a" + "X1pgWmFaY1pkWmVaZlpoWmlaa1psWm1ablpvWnBacVpyWnNaeFp5WntafFp9Wn5agFqBWoJag1qEWoVahlqHWohaiVqKWota" + "jFqNWo5aj1qQWpFak1qUWpVallqXWphamVqcWp1anlqfWqBaoVqiWqNapFqlWqZap1qoWqlaq1qsWv//rVquWq9asFqxWrRa" + "tlq3Wrlaulq7WrxavVq/WsBaw1rEWsVaxlrHWshaylrLWs1azlrPWtBa0VrTWtVa11rZWtpa21rdWt5a31riWuRa5VrnWuha" + "6lrsWu1a7lrvWvBa8lrzWvRa9Vr2Wvda+Fr5Wvpa+1r8Wv1a/lr/WgBbAVsCWwNbBFsFWwZbB1sIWwpbC1sMWw1bDlsPWxBb" + "EVsSWxNbFFsVWxhbGVsaWxtbHFsdWx5bH1sgWyFbIlsjWyRbJVsmWydbKFspWypbK1ssWy1bLlsvWzBbMVszWzVbNls4Wzlb" + "Ols7WzxbPVs+Wz9bQVtCW0NbRFtFW0ZbR1tIW0lbSltLW0xbTVtOW09bUltWW15bYFthW2dbaFtrW21bbltvW3JbdFt2W3db" + "eFt5W3tbfFt+W39bgluGW4pbjVuOW5BbkVuSW5RbllufW6dbqFupW6xbrVuuW69bsVuyW7dbulu7W7xbwFvBW8NbyFvJW8pb" + "y1vNW85bz1v//9Fb1FvVW9Zb11vYW9lb2lvbW9xb4FviW+Nb5lvnW+lb6lvrW+xb7VvvW/Fb8lvzW/Rb9Vv2W/db/Vv+WwBc" + "AlwDXAVcB1wIXAtcDFwNXA5cEFwSXBNcF1wZXBtcHlwfXCBcIVwjXCZcKFwpXCpcK1wtXC5cL1wwXDJcM1w1XDZcN1xDXERc" + "RlxHXExcTVxSXFNcVFxWXFdcWFxaXFtcXFxdXF9cYlxkXGdcaFxpXGpca1xsXG1ccFxyXHNcdFx1XHZcd1x4XHtcfFx9XH5c" + "gFyDXIRchVyGXIdciVyKXItcjlyPXJJck1yVXJ1cnlyfXKBcoVykXKVcplynXKhcqlyuXK9csFyyXLRctly5XLpcu1y8XL5c" + "wFzCXMNcxVzGXMdcyFzJXMpczFzNXM5cz1zQXNFc01zUXNVc1lzXXNhc2lzbXNxc3VzeXN9c4FziXONc51zpXOtc7FzuXO9c" + "8VzyXPNc9Fz1XPZc91z4XPlc+lz8XP1c/lz/XABd//8BXQRdBV0IXQldCl0LXQxdDV0PXRBdEV0SXRNdFV0XXRhdGV0aXRxd" + "HV0fXSBdIV0iXSNdJV0oXSpdK10sXS9dMF0xXTJdM101XTZdN104XTldOl07XTxdP11AXUFdQl1DXURdRV1GXUhdSV1NXU5d" + "T11QXVFdUl1TXVRdVV1WXVddWV1aXVxdXl1fXWBdYV1iXWNdZF1lXWZdZ11oXWpdbV1uXXBdcV1yXXNddV12XXddeF15XXpd" + "e118XX1dfl1/XYBdgV2DXYRdhV2GXYddiF2JXYpdi12MXY1djl2PXZBdkV2SXZNdlF2VXZZdl12YXZpdm12cXZ5dn12gXaFd" + "ol2jXaRdpV2mXaddqF2pXapdq12sXa1drl2vXbBdsV2yXbNdtF21XbZduF25Xbpdu128Xb1dvl2/XcBdwV3CXcNdxF3GXcdd" + "yF3JXcpdy13MXc5dz13QXdFd0l3TXdRd1V3WXddd2F3ZXdpd3F3fXeBd413kXepd7F3tXf//8F31XfZd+F35Xfpd+138Xf9d" + "AF4EXgdeCV4KXgteDV4OXhJeE14XXh5eH14gXiFeIl4jXiReJV4oXileKl4rXixeL14wXjJeM140XjVeNl45XjpePl4/XkBe" + "QV5DXkZeR15IXkleSl5LXk1eTl5PXlBeUV5SXlNeVl5XXlheWV5aXlxeXV5fXmBeY15kXmVeZl5nXmheaV5qXmtebF5tXm5e" + "b15wXnFedV53Xnlefl6BXoJeg16FXoheiV6MXo1ejl6SXphem16dXqFeol6jXqReqF6pXqpeq16sXq5er16wXrFesl60Xrpe" + "u168Xr1ev17AXsFewl7DXsRexV7GXsdeyF7LXsxezV7OXs9e0F7UXtVe117YXtle2l7cXt1e3l7fXuBe4V7iXuNe5F7lXuZe" + "517pXute7F7tXu5e717wXvFe8l7zXvVe+F75Xvte/F79XgVfBl8HXwlfDF8NXw5fEF8SXxRfFl8ZXxpfHF8dXx5fIV8iXyNf" + "JF///yhfK18sXy5fMF8yXzNfNF81XzZfN184XztfPV8+Xz9fQV9CX0NfRF9FX0ZfR19IX0lfSl9LX0xfTV9OX09fUV9UX1lf" + "Wl9bX1xfXl9fX2BfY19lX2dfaF9rX25fb19yX3RfdV92X3hfel99X35ff1+DX4ZfjV+OX49fkV+TX5Rfll+aX5tfnV+eX59f" + "oF+iX6NfpF+lX6Zfp1+pX6tfrF+vX7BfsV+yX7NftF+2X7hfuV+6X7tfvl+/X8BfwV/CX8dfyF/KX8tfzl/TX9Rf1V/aX9tf" + "3F/eX99f4l/jX+Vf5l/oX+lf7F/vX/Bf8l/zX/Rf9l/3X/lf+l/8XwdgCGAJYAtgDGAQYBFgE2AXYBhgGmAeYB9gImAjYCRg" + "LGAtYC5gMGAxYDJgM2A0YDZgN2A4YDlgOmA9YD5gQGBEYEVgRmBHYEhgSWBKYExgTmBPYFFgU2BUYFZgV2BYYFtgXGBeYF9g" + "YGBhYGVgZmBuYHFgcmB0YHVgd2B+YIBg//+BYIJghWCGYIdgiGCKYItgjmCPYJBgkWCTYJVgl2CYYJlgnGCeYKFgomCkYKVg" + "p2CpYKpgrmCwYLNgtWC2YLdguWC6YL1gvmC/YMBgwWDCYMNgxGDHYMhgyWDMYM1gzmDPYNBg0mDTYNRg1mDXYNlg22DeYOFg" + "4mDjYORg5WDqYPFg8mD1YPdg+GD7YPxg/WD+YP9gAmEDYQRhBWEHYQphC2EMYRBhEWESYRNhFGEWYRdhGGEZYRthHGEdYR5h" + "IWEiYSVhKGEpYSphLGEtYS5hL2EwYTFhMmEzYTRhNWE2YTdhOGE5YTphO2E8YT1hPmFAYUFhQmFDYURhRWFGYUdhSWFLYU1h" + "T2FQYVJhU2FUYVZhV2FYYVlhWmFbYVxhXmFfYWBhYWFjYWRhZWFmYWlhamFrYWxhbWFuYW9hcWFyYXNhdGF2YXhheWF6YXth" + "fGF9YX5hf2GAYYFhgmGDYYRhhWGGYYdhiGGJYYphjGGNYY9hkGGRYZJhk2GVYf//lmGXYZhhmWGaYZthnGGeYZ9hoGGhYaJh" + "o2GkYaVhpmGqYathrWGuYa9hsGGxYbJhs2G0YbVhtmG4YblhumG7YbxhvWG/YcBhwWHDYcRhxWHGYcdhyWHMYc1hzmHPYdBh" + "02HVYdZh12HYYdlh2mHbYdxh3WHeYd9h4GHhYeJh42HkYeVh52HoYelh6mHrYexh7WHuYe9h8GHxYfJh82H0YfZh92H4Yflh" + "+mH7Yfxh/WH+YQBiAWICYgNiBGIFYgdiCWITYhRiGWIcYh1iHmIgYiNiJmInYihiKWIrYi1iL2IwYjFiMmI1YjZiOGI5Yjpi" + "O2I8YkJiRGJFYkZiSmJPYlBiVWJWYldiWWJaYlxiXWJeYl9iYGJhYmJiZGJlYmhicWJyYnRidWJ3YnhiemJ7Yn1igWKCYoNi" + "hWKGYodiiGKLYoxijWKOYo9ikGKUYplinGKdYp5io2KmYqdiqWKqYq1irmKvYrBismKzYrRitmK3YrhiumK+YsBiwWL//8Ni" + "y2LPYtFi1WLdYt5i4GLhYuRi6mLrYvBi8mL1Yvhi+WL6YvtiAGMDYwRjBWMGYwpjC2MMYw1jD2MQYxJjE2MUYxVjF2MYYxlj" + "HGMmYydjKWMsYy1jLmMwYzFjM2M0YzVjNmM3YzhjO2M8Yz5jP2NAY0FjRGNHY0hjSmNRY1JjU2NUY1ZjV2NYY1ljWmNbY1xj" + "XWNgY2RjZWNmY2hjamNrY2xjb2NwY3Jjc2N0Y3VjeGN5Y3xjfWN+Y39jgWODY4RjhWOGY4tjjWORY5NjlGOVY5djmWOaY5tj" + "nGOdY55jn2OhY6RjpmOrY69jsWOyY7VjtmO5Y7tjvWO/Y8BjwWPCY8NjxWPHY8hjymPLY8xj0WPTY9Rj1WPXY9hj2WPaY9tj" + "3GPdY99j4mPkY+Vj5mPnY+hj62PsY+5j72PwY/Fj82P1Y/dj+WP6Y/tj/GP+YwNkBGQGZAdkCGQJZApkDWQOZBFkEmQVZBZk" + "F2QYZBlkGmQdZB9kImQjZCRk//8lZCdkKGQpZCtkLmQvZDBkMWQyZDNkNWQ2ZDdkOGQ5ZDtkPGQ+ZEBkQmRDZElkS2RMZE1k" + "TmRPZFBkUWRTZFVkVmRXZFlkWmRbZFxkXWRfZGBkYWRiZGNkZGRlZGZkaGRqZGtkbGRuZG9kcGRxZHJkc2R0ZHVkdmR3ZHtk" + "fGR9ZH5kf2SAZIFkg2SGZIhkiWSKZItkjGSNZI5kj2SQZJNklGSXZJhkmmSbZJxknWSfZKBkoWSiZKNkpWSmZKdkqGSqZKtk" + "r2SxZLJks2S0ZLZkuWS7ZL1kvmS/ZMFkw2TEZMZkx2TIZMlkymTLZMxkz2TRZNNk1GTVZNZk2WTaZNtk3GTdZN9k4GThZONk" + "5WTnZOhk6WTqZOtk7GTtZO5k72TwZPFk8mTzZPRk9WT2ZPdk+GT5ZPpk+2T8ZP1k/mT/ZAFlAmUDZQRlBWUGZQdlCGUKZQtl" + "DGUNZQ5lD2UQZRFlE2UUZRVlFmUXZRllGmUbZRxlHWUeZR9lIGUhZf//ImUjZSRlJmUnZShlKWUqZSxlLWUwZTFlMmUzZTdl" + "OmU8ZT1lQGVBZUJlQ2VEZUZlR2VKZUtlTWVOZVBlUmVTZVRlV2VYZVplXGVfZWBlYWVkZWVlZ2VoZWllamVtZW5lb2VxZXNl" + "dWV2ZXhleWV6ZXtlfGV9ZX5lf2WAZYFlgmWDZYRlhWWGZYhliWWKZY1ljmWPZZJllGWVZZZlmGWaZZ1lnmWgZaJlo2WmZahl" + "qmWsZa5lsWWyZbNltGW1ZbZlt2W4Zbplu2W+Zb9lwGXCZcdlyGXJZcplzWXQZdFl02XUZdVl2GXZZdpl22XcZd1l3mXfZeFl" + "42XkZepl62XyZfNl9GX1Zfhl+WX7Zfxl/WX+Zf9lAWYEZgVmB2YIZglmC2YNZhBmEWYSZhZmF2YYZhpmG2YcZh5mIWYiZiNm" + "JGYmZilmKmYrZixmLmYwZjJmM2Y3ZjhmOWY6ZjtmPWY/ZkBmQmZEZkVmRmZHZkhmSWZKZk1mTmZQZlFmWGb//1lmW2ZcZl1m" + "XmZgZmJmY2ZlZmdmaWZqZmtmbGZtZnFmcmZzZnVmeGZ5ZntmfGZ9Zn9mgGaBZoNmhWaGZohmiWaKZotmjWaOZo9mkGaSZpNm" + "lGaVZphmmWaaZptmnGaeZp9moGahZqJmo2akZqVmpmapZqpmq2asZq1mr2awZrFmsmazZrVmtma3Zrhmuma7ZrxmvWa/ZsBm" + "wWbCZsNmxGbFZsZmx2bIZslmymbLZsxmzWbOZs9m0GbRZtJm02bUZtVm1mbXZthm2mbeZt9m4GbhZuJm42bkZuVm52boZupm" + "62bsZu1m7mbvZvFm9Wb2Zvhm+mb7Zv1mAWcCZwNnBGcFZwZnB2cMZw5nD2cRZxJnE2cWZxhnGWcaZxxnHmcgZyFnImcjZyRn" + "JWcnZylnLmcwZzJnM2c2ZzdnOGc5ZztnPGc+Zz9nQWdEZ0VnR2dKZ0tnTWdSZ1RnVWdXZ1hnWWdaZ1tnXWdiZ2NnZGdmZ2dn" + "a2dsZ25ncWd0Z3Zn//94Z3lnemd7Z31ngGeCZ4NnhWeGZ4hnimeMZ41njmePZ5FnkmeTZ5RnlmeZZ5tnn2egZ6FnpGemZ6ln" + "rGeuZ7Fnsme0Z7lnume7Z7xnvWe+Z79nwGfCZ8VnxmfHZ8hnyWfKZ8tnzGfNZ85n1WfWZ9dn22ffZ+Fn42fkZ+Zn52foZ+pn" + "62ftZ+5n8mf1Z/Zn92f4Z/ln+mf7Z/xn/mcBaAJoA2gEaAZoDWgQaBJoFGgVaBhoGWgaaBtoHGgeaB9oIGgiaCNoJGglaCZo" + "J2goaCtoLGgtaC5oL2gwaDFoNGg1aDZoOmg7aD9oR2hLaE1oT2hSaFZoV2hYaFloWmhbaFxoXWheaF9oamhsaG1obmhvaHBo" + "cWhyaHNodWh4aHloemh7aHxofWh+aH9ogGiCaIRoh2iIaIloimiLaIxojWiOaJBokWiSaJRolWiWaJhomWiaaJtonGidaJ5o" + "n2igaKFoo2ikaKVoqWiqaKtorGiuaLFosmi0aLZot2i4aP//uWi6aLtovGi9aL5ov2jBaMNoxGjFaMZox2jIaMpozGjOaM9o" + "0GjRaNNo1GjWaNdo2WjbaNxo3WjeaN9o4WjiaORo5WjmaOdo6GjpaOpo62jsaO1o72jyaPNo9Gj2aPdo+Gj7aP1o/mj/aABp" + "AmkDaQRpBmkHaQhpCWkKaQxpD2kRaRNpFGkVaRZpF2kYaRlpGmkbaRxpHWkeaSFpImkjaSVpJmknaShpKWkqaStpLGkuaS9p" + "MWkyaTNpNWk2aTdpOGk6aTtpPGk+aUBpQWlDaURpRWlGaUdpSGlJaUppS2lMaU1pTmlPaVBpUWlSaVNpVWlWaVhpWWlbaVxp" + "X2lhaWJpZGllaWdpaGlpaWppbGltaW9pcGlyaXNpdGl1aXZpeml7aX1pfml/aYFpg2mFaYppi2mMaY5pj2mQaZFpkmmTaZZp" + "l2mZaZppnWmeaZ9poGmhaaJpo2mkaaVppmmpaapprGmuaa9psGmyabNptWm2abhpuWm6abxpvWn//75pv2nAacJpw2nEacVp" + "xmnHachpyWnLac1pz2nRadJp02nVadZp12nYadlp2mncad1p3mnhaeJp42nkaeVp5mnnaehp6Wnqaetp7Gnuae9p8GnxafNp" + "9Gn1afZp92n4aflp+mn7afxp/mkAagFqAmoDagRqBWoGagdqCGoJagtqDGoNag5qD2oQahFqEmoTahRqFWoWahlqGmobahxq" + "HWoeaiBqImojaiRqJWomaidqKWoraixqLWouajBqMmozajRqNmo3ajhqOWo6ajtqPGo/akBqQWpCakNqRWpGakhqSWpKaktq" + "TGpNak5qT2pRalJqU2pUalVqVmpXalpqXGpdal5qX2pgamJqY2pkamZqZ2poamlqampramxqbWpuam9qcGpyanNqdGp1anZq" + "d2p4anpqe2p9an5qf2qBaoJqg2qFaoZqh2qIaolqimqLaoxqjWqPapJqk2qUapVqlmqYaplqmmqbapxqnWqeap9qoWqiaqNq" + "pGqlaqZq//+naqhqqmqtaq5qr2qwarFqsmqzarRqtWq2ardquGq5arpqu2q8ar1qvmq/asBqwWrCasNqxGrFasZqx2rIaslq" + "ymrLasxqzWrOas9q0GrRatJq02rUatVq1mrXathq2Wraattq3Grdat5q32rgauFq4mrjauRq5Wrmaudq6Grpaupq62rsau1q" + "7mrvavBq8WryavNq9Gr1avZq92r4avlq+mr7avxq/Wr+av9qAGsBawJrA2sEawVrBmsHawhrCWsKawtrDGsNaw5rD2sQaxFr" + "EmsTaxRrFWsWaxdrGGsZaxprG2scax1rHmsfayVrJmsoaylrKmsrayxrLWsuay9rMGsxazNrNGs1azZrOGs7azxrPWs/a0Br" + "QWtCa0RrRWtIa0prS2tNa05rT2tQa1FrUmtTa1RrVWtWa1drWGtaa1trXGtda15rX2tga2FraGtpa2trbGtta25rb2twa3Fr" + "cmtza3RrdWt2a3dreGt6a31rfmt/a4BrhWuIa///jGuOa49rkGuRa5RrlWuXa5hrmWuca51rnmufa6Bromuja6RrpWuma6dr" + "qGupa6trrGuta65rr2uwa7Frsmu2a7hruWu6a7trvGu9a75rwGvDa8RrxmvHa8hryWvKa8xrzmvQa9Fr2Gvaa9xr3Wvea99r" + "4Gvia+Nr5Gvla+Zr52voa+lr7Gvta+5r8Gvxa/Jr9Gv2a/dr+Gv6a/tr/Gv+a/9rAGwBbAJsA2wEbAhsCWwKbAtsDGwObBJs" + "F2wcbB1sHmwgbCNsJWwrbCxsLWwxbDNsNmw3bDlsOmw7bDxsPmw/bENsRGxFbEhsS2xMbE1sTmxPbFFsUmxTbFZsWGxZbFps" + "YmxjbGVsZmxnbGtsbGxtbG5sb2xxbHNsdWx3bHhsemx7bHxsf2yAbIRsh2yKbItsjWyObJFskmyVbJZsl2yYbJpsnGydbJ5s" + "oGyibKhsrGyvbLBstGy1bLZst2y6bMBswWzCbMNsxmzHbMhsy2zNbM5sz2zRbNJs2Gz//9ls2mzcbN1s32zkbOZs52zpbOxs" + "7WzybPRs+Wz/bABtAm0DbQVtBm0IbQltCm0NbQ9tEG0RbRNtFG0VbRZtGG0cbR1tH20gbSFtIm0jbSRtJm0obSltLG0tbS9t" + "MG00bTZtN204bTptP21AbUJtRG1JbUxtUG1VbVZtV21YbVttXW1fbWFtYm1kbWVtZ21obWttbG1tbXBtcW1ybXNtdW12bXlt" + "em17bX1tfm1/bYBtgW2DbYRthm2HbYpti22NbY9tkG2SbZZtl22YbZltmm2cbaJtpW2sba1tsG2xbbNttG22bbdtuW26bbtt" + "vG29bb5twW3CbcNtyG3JbcptzW3Obc9t0G3SbdNt1G3Vbddt2m3bbdxt323ibeNt5W3nbeht6W3qbe1t723wbfJt9G31bfZt" + "+G36bf1t/m3/bQBuAW4CbgNuBG4GbgduCG4JbgtuD24SbhNuFW4YbhluG24cbh5uH24ibiZuJ24obipuLG4ubjBuMW4zbjVu" + "//82bjduOW47bjxuPW4+bj9uQG5BbkJuRW5GbkduSG5JbkpuS25Mbk9uUG5RblJuVW5XblluWm5cbl1uXm5gbmFuYm5jbmRu" + "ZW5mbmduaG5pbmpubG5tbm9ucG5xbnJuc250bnVudm53bnhueW56bntufG59boBugW6CboRuh26Ibopui26Mbo1ujm6RbpJu" + "k26UbpVulm6Xbplumm6bbp1unm6gbqFuo26kbqZuqG6pbqturG6tbq5usG6zbrVuuG65brxuvm6/bsBuw27EbsVuxm7Ibslu" + "ym7Mbs1uzm7QbtJu1m7Ybtlu227cbt1u427nbupu627sbu1u7m7vbvBu8W7ybvNu9W72bvdu+G76bvtu/G79bv5u/24AbwFv" + "A28EbwVvB28IbwpvC28Mbw1vDm8QbxFvEm8WbxdvGG8ZbxpvG28cbx1vHm8fbyFvIm8jbyVvJm8nbyhvLG8ubzBvMm80bzVv" + "N284bzlvOm87bzxvPW8/b0BvQW9Cb///Q29Eb0VvSG9Jb0pvTG9Ob09vUG9Rb1JvU29Ub1VvVm9Xb1lvWm9bb11vX29gb2Fv" + "Y29kb2VvZ29ob2lvam9rb2xvb29wb3Fvc291b3Zvd295b3tvfW9+b39vgG+Bb4Jvg2+Fb4Zvh2+Kb4tvj2+Qb5Fvkm+Tb5Rv" + "lW+Wb5dvmG+Zb5pvm2+db55vn2+gb6Jvo2+kb6Vvpm+ob6lvqm+rb6xvrW+ub69vsG+xb7JvtG+1b7dvuG+6b7tvvG+9b75v" + "v2/Bb8NvxG/Fb8Zvx2/Ib8pvy2/Mb81vzm/Pb9Bv02/Ub9Vv1m/Xb9hv2W/ab9tv3G/db99v4m/jb+Rv5W/mb+dv6G/pb+pv" + "62/sb+1v8G/xb/Jv82/0b/Vv9m/3b/hv+W/6b/tv/G/9b/5v/28AcAFwAnADcARwBXAGcAdwCHAJcApwC3AMcA1wDnAPcBBw" + "EnATcBRwFXAWcBdwGHAZcBxwHXAecB9wIHAhcCJwJHAlcCZwJ3AocClwKnD//ytwLHAtcC5wL3AwcDFwMnAzcDRwNnA3cDhw" + "OnA7cDxwPXA+cD9wQHBBcEJwQ3BEcEVwRnBHcEhwSXBKcEtwTXBOcFBwUXBScFNwVHBVcFZwV3BYcFlwWnBbcFxwXXBfcGBw" + "YXBicGNwZHBlcGZwZ3BocGlwanBucHFwcnBzcHRwd3B5cHpwe3B9cIFwgnCDcIRwhnCHcIhwi3CMcI1wj3CQcJFwk3CXcJhw" + "mnCbcJ5wn3CgcKFwonCjcKRwpXCmcKdwqHCpcKpwsHCycLRwtXC2cLpwvnC/cMRwxXDGcMdwyXDLcMxwzXDOcM9w0HDRcNJw" + "03DUcNVw1nDXcNpw3HDdcN5w4HDhcOJw43DlcOpw7nDwcPFw8nDzcPRw9XD2cPhw+nD7cPxw/nD/cABxAXECcQNxBHEFcQZx" + "B3EIcQtxDHENcQ5xD3ERcRJxFHEXcRtxHHEdcR5xH3EgcSFxInEjcSRxJXEncShxKXEqcStxLHEtcS5xMnEzcTRx//81cTdx" + "OHE5cTpxO3E8cT1xPnE/cUBxQXFCcUNxRHFGcUdxSHFJcUtxTXFPcVBxUXFScVNxVHFVcVZxV3FYcVlxWnFbcV1xX3FgcWFx" + "YnFjcWVxaXFqcWtxbHFtcW9xcHFxcXRxdXF2cXdxeXF7cXxxfnF/cYBxgXGCcYNxhXGGcYdxiHGJcYtxjHGNcY5xkHGRcZJx" + "k3GVcZZxl3GacZtxnHGdcZ5xoXGicaNxpHGlcaZxp3Gpcapxq3Gtca5xr3GwcbFxsnG0cbZxt3G4cbpxu3G8cb1xvnG/ccBx" + "wXHCccRxxXHGccdxyHHJccpxy3HMcc1xz3HQcdFx0nHTcdZx13HYcdlx2nHbcdxx3XHecd9x4XHiceNx5HHmcehx6XHqcetx" + "7HHtce9x8HHxcfJx83H0cfVx9nH3cfhx+nH7cfxx/XH+cf9xAHIBcgJyA3IEcgVyB3IIcglyCnILcgxyDXIOcg9yEHIRchJy" + "E3IUchVyFnIXchhyGXIacv//G3Icch5yH3IgciFyInIjciRyJXImcidyKXIrci1yLnIvcjJyM3I0cjpyPHI+ckByQXJCckNy" + "RHJFckZySXJKcktyTnJPclByUXJTclRyVXJXclhyWnJccl5yYHJjcmRyZXJocmpya3Jscm1ycHJxcnNydHJ2cndyeHJ7cnxy" + "fXKCcoNyhXKGcodyiHKJcoxyjnKQcpFyk3KUcpVylnKXcphymXKacptynHKdcp5yoHKhcqJyo3KkcqVypnKncqhyqXKqcqty" + "rnKxcrJys3K1crpyu3K8cr1yvnK/csByxXLGcsdyyXLKcstyzHLPctFy03LUctVy1nLYctpy23LG5MfkyOTJ5Mrky+TM5M3k" + "zuTP5NDk0eTS5NPk1OTV5Nbk1+TY5Nnk2uTb5Nzk3eTe5N/k4OTh5OLk4+Tk5OXk5uTn5Ojk6eTq5Ovk7OTt5O7k7+Tw5PHk" + "8uTz5PTk9eT25Pfk+OT55Prk++T85P3k/uT/5ADlAeUC5QPlBOX//wXlBuUH5QjlCeUK5QvlDOUN5Q7lD+UQ5RHlEuUT5RTl" + "FeUW5RflGOUZ5RrlG+Uc5R3lHuUf5SDlIeUi5SPlJOUl5QAwATACMLcAyQLHAqgAAzAFMBQgXv8WICYgGCAZIBwgHSAUMBUw" + "CDAJMAowCzAMMA0wDjAPMBYwFzAQMBEwsQDXAPcANiInIigiESIPIioiKSIIIjciGiKlIiUiICISI5kiKyIuImEiTCJIIj0i" + "HSJgIm4ibyJkImUiHiI1IjQiQiZAJrAAMiAzIAMhBP+kAOD/4f8wIKcAFiEGJgUmyyXPJc4lxyXGJaEloCWzJbIlOyCSIZAh" + "kSGTIRMwJuUn5SjlKeUq5SvlLOUt5S7lL+Uw5THlMuUz5TTlNeU25TflOOU55TrlO+U85T3lPuU/5UDlQeVC5UPlROVF5Ubl" + "R+VI5UnlSuVL5UzlTeVO5U/lUOVR5VLlU+VU5VXlVuVX5VjlWeVa5VvlXOVd5V7lX+Vg5WHlYuVj5WTl//9l5WblZ+Vo5Wnl" + "auVr5WzlbeVu5W/lcOVx5XLlc+V05XXlduV35XjleeV65XvlfOV95X7lf+WA5YHlguWD5YTlheVwIXEhciFzIXQhdSF2IXch" + "eCF5IWbnZ+do52nnaudr54gkiSSKJIskjCSNJI4kjySQJJEkkiSTJJQklSSWJJckmCSZJJokmyR0JHUkdiR3JHgkeSR6JHsk" + "fCR9JH4kfySAJIEkgiSDJIQkhSSGJIckYCRhJGIkYyRkJGUkZiRnJGgkaSSsIG3nIDIhMiIyIzIkMiUyJjInMigyKTJu52/n" + "YCFhIWIhYyFkIWUhZiFnIWghaSFqIWshcOdx54blh+WI5YnliuWL5YzljeWO5Y/lkOWR5ZLlk+WU5ZXlluWX5ZjlmeWa5Zvl" + "nOWd5Z7ln+Wg5aHlouWj5aTlpeWm5aflqOWp5arlq+Ws5a3lruWv5bDlseWy5bPltOW15bblt+W45bnluuW75bzlveW+5b/l" + "wOXB5cLlw+XE5f//xeXG5cflyOXJ5crly+XM5c3lzuXP5dDl0eXS5dPl1OXV5dbl1+XY5dnl2uXb5dzl3eXe5d/l4OXh5eLl" + "4+Xk5eXlAf8C/wP/5f8F/wb/B/8I/wn/Cv8L/wz/Df8O/w//EP8R/xL/E/8U/xX/Fv8X/xj/Gf8a/xv/HP8d/x7/H/8g/yH/" + "Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov87/zz/Pf8+/z//QP9B/0L/Q/9E/0X/" + "Rv9H/0j/Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/W/9c/13/4//m5efl6OXp5erl6+Xs5e3l7uXv5fDl" + "8eXy5fPl9OX15fbl9+X45fnl+uX75fzl/eX+5f/lAOYB5gLmA+YE5gXmBuYH5gjmCeYK5gvmDOYN5g7mD+YQ5hHmEuYT5hTm" + "FeYW5hfmGOYZ5hrmG+Yc5h3mHuYf5iDmIeYi5iPmJOb//yXmJuYn5ijmKeYq5ivmLOYt5i7mL+Yw5jHmMuYz5jTmNeY25jfm" + "OOY55jrmO+Y85j3mPuY/5kDmQeZC5kPmROZF5kEwQjBDMEQwRTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYw" + "VzBYMFkwWjBbMFwwXTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgwaTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHow" + "ezB8MH0wfjB/MIAwgTCCMIMwhDCFMIYwhzCIMIkwijCLMIwwjTCOMI8wkDCRMJIwkzBy53PndOd153bnd+d453nneud753zn" + "RuZH5kjmSeZK5kvmTOZN5k7mT+ZQ5lHmUuZT5lTmVeZW5lfmWOZZ5lrmW+Zc5l3mXuZf5mDmYeZi5mPmZOZl5mbmZ+Zo5mnm" + "auZr5mzmbeZu5m/mcOZx5nLmc+Z05nXmduZ35njmeeZ65nvmfOZ95n7mf+aA5oHmguaD5oTm//+F5obmh+aI5onmiuaL5ozm" + "jeaO5o/mkOaR5pLmk+aU5pXmluaX5pjmmeaa5pvmnOad5p7mn+ag5qHmouaj5qTmpeahMKIwozCkMKUwpjCnMKgwqTCqMKsw" + "rDCtMK4wrzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w" + "0DDRMNIw0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw4jDjMOQw5TDmMOcw6DDpMOow6zDsMO0w7jDvMPAw8TDyMPMw" + "9DD1MPYwfed+53/ngOeB54Lng+eE56bmp+ao5qnmquar5qzmreau5q/msOax5rLms+a05rXmtua35rjmuea65rvmvOa95r7m" + "v+bA5sHmwubD5sTmxebG5sfmyObJ5srmy+bM5s3mzubP5tDm0ebS5tPm1ObV5tbm1+bY5tnm2ubb5tzm3ebe5t/m4Obh5uLm" + "4+bk5v//5ebm5ufm6Obp5urm6+bs5u3m7ubv5vDm8eby5vPm9Ob15vbm9+b45vnm+ub75vzm/eb+5v/mAOcB5wLnA+cE5wXn" + "kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MDpAOlA6YDpwOoA6kDheeG54fniOeJ54rni+eM57EDsgOzA7QD" + "tQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPDA8QDxQPGA8cDyAPJA43njueP55DnkeeS55PnNf42/jn+Ov4//kD+Pf4+/kH+" + "Qv5D/kT+lOeV5zv+PP43/jj+Mf6W5zP+NP6X55jnmeea55vnnOed557nn+cG5wfnCOcJ5wrnC+cM5w3nDucP5xDnEecS5xPn" + "FOcV5xbnF+cY5xnnGucb5xznHece5x/nIOch5yLnI+ck5yXnJucn5yjnKecq5yvnLOct5y7nL+cw5zHnMucz5zTnNec25zfn" + "OOc55zrnO+c85z3nPuc/50DnQedC50PnROf//0XnRudH50jnSedK50vnTOdN507nT+dQ51HnUudT51TnVedW51fnWOdZ51rn" + "W+dc513nXudf52DnYedi52PnZOdl5xAEEQQSBBMEFAQVBAEEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcE" + "KAQpBCoEKwQsBC0ELgQvBKDnoeei56PnpOel56bnp+eo56nnquer56znreeu5zAEMQQyBDMENAQ1BFEENgQ3BDgEOQQ6BDsE" + "PAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBK/nsOex57Lns+e057Xntue357jnuee657vnygLLAtkC" + "EyAVICUgNSAFIQkhliGXIZghmSEVIh8iIyJSImYiZyK/IlAlUSVSJVMlVCVVJVYlVyVYJVklWiVbJVwlXSVeJV8lYCVhJWIl" + "YyVkJWUlZiVnJWglaSVqJWslbCVtJW4lbyVwJXElciVzJYElgiWDJYQlhSWGJYcl//+IJYkliiWLJYwljSWOJY8lkyWUJZUl" + "vCW9JeIl4yXkJeUlCSaVIhIwHTAeMLznvee+57/nwOfB58Lnw+fE58XnxucBAeEAzgHgABMB6QAbAegAKwHtANAB7ABNAfMA" + "0gHyAGsB+gDUAfkA1gHYAdoB3AH8AOoAUQLH50QBSAH5AWECyefK58vnzOcFMQYxBzEIMQkxCjELMQwxDTEOMQ8xEDERMRIx" + "EzEUMRUxFjEXMRgxGTEaMRsxHDEdMR4xHzEgMSExIjEjMSQxJTEmMScxKDEpMc3nzufP59Dn0efS59Pn1OfV59bn1+fY59nn" + "2ufb59zn3efe59/n4Ofh5yEwIjAjMCQwJTAmMCcwKDApMKMyjjOPM5wznTOeM6EzxDPOM9Ez0jPVMzD+4v/k/+LnISExMuPn" + "ECDk5+Xn5uf8MJswnDD9MP4wBjCdMJ4wSf5K/kv+TP5N/k7+T/5Q/lH+Uv5U/lX+Vv5X/ln+Wv5b/lz+Xf5e/l/+YP5h/v//" + "Yv5j/mT+Zf5m/mj+af5q/mv+PjDwL/Ev8i/zL/Qv9S/2L/cv+C/5L/ov+y8HMPTn9ef25/fn+Of55/rn++f85/3n/uf/5wDo" + "ACUBJQIlAyUEJQUlBiUHJQglCSUKJQslDCUNJQ4lDyUQJRElEiUTJRQlFSUWJRclGCUZJRolGyUcJR0lHiUfJSAlISUiJSMl" + "JCUlJSYlJyUoJSklKiUrJSwlLSUuJS8lMCUxJTIlMyU0JTUlNiU3JTglOSU6JTslPCU9JT4lPyVAJUElQiVDJUQlRSVGJUcl" + "SCVJJUolSyUB6ALoA+gE6AXoBugH6AjoCegK6AvoDOgN6A7oD+jcct1y33LicuNy5HLlcuZy53Lqcuty9XL2cvly/XL+cv9y" + "AHMCcwRzBXMGcwdzCHMJcwtzDHMNcw9zEHMRcxJzFHMYcxlzGnMfcyBzI3MkcyZzJ3Mocy1zL3MwczJzM3M1czZzOnM7czxz" + "PXNAc0FzQnNDc0RzRXNGc0dzSHP//0lzSnNLc0xzTnNPc1FzU3NUc1VzVnNYc1lzWnNbc1xzXXNec19zYXNic2NzZHNlc2Zz" + "Z3Noc2lzanNrc25zcHNxcwDgAeAC4APgBOAF4AbgB+AI4AngCuAL4AzgDeAO4A/gEOAR4BLgE+AU4BXgFuAX4BjgGeAa4Bvg" + "HOAd4B7gH+Ag4CHgIuAj4CTgJeAm4CfgKOAp4CrgK+As4C3gLuAv4DDgMeAy4DPgNOA14DbgN+A44DngOuA74DzgPeA+4D/g" + "QOBB4ELgQ+BE4EXgRuBH4EjgSeBK4EvgTOBN4E7gT+BQ4FHgUuBT4FTgVeBW4FfgWOBZ4FrgW+Bc4F3gcnNzc3RzdXN2c3dz" + "eHN5c3pze3N8c31zf3OAc4FzgnODc4VzhnOIc4pzjHONc49zkHOSc5NzlHOVc5dzmHOZc5pznHOdc55zoHOhc6NzpHOlc6Zz" + "p3Ooc6pzrHOtc7FztHO1c7ZzuHO5c7xzvXO+c79zwXPDc8RzxXPGc8dz///Lc8xzznPSc9Nz1HPVc9Zz13PYc9pz23Pcc91z" + "33Phc+Jz43Pkc+Zz6HPqc+tz7HPuc+9z8HPxc/Nz9HP1c/Zz93Ne4F/gYOBh4GLgY+Bk4GXgZuBn4GjgaeBq4GvgbOBt4G7g" + "b+Bw4HHgcuBz4HTgdeB24HfgeOB54Hrge+B84H3gfuB/4IDggeCC4IPghOCF4Ibgh+CI4IngiuCL4IzgjeCO4I/gkOCR4JLg" + "k+CU4JXgluCX4JjgmeCa4JvgnOCd4J7gn+Cg4KHgouCj4KTgpeCm4KfgqOCp4Krgq+Cs4K3gruCv4LDgseCy4LPgtOC14Lbg" + "t+C44LnguuC74Phz+XP6c/tz/HP9c/5z/3MAdAF0AnQEdAd0CHQLdAx0DXQOdBF0EnQTdBR0FXQWdBd0GHQZdBx0HXQedB90" + "IHQhdCN0JHQndCl0K3QtdC90MXQydDd0OHQ5dDp0O3Q9dD50P3RAdEJ0Q3REdEV0RnRHdEh0SXRKdEt0THRNdP//TnRPdFB0" + "UXRSdFN0VHRWdFh0XXRgdGF0YnRjdGR0ZXRmdGd0aHRpdGp0a3RsdG50b3RxdHJ0c3R0dHV0eHR5dHp0vOC94L7gv+DA4MHg" + "wuDD4MTgxeDG4MfgyODJ4Mrgy+DM4M3gzuDP4NDg0eDS4NPg1ODV4Nbg1+DY4Nng2uDb4Nzg3eDe4N/g4ODh4OLg4+Dk4OXg" + "5uDn4Ojg6eDq4Ovg7ODt4O7g7+Dw4PHg8uDz4PTg9eD24Pfg+OD54Prg++D84P3g/uD/4ADhAeEC4QPhBOEF4QbhB+EI4Qnh" + "CuEL4QzhDeEO4Q/hEOER4RLhE+EU4RXhFuEX4RjhGeF7dHx0fXR/dIJ0hHSFdIZ0iHSJdIp0jHSNdI90kXSSdJN0lHSVdJZ0" + "l3SYdJl0mnSbdJ10n3SgdKF0onSjdKR0pXSmdKp0q3SsdK10rnSvdLB0sXSydLN0tHS1dLZ0t3S4dLl0u3S8dL10vnS/dMB0" + "wXTCdMN0xHTFdMZ0x3T//8h0yXTKdMt0zHTNdM50z3TQdNF003TUdNV01nTXdNh02XTadNt03XTfdOF05XTndOh06XTqdOt0" + "7HTtdPB08XTydBrhG+Ec4R3hHuEf4SDhIeEi4SPhJOEl4SbhJ+Eo4SnhKuEr4SzhLeEu4S/hMOEx4TLhM+E04TXhNuE34Tjh" + "OeE64TvhPOE94T7hP+FA4UHhQuFD4UThReFG4UfhSOFJ4UrhS+FM4U3hTuFP4VDhUeFS4VPhVOFV4VbhV+FY4VnhWuFb4Vzh" + "XeFe4V/hYOFh4WLhY+Fk4WXhZuFn4WjhaeFq4WvhbOFt4W7hb+Fw4XHhcuFz4XThdeF24Xfh83T1dPh0+XT6dPt0/HT9dP50" + "AHUBdQJ1A3UFdQZ1B3UIdQl1CnULdQx1DnUQdRJ1FHUVdRZ1F3UbdR11HnUgdSF1InUjdSR1JnUndSp1LnU0dTZ1OXU8dT11" + "P3VBdUJ1Q3VEdUZ1R3VJdUp1TXVQdVF1UnVTdVV1VnVXdVh1//9ddV51X3VgdWF1YnVjdWR1Z3VodWl1a3VsdW11bnVvdXB1" + "cXVzdXV1dnV3dXp1e3V8dX11fnWAdYF1gnWEdYV1h3V44XnheuF74XzhfeF+4X/hgOGB4YLhg+GE4YXhhuGH4YjhieGK4Yvh" + "jOGN4Y7hj+GQ4ZHhkuGT4ZThleGW4ZfhmOGZ4Zrhm+Gc4Z3hnuGf4aDhoeGi4aPhpOGl4abhp+Go4anhquGr4azhreGu4a/h" + "sOGx4bLhs+G04bXhtuG34bjhueG64bvhvOG94b7hv+HA4cHhwuHD4cThxeHG4cfhyOHJ4crhy+HM4c3hzuHP4dDh0eHS4dPh" + "1OHV4Yh1iXWKdYx1jXWOdZB1k3WVdZh1m3WcdZ51onWmdad1qHWpdap1rXW2dbd1unW7db91wHXBdcZ1y3XMdc51z3XQddF1" + "03XXddl12nXcdd1133XgdeF15XXpdex17XXude918nXzdfV19nX3dfh1+nX7df11/nUCdgR2BnYHdv//CHYJdgt2DXYOdg92" + "EXYSdhN2FHYWdhp2HHYddh52IXYjdid2KHYsdi52L3YxdjJ2NnY3djl2OnY7dj12QXZCdkR21uHX4djh2eHa4dvh3OHd4d7h" + "3+Hg4eHh4uHj4eTh5eHm4efh6OHp4erh6+Hs4e3h7uHv4fDh8eHy4fPh9OH14fbh9+H44fnh+uH74fzh/eH+4f/hAOIB4gLi" + "A+IE4gXiBuIH4gjiCeIK4gviDOIN4g7iD+IQ4hHiEuIT4hTiFeIW4hfiGOIZ4hriG+Ic4h3iHuIf4iDiIeIi4iPiJOIl4ibi" + "J+Io4iniKuIr4iziLeIu4i/iMOIx4jLiM+JFdkZ2R3ZIdkl2SnZLdk52T3ZQdlF2UnZTdlV2V3ZYdll2WnZbdl12X3ZgdmF2" + "YnZkdmV2ZnZndmh2aXZqdmx2bXZudnB2cXZydnN2dHZ1dnZ2d3Z5dnp2fHZ/doB2gXaDdoV2iXaKdox2jXaPdpB2knaUdpV2" + "l3aYdpp2m3b//5x2nXaedp92oHahdqJ2o3aldqZ2p3aodql2qnardqx2rXavdrB2s3a1drZ2t3a4drl2una7drx2vXa+dsB2" + "wXbDdkpVP5bDVyhjzlQJVcBUkXZMdjyF7nd+go14MXKYlo2XKGyJW/pPCWOXZrhc+oBIaK6AAmbOdvlRVmWscfF/hIiyUGVZ" + "ymGzb62CTGNSYu1TJ1QGe2tRpHX0XdRiy412l4piGYBdVziXYn84cn12z2d+dkZkcE8ljdxiF3qRZe1zLGRzYiyCgZh/Z0hy" + "bmLMYjRP43RKU55Syn6mkC5ehmicaYCB0X7SaMV4jIZRlY1QJIzegt6ABVMSiWVSxHbHdsl2y3bMdtN21XbZdtp23Hbddt52" + "4HbhduJ243bkduZ253bodul26nbrdux27XbwdvN29Xb2dvd2+nb7dv12/3YAdwJ3A3cFdwZ3CncMdw53D3cQdxF3EncTdxR3" + "FXcWdxd3GHcbdxx3HXcedyF3I3ckdyV3J3cqdyt3//8sdy53MHcxdzJ3M3c0dzl3O3c9dz53P3dCd0R3RXdGd0h3SXdKd0t3" + "THdNd053T3dSd1N3VHdVd1Z3V3dYd1l3XHeEhfmW3U8hWHGZnVuxYqVitGZ5jI2cBnJvZ5F4smBRUxdTiI/MgB2NoZQNUMhy" + "B1nrYBlxq4hUWe+CLGcoeyld934tdfVsZo74jzyQO5/UaxmRFHt8X6d41oQ9hdVr2WvWawFeh175de2VXWUKX8Vfn4/BWMKB" + "f5Bblq2XuY8WfyyNQWK/T9hTXlOoj6mPq49NkAdoal+YgWiI1pyLYStSKnZsX4xl0m/obr5bSGR1UbBRxGcZTsl5fJmzcF13" + "Xndfd2B3ZHdnd2l3andtd253b3dwd3F3cndzd3R3dXd2d3d3eHd6d3t3fHeBd4J3g3eGd4d3iHeJd4p3i3ePd5B3k3eUd5V3" + "lneXd5h3mXead5t3nHedd553oXejd6R3pneod6t3rXeud693sXeyd7R3tne3d7h3uXe6d///vHe+d8B3wXfCd8N3xHfFd8Z3" + "x3fId8l3ynfLd8x3znfPd9B30XfSd9N31HfVd9Z32HfZd9p33Xfed9934Hfhd+R3xXV2Xrtz4IOtZOhitZTibFpTw1IPZMKU" + "lHsvTxteNoIWgYqBJG7KbHOaVWNcU/pUZYjgVw1OA15laz986JAWYOZkHHPBiFBnTWIijWx3KY7HkWlf3IMhhRCZwlOVhotr" + "7WDoYH9wzYIxgtNOp2zPhc1k2Xz9aflmSYOVU1Z7p0+MUUttQlxtjtJjyVMsgzaD5We0eD1k31uUXO5d54vGYvRneowAZLpj" + "SYeLmReMIH/ylKdOEJakmAxmFnPmd+h36nfvd/B38Xfyd/R39Xf3d/l3+nf7d/x3A3gEeAV4BngHeAh4CngLeA54D3gQeBN4" + "FXgZeBt4HnggeCF4IngkeCh4KngreC54L3gxeDJ4M3g1eDZ4PXg/eEF4QnhDeER4RnhIeEl4SnhLeE14T3hReFN4VHhYeFl4" + "Wnj//1t4XHheeF94YHhheGJ4Y3hkeGV4ZnhneGh4aXhveHB4cXhyeHN4dHh1eHZ4eHh5eHp4e3h9eH54f3iAeIF4gniDeDpX" + "HVw4Xn+Vf1CggIJTXmVFdTFVIVCFjYRinpQdZzJWbm/iXTVUknBmj29ipGSjY3tfiG/0kOOBsI8YXGhm8V+JbEiWgY1siJFk" + "8HnOV1lqEGJIVFhOC3rpYIRv2ot/Yh6Qi5rkeQNU9HUBYxlTYGzfjxtfcJo7gH+fiE86XGSNxX+lZb1wRVGyUWuGB12gW71i" + "bJF0dQyOIHoBYXl7x074foV3EU7tgR1S+lFxaqhTh44Elc+WwW5kllpphHiFeIZ4iHiKeIt4j3iQeJJ4lHiVeJZ4mXideJ54" + "oHiieKR4pnioeKl4qnireKx4rXiueK94tXi2eLd4uHi6eLt4vHi9eL94wHjCeMN4xHjGeMd4yHjMeM14znjPeNF40njTeNZ4" + "13jYeNp423jceN143njfeOB44XjieON4///keOV45njneOl46njreO147njvePB48XjzePV49nj4ePl4+3j8eP14/nj/eAB5" + "AnkDeQR5BnkHeQh5CXkKeQt5DHlAeKhQ13cQZOaJBFnjY91df3o9aSBPOYKYVTJOrnWXemJeil7vlRtSOVSKcHZjJJWCVyVm" + "P2mHkQdV822vfiKIM2LwfrV1KIPBeMyWno9IYfd0zYtkazpSUI0ha2qAcYTxVgZTzk4bTtFRl3yLkQd8w09/juF7nHpnZBRd" + "rFAGgQF2uXzsbeB/UWdYW/hby3iuZBNkqmMrYxmVLWS+j1R7KXZTYidZRlR5a6NQNGImXoZr4043jYuIhV8ukA15DnkPeRB5" + "EXkSeRR5FXkWeRd5GHkZeRp5G3kceR15H3kgeSF5InkjeSV5JnkneSh5KXkqeSt5LHkteS55L3kweTF5MnkzeTV5Nnk3eTh5" + "OXk9eT95QnlDeUR5RXlHeUp5S3lMeU15TnlPeVB5UXlSeVR5VXlYeVl5YXljef//ZHlmeWl5anlreWx5bnlweXF5cnlzeXR5" + "dXl2eXl5e3l8eX15fnl/eYJ5g3mGeYd5iHmJeYt5jHmNeY55kHmReZJ5IGA9gMViOU5VU/iQuGPGgOZlLmxGT+5g4W3eizlf" + "y4ZTXyFjWlFhg2NoAFJjY0iOElCbXHd5/FswUjt6vGBTkNd2t1+XX4R2bI5vcHt2SXuqd/NRk5AkWE5P9G7qj0xlG3vEcqRt" + "33/hWrVilV4wV4KELHsdXh9fEpAUf6CYgmPHbph4uXB4UVuXq1c1dUNPOHWXXuZgYFnAbb9riXj8U9WWy1EBUoljClSTlAOM" + "zI05cp94doftjw2M4FOTeZR5lXmWeZd5mHmZeZt5nHmdeZ55n3mgeaF5onmjeaR5pXmmeah5qXmqeat5rHmtea55r3mwebF5" + "snm0ebV5tnm3ebh5vHm/ecJ5xHnFecd5yHnKecx5znnPedB503nUedZ513nZedp523nced153nngeeF54nnleeh56nn//+x5" + "7nnxefJ583n0efV59nn3efl5+nn8ef55/3kBegR6BXoHegh6CXoKegx6D3oQehF6EnoTehV6FnoYehl6G3ocegFO73buU4mU" + "dpgOny2VmluiiyJOHE6sUWOEwmGoUgtol09rYLtRHm1cUZZil2VhlkaMF5DYdf2QY3fSa4py7HL7izVYeXdMjVxnQJWagKZe" + "IW6SWe967Xc7lbVrrWUOfwZYUVEflvlbqVgoVHKOZmV/mORWnZT+dkGQh2PGVBpZOlmbV7KONWf6jTWCQVLwYBVY/oboXEWe" + "xE+dmLmLJVp2YIRTfGJPkAKRf5lpYAyAP1EzgBRcdZkxbYxOHXofeiF6InokeiV6Jnoneih6KXoqeit6LHotei56L3owejF6" + "Mno0ejV6Nno4ejp6PnpAekF6QnpDekR6RXpHekh6SXpKekt6THpNek56T3pQelJ6U3pUelV6VnpYell6Wnpbelx6XXpeel96" + "YHphemJ6Y3pkemV6Znpnemh6//9pemp6a3psem16bnpvenF6cnpzenV6e3p8en16fnqCeoV6h3qJeop6i3qMeo56j3qQepN6" + "lHqZepp6m3qeeqF6onowjdFTWn9PexBPT04AltVs0HPphQZeanX7fwpq/neSlEF+4VHmcM1T1I8DgymNr3JtmdtsSlezgrll" + "qoA/YjKWqFn/Tr+Lun4+ZfKDXpdhVd6YpYAqU/2LIFS6gJ9euGw5jayCWpEpVBtsBlK3fl9XGnF+bIl8S1n9Tv9fJGGqfDBO" + "AVyrZwKH8FwLlc6Yr3X9cCKQr1Edf72LSVnkUVtPJlQrWXdlpIB1W3ZiwmKQj0VeH2wmew9P2E8NZ6N6pHqneql6qnqreq56" + "r3qwerF6snq0erV6tnq3erh6uXq6ert6vHq9er56wHrBesJ6w3rEesV6xnrHesh6yXrKesx6zXrOes960HrRetJ603rUetV6" + "13rYetp623rcet164XrieuR653roeul66nrreux67nrwevF68nrzev//9Hr1evZ693r4evt6/Hr+egB7AXsCewV7B3sJewx7" + "DXsOexB7EnsTexZ7F3sYexp7HHsdex97IXsieyN7J3spey17bm2qbY95sYgXXyt1mmKFj+9P3JGnZS+BUYGcXlCBdI1vUoaJ" + "S40NWYVQ2E4cljZyeYEfjcxbo4tElodZGn+QVHZWDlblizllgmmZlNZ2iW5yXhh1RmfRZ/96nYB2jR9hxnliZWONiFEaUqKU" + "OH+bgLJ+l1wvbmBn2XuLdtiaj4GUf9V8HmRQlT96SlTlVExrAWQIYj2e84CZdXJSaZdbhDxo5IYBlpSW7JQqTgRU2X45aN+N" + "FYD0ZppeuX8vezB7Mns0ezV7Nns3ezl7O3s9ez97QHtBe0J7Q3tEe0Z7SHtKe017TntTe1V7V3tZe1x7Xntfe2F7Y3tke2V7" + "Zntne2h7aXtqe2t7bHtte297cHtze3R7dnt4e3p7fHt9e397gXuCe4N7hHuGe4d7iHuJe4p7i3uMe457j3v//5F7knuTe5Z7" + "mHuZe5p7m3uee597oHuje6R7pXuue697sHuye7N7tXu2e7d7uXu6e7t7vHu9e757v3vAe8J7w3vEe8JXP4CXaOVdO2WfUm1g" + "mp+bT6yObFGrWxNf6V1ebPFiIY1xUamU/lKfbN+C13KiV4RnLY0fWZyPx4OVVI17ME+9bGRb0VkTn+RTyoaomjeMoYBFZX6Y" + "+lbHli5S3HRQUuFbAmMCiVZO0GIqYPpoc1GYW6BRwomhe4aZUH/vYExwL41JUX9eG5BwdMSJLVdFeFJfn5/6lWiPPJvhi3h2" + "QmjcZ+qNNY09UoqP2m7NaAWV7ZD9Vpxn+YjHj8hUxXvIe8l7ynvLe817znvPe9B70nvUe9V71nvXe9h723vce95733vge+J7" + "43vke+d76Hvpe+t77Hvte+978Hvye/N79Hv1e/Z7+Hv5e/p7+3v9e/97AHwBfAJ8A3wEfAV8BnwIfAl8CnwNfA58EHwRfBJ8" + "E3wUfBV8F3wYfBl8//8afBt8HHwdfB58IHwhfCJ8I3wkfCV8KHwpfCt8LHwtfC58L3wwfDF8MnwzfDR8NXw2fDd8OXw6fDt8" + "PHw9fD58Qny4mmlbd20mbKVOs1uHmmORqGGvkOmXK1S1bdJb/VGKVVV/8H+8ZE1j8WW+YY1gCnFXbElsL1ltZyqC1ViOVmqM" + "62vdkH1ZF4D3U2ltdVSdVXeDz4M4aL55jFRVTwhU0naJjAKWs2y4bWuNEIlknjqNP1bRntV1iF/gcmhg/FSoTipqYYhSYHCP" + "xFTYcHmGP54qbY9bGF+ifolVr080czxUmlMZUA5UfFROTv1fWnT2WGuE4YB0h9ByynxWbkN8RHxFfEZ8R3xIfEl8SnxLfEx8" + "TnxPfFB8UXxSfFN8VHxVfFZ8V3xYfFl8WnxbfFx8XXxefF98YHxhfGJ8Y3xkfGV8ZnxnfGh8aXxqfGt8bHxtfG58b3xwfHF8" + "cnx1fHZ8d3x4fHl8enx+fH98gHyBfIJ8g3yEfIV8hnyHfP//iHyKfIt8jHyNfI58j3yQfJN8lHyWfJl8mnybfKB8oXyjfKZ8" + "p3yofKl8q3ysfK18r3ywfLR8tXy2fLd8uHy6fLt8J19OhixVpGKSTqpsN2KxgtdUTlM+c9FuO3USUhZT3YvQaYpfAGDubU9X" + "Imuvc1No2I8Tf2Jjo2AkVep1YowVcaNtplt7XlKDTGHEnvp4V4cnfId28FH2YExxQ2ZMXk1gDoxwcCVjiY+9X2Jg1IbeVsFr" + "lGBnYUlT4GBmZj+N/XkaT+lwR2yzi/KL2H5kgw9mWlpCm1Ft921BjDttGU9rcLeDFmLRYA2XJ414eftRPlf6VzpneHU9eu95" + "lXu/fMB8wnzDfMR8xnzJfMt8znzPfNB80XzSfNN81HzYfNp823zdfN584XzifON85HzlfOZ853zpfOp863zsfO187nzwfPF8" + "8nzzfPR89Xz2fPd8+Xz6fPx8/Xz+fP98AH0BfQJ9A30EfQV9Bn0HfQh9CX0LfQx9DX0OfQ99EH3//xF9En0TfRR9FX0WfRd9" + "GH0ZfRp9G30cfR19Hn0ffSF9I30kfSV9Jn0ofSl9Kn0sfS19Ln0wfTF9Mn0zfTR9NX02fYyAZZn5j8BvpYshnuxZ6X4JfwlU" + "gWfYaJGPTXzGlspTJWC+dXJsc1PJWqd+JGPgUQqB8V3fhIBigFFjWw5PbXlCUrhgTm3EW8JboYuwi+JlzF9FlpNZ536qfglW" + "t2c5WXNPtlugUlqDipg+jTJ1vpRHUDx69062Z36awVp8a9F2WlcWXDp79JVOcXxRqYBwgnhZBH8ng8Bo7GexeHd442JhY4B7" + "7U9qUs9RUIPbaXSS9Y0xjcGJLpWte/ZON304fTl9On07fTx9PX0+fT99QH1BfUJ9Q31EfUV9Rn1HfUh9SX1KfUt9TH1NfU59" + "T31QfVF9Un1TfVR9VX1WfVd9WH1ZfVp9W31cfV19Xn1ffWB9YX1ifWN9ZH1lfWZ9Z31ofWl9an1rfWx9bX1vfXB9cX1yfXN9" + "dH11fXZ9//94fXl9en17fXx9fX1+fX99gH2BfYJ9g32EfYV9hn2HfYh9iX2KfYt9jH2NfY59j32QfZF9kn2TfZR9lX2WfZd9" + "mH1lUDCCUVJvmRBuhW6nbfpe9VDcWQZcRm1fbIZ1i4RoaFZZsosgU3GRTZZJhRJpAXkmcfaApE7KkEdthJoHWrxWBWTwlOt3" + "pU8ageFy0ol6mTR/3n5/UllldZF/j4OP61OWeu1jpWOGdvh5V4g2lipiq1KCglRocGd3Y2t37XoBbdN+44nQWRJiyYWlgkx1" + "H1DLTqV164tKXP5dS3ukZdGRyk4lbV+JJ30mlcVOKIzbj3OXS2aBedGP7HB4bZl9mn2bfZx9nX2efZ99oH2hfaJ9o32kfaV9" + "p32ofal9qn2rfax9rX2vfbB9sX2yfbN9tH21fbZ9t324fbl9un27fbx9vX2+fb99wH3BfcJ9w33EfcV9xn3Hfch9yX3Kfct9" + "zH3Nfc59z33QfdF90n3TfdR91X3Wfdd92H3Zff//2n3bfdx93X3efd994H3hfeJ9433kfeV95n3nfeh96X3qfet97H3tfe59" + "733wffF98n3zffR99X32ffd9+H35ffp9PVyyUkaDYlEOg1t3dma4nKxOymC+fLN8z36VTmaLb2aImFmXg1hsZVyVhF/JdVaX" + "33reesBRr3CYeupjdnqgfpZz7ZdFTnhwXU5SkalTUWXnZfyBBYKOVDFcmnWgl9hi2XK9dUVceZrKg0BcgFTpdz5OrmxagNJi" + "bmPoXXdR3Y0eji+V8U/lU+dgrHBnUlBjQ54fWiZQN3d3U+J+hWQrZYlimGMUUDVyyYmzUcCL3X5HV8yDp5SbURtU+1z7ffx9" + "/X3+ff99AH4BfgJ+A34EfgV+Bn4Hfgh+CX4Kfgt+DH4Nfg5+D34QfhF+En4TfhR+FX4Wfhd+GH4Zfhp+G34cfh1+Hn4ffiB+" + "IX4ifiN+JH4lfiZ+J34ofil+Kn4rfix+LX4ufi9+MH4xfjJ+M340fjV+Nn43fjh+OX7//zp+PH49fj5+P35AfkJ+Q35EfkV+" + "Rn5Ifkl+Sn5Lfkx+TX5Ofk9+UH5RflJ+U35UflV+Vn5Xflh+WX5aflt+XH5dfspP43pabeGQj5qAVZZUYVOvVABf6WN3ae9R" + "aGEKUipY2FJOVw14C3e3Xndh4HxbYpdiok6VcAOA92LkcGCXd1fbgu9n9WjVeJeY0XnzWLNU71M0bktRO1KiW/6Lr4BDVaZX" + "c2BRVy1UenpQYFRbp2OgYuNTY2LHW69n7VSfeuaCd5GTXuSIOFmuVw5j6I3vgFdXd3upT+tfvVs+ayFTUHvCckZo/3c2d/dl" + "tVGPTtR2v1ylenWETllBm4BQXn5ffmB+YX5ifmN+ZH5lfmZ+Z35ofml+an5rfmx+bX5ufm9+cH5xfnJ+c350fnV+dn53fnh+" + "eX56fnt+fH59fn5+f36AfoF+g36EfoV+hn6Hfoh+iX6Kfot+jH6Nfo5+j36QfpF+kn6TfpR+lX6Wfpd+mH6Zfpp+nH6dfp5+" + "//+ufrR+u368ftZ+5H7sfvl+Cn8Qfx5/N385fzt/PH89fz5/P39Af0F/Q39Gf0d/SH9Jf0p/S39Mf01/Tn9Pf1J/U3+ImSdh" + "g25kVwZmRmPwVuxiaWLTXhSWg1fJYodVIYdKgaOPZlWxg2VnVo3dhGpaD2jmYu57EZZwUZxvMIz9Y8iJ0mEGf8Jw5W4FdJRp" + "/HLKXs6QF2dqbV5js1JicgGAbE/lWWqR2XCdbdJSUE73lm2VfoXKeC99IVGSV8Jki4B7fOps8WheabdRmFOoaIFyzp7xe/hy" + "u3kTbwZ0TmfMkaScPHmJg1SDD1QXaD1OiVOxUj54hlMpUohQi0/QT1Z/WX9bf1x/XX9ef2B/Y39kf2V/Zn9nf2t/bH9tf29/" + "cH9zf3V/dn93f3h/en97f3x/fX9/f4B/gn+Df4R/hX+Gf4d/iH+Jf4t/jX+Pf5B/kX+Sf5N/lX+Wf5d/mH+Zf5t/nH+gf6J/" + "o3+lf6Z/qH+pf6p/q3+sf61/rn+xf///s3+0f7V/tn+3f7p/u3++f8B/wn/Df8R/xn/Hf8h/yX/Lf81/z3/Qf9F/0n/Tf9Z/" + "13/Zf9p/23/cf91/3n/if+N/4nXLepJ8pWy2lptSg3TpVOlPVICyg96PcJXJXhxgn20YXltlOIH+lEtgvHDDfq58yVGBaLF8" + "b4IkToaPz5F+Zq5OBYypZEqA2lCXdc5x5Vu9j2Zvhk6CZGOV1l6ZZRdSwojIcKNSDnMzdJdn93gWlzROu5DenMtt21FBjR1U" + "zmKyc/GD9paEn8OUNk+af8xRdXB1lq1chpjmU+ROnG4JdLRpa3iPmVl1GFIkdkFt82dtUZmfS4CZVDx7v3rkf+d/6H/qf+t/" + "7H/tf+9/8n/0f/V/9n/3f/h/+X/6f/1//n//fwKAB4AIgAmACoAOgA+AEYATgBqAG4AdgB6AH4AhgCOAJIArgCyALYAugC+A" + "MIAygDSAOYA6gDyAPoBAgEGARIBFgEeASIBJgE6AT4BQgFGAU4BVgFaAV4D//1mAW4BcgF2AXoBfgGCAYYBigGOAZIBlgGaA" + "Z4BogGuAbIBtgG6Ab4BwgHKAc4B0gHWAdoB3gHiAeYB6gHuAfIB9gIaWhFfiYkeWfGkEWgJk03sPb0uWpoJiU4WYkF6JcLNj" + "ZFNPhoGck56MeDKX741CjX+eXm+EeVVfRpYuYnSaFVTdlKNPxWVlXGFcFX9Rhi9si1+Hc+Ru/37mXBtjalvmbnVTcU6gY2V1" + "oWJujyZP0U6mbLZ+uosdhLqHV387kCOVqXuhmviIPYQbbYaa3H6IWbuem3MBeIKGbJqCmhtWF1TLV3BOpp5WU8iPCYGSd5KZ" + "7obhbhOF/GZiYStvfoCBgIKAhYCIgIqAjYCOgI+AkICRgJKAlICVgJeAmYCegKOApoCngKiArICwgLOAtYC2gLiAuYC7gMWA" + "x4DIgMmAyoDLgM+A0IDRgNKA04DUgNWA2IDfgOCA4oDjgOaA7oD1gPeA+YD7gP6A/4AAgQGBA4EEgQWBB4EIgQuB//8MgRWB" + "F4EZgRuBHIEdgR+BIIEhgSKBI4EkgSWBJoEngSiBKYEqgSuBLYEugTCBM4E0gTWBN4E5gTqBO4E8gT2BP4EpjJKCK4PydhNs" + "2V+9gytzBYMaldtr23fGlG9TAoOSUT1ejIw4jUhOq3OaZ4VodpEJl2RxoWwJd5JaQZXPa45/J2bQW7lZmlrolfeV7E4MhJmE" + "rGrfdjCVG3OmaF9bL3eakWGX3Hz3jxyMJV9zfNh5xYnMbByHxltCXsloIHf1fpVRTVHJUilaBX9il9eCz2OEd9CF0nk6bple" + "mVkRhW1wEWy/Yr92T2WvYP2VDmafhyOe7ZQNVH1ULIx4ZECBQYFCgUOBRIFFgUeBSYFNgU6BT4FSgVaBV4FYgVuBXIFdgV6B" + "X4FhgWKBY4FkgWaBaIFqgWuBbIFvgXKBc4F1gXaBd4F4gYGBg4GEgYWBhoGHgYmBi4GMgY2BjoGQgZKBk4GUgZWBloGXgZmB" + "moGegZ+BoIGhgaKBpIGlgf//p4GpgauBrIGtga6Br4GwgbGBsoG0gbWBtoG3gbiBuYG8gb2BvoG/gcSBxYHHgciByYHLgc2B" + "zoHPgdCB0YHSgdOBeWQRhiFqnIHoeGlkVJu5Yitnq4OoWNieq2wgb95bTJYLjF9y0GfHYmFyqU7GWc1rk1iuZlVe31JVYShn" + "7nZmd2dyRnr/YupUUFSglKOQHFqzfhZsQ052WRCASFlXUzd1vpbKViBjEYF8YPmV1m1iVIGZhVHpWv2ArlkTlypQ5Ww8XN9i" + "YE8/U3uBBpC6biuFyGJ0Xr54tWR7Y/VfGFp/kR+eP1xPY0KAfVtuVUqVTZWFbahg4Gfect1RgVvUgdWB1oHXgdiB2YHagduB" + "3IHdgd6B34HggeGB4oHkgeWB5oHogemB64Huge+B8IHxgfKB9YH2gfeB+IH5gfqB/YH/gQOCB4IIggmCCoILgg6CD4IRghOC" + "FYIWgheCGIIZghqCHYIggiSCJYImgieCKYIugjKCOoI8gj2CP4L//0CCQYJCgkOCRYJGgkiCSoJMgk2CToJQglGCUoJTglSC" + "VYJWgleCWYJbglyCXYJegmCCYYJigmOCZIJlgmaCZ4Jpgudi3mxbcm1irpS9fhOBU22cUQRfdFmqUhJgc1mWZlCGn3UqY+Zh" + "73z6i+ZUJ2slnrRr1YVVVHZQpGxqVbSNLHIVXhVgNnTNYpJjTHKYX0NuPm0AZVhv2HbQePx2VHUkUttTU06eXsFlKoDWgJti" + "hlQoUq5wjYjRjeFseFTagPlX9IhUjWqWTZFpT5tst1XGdjB4qGL5cI5vbV/shNpofHj3e6iBC2dPnmdjsHhvVxJ4OZd5Yqti" + "iFI1dNdraoJrgmyCbYJxgnWCdoJ3gniCe4J8goCCgYKDgoWChoKHgomCjIKQgpOClIKVgpaCmoKbgp6CoIKigqOCp4KygrWC" + "toK6gruCvIK/gsCCwoLDgsWCxoLJgtCC1oLZgtqC3YLigueC6ILpguqC7ILtgu6C8ILygvOC9YL2gviC///6gvyC/YL+gv+C" + "AIMKgwuDDYMQgxKDE4MWgxiDGYMdgx6DH4MggyGDIoMjgySDJYMmgymDKoMugzCDMoM3gzuDPYNkVT6BsnWudjlT3nX7UEFc" + "bIvHe09QR3KXmtiYAm/idGh5h2Sld/xikZgrjcFUWIBSTmpX+YINhHNe7VH2dMSLT1xhV/xsh5hGWjR4RJvrj5V8VlJRYvqU" + "xk6Gg2GE6YOyhNRXNGcDV25mZm0xjN1mEXAfZzprFmgaYrtZA07EUQZv0mePbHZRy2hHWWdrZnUOXRCBUJ/XZUh5QXmRmneN" + "glxeTgFPL1RRWQx4aFYUbMSPA199bONsq4uQYz6DP4NBg0KDRINFg0iDSoNLg0yDTYNOg1ODVYNWg1eDWINZg12DYoNwg3GD" + "coNzg3SDdYN2g3mDeoN+g3+DgIOBg4KDg4OEg4eDiIOKg4uDjIONg4+DkIORg5SDlYOWg5eDmYOag52Dn4Ohg6KDo4Okg6WD" + "poOng6yDrYOug///r4O1g7uDvoO/g8KDw4PEg8aDyIPJg8uDzYPOg9CD0YPSg9OD1YPXg9mD2oPbg96D4oPjg+SD5oPng+iD" + "64Psg+2DcGA9bXVyZmKOlMWUQ1PBj357304mjH5O1J6xlLOUTVJcb2OQRW00jBFYTF0ga0lrqmdbVFSBjH+ZWDeFOl+iYkdq" + "OZVyZYRgZWind1ROqE/nXZiXrGTYf+1cz0+NegdSBIMUTi9gg3qmlLVPsk7meTR05FK5gtJkvXndW4FsUpd7jyJsPlB/UwVu" + "zmR0ZjBsxWB3mPeLhl48dHd6y3kYTrGQA3RCbNpWS5HFbIuNOlPGhvJmr45IXHGaIG7ug++D84P0g/WD9oP3g/qD+4P8g/6D" + "/4MAhAKEBYQHhAiECYQKhBCEEoQThBSEFYQWhBeEGYQahBuEHoQfhCCEIYQihCOEKYQqhCuELIQthC6EL4QwhDKEM4Q0hDWE" + "NoQ3hDmEOoQ7hD6EP4RAhEGEQoRDhESERYRHhEiESYT//0qES4RMhE2EToRPhFCEUoRThFSEVYRWhFiEXYRehF+EYIRihGSE" + "ZYRmhGeEaIRqhG6Eb4RwhHKEdIR3hHmEe4R8hNZTNlqLn6ONu1MIV6eYQ2ebkclsaFHKdfNirHI4Up1SOn+UcDh2dFNKnrdp" + "bnjAltmIpH82ccNxiVHTZ+R05FgYZbdWqYt2mXBi1X75YO1w7FjBTrpOzV/nl/tOpIsDUopZq35UYs1O5WUOYjiDyYRjg42H" + "lHG2brlb0n6XUclj1GeJgDmDFYgSUXpbglmxj3NOXWxlUSWJb48ulkqFXnQQlfCVpm3lgjFfkmQSbSiEboHDnF5YW40JTsFT" + "fYR+hH+EgISBhIOEhISFhIaEioSNhI+EkISRhJKEk4SUhJWEloSYhJqEm4SdhJ6En4SghKKEo4SkhKWEpoSnhKiEqYSqhKuE" + "rISthK6EsISxhLOEtYS2hLeEu4S8hL6EwITChMOExYTGhMeEyITLhMyEzoTPhNKE1ITVhNeE///YhNmE2oTbhNyE3oThhOKE" + "5ITnhOiE6YTqhOuE7YTuhO+E8YTyhPOE9IT1hPaE94T4hPmE+oT7hP2E/oQAhQGFAoUeT2NlUWjTVSdOFGSammtiwlpfdHKC" + "qW3uaOdQjoMCeEBnOVKZbLF+u1BlVV5xW3tSZspz64JJZ3FcIFJ9cWuI6pVVlsVkYY2zgYRVVWxHYi5/klgkT0ZVT41MZgpO" + "GlzziKJoTmMNeudwjYL6UvaXEVzoVLWQzX5iWUqNx4YMgg2CZo1EZARcUWGJbT55vos3eDN1e1Q4T6uO8W0gWsV+XnmIbKFb" + "dloadb6ATmEXbvBYH3UldXJyR1PzfgOFBIUFhQaFB4UIhQmFCoULhQ2FDoUPhRCFEoUUhRWFFoUYhRmFG4UchR2FHoUghSKF" + "I4UkhSWFJoUnhSiFKYUqhS2FLoUvhTCFMYUyhTOFNIU1hTaFPoU/hUCFQYVChUSFRYVGhUeFS4VMhU2FToVPhVCFUYVShVOF" + "VIVVhf//V4VYhVqFW4VchV2FX4VghWGFYoVjhWWFZoVnhWmFaoVrhWyFbYVuhW+FcIVxhXOFdYV2hXeFeIV8hX2Ff4WAhYGF" + "AXfbdmlS3IAjVwheMVnucr1lf27XizhccYZBU/N3/mL2ZcBO35iAhp5bxovyU+J3f09OXHaay1kPXzp561gWTv9ni07tYpOK" + "HZC/Ui9m3FVsVgKQ1U6NT8qRcJkPbAJeQ2CkW8aJ1Ys2ZUtilpmIW/9biGMuVddTJnZ9USyFomezaIprkmKTj9RTEoLRbY91" + "Zk5OjXBbn3GvhZFm2WZyfwCHzZ4gn15cL2fwjxFoX2cNYtZ6hVi2XnBlMW+ChYOFhoWIhYmFioWLhYyFjYWOhZCFkYWShZOF" + "lIWVhZaFl4WYhZmFmoWdhZ6Fn4WghaGFooWjhaWFpoWnhamFq4Wsha2FsYWyhbOFtIW1hbaFuIW6hbuFvIW9hb6Fv4XAhcKF" + "w4XEhcWFxoXHhciFyoXLhcyFzYXOhdGF0oX//9SF1oXXhdiF2YXahduF3YXehd+F4IXhheKF44XlheaF54XoheqF64Xshe2F" + "7oXvhfCF8YXyhfOF9IX1hfaF94X4hVVgN1INgFRkcIgpdQVeE2j0YhyXzFM9cgGMNGxhdw56LlSsd3qYHIL0i1V4FGfBcK9l" + "lWQ2Vh1gwXn4Ux1Oe2uGgPpb41XbVjpPPE9ymfNdfmc4gAJggpgBkItbvIv1ixxkWILeZP1Vz4JlkddPIH0fkJ9881BRWK9u" + "v1vJi4OAeJGchJd7fYaLlo+W5X7Tmo54gVxXekKQp5ZfeVlbX2MLe9GErWgGVSl/EHQifQGVQGJMWNZOg1t5WVRY+YX6hfyF" + "/YX+hQCGAYYChgOGBIYGhgeGCIYJhgqGC4YMhg2GDoYPhhCGEoYThhSGFYYXhhiGGYYahhuGHIYdhh6GH4YghiGGIoYjhiSG" + "JYYmhiiGKoYrhiyGLYYuhi+GMIYxhjKGM4Y0hjWGNoY3hjmGOoY7hj2GPoY/hkCG//9BhkKGQ4ZEhkWGRoZHhkiGSYZKhkuG" + "TIZShlOGVYZWhleGWIZZhluGXIZdhl+GYIZhhmOGZIZlhmaGZ4ZohmmGaoZtcx5jS44Pjs6A1IKsYvBT8GxekSpZAWBwbE1X" + "SmQqjSt26W5bV4Bq8HVtby2MCIxmV+9rkoizeKJj+VOtcGRsWFgqZAJY4GibgRBV1nwYULqOzG2fjetwj2ObbdRu5n4EhENo" + "A5DYbXaWqItXWXly5IV+gbx1ioqvaFRSIo4RldBjmJhEjnxVU0//Zo9W1WCVbUNSSVwpWftta1gwdRx1bGAUgkaBEWNhZ+KP" + "OnfzjTSNwZQWXoVTLFTDcG2Gb4ZwhnKGc4Z0hnWGdoZ3hniGg4aEhoWGhoaHhoiGiYaOho+GkIaRhpKGlIaWhpeGmIaZhpqG" + "m4aehp+GoIahhqKGpYamhquGrYauhrKGs4a3hriGuYa7hryGvYa+hr+GwYbChsOGxYbIhsyGzYbShtOG1YbWhteG2obchv//" + "3YbghuGG4objhuWG5obnhuiG6obrhuyG74b1hvaG94b6hvuG/Ib9hv+GAYcEhwWHBocLhwyHDocPhxCHEYcUhxaHQGz3XlxQ" + "rU6tXjpjR4IakFBobpGzdwxU3JRkX+V6dmhFY1J7337bdXdQlWI0WQ+Q+FHDeYF6/laSXxSQgm1gXB9XEFRUUU1u4laoY5OY" + "f4EVhyqJAJAeVG9cwIHWYlhiMYE1nkCWbpp8mi1ppVnTYj5VFmPHVNmGPG0DWuZ0nIhqaxZZTIwvX35uqXN9mDhO93CMW5d4" + "PWNaZpZ2y2CbW0laB05VgWpsi3OhTolnUX+AX/plG2fYX4RZAVoZhxuHHYcfhyCHJIcmhyeHKIcqhyuHLIcthy+HMIcyhzOH" + "NYc2hziHOYc6hzyHPYdAh0GHQodDh0SHRYdGh0qHS4dNh0+HUIdRh1KHVIdVh1aHWIdah1uHXIddh16HX4dhh2KHZodnh2iH" + "aYdqh2uHbIdth2+HcYdyh3OHdYf//3eHeId5h3qHf4eAh4GHhIeGh4eHiYeKh4yHjoePh5CHkYeSh5SHlYeWh5iHmYeah5uH" + "nIedh56HoIehh6KHo4ekh81drl9xU+aX3Y9FaPRWL1XfYDpOTW/0fseCDoTUWR9PKk8+XKx+KmcahXNUT3XDgIJVT5tNTy1u" + "E4wJXHBha1MfdiluioaHZfuVuX47VDN6Cn3uleFVwX/udB1jF4ehbZ16EWKhZWdT4WODbOtdXFSolExOYWzsi0tc4GWcgqdo" + "PlQ0VMtrZmuUTkJjSFMegg1Prk9eVwpi/pZkZmly/1KhUp9g74sUZplxkGd/iVJ4/XdwZjtWOFQhlXpypYemh6eHqYeqh66H" + "sIexh7KHtIe2h7eHuIe5h7uHvIe+h7+HwYfCh8OHxIfFh8eHyIfJh8yHzYfOh8+H0IfUh9WH1ofXh9iH2Yfah9yH3Yfeh9+H" + "4Yfih+OH5Ifmh+eH6Ifph+uH7Ifth++H8Ifxh/KH84f0h/WH9of3h/iH///6h/uH/If9h/+HAIgBiAKIBIgFiAaIB4gIiAmI" + "C4gMiA2IDogPiBCIEYgSiBSIF4gYiBmIGogciB2IHogfiCCII4gAem9gDF6JYJ2BFVncYIRx73CqblBsgHKEaq2ILV5gTrNa" + "nFXjlBdt+3yZlg9ixn6Od36GI1Mel5aPh2bhXKBP7XILTqZTD1kTVIBjKJVIUdlOnJykfrhUJI1UiDeC8pWObSZfzFo+ZmmW" + "sHMuc79TeoGFmaF/qlt3llCWv374dqJTdpWZmbF7RIlYbmFO1H9leeaL82DNVKtOeZj3XWFqz1ARVGGMJ4RdeASXSlLuVKNW" + "AJWIbbVbxm1TZiSIJYgmiCeIKIgpiCqIK4gsiC2ILogviDCIMYgziDSINYg2iDeIOIg6iDuIPYg+iD+IQYhCiEOIRohHiEiI" + "SYhKiEuITohPiFCIUYhSiFOIVYhWiFiIWohbiFyIXYheiF+IYIhmiGeIaohtiG+IcYhziHSIdYh2iHiIeYh6iP//e4h8iICI" + "g4iGiIeIiYiKiIyIjoiPiJCIkYiTiJSIlYiXiJiImYiaiJuInYieiJ+IoIihiKOIpYimiKeIqIipiKqID1xdWyFoloB4VRF7" + "SGVUaZtOR2tOh4uXT1MfYzpkqpCcZcGAEIyZUbBoeFP5h8hhxGz7bCKMUVyqha+CDJUja5uPsGX7X8Nf4U9FiB9mZYEpc/pg" + "dFERUotXYl+ikEyIkpF4Xk9nJ2DTWURR9lH4gAhTeWzElopxEU/uT55/PWfFVQiVwHmWiON+n1gMYgCXWoYYVnuYkF+4i8SE" + "V5HZU+1lj15cdWRgbn1/Wup+7X5pj6dVo1usYMtlhHOsiK6Ir4iwiLKIs4i0iLWItoi4iLmIuoi7iL2Ivoi/iMCIw4jEiMeI" + "yIjKiMuIzIjNiM+I0IjRiNOI1ojXiNqI24jciN2I3ojgiOGI5ojniOmI6ojriOyI7YjuiO+I8oj1iPaI94j6iPuI/Yj/iACJ" + "AYkDiQSJBYkGiQeJCIn//wmJC4kMiQ2JDokPiRGJFIkViRaJF4kYiRyJHYkeiR+JIIkiiSOJJIkmiSeJKIkpiSyJLYkuiS+J" + "MYkyiTOJNYk3iQmQY3Ypd9p+dJebhWZbdHrqlkCIy1KPcapf7GXii/tbb5rhXYlrW2yti6+LCpDFj4tTvGImni2eQFQrTr2C" + "WXKchhZdWYivbcWW0VSaTraLCXG9VAmW33D5bdB2JU4UeBKHqVz2XgCKnJgOlo5wv2xEWaljPHdNiBRvc4IwWNVxjFMaeMGW" + "AVVmXzBxtFsajIyag2suWS+e53loZ2xib0+hdYp/C20zlids8E7SdXtRN2g+b4CQcIGWWXZ0OIk5iTqJO4k8iT2JPok/iUCJ" + "QolDiUWJRolHiUiJSYlKiUuJTIlNiU6JT4lQiVGJUolTiVSJVYlWiVeJWIlZiVqJW4lciV2JYIlhiWKJY4lkiWWJZ4loiWmJ" + "aolriWyJbYluiW+JcIlxiXKJc4l0iXWJdol3iXiJeYl6iXyJ//99iX6JgImCiYSJhYmHiYiJiYmKiYuJjImNiY6Jj4mQiZGJ" + "komTiZSJlYmWiZeJmImZiZqJm4mciZ2JnomfiaCJoYlHZCdcZZCReiOM2lmsVACCb4OBiQCAMGlOVjaAN3LOkbZRX051mJZj" + "Gk72U/NmS4EcWbJtAE75WDtT1mPxlJ1PCk9jiJCYN1lXkPt56k7wgJF1gmycW+hZXV8FaYGGGlDyXVlO43flTnqCkWITZpGQ" + "eVy/TnlfxoE4kISAq3WmTtSID2HFa8ZfSU7KdqJu44uuiwqM0YsCX/x/zH/OfjWDa4PgVrdr85c0lvtZH1T2lOttxVtumTlc" + "FV+QlqKJo4mkiaWJpomniaiJqYmqiauJrImtia6Jr4mwibGJsomzibSJtYm2ibeJuIm5ibqJu4m8ib2Jvom/icCJw4nNidOJ" + "1InVideJ2InZiduJ3YnfieCJ4YniieSJ54noiemJ6onsie2J7onwifGJ8on0ifWJ9on3ifiJ+Yn6if//+4n8if2J/on/iQGK" + "AooDigSKBYoGigiKCYoKiguKDIoNig6KD4oQihGKEooTihSKFYoWiheKGIoZihqKG4ocih2KcFPxgjFqdFpwnpReKH+5gySE" + "JYRng0eHzo9ijch2cV+WmGx4IGbfVOViY0/Dgch1uF7NlgqO+YaPVPNsjG04bH9gx1IodX1eGE+gYOdfJFwxda6QwJS5crls" + "OG5JkQlny1PzU1FPyZHxi8hTfF7Cj+Rtjk7CdoZpXoYaYQaCWU/eTz6QfJwJYR1uFG6FlohOMVrolg5Of1y5eYdb7Yu9f4lz" + "31eLgsGQAVRHkLtV6lyhXwhhMmvxcrKAiYoeih+KIIohiiKKI4okiiWKJooniiiKKYoqiiuKLIotii6KL4owijGKMoozijSK" + "NYo2ijeKOIo5ijqKO4o8ij2KP4pAikGKQopDikSKRYpGikeKSYpKikuKTIpNik6KT4pQilGKUopTilSKVYpWileKWIpZilqK" + "W4pcil2KXor//1+KYIphimKKY4pkimWKZopnimiKaYpqimuKbIptim6Kb4pwinGKcopzinSKdYp2ineKeIp6inuKfIp9in6K" + "f4qAinRt01vViISYa4xtmjOeCm6kUUNRo1eBiJ9T9GOVj+1WWFQGVz9zkG4Yf9yP0YI/YShgYpbwZqZ+io3DjaWUs1ykfAhn" + "pmAFlhiAkU7nkABTaJZBUdCPdIVdkVVm9ZdVWx1TOHhCZz1oyVR+cLBbfY+NUShXsVQSZYJmXo1DjQ+BbIRtkN98/1H7haNn" + "6WWhb6SGgY5qViCQgnZ2cOVxI43pYhlS/Ww8jQ5gnliOYf5mYI1OYrNVI24tZ2ePgYqCioOKhIqFioaKh4qIiouKjIqNio6K" + "j4qQipGKkoqUipWKloqXipiKmYqaipuKnIqdip6Kn4qgiqGKooqjiqSKpYqmiqeKqIqpiqqKq4qsiq2KroqvirCKsYqyirOK" + "tIq1iraKt4q4irmKuoq7iryKvYq+ir+KwIrBisKK///DisSKxYrGiseKyIrJisqKy4rMis2KzorPitCK0YrSitOK1IrVitaK" + "14rYitmK2orbityK3Yreit+K4IrhiuKK44rhlPiVKHcFaKhpi1RNTrhwyItYZItlhVuEejpQ6Fu7d+FreYqYfL5sz3apZZeP" + "LV1VXDiGCGhgUxhi2Xpbbv1+H2rgenBfM28gX4xjqG1WZwhOEF4mjddOwIA0dpyW22ItZn5ivGx1jWdxaX9GUYeA7FNukJhi" + "8lTwhpmPBYAXlReF2Y9Zbc1zn2UfdwR1J3j7gR6NiJSmT5VnuXXKiweXL2NHlTWWuIQjY0F3gV/wcolOFGB0Ze9iY2s/ZeSK" + "5YrmiueK6IrpiuqK64rsiu2K7orvivCK8YryivOK9Ir1ivaK94r4ivmK+or7ivyK/Yr+iv+KAIsBiwKLA4sEiwWLBosIiwmL" + "CosLiwyLDYsOiw+LEIsRixKLE4sUixWLFosXixiLGYsaixuLHIsdix6LH4sgiyGLIosji///JIsliyeLKIspiyqLK4ssiy2L" + "LosvizCLMYsyizOLNIs1izaLN4s4izmLOos7izyLPYs+iz+LQItBi0KLQ4tEi0WLJ17HddGQwYudgp1nL2UxVBiH5XeigAKB" + "QWxLTsd+TID0dg1plmtnYjxQhE9AVwdjYmu+jepT6GW4ftdfGmO3Y/OB9IFufxxe2Vw2Unpm6XkaeiiNmXDUdd5uu2ySei1O" + "xXbgX5+Ud4jIfs15v4DNkfJOF08fgmhU3l0ybcyLpXx0j5iAGl6SVLF2mVs8ZqSa4HMqaNuGMWcqc/iL24sQkPl623BuccRi" + "qXcxVjtOV4TxZ6lSwIYujfiUUXtGi0eLSItJi0qLS4tMi02LTotPi1CLUYtSi1OLVItVi1aLV4tYi1mLWotbi1yLXYtei1+L" + "YIthi2KLY4tki2WLZ4toi2mLaotri22Lbotvi3CLcYtyi3OLdIt1i3aLd4t4i3mLeot7i3yLfYt+i3+LgIuBi4KLg4uEi4WL" + "hov//4eLiIuJi4qLi4uMi42LjouPi5CLkYuSi5OLlIuVi5aLl4uYi5mLmoubi5yLnYuei5+LrIuxi7uLx4vQi+qLCYwejE9P" + "6GxdeXuak2Iqcv1iE04WeGyPsGRajcZ7aWiEXsWIhlmeZO5YtnIOaSWV/Y9YjWBXAH8GjMZRSWPZYlNTTGgidAGDTJFEVUB3" + "fHBKbXlRqFREjf9Zy27EbVxbK33UTn18025QW+qBDW5XWwOb1Wgqjpdb/H47YLV+uZBwjU9ZzWPfebONUlPPZVZ5xYs7lsR+" + "u5SCfjRWiZEAZ2p/Clx1kChm5l1QT95nWlBcT1BXp14Q6BHoEugT6BToOIw5jDqMO4w8jD2MPow/jECMQoxDjESMRYxIjEqM" + "S4xNjE6MT4xQjFGMUoxTjFSMVoxXjFiMWYxbjFyMXYxejF+MYIxjjGSMZYxmjGeMaIxpjGyMbYxujG+McIxxjHKMdIx1jHaM" + "d4x7jHyMfYx+jH+MgIyBjIOMhIyGjIeM//+IjIuMjYyOjI+MkIyRjJKMk4yVjJaMl4yZjJqMm4ycjJ2MnoyfjKCMoYyijKOM" + "pIyljKaMp4yojKmMqoyrjKyMrYyNTgxOQFEQTv9eRVMVTphOHk4ym2xbaVYoTrp5P04VU0dOLVk7cm5TEGzfVuSAl5nTa353" + "F582Tp9OEJ9cTmlOk06IgltbbFUPVsROjVOdU6NTpVOuU2WXXY0aU/VTJlMuUz5TXI1mU2NTAlIIUg5SLVIzUj9SQFJMUl5S" + "YVJcUq+EfVKCUoFSkFKTUoJRVH+7TsNOyU7CTuhO4U7rTt5OG0/zTiJPZE/1TiVPJ08JTytPXk9nTzhlWk9dT66Mr4ywjLGM" + "soyzjLSMtYy2jLeMuIy5jLqMu4y8jL2Mvoy/jMCMwYzCjMOMxIzFjMaMx4zIjMmMyozLjMyMzYzOjM+M0IzRjNKM04zUjNWM" + "1ozXjNiM2YzajNuM3IzdjN6M34zgjOGM4ozjjOSM5YzmjOeM6IzpjOqM64zsjP//7YzujO+M8IzxjPKM84z0jPWM9oz3jPiM" + "+Yz6jPuM/Iz9jP6M/4wAjQGNAo0DjQSNBY0GjQeNCI0JjQqNC40MjQ2NX09XTzJPPU92T3RPkU+JT4NPj09+T3tPqk98T6xP" + "lE/mT+hP6k/FT9pP40/cT9FP30/4TylQTFDzTyxQD1AuUC1Q/k8cUAxQJVAoUH5QQ1BVUEhQTlBsUHtQpVCnUKlQulDWUAZR" + "7VDsUOZQ7lAHUQtR3U49bFhPZU/OT6CfRmx0fG5R/V3JnpiZgVEUWflSDVMHihBT61EZWVVRoE5WUbNOboikiLVOFIHSiIB5" + "NFsDiLh/q1GxUb1RvFEOjQ+NEI0RjRKNE40UjRWNFo0XjRiNGY0ajRuNHI0gjVGNUo1XjV+NZY1ojWmNao1sjW6Nb41xjXKN" + "eI15jXqNe418jX2Nfo1/jYCNgo2DjYaNh42IjYmNjI2NjY6Nj42QjZKNk42VjZaNl42YjZmNmo2bjZyNnY2ejaCNoY3//6KN" + "pI2ljaaNp42ojamNqo2rjayNrY2uja+NsI2yjbaNt425jbuNvY3AjcGNwo3FjceNyI3JjcqNzY3QjdKN043UjcdRllGiUaVR" + "oIumi6eLqou0i7WLt4vCi8OLy4vPi86L0ovTi9SL1ovYi9mL3Ivfi+CL5Ivoi+mL7ovwi/OL9ov5i/yL/4sAjAKMBIwHjAyM" + "D4wRjBKMFIwVjBaMGYwbjBiMHYwfjCCMIYwljCeMKowrjC6ML4wyjDOMNYw2jGlTelMdliKWIZYxliqWPZY8lkKWSZZUll+W" + "Z5ZslnKWdJaIlo2Wl5awlpeQm5CdkJmQrJChkLSQs5C2kLqQ1Y3YjdmN3I3gjeGN4o3ljeaN543pje2N7o3wjfGN8o30jfaN" + "/I3+jf+NAI4BjgKOA44EjgaOB44IjguODY4OjhCOEY4SjhOOFY4WjheOGI4ZjhqOG44cjiCOIY4kjiWOJo4njiiOK44tjjCO" + "Mo4zjjSONo43jjiOO448jj6O//8/jkOORY5GjkyOTY5Ojk+OUI5TjlSOVY5WjleOWI5ajluOXI5djl6OX45gjmGOYo5jjmSO" + "ZY5njmiOao5rjm6OcY64kLCQz5DFkL6Q0JDEkMeQ05DmkOKQ3JDXkNuQ65DvkP6QBJEikR6RI5ExkS+ROZFDkUaRDVJCWaJS" + "rFKtUr5S/1TQUtZS8FLfU+5xzXf0XvVR/FEvm7ZTAV9ade9dTFepV6FXfli8WMVY0VgpVyxXKlczVzlXLlcvV1xXO1dCV2lX" + "hVdrV4ZXfFd7V2hXbVd2V3NXrVekV4xXslfPV6dXtFeTV6BX1VfYV9pX2VfSV7hX9FfvV/hX5FfdV3OOdY53jniOeY56jnuO" + "fY5+joCOgo6DjoSOho6IjomOio6LjoyOjY6OjpGOko6TjpWOlo6XjpiOmY6ajpuOnY6fjqCOoY6ijqOOpI6ljqaOp46ojqmO" + "qo6tjq6OsI6xjrOOtI61jraOt464jrmOu468jr2Ovo6/jsCOwY7Cjv//w47EjsWOxo7HjsiOyY7KjsuOzI7Njs+O0I7RjtKO" + "047UjtWO1o7XjtiO2Y7ajtuO3I7djt6O347gjuGO4o7jjuSOC1gNWP1X7VcAWB5YGVhEWCBYZVhsWIFYiViaWIBYqJkZn/9h" + "eYJ9gn+Cj4KKgqiChIKOgpGCl4KZgquCuIK+grCCyILKguOCmIK3gq6Cy4LMgsGCqYK0gqGCqoKfgsSCzoKkguGCCYP3guSC" + "D4MHg9yC9ILSgtiCDIP7gtOCEYMagwaDFIMVg+CC1YIcg1GDW4NcgwiDkoM8gzSDMYObg16DL4NPg0eDQ4Nfg0CDF4Nggy2D" + "OoMzg2aDZYPljuaO547ojumO6o7rjuyO7Y7uju+O8I7xjvKO8470jvWO9o73jviO+Y76jvuO/I79jv6O/44AjwGPAo8DjwSP" + "BY8GjwePCI8JjwqPC48Mjw2PDo8PjxCPEY8SjxOPFI8VjxaPF48YjxmPGo8bjxyPHY8ejx+PII8hjyKPI4///ySPJY8mjyeP" + "KI8pjyqPK48sjy2PLo8vjzCPMY8yjzOPNI81jzaPN484jzmPOo87jzyPPY8+jz+PQI9Bj0KPQ49Ej2iDG4Npg2yDaoNtg26D" + "sIN4g7ODtIOgg6qDk4Ocg4WDfIO2g6mDfYO4g3uDmIOeg6iDuoO8g8GDAYTlg9iDB1gYhAuE3YP9g9aDHIQ4hBGEBoTUg9+D" + "D4QDhPiD+YPqg8WDwIMmhPCD4YNchFGEWoRZhHOEh4SIhHqEiYR4hDyERoRphHaEjISOhDGEbYTBhM2E0ITmhL2E04TKhL+E" + "uoTghKGEuYS0hJeE5YTjhAyFDXU4hfCEOYUfhTqFRY9Gj0ePSI9Jj0qPS49Mj02PTo9Pj1CPUY9Sj1OPVI9Vj1aPV49Yj1mP" + "Wo9bj1yPXY9ej1+PYI9hj2KPY49kj2WPao+Aj4yPko+dj6CPoY+ij6SPpY+mj6ePqo+sj62Pro+vj7KPs4+0j7WPt4+4j7qP" + "u4+8j7+PwI/Dj8aP///Jj8qPy4/Mj82Pz4/Sj9aP14/aj+CP4Y/jj+eP7I/vj/GP8o/0j/WP9o/6j/uP/I/+j/+PB5AIkAyQ" + "DpATkBWQGJBWhTuF/4T8hFmFSIVohWSFXoV6haJ3Q4VyhXuFpIWohYeFj4V5ha6FnIWFhbmFt4WwhdOFwYXchf+FJ4YFhimG" + "FoY8hv5eCF88WUFZN4BVWVpZWFkPUyJcJVwsXDRcTGJqYp9iu2LKYtpi12LuYiJj9mI5Y0tjQ2OtY/ZjcWN6Y45jtGNtY6xj" + "imNpY65jvGPyY/hj4GP/Y8Rj3mPOY1JkxmO+Y0VkQWQLZBtkIGQMZCZkIWReZIRkbWSWZBmQHJAjkCSQJZAnkCiQKZAqkCuQ" + "LJAwkDGQMpAzkDSQN5A5kDqQPZA/kECQQ5BFkEaQSJBJkEqQS5BMkE6QVJBVkFaQWZBakFyQXZBekF+QYJBhkGSQZpBnkGmQ" + "apBrkGyQb5BwkHGQcpBzkHaQd5B4kHmQepB7kHyQfpCBkP//hJCFkIaQh5CJkIqQjJCNkI6Qj5CQkJKQlJCWkJiQmpCckJ6Q" + "n5CgkKSQpZCnkKiQqZCrkK2QspC3kLyQvZC/kMCQemS3ZLhkmWS6ZMBk0GTXZORk4mQJZSVlLmULX9JfGXURX19T8VP9U+lT" + "6FP7UxJUFlQGVEtUUlRTVFRUVlRDVCFUV1RZVCNUMlSCVJRUd1RxVGRUmlSbVIRUdlRmVJ1U0FStVMJUtFTSVKdUplTTVNRU" + "clSjVNVUu1S/VMxU2VTaVNxUqVSqVKRU3VTPVN5UG1XnVCBV/VQUVfNUIlUjVQ9VEVUnVSpVZ1WPVbVVSVVtVUFVVVU/VVBV" + "PFXCkMOQxpDIkMmQy5DMkM2Q0pDUkNWQ1pDYkNmQ2pDekN+Q4JDjkOSQ5ZDpkOqQ7JDukPCQ8ZDykPOQ9ZD2kPeQ+ZD6kPuQ" + "/JD/kACRAZEDkQWRBpEHkQiRCZEKkQuRDJENkQ6RD5EQkRGREpETkRSRFZEWkReRGJEakRuRHJH//x2RH5EgkSGRJJElkSaR" + "J5EokSmRKpErkSyRLZEukTCRMpEzkTSRNZE2kTeROJE6kTuRPJE9kT6RP5FAkUGRQpFEkTdVVlV1VXZVd1UzVTBVXFWLVdJV" + "g1WxVblViFWBVZ9VflXWVZFVe1XfVb1VvlWUVZlV6lX3VclVH1bRVetV7FXUVeZV3VXEVe9V5VXyVfNVzFXNVehV9VXkVZSP" + "HlYIVgxWAVYkViNW/lUAVidWLVZYVjlWV1YsVk1WYlZZVlxWTFZUVoZWZFZxVmtWe1Z8VoVWk1avVtRW11bdVuFW9VbrVvlW" + "/1YEVwpXCVccVw9eGV4UXhFeMV47XjxeRZFHkUiRUZFTkVSRVZFWkViRWZFbkVyRX5FgkWaRZ5FokWuRbZFzkXqRe5F8kYCR" + "gZGCkYORhJGGkYiRipGOkY+Rk5GUkZWRlpGXkZiRmZGckZ2RnpGfkaCRoZGkkaWRppGnkaiRqZGrkayRsJGxkbKRs5G2kbeR" + "uJG5kbuR//+8kb2RvpG/kcCRwZHCkcORxJHFkcaRyJHLkdCR0pHTkdSR1ZHWkdeR2JHZkdqR25Hdkd6R35HgkeGR4pHjkeSR" + "5ZE3XkReVF5bXl5eYV6MXHpcjVyQXJZciFyYXJlckVyaXJxctVyiXL1crFyrXLFco1zBXLdcxFzSXORcy1zlXAJdA10nXSZd" + "Ll0kXR5dBl0bXVhdPl00XT1dbF1bXW9dXV1rXUtdSl1pXXRdgl2ZXZ1dc4y3XcVdc193X4Jfh1+JX4xflV+ZX5xfqF+tX7Vf" + "vF9iiGFfrXKwcrRyt3K4csNywXLOcs1y0nLocu9y6XLycvRy93IBc/NyA3P6cuaR55HokemR6pHrkeyR7ZHuke+R8JHxkfKR" + "85H0kfWR9pH3kfiR+ZH6kfuR/JH9kf6R/5EAkgGSApIDkgSSBZIGkgeSCJIJkgqSC5IMkg2SDpIPkhCSEZISkhOSFJIVkhaS" + "F5IYkhmSGpIbkhySHZIekh+SIJIhkiKSI5Ikkv//JZImkieSKJIpkiqSK5Iski2SLpIvkjCSMZIykjOSNJI1kjaSN5I4kjmS" + "OpI7kjySPZI+kj+SQJJBkkKSQ5JEkkWS+3IXcxNzIXMKcx5zHXMVcyJzOXMlcyxzOHMxc1BzTXNXc2BzbHNvc35zG4IlWeeY" + "JFkCWWOZZ5lomWmZaplrmWyZdJl3mX2ZgJmEmYeZipmNmZCZkZmTmZSZlZmAXpFei16WXqVeoF65XrVevl6zXlON0l7RXtte" + "6F7qXrqBxF/JX9Zfz18DYO5fBGDhX+Rf/l8FYAZg6l/tX/hfGWA1YCZgG2APYA1gKWArYApgP2AhYHhgeWB7YHpgQmBGkkeS" + "SJJJkkqSS5JMkk2STpJPklCSUZJSklOSVJJVklaSV5JYklmSWpJbklySXZJekl+SYJJhkmKSY5JkkmWSZpJnkmiSaZJqkmuS" + "bJJtkm6Sb5JwknGScpJzknWSdpJ3kniSeZJ6knuSfJJ9kn6Sf5KAkoGSgpKDkoSShZL//4aSh5KIkomSipKLkoySjZKPkpCS" + "kZKSkpOSlJKVkpaSl5KYkpmSmpKbkpySnZKekp+SoJKhkqKSo5KkkqWSppKnkmpgfWCWYJpgrWCdYINgkmCMYJtg7GC7YLFg" + "3WDYYMZg2mC0YCBhJmEVYSNh9GAAYQ5hK2FKYXVhrGGUYadht2HUYfVh3V+zlumV65XxlfOV9ZX2lfyV/pUDlgSWBpYIlgqW" + "C5YMlg2WD5YSlhWWFpYXlhmWGpYsTj9yFWI1bFRsXGxKbKNshWyQbJRsjGxobGlsdGx2bIZsqWzQbNRsrWz3bPhs8WzXbLJs" + "4GzWbPps62zubLFs02zvbP5sqJKpkqqSq5Kskq2Sr5KwkrGSspKzkrSStZK2kreSuJK5krqSu5K8kr2SvpK/ksCSwZLCksOS" + "xJLFksaSx5LJksqSy5LMks2SzpLPktCS0ZLSktOS1JLVktaS15LYktmS2pLbktyS3ZLekt+S4JLhkuKS45LkkuWS5pLnkuiS" + "///pkuqS65Lsku2S7pLvkvCS8ZLykvOS9JL1kvaS95L4kvmS+pL7kvyS/ZL+kv+SAJMBkwKTA5MEkwWTBpMHkwiTCZM5bSdt" + "DG1DbUhtB20EbRltDm0rbU1tLm01bRptT21SbVRtM22RbW9tnm2gbV5tk22UbVxtYG18bWNtGm7HbcVt3m0Obr9t4G0RbuZt" + "3W3ZbRZuq20Mbq5tK25ubk5ua26ybl9uhm5TblRuMm4lbkRu326xbphu4G4tb+JupW6nbr1uu263btdutG7Pbo9uwm6fbmJv" + "Rm9HbyRvFW/5bi9vNm9Lb3RvKm8JbylviW+Nb4xveG9yb3xvem/RbwqTC5MMkw2TDpMPkxCTEZMSkxOTFJMVkxaTF5MYkxmT" + "GpMbkxyTHZMekx+TIJMhkyKTI5MkkyWTJpMnkyiTKZMqkyuTLJMtky6TL5MwkzGTMpMzkzSTNZM2kzeTOJM5kzqTO5M8kz2T" + "P5NAk0GTQpNDk0STRZNGk0eTSJNJk///SpNLk0yTTZNOk0+TUJNRk1KTU5NUk1WTVpNXk1iTWZNak1uTXJNdk16TX5Ngk2GT" + "YpNjk2STZZNmk2eTaJNpk2uTyW+nb7lvtm/Cb+Fv7m/eb+Bv728acCNwG3A5cDVwT3BecIBbhFuVW5NbpVu4Wy91npo0ZORb" + "7lswifBbR44Hi7aP04/Vj+WP7o/kj+mP5o/zj+iPBZAEkAuQJpARkA2QFpAhkDWQNpAtkC+QRJBRkFKQUJBokFiQYpBbkLlm" + "dJB9kIKQiJCDkIuQUF9XX1ZfWF87XKtUUFxZXHFbY1xmXLx/Kl8pXy1fdII8XzubblyBWYNZjVmpWapZo1lsk22TbpNvk3CT" + "cZNyk3OTdJN1k3aTd5N4k3mTepN7k3yTfZN+k3+TgJOBk4KTg5OEk4WThpOHk4iTiZOKk4uTjJONk46TkJORk5KTk5OUk5WT" + "lpOXk5iTmZOak5uTnJOdk56Tn5Ogk6GTopOjk6STpZOmk6eTqJOpk6qTq5P//6yTrZOuk6+TsJOxk7KTs5O0k7WTtpO3k7iT" + "uZO6k7uTvJO9k76Tv5PAk8GTwpPDk8STxZPGk8eTyJPJk8uTzJPNk5dZylmrWZ5ZpFnSWbJZr1nXWb5ZBVoGWt1ZCFrjWdhZ" + "+VkMWglaMlo0WhFaI1oTWkBaZ1pKWlVaPFpiWnVa7ICqWptad1p6Wr5a61qyWtJa1Fq4WuBa41rxWtZa5lrYWtxaCVsXWxZb" + "Mls3W0BbFVwcXFpbZVtzW1FbU1tiW3Wad5p4mnqaf5p9moCagZqFmoiaipqQmpKak5qWmpiam5qcmp2an5qgmqKao5qlmqea" + "n36hfqN+pX6ofql+zpPPk9CT0ZPSk9OT1JPVk9eT2JPZk9qT25Pck92T3pPfk+CT4ZPik+OT5JPlk+aT55Pok+mT6pPrk+yT" + "7ZPuk++T8JPxk/KT85P0k/WT9pP3k/iT+ZP6k/uT/JP9k/6T/5MAlAGUApQDlASUBZQGlAeUCJQJlAqUC5QMlA2U//8OlA+U" + "EJQRlBKUE5QUlBWUFpQXlBiUGZQalBuUHJQdlB6UH5QglCGUIpQjlCSUJZQmlCeUKJQplCqUK5QslC2ULpStfrB+vn7AfsF+" + "wn7Jfst+zH7QftR+137bfuB+4X7ofut+7n7vfvF+8n4Nf/Z++n77fv5+AX8CfwN/B38Ifwt/DH8PfxF/En8Xfxl/HH8bfx9/" + "IX8ifyN/JH8lfyZ/J38qfyt/LH8tfy9/MH8xfzJ/M381f3pef3XbXT51lZCOc5FzrnOic59zz3PCc9Fzt3Ozc8BzyXPIc+Vz" + "2XN8mAp06XPnc95zunPycw90KnRbdCZ0JXQodDB0LnQsdC+UMJQxlDKUM5Q0lDWUNpQ3lDiUOZQ6lDuUPJQ9lD+UQJRBlEKU" + "Q5RElEWURpRHlEiUSZRKlEuUTJRNlE6UT5RQlFGUUpRTlFSUVZRWlFeUWJRZlFqUW5RclF2UXpRflGCUYZRilGOUZJRllGaU" + "Z5RolGmUapRslG2UbpRvlP//cJRxlHKUc5R0lHWUdpR3lHiUeZR6lHuUfJR9lH6Uf5SAlIGUgpSDlISUkZSWlJiUx5TPlNOU" + "1JTalOaU+5QclSCVG3QadEF0XHRXdFV0WXR3dG10fnScdI50gHSBdId0i3SedKh0qXSQdKd00nS6dOqX65fsl0xnU2deZ0hn" + "aWelZ4dnamdzZ5hnp2d1Z6hnnmetZ4tnd2d8Z/BnCWjYZwpo6WewZwxo2We1Z9pns2fdZwBow2e4Z+JnDmjBZ/1nMmgzaGBo" + "YWhOaGJoRGhkaINoHWhVaGZoQWhnaEBoPmhKaEloKWi1aI9odGh3aJNoa2jCaG5p/GgfaSBp+WgnlTOVPZVDlUiVS5VVlVqV" + "YJVulXSVdZV3lXiVeZV6lXuVfJV9lX6VgJWBlYKVg5WElYWVhpWHlYiViZWKlYuVjJWNlY6Vj5WQlZGVkpWTlZSVlZWWlZeV" + "mJWZlZqVm5WclZ2VnpWflaCVoZWilaOVpJWllaaVp5WolamVqpX//6uVrJWtla6Vr5WwlbGVspWzlbSVtZW2lbeVuJW5lbqV" + "u5W8lb2VvpW/lcCVwZXClcOVxJXFlcaVx5XIlcmVypXLlSRp8GgLaQFpV2njaBBpcWk5aWBpQmldaYRpa2mAaZhpeGk0acxp" + "h2mIac5piWlmaWNpeWmbaadpu2mraa1p1GmxacFpymnfaZVp4GmNaf9pL2rtaRdqGGplavJpRGo+aqBqUGpbajVqjmp5aj1q" + "KGpYanxqkWqQaqlql2qrajdzUnOBa4Jrh2uEa5Jrk2uNa5prm2uha6pra49tj3GPco9zj3WPdo94j3ePeY96j3yPfo+Bj4KP" + "hI+Hj4uPzJXNlc6Vz5XQldGV0pXTldSV1ZXWldeV2JXZldqV25Xcld2V3pXfleCV4ZXileOV5JXlleaV55Xslf+VB5YTlhiW" + "G5YeliCWI5YkliWWJpYnliiWKZYrliyWLZYvljCWN5Y4ljmWOpY+lkGWQ5ZKlk6WT5ZRllKWU5ZWlleW//9YllmWWpZcll2W" + "XpZglmOWZZZmlmuWbZZulm+WcJZxlnOWeJZ5lnqWe5Z8ln2WfpZ/loCWgZaCloOWhJaHlomWipaNj46Pj4+Yj5qPzo4LYhdi" + "G2IfYiJiIWIlYiRiLGLnge909HT/dA91EXUTdTRl7mXvZfBlCmYZZnJnA2YVZgBmhXD3Zh1mNGYxZjZmNWYGgF9mVGZBZk9m" + "VmZhZldmd2aEZoxmp2adZr5m22bcZuZm6WYyjTONNo07jT2NQI1FjUaNSI1JjUeNTY1VjVmNx4nKicuJzInOic+J0InRiW5y" + "n3JdcmZyb3J+cn9yhHKLco1yj3KScghjMmOwY4yWjpaRlpKWk5aVlpaWmpablp2WnpaflqCWoZailqOWpJallqaWqJaplqqW" + "q5aslq2WrpavlrGWspa0lrWWt5a4lrqWu5a/lsKWw5bIlsqWy5bQltGW05bUltaW15bYltmW2pbbltyW3Zbelt+W4ZbiluOW" + "5JblluaW55brlv//7Jbtlu6W8JbxlvKW9Jb1lviW+pb7lvyW/Zb/lgKXA5cFlwqXC5cMlxCXEZcSlxSXFZcXlxiXGZcalxuX" + "HZcflyCXP2TYZASA6mvza/1r9Wv5awVsB2wGbA1sFWwYbBlsGmwhbClsJGwqbDJsNWVVZWtlTXJSclZyMHJihhZSn4CcgJOA" + "vIAKZ72AsYCrgK2AtIC3gOeA6IDpgOqA24DCgMSA2YDNgNeAEGfdgOuA8YD0gO2ADYEOgfKA/IAVZxKBWow2gR6BLIEYgTKB" + "SIFMgVOBdIFZgVqBcYFggWmBfIF9gW2BZ4FNWLVaiIGCgZGB1W6jgaqBzIEmZ8qBu4EhlyKXI5cklyWXJpcnlyiXKZcrlyyX" + "LpcvlzGXM5c0lzWXNpc3lzqXO5c8lz2XP5dAl0GXQpdDl0SXRZdGl0eXSJdJl0qXS5dMl02XTpdPl1CXUZdUl1WXV5dYl1qX" + "XJddl1+XY5dkl2aXZ5dol2qXa5dsl22Xbpdvl3CXcZf//3KXdZd3l3iXeZd6l3uXfZd+l3+XgJeBl4KXg5eEl4aXh5eIl4mX" + "ipeMl46Xj5eQl5OXlZeWl5eXmZeal5uXnJedl8GBpoEkazdrOWtDa0ZrWWvRmNKY05jVmNmY2piza0BfwmvziZBlUZ+TZbxl" + "xmXEZcNlzGXOZdJl1mWAcJxwlnCdcLtwwHC3cKtwsXDocMpwEHETcRZxL3ExcXNxXHFocUVxcnFKcXhxenGYcbNxtXGocaBx" + "4HHUcedx+XEdcihybHAYcWZxuXE+Yj1iQ2JIYkliO3lAeUZ5SXlbeVx5U3laeWJ5V3lgeW95Z3l6eYV5inmaead5s3nRX9Bf" + "npefl6GXopekl6WXppenl6iXqZeql6yXrpewl7GXs5e1l7aXt5e4l7mXupe7l7yXvZe+l7+XwJfBl8KXw5fEl8WXxpfHl8iX" + "yZfKl8uXzJfNl86Xz5fQl9GX0pfTl9SX1ZfWl9eX2JfZl9qX25fcl92X3pffl+CX4Zfil+OX///kl+WX6Jful++X8Jfxl/KX" + "9Jf3l/iX+Zf6l/uX/Jf9l/6X/5cAmAGYApgDmASYBZgGmAeYCJgJmAqYC5gMmA2YDpg8YF1gWmBnYEFgWWBjYKtgBmENYV1h" + "qWGdYcth0WEGYoCAf4CTbPZs/G32d/h3AHgJeBd4GHgReKtlLXgceB14OXg6eDt4H3g8eCV4LHgjeCl4TnhteFZ4V3gmeFB4" + "R3hMeGp4m3iTeJp4h3iceKF4o3iyeLl4pXjUeNl4yXjsePJ4BXn0eBN5JHkeeTR5m5/5nvue/J7xdgR3DXf5dgd3CHcadyJ3" + "GXctdyZ3NXc4d1B3UXdHd0N3Wndodw+YEJgRmBKYE5gUmBWYFpgXmBiYGZgamBuYHJgdmB6YH5ggmCGYIpgjmCSYJZgmmCeY" + "KJgpmCqYK5gsmC2YLpgvmDCYMZgymDOYNJg1mDaYN5g4mDmYOpg7mDyYPZg+mD+YQJhBmEKYQ5hEmEWYRphHmEiYSZhKmEuY" + "TJhNmP//TphPmFCYUZhSmFOYVJhVmFaYV5hYmFmYWphbmFyYXZhemF+YYJhhmGKYY5hkmGWYZphnmGiYaZhqmGuYbJhtmG6Y" + "Yndld393jXd9d4B3jHeRd593oHewd7V3vXc6dUB1TnVLdUh1W3VydXl1g3VYf2F/X39Iimh/dH9xf3l/gX9+f8125XYyiIWU" + "hpSHlIuUipSMlI2Uj5SQlJSUl5SVlJqUm5SclKOUpJSrlKqUrZSslK+UsJSylLSUtpS3lLiUuZS6lLyUvZS/lMSUyJTJlMqU" + "y5TMlM2UzpTQlNGU0pTVlNaU15TZlNiU25TelN+U4JTilOSU5ZTnlOiU6pRvmHCYcZhymHOYdJiLmI6YkpiVmJmYo5iomKmY" + "qpirmKyYrZiumK+YsJixmLKYs5i0mLWYtpi3mLiYuZi6mLuYvJi9mL6Yv5jAmMGYwpjDmMSYxZjGmMeYyJjJmMqYy5jMmM2Y" + "z5jQmNSY1pjXmNuY3JjdmOCY4ZjimOOY5Jj//+WY5pjpmOqY65jsmO2Y7pjvmPCY8ZjymPOY9Jj1mPaY95j4mPmY+pj7mPyY" + "/Zj+mP+YAJkBmQKZA5kEmQWZBpkHmemU65TulO+U85T0lPWU95T5lPyU/ZT/lAOVApUGlQeVCZUKlQ2VDpUPlRKVE5UUlRWV" + "FpUYlRuVHZUelR+VIpUqlSuVKZUslTGVMpU0lTaVN5U4lTyVPpU/lUKVNZVElUWVRpVJlUyVTpVPlVKVU5VUlVaVV5VYlVmV" + "W5VelV+VXZVhlWKVZJVllWaVZ5VolWmVapVrlWyVb5VxlXKVc5U6led37HfJltV57Xnjeet5BnpHXQN6AnoeehR6CJkJmQqZ" + "C5kMmQ6ZD5kRmRKZE5kUmRWZFpkXmRiZGZkamRuZHJkdmR6ZH5kgmSGZIpkjmSSZJZkmmSeZKJkpmSqZK5ksmS2ZL5kwmTGZ" + "MpkzmTSZNZk2mTeZOJk5mTqZO5k8mT2ZPpk/mUCZQZlCmUOZRJlFmUaZR5lImUmZ//9KmUuZTJlNmU6ZT5lQmVGZUplTmVaZ" + "V5lYmVmZWplbmVyZXZlemV+ZYJlhmWKZZJlmmXOZeJl5mXuZfpmCmYOZiZk5ejd6UXrPnqWZcHqIdo52k3aZdqR23nTgdCx1" + "IJ4iniieKZ4qniueLJ4ynjGeNp44njeeOZ46nj6eQZ5CnkSeRp5HnkieSZ5LnkyeTp5RnlWeV55anlueXJ5enmOeZp5nnmie" + "aZ5qnmuebJ5xnm2ec56SdZR1lnWgdZ11rHWjdbN1tHW4dcR1sXWwdcN1wnXWdc1143XodeZ15HXrded1A3bxdfx1/3UQdgB2" + "BXYMdhd2CnYldhh2FXYZdoyZjpmamZuZnJmdmZ6Zn5mgmaGZopmjmaSZppmnmamZqpmrmayZrZmuma+ZsJmxmbKZs5m0mbWZ" + "tpm3mbiZuZm6mbuZvJm9mb6Zv5nAmcGZwpnDmcSZxZnGmceZyJnJmcqZy5nMmc2ZzpnPmdCZ0ZnSmdOZ1JnVmdaZ15nYmf//" + "2ZnamduZ3Jndmd6Z35ngmeGZ4pnjmeSZ5ZnmmeeZ6JnpmeqZ65nsme2Z7pnvmfCZ8ZnymfOZ9Jn1mfaZ95n4mfmZG3Y8diJ2" + "IHZAdi12MHY/djV2Q3Y+djN2TXZedlR2XHZWdmt2b3bKf+Z6eHp5eoB6hnqIepV6pnqgeqx6qHqterN6ZIhpiHKIfYh/iIKI" + "oojGiLeIvIjJiOKIzojjiOWI8YgaifyI6Ij+iPCIIYkZiROJG4kKiTSJK4k2iUGJZol7iYt15YCydrR23HcSgBSAFoAcgCCA" + "IoAlgCaAJ4ApgCiAMYALgDWAQ4BGgE2AUoBpgHGAg4l4mICYg5j6mfuZ/Jn9mf6Z/5kAmgGaApoDmgSaBZoGmgeaCJoJmgqa" + "C5oMmg2aDpoPmhCaEZoSmhOaFJoVmhaaF5oYmhmaGpobmhyaHZoemh+aIJohmiKaI5okmiWaJponmiiaKZoqmiuaLJotmi6a" + "L5owmjGaMpozmjSaNZo2mjeaOJr//zmaOpo7mjyaPZo+mj+aQJpBmkKaQ5pEmkWaRppHmkiaSZpKmkuaTJpNmk6aT5pQmlGa" + "UppTmlSaVZpWmleaWJpZmomYjJiNmI+YlJiamJuYnpifmKGYopilmKaYTYZUhmyGboZ/hnqGfIZ7hqiGjYaLhqyGnYanhqOG" + "qoaThqmGtobEhrWGzoawhrqGsYavhsmGz4a0humG8Ybyhu2G84bQhhOH3ob0ht+G2IbRhgOHB4f4hgiHCocNhwmHI4c7hx6H" + "JYcuhxqHPodIhzSHMYcphzeHP4eChyKHfYd+h3uHYIdwh0yHboeLh1OHY4d8h2SHWYdlh5OHr4eoh9KHWppbmlyaXZpeml+a" + "YJphmmKaY5pkmmWaZppnmmiaaZpqmmuacpqDmomajZqOmpSalZqZmqaaqZqqmquarJqtmq6ar5qymrOatJq1mrmau5q9mr6a" + "v5rDmsSaxprHmsiayZrKms2azprPmtCa0prUmtWa1prXmtma2prbmtya///dmt6a4JrimuOa5Jrlmuea6Jrpmuqa7JrumvCa" + "8ZrymvOa9Jr1mvaa95r4mvqa/Jr9mv6a/5oAmwGbApsEmwWbBpvGh4iHhYeth5eHg4erh+WHrIe1h7OHy4fTh72H0YfAh8qH" + "24fqh+CH7ocWiBOI/ocKiBuIIYg5iDyINn9Cf0R/RX8Qgvp6/XoIewN7BHsVewp7K3sPe0d7OHsqexl7LnsxeyB7JXskezN7" + "Pnsee1h7WntFe3V7THtde2B7bnt7e2J7cntxe5B7pnune7h7rHude6h7hXuqe5x7onure7R70XvBe8x73Xvae+V75nvqewx8" + "/nv8ew98FnwLfAebCZsKmwubDJsNmw6bEJsRmxKbFJsVmxabF5sYmxmbGpsbmxybHZsemyCbIZsimySbJZsmmyebKJspmyqb" + "K5ssmy2bLpswmzGbM5s0mzWbNps3mzibOZs6mz2bPps/m0CbRptKm0ubTJtOm1CbUptTm1WbVptXm1ibWZtam///W5tcm12b" + "Xptfm2CbYZtim2ObZJtlm2abZ5tom2mbaptrm2ybbZtum2+bcJtxm3Kbc5t0m3Wbdpt3m3ibeZt6m3ubH3wqfCZ8OHxBfEB8" + "/oEBggKCBILsgUSIIYIigiOCLYIvgiiCK4I4gjuCM4I0gj6CRIJJgkuCT4Jagl+CaIJ+iIWIiIjYiN+IXomdf59/p3+vf7B/" + "sn98fEllkXydfJx8nnyifLJ8vHy9fMF8x3zMfM18yHzFfNd86Hxugqhmv3/Of9V/5X/hf+Z/6X/uf/N/+Hx3faZ9rn1Hfpt+" + "uJ60nnONhI2UjZGNsY1njW2NR4xJjEqRUJFOkU+RZJF8m32bfpt/m4CbgZuCm4ObhJuFm4abh5uIm4mbipuLm4ybjZuOm4+b" + "kJuRm5Kbk5uUm5WblpuXm5ibmZuam5ubnJudm56bn5ugm6Gbopujm6SbpZumm6ebqJupm6qbq5usm62brpuvm7CbsZuym7Ob" + "tJu1m7abt5u4m7mbupv//7ubvJu9m76bv5vAm8GbwpvDm8SbxZvGm8ebyJvJm8qby5vMm82bzpvPm9Cb0ZvSm9Ob1JvVm9ab" + "15vYm9mb2pvbm2KRYZFwkWmRb5F9kX6RcpF0kXmRjJGFkZCRjZGRkaKRo5Gqka2RrpGvkbWRtJG6kVWMfp64jeuNBY5ZjmmO" + "tY2/jbyNuo3EjdaN143ajd6Nzo3PjduNxo3sjfeN+I3jjfmN+43kjQmO/Y0Ujh2OH44sji6OI44vjjqOQI45jjWOPY4xjkmO" + "QY5CjlGOUo5KjnCOdo58jm+OdI6Fjo+OlI6QjpyOno54jIKMioyFjJiMlIybZdaJ3onaidyJ3Jvdm96b35vgm+Gb4pvjm+Sb" + "5Zvmm+eb6Jvpm+qb65vsm+2b7pvvm/Cb8Zvym/Ob9Jv1m/ab95v4m/mb+pv7m/yb/Zv+m/+bAJwBnAKcA5wEnAWcBpwHnAic" + "CZwKnAucDJwNnA6cD5wQnBGcEpwTnBScFZwWnBecGJwZnBqc//8bnBycHZwenB+cIJwhnCKcI5wknCWcJpwnnCicKZwqnCuc" + "LJwtnC6cL5wwnDGcMpwznDScNZw2nDecOJw5nDqcO5zlieuJ74k+iiaLU5fplvOW75YGlwGXCJcPlw6XKpctlzCXPpeAn4Of" + "hZ+Gn4efiJ+Jn4qfjJ/+ngufDZ+5lryWvZbOltKWv3fglo6SrpLIkj6TapPKk4+TPpRrlH+cgpyFnIach5yInCN6i5yOnJCc" + "kZySnJSclZyanJucnpyfnKCcoZyinKOcpZymnKecqJypnKucrZyunLCcsZyynLOctJy1nLact5y6nLucvJy9nMScxZzGnMec" + "ypzLnDycPZw+nD+cQJxBnEKcQ5xEnEWcRpxHnEicSZxKnEucTJxNnE6cT5xQnFGcUpxTnFScVZxWnFecWJxZnFqcW5xcnF2c" + "XpxfnGCcYZxinGOcZJxlnGacZ5xonGmcapxrnGycbZxunG+ccJxxnHKcc5x0nHWcdpx3nHiceZx6nP//e5x9nH6cgJyDnISc" + "iZyKnIycj5yTnJacl5yYnJmcnZyqnKycr5y5nL6cv5zAnMGcwpzInMmc0ZzSnNqc25zgnOGczJzNnM6cz5zQnNOc1JzVnNec" + "2JzZnNyc3ZzfnOKcfJeFl5GXkpeUl6+Xq5ejl7KXtJexmrCat5pYnraaupq8msGawJrFmsKay5rMmtGaRZtDm0ebSZtIm02b" + "UZvomA2ZLplVmVSZ35rhmuaa75rrmvua7Zr5mgibD5sTmx+bI5u9nr6eO36CnoeeiJ6LnpKe1pOdnp+e257cnt2e4J7fnuKe" + "6Z7nnuWe6p7vniKfLJ8vnzmfN589nz6fRJ/jnOSc5ZzmnOec6JzpnOqc65zsnO2c7pzvnPCc8ZzynPOc9Jz1nPac95z4nPmc" + "+pz7nPyc/Zz+nP+cAJ0BnQKdA50EnQWdBp0HnQidCZ0KnQudDJ0NnQ6dD50QnRGdEp0TnRSdFZ0WnRedGJ0ZnRqdG50cnR2d" + "Hp0fnSCdIZ3//yKdI50knSWdJp0nnSidKZ0qnSudLJ0tnS6dL50wnTGdMp0znTSdNZ02nTedOJ05nTqdO508nT2dPp0/nUCd" + "QZ1CnTTiNeI24jfiOOI54jriO+I84j3iPuI/4kDiQeJC4kPiROJF4kbiR+JI4kniSuJL4kziTeJO4k/iUOJR4lLiU+JU4lXi" + "VuJX4ljiWeJa4lviXOJd4l7iX+Jg4mHiYuJj4mTiZeJm4mfiaOJp4mria+Js4m3ibuJv4nDiceJy4nPidOJ14nbid+J44nni" + "euJ74nzifeJ+4n/igOKB4oLig+KE4oXihuKH4ojiieKK4ovijOKN4o7ij+KQ4pHiQ51EnUWdRp1HnUidSZ1KnUudTJ1NnU6d" + "T51QnVGdUp1TnVSdVZ1WnVedWJ1ZnVqdW51cnV2dXp1fnWCdYZ1inWOdZJ1lnWadZ51onWmdap1rnWydbZ1unW+dcJ1xnXKd" + "c510nXWddp13nXideZ16nXudfJ19nX6df52AnYGd//+CnYOdhJ2FnYadh52InYmdip2LnYydjZ2OnY+dkJ2RnZKdk52UnZWd" + "lp2XnZidmZ2anZudnJ2dnZ6dn52gnaGdop2S4pPilOKV4pbil+KY4pnimuKb4pzineKe4p/ioOKh4qLio+Kk4qXipuKn4qji" + "qeKq4qvirOKt4q7ir+Kw4rHisuKz4rTiteK24rfiuOK54rriu+K84r3ivuK/4sDiweLC4sPixOLF4sbix+LI4sniyuLL4szi" + "zeLO4s/i0OLR4tLi0+LU4tXi1uLX4tji2eLa4tvi3OLd4t7i3+Lg4uHi4uLj4uTi5eLm4ufi6OLp4uri6+Ls4u3i7uLv4qOd" + "pJ2lnaadp52onamdqp2rnaydrZ2una+dsJ2xnbKds520nbWdtp23nbiduZ26nbudvJ29nb6dv53AncGdwp3DncSdxZ3Gnced" + "yJ3Jncqdy53Mnc2dzp3PndCd0Z3SndOd1J3Vndad153Yndmd2p3bndyd3Z3end+d4J3hnf//4p3jneSd5Z3mneed6J3pneqd" + "653sne2d7p3vnfCd8Z3ynfOd9J31nfad9534nfmd+p37nfyd/Z3+nf+dAJ4BngKe8OLx4vLi8+L04vXi9uL34vji+eL64vvi" + "/OL94v7i/+IA4wHjAuMD4wTjBeMG4wfjCOMJ4wrjC+MM4w3jDuMP4xDjEeMS4xPjFOMV4xbjF+MY4xnjGuMb4xzjHeMe4x/j" + "IOMh4yLjI+Mk4yXjJuMn4yjjKeMq4yvjLOMt4y7jL+Mw4zHjMuMz4zTjNeM24zfjOOM54zrjO+M84z3jPuM/40DjQeNC40Pj" + "RONF40bjR+NI40njSuNL40zjTeMDngSeBZ4GngeeCJ4JngqeC54Mng2eDp4PnhCeEZ4SnhOeFJ4VnhaeF54YnhmeGp4bnhye" + "HZ4eniSeJ54unjCeNJ47njyeQJ5NnlCeUp5TnlSeVp5Znl2eX55gnmGeYp5lnm6eb55ynnSedZ52nneeeJ55nnqee558nn2e" + "gJ7//4Geg56EnoWehp6JnoqejJ6Nno6ej56QnpGelJ6Vnpael56Ynpmemp6bnpyenp6gnqGeop6jnqSepZ6nnqieqZ6qnk7j" + "T+NQ41HjUuNT41TjVeNW41fjWONZ41rjW+Nc413jXuNf42DjYeNi42PjZONl42bjZ+No42njauNr42zjbeNu42/jcONx43Lj" + "c+N043XjduN343jjeeN643vjfON9437jf+OA44HjguOD44TjheOG44fjiOOJ44rji+OM443jjuOP45DjkeOS45PjlOOV45bj" + "l+OY45njmuOb45zjneOe45/joOOh46Ljo+Ok46XjpuOn46jjqeOq46vjq56snq2erp6vnrCesZ6ynrOetZ62nreeuZ66nrye" + "v57AnsGewp7DnsWexp7Hnsieyp7Lnsye0J7SntOe1Z7Wntee2Z7ant6e4Z7jnuSe5p7onuue7J7tnu6e8J7xnvKe8570nvWe" + "9p73nvie+p79nv+eAJ8BnwKfA58EnwWf//8GnwefCJ8JnwqfDJ8PnxGfEp8UnxWfFp8YnxqfG58cnx2fHp8fnyGfI58knyWf" + "Jp8nnyifKZ8qnyufLZ8unzCfMZ+s463jruOv47DjseOy47PjtOO147bjt+O447njuuO747zjveO+47/jwOPB48Ljw+PE48Xj" + "xuPH48jjyePK48vjzOPN487jz+PQ49Hj0uPT49Tj1ePW49fj2OPZ49rj2+Pc493j3uPf4+Dj4ePi4+Pj5OPl4+bj5+Po4+nj" + "6uPr4+zj7ePu4+/j8OPx4/Lj8+P04/Xj9uP34/jj+eP64/vj/OP94/7j/+MA5AHkAuQD5ATkBeQG5AfkCOQJ5DKfM580nzWf" + "Np84nzqfPJ8/n0CfQZ9Cn0OfRZ9Gn0efSJ9Jn0qfS59Mn02fTp9Pn1KfU59Un1WfVp9Xn1ifWZ9an1ufXJ9dn16fX59gn2Gf" + "Yp9jn2SfZZ9mn2efaJ9pn2qfa59sn22fbp9vn3CfcZ9yn3OfdJ91n3afd594n///eZ96n3uffJ99n36fgZ+Cn42fjp+Pn5Cf" + "kZ+Sn5OflJ+Vn5afl5+Yn5yfnZ+en6Gfop+jn6SfpZ8s+Xn5lfnn+fH5CuQL5AzkDeQO5A/kEOQR5BLkE+QU5BXkFuQX5Bjk" + "GeQa5BvkHOQd5B7kH+Qg5CHkIuQj5CTkJeQm5CfkKOQp5CrkK+Qs5C3kLuQv5DDkMeQy5DPkNOQ15DbkN+Q45DnkOuQ75Dzk" + "PeQ+5D/kQORB5ELkQ+RE5EXkRuRH5EjkSeRK5EvkTORN5E7kT+RQ5FHkUuRT5FTkVeRW5FfkWORZ5FrkW+Rc5F3kXuRf5GDk" + "YeRi5GPkZORl5GbkZ+QM+g36DvoP+hH6E/oU+hj6H/og+iH6I/ok+if6KPop+oEuFugX6BjohC5zNEc0iC6LLh7onjUaNg42" + "jC6XLm45GDkm6M853zlzOtA5K+gs6E47bjzgPKcuMegy6KouVkBfQa4uN0OzLrYuty476LFDrEO7Lt1D1kRhRkxGQ+j//yNH" + "KUd8R41Hyi5HSXpJfUmCSYNJhUmGSZ9Jm0m3SbZJVOhV6KNMn0ygTKFMd0yiTBNNFE0VTRZNF00YTRlNrk1k6GjkaeRq5Gvk" + "bORt5G7kb+Rw5HHkcuRz5HTkdeR25HfkeOR55Hrke+R85H3kfuR/5IDkgeSC5IPkhOSF5Ibkh+SI5InkiuSL5IzkjeSO5I/k" + "kOSR5JLkk+SU5JXkluSX5JjkmeSa5JvknOSd5J7kn+Sg5KHkouSj5KTkpeSm5KfkqOSp5Krkq+Ss5K3kruSv5LDkseSy5LPk" + "tOS15Lbkt+S45LnkuuS75LzkveS+5L/kwOTB5MLkw+TE5MXk" +) +GB18030_ENC_EXC = {} +GB18030_ENC_REJECT = frozenset() + +GB18030_RANGES = ((0x80, 0xA3, 0), (0xA5, 0xA6, 36), (0xA9, 0xAF, 38), (0xB2, 0xB6, 45), (0xB8, 0xD6, 50), (0xD8, 0xDF, 81), (0xE2, 0xE7, 89), (0xEB, 0xEB, 95), (0xEE, 0xF1, 96), (0xF4, 0xF6, 100), (0xF8, 0xF8, 103), (0xFB, 0xFB, 104), (0xFD, 0x100, 105), (0x102, 0x112, 109), (0x114, 0x11A, 126), (0x11C, 0x12A, 133), (0x12C, 0x143, 148), (0x145, 0x147, 172), (0x149, 0x14C, 175), (0x14E, 0x16A, 179), (0x16C, 0x1CD, 208), (0x1CF, 0x1CF, 306), (0x1D1, 0x1D1, 307), (0x1D3, 0x1D3, 308), (0x1D5, 0x1D5, 309), (0x1D7, 0x1D7, 310), (0x1D9, 0x1D9, 311), (0x1DB, 0x1DB, 312), (0x1DD, 0x1F8, 313), (0x1FA, 0x250, 341), (0x252, 0x260, 428), (0x262, 0x2C6, 443), (0x2C8, 0x2C8, 544), (0x2CC, 0x2D8, 545), (0x2DA, 0x390, 558), (0x3A2, 0x3A2, 741), (0x3AA, 0x3B0, 742), (0x3C2, 0x3C2, 749), (0x3CA, 0x400, 750), (0x402, 0x40F, 805), (0x450, 0x450, 819), (0x452, 0x200F, 820), (0x2011, 0x2012, 7922), (0x2017, 0x2017, 7924), (0x201A, 0x201B, 7925), (0x201E, 0x2024, 7927), (0x2027, 0x202F, 7934), (0x2031, 0x2031, 7943), (0x2034, 0x2034, 7944), (0x2036, 0x203A, 7945), (0x203C, 0x20AB, 7950), (0x20AD, 0x2102, 8062), (0x2104, 0x2104, 8148), (0x2106, 0x2108, 8149), (0x210A, 0x2115, 8152), (0x2117, 0x2120, 8164), (0x2122, 0x215F, 8174), (0x216C, 0x216F, 8236), (0x217A, 0x218F, 8240), (0x2194, 0x2195, 8262), (0x219A, 0x2207, 8264), (0x2209, 0x220E, 8374), (0x2210, 0x2210, 8380), (0x2212, 0x2214, 8381), (0x2216, 0x2219, 8384), (0x221B, 0x221C, 8388), (0x2221, 0x2222, 8390), (0x2224, 0x2224, 8392), (0x2226, 0x2226, 8393), (0x222C, 0x222D, 8394), (0x222F, 0x2233, 8396), (0x2238, 0x223C, 8401), (0x223E, 0x2247, 8406), (0x2249, 0x224B, 8416), (0x224D, 0x2251, 8419), (0x2253, 0x225F, 8424), (0x2262, 0x2263, 8437), (0x2268, 0x226D, 8439), (0x2270, 0x2294, 8445), (0x2296, 0x2298, 8482), (0x229A, 0x22A4, 8485), (0x22A6, 0x22BE, 8496), (0x22C0, 0x2311, 8521), (0x2313, 0x245F, 8603), (0x246A, 0x2473, 8936), (0x249C, 0x24FF, 8946), (0x254C, 0x254F, 9046), (0x2574, 0x2580, 9050), (0x2590, 0x2592, 9063), (0x2596, 0x259F, 9066), (0x25A2, 0x25B1, 9076), (0x25B4, 0x25BB, 9092), (0x25BE, 0x25C5, 9100), (0x25C8, 0x25CA, 9108), (0x25CC, 0x25CD, 9111), (0x25D0, 0x25E1, 9113), (0x25E6, 0x2604, 9131), (0x2607, 0x2608, 9162), (0x260A, 0x263F, 9164), (0x2641, 0x2641, 9218), (0x2643, 0x2E80, 9219), (0x2E82, 0x2E83, 11329), (0x2E85, 0x2E87, 11331), (0x2E89, 0x2E8A, 11334), (0x2E8D, 0x2E96, 11336), (0x2E98, 0x2EA6, 11346), (0x2EA8, 0x2EA9, 11361), (0x2EAB, 0x2EAD, 11363), (0x2EAF, 0x2EB2, 11366), (0x2EB4, 0x2EB5, 11370), (0x2EB8, 0x2EBA, 11372), (0x2EBC, 0x2EC9, 11375), (0x2ECB, 0x2FEF, 11389), (0x2FFC, 0x2FFF, 11682), (0x3004, 0x3004, 11686), (0x3018, 0x301C, 11687), (0x301F, 0x3020, 11692), (0x302A, 0x303D, 11694), (0x303F, 0x3040, 11714), (0x3094, 0x309A, 11716), (0x309F, 0x30A0, 11723), (0x30F7, 0x30FB, 11725), (0x30FF, 0x3104, 11730), (0x312A, 0x321F, 11736), (0x322A, 0x3230, 11982), (0x3232, 0x32A2, 11989), (0x32A4, 0x338D, 12102), (0x3390, 0x339B, 12336), (0x339F, 0x33A0, 12348), (0x33A2, 0x33C3, 12350), (0x33C5, 0x33CD, 12384), (0x33CF, 0x33D0, 12393), (0x33D3, 0x33D4, 12395), (0x33D6, 0x3446, 12397), (0x3448, 0x3472, 12510), (0x3474, 0x359D, 12553), (0x359F, 0x360D, 12851), (0x360F, 0x3619, 12962), (0x361B, 0x3917, 12973), (0x3919, 0x396D, 13738), (0x396F, 0x39CE, 13823), (0x39D1, 0x39DE, 13919), (0x39E0, 0x3A72, 13933), (0x3A74, 0x3B4D, 14080), (0x3B4F, 0x3C6D, 14298), (0x3C6F, 0x3CDF, 14585), (0x3CE1, 0x4055, 14698), (0x4057, 0x415E, 15583), (0x4160, 0x4336, 15847), (0x4338, 0x43AB, 16318), (0x43AD, 0x43B0, 16434), (0x43B2, 0x43DC, 16438), (0x43DE, 0x44D5, 16481), (0x44D7, 0x464B, 16729), (0x464D, 0x4660, 17102), (0x4662, 0x4722, 17122), (0x4724, 0x4728, 17315), (0x472A, 0x477B, 17320), (0x477D, 0x478C, 17402), (0x478E, 0x4946, 17418), (0x4948, 0x4979, 17859), (0x497B, 0x497C, 17909), (0x497E, 0x4981, 17911), (0x4984, 0x4984, 17915), (0x4987, 0x499A, 17916), (0x499C, 0x499E, 17936), (0x49A0, 0x49B5, 17939), (0x49B8, 0x4C76, 17961), (0x4C78, 0x4C9E, 18664), (0x4CA4, 0x4D12, 18703), (0x4D1A, 0x4DAD, 18814), (0x4DAF, 0x4DFF, 18962), (0x9FA6, 0xD7FF, 19043), (0xE76C, 0xE76C, 33469), (0xE7C8, 0xE7C8, 33470), (0xE7E7, 0xE7F3, 33471), (0xE815, 0xE815, 33484), (0xE819, 0xE81D, 33485), (0xE81F, 0xE825, 33490), (0xE827, 0xE82A, 33497), (0xE82D, 0xE830, 33501), (0xE833, 0xE83A, 33505), (0xE83C, 0xE842, 33513), (0xE844, 0xE853, 33520), (0xE856, 0xE863, 33536), (0xE865, 0xF92B, 33550), (0xF92D, 0xF978, 37845), (0xF97A, 0xF994, 37921), (0xF996, 0xF9E6, 37948), (0xF9E8, 0xF9F0, 38029), (0xF9F2, 0xFA0B, 38038), (0xFA10, 0xFA10, 38064), (0xFA12, 0xFA12, 38065), (0xFA15, 0xFA17, 38066), (0xFA19, 0xFA1E, 38069), (0xFA22, 0xFA22, 38075), (0xFA25, 0xFA26, 38076), (0xFA2A, 0xFE2F, 38078), (0xFE32, 0xFE32, 39108), (0xFE45, 0xFE48, 39109), (0xFE53, 0xFE53, 39113), (0xFE58, 0xFE58, 39114), (0xFE67, 0xFE67, 39115), (0xFE6C, 0xFF00, 39116), (0xFF5F, 0xFFDF, 39265), (0xFFE6, 0xFFFF, 39394)) + +# ---- big5 ---- +BIG5_DEC = _g( + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////8AMAz/ATACMA7/IiAb/xr/" + "H/8B/zD+JiAlIFD+ZP9S/rcAVP5V/lb+V/5c/xMgMf4UIDP+dCU0/k/+CP8J/zX+Nv5b/13/N/44/hQwFTA5/jr+EDARMDv+" + "PP4KMAswPf4+/ggwCTA//kD+DDANMEH+Qv4OMA8wQ/5E/ln+Wv7/////////////////////////////////////////////" + "/////////////////////////////////////////////1v+XP5d/l7+GCAZIBwgHSAdMB4wNSAyIAP/Bv8K/zsgpwADMMsl" + "zyWzJbIlziUGJgUmxyXGJaEloCW9JbwlozIFIT4g4/8//80CSf5K/k3+Tv5L/kz+X/5g/mH+C/8N/9cA9wCxABoiHP8e/x3/" + "ZiJnImAiHiJSImEiYv5j/mT+Zf5m/jwiKSIqIqUiICIfIr8i0jPRMysiLiI1IjQiQCZCJkEmCSaRIZMhkCGSIZYhlyGZIZgh" + "JSIjIg//PP8P/zz/BP+lABIwogCjAAX/IP8DIQkhaf5q/mv+1TOcM50znjPOM6EzjjOPM8QzsABZUVtRXlFdUWFRY1HnVel0" + "znyBJYIlgyWEJYUlhiWHJYgljyWOJY0ljCWLJYoliSU8JTQlLCUkJRwllCUAJQIllSUMJRAlFCUYJW0l////////////////" + "//////////////////////////////////////////////////////////////////////////9uJXAlbyVQJV4laiVhJeIl" + "4yXlJeQlcSVyJXMlEP8R/xL/E/8U/xX/Fv8X/xj/Gf9gIWEhYiFjIWQhZSFmIWchaCFpISEwIjAjMCQwJTAmMCcwKDApMEFT" + "RFNFUyH/Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov9B/0L/Q/9E/0X/Rv9H/0j/" + "Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MD" + "pAOlA6YDpwOoA6kDsQOyA7MDtAO1A7YDtwO4A7kDugO7A7wDvQO+A78DwAPBA8MDxAPFA8YDxwPIA8kDBTEGMQcxCDEJMQox" + "CzEMMQ0xDjEPMf//////////////////////////////////////////////////////////////////////////////////" + "////////EDERMRIxEzEUMRUxFjEXMRgxGTEaMRsxHDEdMR4xHzEgMSExIjEjMSQxJTEmMScxKDEpMdkCyQLKAscCywL/////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////8ATllOAU4DTkNOXU6GToxOuk4/UWVR" + "a1HgUQBSAVKbUhVTQVNcU8hTCU4LTghOCk4rTjhO4VFFTkhOX05eTo5OoU5AUQNS+lJDU8lT41MfV+tYFVknWXNZUFtRW1Nb" + "+FsPXCJcOFxxXN1d5V3xXfJd813+XXJe/l4LXxNfTWL/////////////////////////////////////////////////////" + "/////////////////////////////////////xFOEE4NTi1OME45TktOOVyITpFOlU6STpROok7BTsBOw07GTsdOzU7KTstO" + "xE5DUUFRZ1FtUW5RbFGXUfZRBlIHUghS+1L+Uv9SFlM5U0hTR1NFU15ThFPLU8pTzVPsWClZK1kqWS1ZVFsRXCRcOlxvXPRd" + "e17/XhRfFV/DXwhiNmJLYk5iL2WHZZdlpGW5ZeVl8GYIZyhnIGtia3lry2vUa9trD2w0bGtwKnI2cjtyR3JZcltyrHKLcxlO" + "Fk4VThROGE47Tk1OT05OTuVO2E7UTtVO1k7XTuNO5E7ZTt5ORVFEUYlRilGsUflR+lH4UQpSoFKfUgVTBlMXUx1T305KU0lT" + "YVNgU29TblO7U+9T5FPzU+xT7lPpU+hT/FP4U/VT61PmU+pT8lPxU/BT5VPtU/tT21baVhZZ////////////////////////" + "//////////////////////////////////////////////////////////////////8uWTFZdFl2WVVbg1s8XOhd513mXQJe" + "A15zXnxeAV8YXxdfxV8KYlNiVGJSYlFipWXmZS5nLGcqZytnLWdja81rEWwQbDhsQWxAbD5sr3KEc4lz3HTmdBh1H3UodSl1" + "MHUxdTJ1M3WLdX12rna/du5223fid/N3Onm+eXR6y3oeTh9OUk5TTmlOmU6kTqZOpU7/TglPGU8KTxVPDU8QTxFPD0/yTvZO" + "+07wTvNO/U4BTwtPSVFHUUZRSFFoUXFRjVGwURdSEVISUg5SFlKjUghTIVMgU3BTcVMJVA9UDFQKVBBUAVQLVARUEVQNVAhU" + "A1QOVAZUElTgVt5W3VYzVzBXKFctVyxXL1cpVxlZGlk3WThZhFl4WYNZfVl5WYJZgVlXW1hbh1uIW4VbiVv6WxZceVzeXQZe" + "dl50Xv//////////////////////////////////////////////////////////////////////////////////////////" + "D18bX9lf1l8OYgxiDWIQYmNiW2JYYjZl6WXoZexl7WXyZvNmCWc9ZzRnMWc1ZyFrZGt7axZsXWxXbFlsX2xgbFBsVWxhbFts" + "TWxObHBwX3Jdcn52+XpzfPh8Nn+Kf71/AYADgAyAEoAzgH+AiYCLgIyA44HqgfOB/IEMghuCH4JugnKCfoJrhkCITIhjiH+J" + "IZYyTqhOTU9PT0dPV09eTzRPW09VTzBPUE9RTz1POk84T0NPVE88T0ZPY09cT2BPL09OTzZPWU9dT0hPWk9MUUtRTVF1UbZR" + "t1ElUiRSKVIqUihSq1KpUqpSrFIjU3NTdVMdVC1UHlQ+VCZUTlQnVEZUQ1QzVEhUQlQbVClUSlQ5VDtUOFQuVDVUNlQgVDxU" + "QFQxVCtUH1QsVOpW8FbkVutWSldRV0BXTVf/////////////////////////////////////////////////////////////" + "/////////////////////////////0dXTlc+V1BXT1c7V+9YPlmdWZJZqFmeWaNZmVmWWY1ZpFmTWYpZpVldW1xbWltbW4xb" + "i1uPWyxcQFxBXD9cPlyQXJFclFyMXOtdDF6PXodeil73XgRfH19kX2Jfd195X9hfzF/XX81f8V/rX/hf6l8SYhFihGKXYpZi" + "gGJ2YolibWKKYnxifmJ5YnNikmJvYphibmKVYpNikWKGYjllO2U4ZfFl9GZfZ05nT2dQZ1FnXGdWZ15nSWdGZ2BnU2dXZ2Vr" + "z2tCbF5smWyBbIhsiWyFbJtsamx6bJBscGyMbGhslmySbH1sg2xybH5sdGyGbHZsjWyUbJhsgmx2cHxwfXB4cGJyYXJgcsRy" + "wnKWcyx1K3U3dTh1gnbvduN3wXnAeb95dnr7fFV/loCTgJ2AmICbgJqAsoBvgpKC////////////////////////////////" + "//////////////////////////////////////////////////////////+Lgo2Ci4nSiQCKN4xGjFWMnYxkjXCNs42rjsqO" + "m4+wj8KPxo/Fj8SP4V2RkKKQqpCmkKOQSZHGkcyRMpYuljGWKpYsliZOVk5zTotOm06eTqtOrE5vT51PjU9zT39PbE+bT4tP" + "hk+DT3BPdU+IT2lPe0+WT35Pj0+RT3pPVFFSUVVRaVF3UXZReFG9Uf1RO1I4UjdSOlIwUi5SNlJBUr5Su1JSU1RTU1NRU2ZT" + "d1N4U3lT1lPUU9dTc1R1VJZUeFSVVIBUe1R3VIRUklSGVHxUkFRxVHZUjFSaVGJUaFSLVH1UjlT6VoNXd1dqV2lXYVdmV2RX" + "fFccWUlZR1lIWURZVFm+WbtZ1Fm5Wa5Z0VnGWdBZzVnLWdNZylmvWbNZ0lnFWV9bZFtjW5dbmluYW5xbmVubWxpcSFxFXP//" + "////////////////////////////////////////////////////////////////////////////////////////Rly3XKFc" + "uFypXKtcsVyzXBheGl4WXhVeG14RXnheml6XXpxelV6WXvZeJl8nXylfgF+BX39ffF/dX+Bf/V/1X/9fD2AUYC9gNWAWYCpg" + "FWAhYCdgKWArYBtgFmIVYj9iPmJAYn9iyWLMYsRiv2LCYrli0mLbYqti02LUYstiyGKoYr1ivGLQYtlix2LNYrVi2mKxYthi" + "1mLXYsZirGLOYj5lp2W8ZfplFGYTZgxmBmYCZg5mAGYPZhVmCmYHZg1nC2dtZ4tnlWdxZ5xnc2d3Z4dnnWeXZ29ncGd/Z4ln" + "fmeQZ3VnmmeTZ3xnamdyZyNrZmtna39rE2wbbONs6GzzbLFszGzlbLNsvWy+bLxs4myrbNVs02y4bMRsuWzBbK5s12zFbPFs" + "v2y7bOFs22zKbKxs72zcbNZs4Gz/////////////////////////////////////////////////////////////////////" + "/////////////////////5VwjnCScIpwmXAsci1yOHJIcmdyaXLAcs5y2XLXctByqXOoc59zq3Olcz11nXWZdZp1hHbCdvJ2" + "9Hbld/13PnlAeUF5yXnIeXp6eXr6ev58VH+Mf4t/BYC6gKWAooCxgKGAq4CpgLSAqoCvgOWB/oENgrOCnYKZgq2CvYKfgrmC" + "sYKsgqWCr4K4gqOCsIK+greCToZxhh1SaIjLjs6P1I/Rj7WQuJCxkLaQx5HRkXeVgJUclkCWP5Y7lkSWQpa5luiWUpdel59O" + "rU6uTuFPtU+vT79P4E/RT89P3U/DT7ZP2E/fT8pP10+uT9BPxE/CT9pPzk/eT7dPV1GSUZFRoFFOUkNSSlJNUkxSS1JHUsdS" + "yVLDUsFSDVNXU3tTmlPbU6xUwFSoVM5UyVS4VKZUs1THVMJUvVSqVMFU////////////////////////////////////////" + "///////////////////////////////////////////////////EVMhUr1SrVLFUu1SpVKdUv1T/VoJXi1egV6NXolfOV65X" + "k1dVWVFZT1lOWVBZ3FnYWf9Z41noWQNa5VnqWdpZ5lkBWvtZaVujW6ZbpFuiW6VbAVxOXE9cTVxLXNlc0lz3XR1eJV4fXn1e" + "oF6mXvpeCF8tX2VfiF+FX4pfi1+HX4xfiV8SYB1gIGAlYA5gKGBNYHBgaGBiYEZgQ2BsYGtgamBkYEFi3GIWYwlj/GLtYgFj" + "7mL9Ygdj8WL3Yu9i7GL+YvRiEWMCYz9lRWWrZb1l4mUlZi1mIGYnZi9mH2YoZjFmJGb3Zv9n02fxZ9Rn0GfsZ7Znr2f1Z+ln" + "72fEZ9FntGfaZ+VnuGfPZ95n82ewZ9ln4mfdZ9JnamuDa4ZrtWvSa9drH2zJbAttMm0qbUFtJW0MbTFtHm0Xbf//////////" + "////////////////////////////////////////////////////////////////////////////////O209bT5tNm0bbfVs" + "OW0nbThtKW0ubTVtDm0rbatwunCzcKxwr3CtcLhwrnCkcDBycnJvcnRy6XLgcuFyt3PKc7tzsnPNc8Bzs3MadS11T3VMdU51" + "S3WrdaR1pXWidaN1eHaGdod2iHbIdsZ2w3bFdgF3+Xb4dgl3C3f+dvx2B3fcdwJ4FHgMeA14RnlJeUh5R3m5ebp50XnSect5" + "f3qBev96/Xp9fAJ9BX0AfQl9B30EfQZ9OH+Of79/BIAQgA2AEYA2gNaA5YDagMOAxIDMgOGA24DOgN6A5IDdgPSBIoLnggOD" + "BYPjgtuC5oIEg+WCAoMJg9KC14LxggGD3ILUgtGC3oLTgt+C74IGg1CGeYZ7hnqGTYhriIGJ1IkIigKKA4qejKCMdI1zjbSN" + "zY7MjvCP5o/ij+qP5Y//////////////////////////////////////////////////////////////////////////////" + "/////////////+2P64/kj+iPypDOkMGQw5BLkUqRzZGClVCWS5ZMlk2WYpdpl8uX7ZfzlwGYqJjbmN+YlpmZmVhOs04MUA1Q" + "I1DvTyZQJVD4TylQFlAGUDxQH1AaUBJQEVD6TwBQFFAoUPFPIVALUBlQGFDzT+5PLVAqUP5PK1AJUHxRpFGlUaJRzVHMUcZR" + "y1FWUlxSVFJbUl1SKlN/U59TnVPfU+hUEFUBVTdV/FTlVPJUBlX6VBRV6VTtVOFUCVXuVOpU5lQnVQdV/VQPVQNXBFfCV9RX" + "y1fDVwlYD1lXWVhZWlkRWhhaHFofWhtaE1rsWSBaI1opWiVaDFoJWmtbWFywW7Nbtlu0W65btVu5W7hbBFxRXFVcUFztXP1c" + "+1zqXOhc8Fz2XAFd9FzuXS1eK16rXq1ep14xX5JfkV+QX1lg////////////////////////////////////////////////" + "//////////////////////////////////////////9jYGVgUGBVYG1gaWBvYIRgn2CaYI1glGCMYIVglmBHYvNiCGP/Yk5j" + "PmMvY1VjQmNGY09jSWM6Y1BjPWMqYytjKGNNY0xjSGVJZZllwWXFZUJmSWZPZkNmUmZMZkVmQWb4ZhRnFWcXZyFoOGhIaEZo" + "U2g5aEJoVGgpaLNoF2hMaFFoPWj0Z1BoQGg8aENoKmhFaBNoGGhBaIpriWu3ayNsJ2wobCZsJGzwbGptlW2IbYdtZm14bXdt" + "WW2TbWxtiW1ubVptdG1pbYxtim15bYVtZW2Ubcpw2HDkcNlwyHDPcDlyeXL8cvly/XL4cvdyhnPtcwl07nPgc+pz3nNUdV11" + "XHVadVl1vnXFdcd1snWzdb11vHW5dcJ1uHWLdrB2ynbNds52KXcfdyB3KHfpdzB4J3g4eB14NHg3eP//////////////////" + "////////////////////////////////////////////////////////////////////////JXgteCB4H3gyeFV5UHlgeV95" + "VnleeV15V3laeeR543nned955nnpedh5hHqIetl6BnsRe4l8IX0XfQt9Cn0gfSJ9FH0QfRV9Gn0cfQ19GX0bfTp/X3+Uf8V/" + "wX8GgBiAFYAZgBeAPYA/gPGAAoHwgAWB7YD0gAaB+IDzgAiB/YAKgfyA74DtgeyBAIIQgiqCK4IogiyCu4Irg1KDVINKgziD" + "UINJgzWDNINPgzKDOYM2gxeDQIMxgyiDQ4NUhoqGqoaThqSGqYaMhqOGnIZwiHeIgYiCiH2IeYgYihCKDooMihWKCooXihOK" + "FooPihGKSIx6jHmMoYyijHeNrI7SjtSOz46xjwGQBpD3jwCQ+o/0jwOQ/Y8FkPiPlZDhkN2Q4pBSkU2RTJHYkd2R15HckdmR" + "g5VilmOWYZb/////////////////////////////////////////////////////////////////////////////////////" + "/////1uWXZZklliWXpa7luKYrJmomtiaJZsymzybfk56UH1QXFBHUENQTFBaUElQZVB2UE5QVVB1UHRQd1BPUA9Qb1BtUFxR" + "lVHwUWpSb1LSUtlS2FLVUhBTD1MZUz9TQFM+U8NT/GZGVWpVZlVEVV5VYVVDVUpVMVVWVU9VVVUvVWRVOFUuVVxVLFVjVTNV" + "QVVXVQhXC1cJV99XBVgKWAZY4FfkV/pXAlg1WPdX+VcgWWJZNlpBWklaZlpqWkBaPFpiWlpaRlpKWnBbx1vFW8Rbwlu/W8Zb" + "CVwIXAdcYFxcXF1cB10GXQ5dG10WXSJdEV0pXRRdGV0kXSddF13iXTheNl4zXjdet164XrZetV6+XjVfN19XX2xfaV9rX5df" + "mV+eX5hfoV+gX5xff2CjYIlgoGCoYMtgtGDmYL1g////////////////////////////////////////////////////////" + "///////////////////////////////////FYLtgtWDcYLxg2GDVYMZg32C4YNpgx2AaYhtiSGKgY6djcmOWY6JjpWN3Y2dj" + "mGOqY3FjqWOJY4Njm2NrY6hjhGOIY5ljoWOsY5Jjj2OAY3tjaWNoY3pjXWVWZVFlWWVXZV9VT2VYZVVlVGWcZZtlrGXPZctl" + "zGXOZV1mWmZkZmhmZmZeZvlm11IbZ4For2iiaJNotWh/aHZosWinaJdosGiDaMRorWiGaIVolGidaKhon2ihaIJoMmu6a+tr" + "7GsrbI5tvG3zbdltsm3hbcxt5G37bfptBW7Hbcttr23Rba5t3m35bbht9231bcVt0m0abrVt2m3rbdht6m3xbe5t6G3GbcRt" + "qm3sbb9t5m35cAlxCnH9cO9wPXJ9coFyHHMbcxZzE3MZc4dzBXQKdAN0BnT+cw104HT2dP//////////////////////////" + "////////////////////////////////////////////////////////////////93QcdSJ1ZXVmdWJ1cHWPddR11XW1dcp1" + "zXWOdtR20nbbdjd3Pnc8dzZ3OHc6d2t4Q3hOeGV5aHlteft5knqVeiB7KHsbeyx7JnsZex57LnuSfJd8lXxGfUN9cX0ufTl9" + "PH1AfTB9M31EfS99Qn0yfTF9PX+ef5p/zH/Of9J/HIBKgEaAL4EWgSOBK4EpgTCBJIECgjWCN4I2gjmCjoOeg5iDeIOig5aD" + "vYOrg5KDioOTg4mDoIN3g3uDfIOGg6eDVYZqX8eGwIa2hsSGtYbGhsuGsYavhsmGU4ieiIiIq4iSiJaIjYiLiJOJj4kqih2K" + "I4olijGKLYofihuKIopJjFqMqYysjKuMqIyqjKeMZ41mjb6Nuo3bjt+OGZANkBqQF5AjkB+QHZAQkBWQHpAgkA+QIpAWkBuQ" + "FJD//////////////////////////////////////////////////////////////////////////////////////////+iQ" + "7ZD9kFeRzpH1keaR45Hnke2R6ZGJlWqWdZZzlniWcJZ0lnaWd5ZslsCW6pbpluB633oCmAOYWpvlnHWef56lnrueolCNUIVQ" + "mVCRUIBQllCYUJpQAGfxUXJSdFJ1UmlS3lLdUttSWlOlU3tVgFWnVXxVilWdVZhVglWcVapVlFWHVYtVg1WzVa5Vn1U+VbJV" + "mlW7VaxVsVV+VYlVq1WZVQ1XL1gqWDRYJFgwWDFYIVgdWCBY+Vj6WGBZd1qaWn9aklqbWqdac1txW9JbzFvTW9BbClwLXDFc" + "TF1QXTRdR139XUVePV5AXkNefl7KXsFewl7EXjxfbV+pX6pfqF/RYOFgsmC2YOBgHGEjYfpgFWHwYPtg9GBoYfFgDmH2YAlh" + "AGESYR9iSWKjY4xjz2PAY+ljyWPGY81j////////////////////////////////////////////////////////////////" + "///////////////////////////SY+Nj0GPhY9Zj7WPuY3Zj9GPqY9tjUmTaY/ljXmVmZWJlY2WRZZBlr2VuZnBmdGZ2Zm9m" + "kWZ6Zn5md2b+Zv9mH2cdZ/po1WjgaNho12gFad9o9WjuaOdo+WjSaPJo42jLaM1oDWkSaQ5pyWjaaG5p+2g+azprPWuYa5Zr" + "vGvvay5sL2wsbC9uOG5UbiFuMm5nbkpuIG4lbiNuG25bblhuJG5Wbm5uLW4mbm9uNG5NbjpuLG5Dbh1uPm7LboluGW5ObmNu" + "RG5ybmluX24ZcRpxJnEwcSFxNnFucRxxTHKEcoByNnMlczRzKXM6dCp0M3QidCV0NXQ2dDR0L3QbdCZ0KHQldSZ1a3VqdeJ1" + "23Xjddl12HXedeB1e3Z8dpZ2k3a0dtx2T3ftd114bHhveA16CHoLegV6AHqYev//////////////////////////////////" + "////////////////////////////////////////////////////////l3qWeuV643pJe1Z7RntQe1J7VHtNe0t7T3tRe598" + "pXxefVB9aH1VfSt9bn1yfWF9Zn1ifXB9c32EVdR/1X8LgFKAhYBVgVSBS4FRgU6BOYFGgT6BTIFTgXSBEoIcgumDA4T4gw2E" + "4IPFgwuEwYPvg/GD9INXhAqE8IMMhMyD/YPyg8qDOIQOhASE3IMHhNSD34Nbht+G2YbthtSG24bkhtCG3oZXiMGIwoixiIOJ" + "lok7imCKVYpeijyKQYpUiluKUIpGijSKOoo2ilaKYYyCjK+MvIyzjL2MwYy7jMCMtIy3jLaMv4y4jIqNhY2Bjc6N3Y3LjdqN" + "0Y3MjduNxo37jviO/I6cjy6QNZAxkDiQMpA2kAKR9ZAJkf6QY5Flkc+RFJIVkiOSCZIekg2SEJIHkhGSlJWPlYuVkZX/////" + "/////////////////////////////////////////////////////////////////////////////////////5OVkpWOlYqW" + "jpaLln2WhZaGlo2WcpaElsGWxZbElsaWx5bvlvKWzJcFmAaYCJjnmOqY75jpmPKY7Ziuma2Zw57NntGegk6tULVQslCzUMVQ" + "vlCsULdQu1CvUMdQf1J3Un1S31LmUuRS4lLjUi9T31XoVdNV5lXOVdxVx1XRVeNV5FXvVdpV4VXFVcZV5VXJVRJXE1deWFFY" + "WFhXWFpYVFhrWExYbVhKWGJYUlhLWGdZwVrJWsxavlq9Wrxas1rCWrJaaV1vXUxeeV7JXsheEl9ZX6xfrl8aYQ9hSGEfYfNg" + "G2H5YAFhCGFOYUxhRGFNYT5hNGEnYQ1hBmE3YSFiImITZD5kHmQqZC1kPWQsZA9kHGQUZA1kNmQWZBdkBmRsZZ9lsGWXZolm" + "h2aIZpZmhGaYZo1mA2eUaW1p////////////////////////////////////////////////////////////////////////" + "//////////////////9aaXdpYGlUaXVpMGmCaUppaGlraV5pU2l5aYZpXWljaVtpR2tya8Brv2vTa/1rom6vbtNutm7CbpBu" + "nW7HbsVupW6Ybrxuum6rbtFulm6cbsRu1G6qbqdutG5OcVlxaXFkcUlxZ3FccWxxZnFMcWVxXnFGcWhxVnE6clJyN3NFcz9z" + "PnNvdFp0VXRfdF50QXQ/dFl0W3RcdHZ1eHUAdvB1AXbydfF1+nX/dfR183Xedt92W3drd2Z3Xndjd3l3andsd1x3ZXdod2J3" + "7neOeLB4l3iYeIx4iXh8eJF4k3h/eHp5f3mBeSyEvXkcehp6IHoUeh96HnqfeqB6d3vAe2B7bntne7F8s3y1fJN9eX2RfYF9" + "j31bfW5/aX9qf3J/qX+of6R/VoBYgIaAhIBxgXCBeIFlgW6Bc4Frgf//////////////////////////////////////////" + "////////////////////////////////////////////////eYF6gWaBBYJHgoKEd4Q9hDGEdYRmhGuESYRshFuEPIQ1hGGE" + "Y4RphG2ERoRehlyGX4b5hhOHCIcHhwCH/ob7hgKHA4cGhwqHWYjfiNSI2YjciNiI3YjhiMqI1YjSiJyJ44lrinKKc4pmimmK" + "cIqHinyKY4qginGKhYptimKKbopsinmKe4o+imiKYoyKjImMyozHjMiMxIyyjMOMwozFjOGN343oje+N8436jeqN5I3mjbKO" + "A48Jj/6OCo+fj7KPS5BKkFOQQpBUkDyQVZBQkEeQT5BOkE2QUZA+kEGQEpEXkWyRapFpkcmRN5JXkjiSPZJAkj6SW5JLkmSS" + "UZI0kkmSTZJFkjmSP5JakpiVmJaUlpWWzZbLlsmWypb3lvuW+Zb2llaXdJd2lxCYEZgTmAqYEpgMmPyY9Jj/////////////" + "//////////////////////////////////////////////////////////////////////////////2Y/pizmbGZtJnhmumc" + "gp4OnxOfIJ/nUO5Q5VDWUO1Q2lDVUM9Q0VDxUM5Q6VBiUfNRg1KCUjFTrVP+VQBWG1YXVv1VFFYGVglWDVYOVvdVFlYfVghW" + "EFb2VRhXFld1WH5Yg1iTWIpYeViFWH1Y/VglWSJZJFlqWWlZ4VrmWula11rWWtha41p1W95b51vhW+Vb5lvoW+Jb5FvfWw1c" + "YlyEXYddW15jXlVeV15UXtNe1l4KX0ZfcF+5X0dhP2FLYXdhYmFjYV9hWmFYYXVhKmKHZFhkVGSkZHhkX2R6ZFFkZ2Q0ZG1k" + "e2RyZaFl12XWZaJmqGadZpxpqGmVacFprmnTactpm2m3abtpq2m0adBpzWmtacxppmnDaaNpSWtMazNsM28Ub/5uE2/0bilv" + "Pm8gbyxvD28CbyJv////////////////////////////////////////////////////////////////////////////////" + "////////////bu9uBm8xbzhvMm8jbxVvK28vb4hvKm/sbgFv8m7MbvdulHGZcX1xinGEcZJxPnKScpZyRHNQc2R0Y3RqdHB0" + "bXQEdZF1J3YNdgt2CXYTduF243aEd313f3dhd8F4n3ineLN4qXijeI55j3mNeS56MXqqeql67XrveqF7lXuLe3V7l3ude5R7" + "j3u4e4d7hHu5fL18vny7fbB9nH29fb59oH3KfbR9sn2xfbp9on2/fbV9uH2tfdJ9x32sfXB/4H/hf99/XoBagIeAUIGAgY+B" + "iIGKgX+BgoHngfqBB4IUgh6CS4LJhL+ExoTEhJmEnoSyhJyEy4S4hMCE04SQhLyE0YTKhD+HHIc7hyKHJYc0hxiHVYc3hymH" + "84gCifSI+Yj4iP2I6Igaie+IpoqMip6Ko4qNiqGKk4qkiv//////////////////////////////////////////////////" + "////////////////////////////////////////qoqliqiKmIqRipqKp4pqjI2MjIzTjNGM0oxrjZmNlY38jRSPEo8VjxOP" + "o49gkFiQXJBjkFmQXpBikF2QW5AZkRiRHpF1kXiRd5F0kXiSgJKFkpiSlpJ7kpOSnJKoknySkZKhlaiVqZWjlaWVpJWZlpyW" + "m5bMltKWAJd8l4WX9pcXmBiYr5ixmAOZBZkMmQmZwZmvmrCa5ppBm0Kb9Jz2nPOcvJ47n0qfBFEAUftQ9VD5UAJRCFEJUQVR" + "3FGHUohSiVKNUopS8FKyUy5WO1Y5VjJWP1Y0VilWU1ZOVldWdFY2Vi9WMFaAWJ9YnlizWJxYrlipWKZYbVkJW/taC1v1Wgxb" + "CFvuW+xb6VvrW2RcZVydXZRdYl5fXmFe4l7aXt9e3V7jXuBeSF9xX7dftV92YWdhbmFdYVVhgmH/////////////////////" + "/////////////////////////////////////////////////////////////////////3xhcGFrYX5hp2GQYathjmGsYZph" + "pGGUYa5hLmJpZG9keWSeZLJkiGSQZLBkpWSTZJVkqWSSZK5krWSrZJpkrGSZZKJks2R1ZXdleGWuZqtmtGaxZiNqH2roaQFq" + "HmoZav1pIWoTagpq82kCagVq7WkRalBrTmuka8Vrxms/b3xvhG9Rb2ZvVG+Gb21vW294b25vjm96b3BvZG+Xb1hv1W5vb2Bv" + "X2+fcaxxsXGocVZym3JOc1dzaXSLdIN0fnSAdH91IHYpdh92JHYmdiF2Inaadrp25HaOd4d3jHeRd4t3y3jFeLp4yni+eNV4" + "vHjQeD96PHpAej16N3o7eq96rnqte7F7xHu0e8Z7x3vBe6B7zHvKfOB99H3vfft92H3sfd196H3jfdp93n3pfZ592X3yffl9" + "dX93f69/////////////////////////////////////////////////////////////////////////////////////////" + "///pfyaAm4GcgZ2BoIGagZiBF4U9hRqF7oQshS2FE4URhSOFIYUUheyEJYX/hAaFgod0h3aHYIdmh3iHaIdZh1eHTIdTh1uI" + "XYgQiQeJEokTiRWJCom8itKKx4rEipWKy4r4irKKyYrCir+KsIrWis2Ktoq5ituKTIxOjGyM4IzejOaM5IzsjO2M4ozjjNyM" + "6ozhjG2Nn42jjSuOEI4djiKOD44pjh+OIY4ejrqOHY8bjx+PKY8mjyqPHI8ejyWPaZBukGiQbZB3kDCRLZEnkTGRh5GJkYuR" + "g5HFkruSt5LqkqyS5JLBkrOSvJLSkseS8JKykq2VsZUElwaXB5cJl2CXjZeLl4+XIZgrmByYs5gKmROZEpkYmd2Z0JnfmduZ" + "0ZnVmdKZ2Zm3mu6a75onm0WbRJt3m2+bBp0Jnf//////////////////////////////////////////////////////////" + "////////////////////////////////A52pnr6ezp6oWFKfElEYURRREFEVUYBRqlHdUZFSk1LzUllWa1Z5VmlWZFZ4VmpW" + "aFZlVnFWb1ZsVmJWdlbBWL5Yx1jFWG5ZHVs0W3hb8FsOXEpfsmGRYalhimHNYbZhvmHKYchhMGLFZMFky2S7ZLxk2mTEZMdk" + "wmTNZL9k0mTUZL5kdGXGZslmuWbEZsdmuGY9ajhqOmpZamtqWGo5akRqYmphaktqR2o1al9qSGpZa3drBWzCb7FvoW/Db6Rv" + "wW+nb7NvwG+5b7Zvpm+gb7RvvnHJcdBx0nHIcdVxuXHOcdlx3HHDccRxaHOcdKN0mHSfdJ504nQMdQ11NHY4djp253bldqB3" + "nnefd6V36HjaeOx453imeU16TnpGekx6S3q6etl7EXzJe+R723vhe+l75nvVfNZ8Cn7/////////////////////////////" + "/////////////////////////////////////////////////////////////xF+CH4bfiN+Hn4dfgl+EH55f7J/8H/xf+5/" + "KICzgamBqIH7gQiCWIJZgkqFWYVIhWiFaYVDhUmFbYVqhV6Fg4efh56HooeNh2GIKokyiSWJK4khiaqJponmivqK64rxigCL" + "3Irniu6K/ooBiwKL94rtivOK9or8imuMbYyTjPSMRI4xjjSOQo45jjWOO48vjziPM4+oj6aPdZB0kHiQcpB8kHqQNJGSkSCT" + "NpP4kjOTL5Mik/ySK5MEkxqTEJMmkyGTFZMukxmTu5WnlqiWqpbVlg6XEZcWlw2XE5cPl1uXXJdml5iXMJg4mDuYN5gtmDmY" + "JJgQmSiZHpkbmSGZGpntmeKZ8Zm4mrya+5rtmiibkZsVnSOdJp0onRKdG53YntSejZ+cnypRH1EhUTJR9VKOVoBWkFaFVodW" + "//////////////////////////////////////////////////////////////////////////////////////////+PVtVY" + "01jRWM5YMFsqWyRbels3XGhcvF26Xb1duF1rXkxfvV/JYcJhx2HmYcthMmI0Ys5kymTYZOBk8GTmZOxk8WTiZO1kgmWDZdlm" + "1maAapRqhGqiapxq22qjan5ql2qQaqBqXGuua9prCGzYb/Fv32/gb9tv5G/rb+9vgG/sb+Fv6W/Vb+5v8G/ncd9x7nHmceVx" + "7XHscfRx4HE1ckZycHNyc6l0sHSmdKh0RnZCdkx26nazd6p3sHesd6d3rXfvd/d4+nj0eO94AXmneap5V3q/egd8DXz+e/d7" + "DHzge+B83HzefOJ833zZfN18Ln4+fkZ+N34yfkN+K349fjF+RX5BfjR+OX5IfjV+P34vfkR/83/8f3GAcoBwgG+Ac4DGgcOB" + "uoHCgcCBv4G9gcmBvoHogQmCcYKqhf//////////////////////////////////////////////////////////////////" + "////////////////////////hIV+hZyFkYWUha+Fm4WHhaiFioVnhsCH0Yezh9KHxoerh7uHuofIh8uHO4k2iUSJOIk9iayJ" + "DosXixmLG4sKiyCLHYsEixCLQYw/jHOM+oz9jPyM+Iz7jKiNSY5LjkiOSo5Ejz6PQo9Fjz+Pf5B9kISQgZCCkICQOZGjkZ6R" + "nJFNk4KTKJN1k0qTZZNLkxiTfpNsk1uTcJNak1STypXLlcyVyJXGlbGWuJbWlhyXHpegl9OXRpi2mDWZAZr/ma6bq5uqm62b" + "O50/nYuez57entye3Z7bnj6fS5/iU5VWrlbZWNhYOFtdX+NhM2L0ZPJk/mQGZfpk+2T3ZLdl3GYmZ7NqrGrDartquGrCaq5q" + "r2pfa3hrr2sJcAtw/m8GcPpvEXAPcPtx/HH+cfhxd3N1c6d0v3QVdVZ2WHb/////////////////////////////////////" + "/////////////////////////////////////////////////////1J2vXe/d7t3vHcOea55YXpiemB6xHrFeit8J3wqfB58" + "I3whfOd8VH5Vfl5+Wn5hflJ+WX5If/l/+393gHaAzYHPgQqCz4Wphc2F0IXJhbCFuoW5haaF74fsh/KH4IeGibKJ9IkoizmL" + "LIsri1CMBY1ZjmOOZo5kjl+OVY7AjkmPTY+HkIOQiJCrkayR0JGUk4qTlpOik7OTrpOsk7CTmJOak5eT1JXWldCV1ZXiltyW" + "2Zbblt6WJJejl6aXrZf5l02YT5hMmE6YU5i6mD6ZP5k9mS6ZpZkOmsGaA5sGm0+bTptNm8qbyZv9m8ibwJtRnV2dYJ3gnhWf" + "LJ8zUaVW3ljfWOJY9VuQn+xe8mH3YfZh9WEAZQ9l4GbdZuVq3WraatNqG3AfcChwGnAdcBVwGHAGcg1yWHKicnhz////////" + "//////////////////////////////////////////////////////////////////////////////////96c710ynTjdId1" + "hnVfdmF2x3cZebF5a3ppej58P3w4fD18N3xAfGt+bX55fml+an6Ff3N+tn+5f7h/2IHphd2F6oXVheSF5YX3hfuHBYgNiPmH" + "/odgiV+JVoleiUGLXItYi0mLWotOi0+LRotZiwiNCo18jnKOh452jmyOeo50jlSPTo+tj4qQi5Cxka6R4ZPRk9+Tw5PIk9yT" + "3ZPWk+KTzZPYk+ST15Pok9yVtJbjliqXJ5dhl9yX+5demFiYW5i8mEWZSZkWmhmaDZvom+eb1pvbm4mdYZ1ynWqdbJ2Snpee" + "k560nvhSqFa3VrZWtFa8VuRYQFtDW31b9lvJXfhh+mEYZRRlGWXmZidn7Go+cDBwMnAQcntzz3RidmV2JnkqeSx5K3nHevZ6" + "THxDfE1873zwfK6PfX58fv//////////////////////////////////////////////////////////////////////////" + "////////////////gn5MfwCA2oFmgvuF+YURhvqFBoYLhgeGCoYUiBWIZIm6ifiJcItsi2aLb4tfi2uLD40NjYmOgY6FjoKO" + "tJHLkRiUA5T9k+GVMJfEmFKZUZmomSuaMJo3mjWaE5wNnHmetZ7oni+fX59jn2GfN1E4UcFWwFbCVhRZbFzNXfxh/mEdZRxl" + "lWXpZvtqBGv6arJrTHAbcqdy1nTUdGl203dQfI9+jH68fxeGLYYahiOIIoghiB+Iaolsib2JdIt3i32LE42Kjo2Oi45fj6+P" + "upEulDOUNZQ6lDiUMpQrlOKVOJc5lzKX/5dnmGWYV5lFmkOaQJo+ms+aVJtRmy2cJZyvnbSdwp24nZ2e754Zn1yfZp9nnzxR" + "O1HIVspWyVZ/W9Rd0l1OX/9hJGUKa2FrUXBYcIBz5HSKdW52bHb/////////////////////////////////////////////" + "/////////////////////////////////////////////7N5YHxffH6AfYDfgXKJb4n8iYCLFo0XjZGOk45hj0iRRJRRlFKU" + "PZc+l8OXwZdrmFWZVZpNmtKaGptJnDGcPpw7nNOd1500n2yfap+Un8xW1l0AYiNlK2UqZexmEGvadMp6ZHxjfGV8k36WfpR+" + "4oE4hj+GMYiKi5CQj5BjlGCUZJRol2+YXJlamluaV5rTmtSa0ZpUnFecVpzlnZ+e9J7RVulYLGVecHF2cnbXd1B/iH82iDmI" + "YoiTi5KLlot3ghuNwJFqlEKXSJdEl8aXcJhfmiKbWJtfnPmd+p18nn2eB593n3Kf814Wa2NwbHxufDuIwImhjsGRcpRwlHGY" + "XpnWmiObzJ5kcNp3mot3lMmXYpplmpx+nIuqjsWRfZR+lHyUd5x4nPeeVIx/lBqeKHJqmjGbG54ennJ8////////////////" + "///////////////////////////////////////////////////////////////////////////+MJ0wnjAFMEEwQjBDMEQw" + "RTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYwVzBYMFkwWjBbMFwwXTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgw" + "aTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHowezB8MH0wfjB/MIAwgTCCMIMwhDCFMIYwhzCIMIkwijCLMIww" + "jTCOMI8wkDCRMJIwkzChMKIwozCkMKUwpjCnMKgwqTCqMKswrDCtMK4wrzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0w" + "vjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w0DDRMNIw0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw" + "4jDjMOQw5TDmMP//////////////////////////////////////////////////////////////////////////////////" + "////////5zDoMOkw6jDrMOww7TDuMO8w8DDxMPIw8zD0MPUw9jAUBBUEAQQWBBcEGAQZBBoEGwQcBCMEJAQlBCYEJwQoBCkE" + "KgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUEUQQ2BDcEOAQ5BDoEOwQ8BD0EPgQ/BEAEQQRCBEMERARFBEYERwRIBEkESgRLBEwE" + "TQROBE8EYCRhJGIkYyRkJGUkZiRnJGgkaSR0JHUkdiR3JHgkeSR6JHskfCR9JP//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "Qk5cTvVRGlOCUwdODE5HTo1O11YM+m5cc18PTodRDk4uTpNOwk7JTshOmFH8UmxTuVMgVwNZLFkQXP9d4WWza8xrFGw/cjFO" + "PE7oTtxO6U7hTt1O2k4MUhxTTFMiVyNXF1kvWYFbhFsSXDtcdFxzXARegF6CXslfCWJQYhVs////////////////////////" + "//////////////////////////////////////////////////////////////////82bENsP2w7bK5ysHKKc7h5ioAelg5P" + "GE8sT/VOFE/xTgBP904ITx1PAk8FTyJPE08ET/ROEk+xURNSCVIQUqZSIlMfU01TilMHVOFW31YuVypXNFc8WYBZfFmFWXtZ" + "fll3WX9ZVlsVXCVcfFx6XHtcflzfXXVehF4CXxpfdF/VX9Rfz19cYl5iZGJhYmZiYmJZYmBiWmJlYu9l7mU+ZzlnOGc7Zzpn" + "P2c8ZzNnGGxGbFJsXGxPbEpsVGxLbExscXBecrRytXKOcyp1f3Z1elF/eIJ8goCCfYJ/gk2GfomZkJeQmJCbkJSQIpYkliCW" + "I5ZWTztPYk9JT1NPZE8+T2dPUk9fT0FPWE8tTzNPP09hT49RuVEcUh5SIVKtUq5SCVNjU3JTjlOPUzBUN1QqVFRURVQZVBxU" + "JVQYVP//////////////////////////////////////////////////////////////////////////////////////////" + "PVRPVEFUKFQkVEdU7lbnVuVWQVdFV0xXSVdLV1JXBllAWaZZmFmgWZdZjlmiWZBZj1mnWaFZjluSWyhcKlyNXI9ciFyLXIlc" + "klyKXIZck1yVXOBdCl4OXoteiV6MXohejV4FXx1feF92X9Jf0V/QX+1f6F/uX/Nf4V/kX+Nf+l/vX/df+18AYPRfOmKDYoxi" + "jmKPYpRih2JxYntiemJwYoFiiGJ3Yn1icmJ0Yjdl8GX0ZfNl8mX1ZUVnR2dZZ1VnTGdIZ11nTWdaZ0tn0GsZbBpseGxnbGts" + "hGyLbI9scWxvbGlsmmxtbIdslWycbGZsc2xlbHtsjmx0cHpwY3K/cr1yw3LGcsFyunLFcpVzl3OTc5RzknM6dTl1lHWVdYF2" + "PXk0gJWAmYCQgJKAnICQgo+ChYKOgpGCk4L/////////////////////////////////////////////////////////////" + "/////////////////////////////4qCg4KEgniMyY+/j5+QoZClkJ6Qp5CgkDCWKJYvli2WM06YT3xPhU99T4BPh092T3RP" + "iU+ET3dPTE+XT2pPmk95T4FPeE+QT5xPlE+eT5JPgk+VT2tPbk+eUbxRvlE1UjJSM1JGUjFSvFIKUwtTPFOSU5RTh1R/VIFU" + "kVSCVIhUa1R6VH5UZVRsVHRUZlSNVG9UYVRgVJhUY1RnVGRU91b5Vm9XcldtV2tXcVdwV3ZXgFd1V3tXc1d0V2JXaFd9VwxZ" + "RVm1WbpZz1nOWbJZzFnBWbZZvFnDWdZZsVm9WcBZyFm0WcdZYltlW5NblVtEXEdcrlykXKBctVyvXKhcrFyfXKNcrVyiXKpc" + "p1ydXKVctlywXKZcF14UXhleKF8iXyNfJF9UX4Jffl99X95f5V8tYCZgGWAyYAtg////////////////////////////////" + "//////////////////////////////////////////////////////////80YApgF2AzYBpgHmAsYCJgDWAQYC5gE2ARYAxg" + "CWAcYBRiPWKtYrRi0WK+YqpitmLKYq5is2KvYrtiqWKwYrhiPWWoZbtlCWb8ZQRmEmYIZvtlA2YLZg1mBWb9ZRFmEGb2Zgpn" + "hWdsZ45nkmd2Z3tnmGeGZ4RndGeNZ4xnemefZ5FnmWeDZ31ngWd4Z3lnlGcla4Brfmveax1sk2zsbOts7mzZbLZs1GytbOds" + "t2zQbMJsumzDbMZs7WzybNJs3Wy0bIpsnWyAbN5swGwwbc1sx2ywbPlsz2zpbNFslHCYcIVwk3CGcIRwkXCWcIJwmnCDcGpy" + "1nLLcthyyXLcctJy1HLacsxy0XKkc6FzrXOmc6JzoHOsc51z3XTodD91QHU+dYx1mHWvdvN28XbwdvV2+Hf8d/l3+3f6d///" + "////////////////////////////////////////////////////////////////////////////////////////93dCeT95" + "xXl4ent6+3p1fP18NYCPgK6Ao4C4gLWArYAggqCCwIKrgpqCmIKbgrWCp4KugryCnoK6grSCqIKhgqmCwoKkgsOCtoKignCG" + "b4Zthm6GVozSj8uP04/Nj9aP1Y/Xj7KQtJCvkLOQsJA5lj2WPJY6lkOWzU/FT9NPsk/JT8tPwU/UT9xP2U+7T7NP20/HT9ZP" + "uk/AT7lP7E9EUklSwFLCUj1TfFOXU5ZTmVOYU7pUoVStVKVUz1TDVA2Dt1SuVNZUtlTFVMZUoFRwVLxUolS+VHJU3lSwVLVX" + "nlefV6RXjFeXV51Xm1eUV5hXj1eZV6VXmleVV/RYDVlTWeFZ3lnuWQBa8VndWfpZ/Vn8WfZZ5FnyWfdZ21npWfNZ9VngWf5Z" + "9FntWahbTFzQXNhczFzXXMtc21z/////////////////////////////////////////////////////////////////////" + "/////////////////////95c2lzJXMdcylzWXNNc1FzPXMhcxlzOXN9c+Fz5XSFeIl4jXiBeJF6wXqReol6bXqNepV4HXy5f" + "Vl+GXzdgOWBUYHJgXmBFYFNgR2BJYFtgTGBAYEJgX2AkYERgWGBmYG5gQmJDYs9iDWMLY/ViDmMDY+ti+WIPYwxj+GL2YgBj" + "E2MUY/piFWP7YvBiQWVDZaplv2U2ZiFmMmY1ZhxmJmYiZjNmK2Y6Zh1mNGY5Zi5mD2cQZ8Fn8mfIZ7pn3Ge7Z/hn2GfAZ7dn" + "xWfrZ+Rn32e1Z81ns2f3Z/Zn7mfjZ8JnuWfOZ+dn8GeyZ/xnxmftZ8xnrmfmZ9tn+mfJZ8pnw2fqZ8tnKGuCa4RrtmvWa9hr" + "4GsgbCFsKG00bS1tH208bT9tEm0KbdpsM20EbRltOm0abRFtAG0dbUJt////////////////////////////////////////" + "//////////////////////////////////////////////////8BbRhtN20DbQ9tQG0HbSBtLG0IbSJtCW0Qbbdwn3C+cLFw" + "sHChcLRwtXCpcEFySXJKcmxycHJzcm5yynLkcuhy63Lfcupy5nLjcoVzzHPCc8hzxXO5c7ZztXO0c+tzv3PHc75zw3PGc7hz" + "y3PsdO50LnVHdUh1p3WqdXl2xHYIdwN3BHcFdwp393b7dvp253fodwZ4EXgSeAV4EHgPeA54CXgDeBN4SnlMeUt5RXlEedV5" + "zXnPedZ5znmAen560XoAewF7enx4fHl8f3yAfIF8A30IfQF9WH+Rf41/vn8HgA6AD4AUgDeA2IDHgOCA0YDIgMKA0IDFgOOA" + "2YDcgMqA1YDJgM+A14DmgM2A/4EhgpSC2YL+gvmCB4PoggCD1YI6g+uC1oL0guyC4YLygvWCDIP7gvaC8ILqgv//////////" + "////////////////////////////////////////////////////////////////////////////////5ILggvqC84LtgneG" + "dIZ8hnOGQYhOiGeIaohpiNOJBIoHinKN44/hj+6P4I/xkL2Qv5DVkMWQvpDHkMuQyJDUkdORVJZPllGWU5ZKlk6WHlAFUAdQ" + "E1AiUDBQG1D1T/RPM1A3UCxQ9k/3TxdQHFAgUCdQNVAvUDFQDlBaUZRRk1HKUcRRxVHIUc5RYVJaUlJSXlJfUlVSYlLNUg5T" + "nlMmVeJUF1USVedU81TkVBpV/1QEVQhV61QRVQVV8VQKVftU91T4VOBUDlUDVQtVAVcCV8xXMljVV9JXulfGV71XvFe4V7ZX" + "v1fHV9BXuVfBVw5ZSlkZWhZaLVouWhVaD1oXWgpaHlozWmxbp1utW6xbA1xWXFRc7Fz/XO5c8Vz3XABd+VwpXiheqF6uXqpe" + "rF4zXzBfZ19dYFpgZ2D/////////////////////////////////////////////////////////////////////////////" + "/////////////0FgomCIYIBgkmCBYJ1gg2CVYJtgl2CHYJxgjmAZYkZi8mIQY1ZjLGNEY0VjNmNDY+RjOWNLY0pjPGMpY0Fj" + "NGNYY1RjWWMtY0djM2NaY1FjOGNXY0BjSGNKZUZlxmXDZcRlwmVKZl9mR2ZRZhJnE2cfaBpoSWgyaDNoO2hLaE9oFmgxaBxo" + "NWgraC1oL2hOaERoNGgdaBJoFGgmaChoLmhNaDpoJWggaCxrL2stazFrNGtta4KAiGvma+Rr6Gvja+Jr52slbHptY21kbXZt" + "DW1hbZJtWG1ibW1tb22RbY1t721/bYZtXm1nbWBtl21wbXxtX22CbZhtL21obYttfm2AbYRtFm2DbXttfW11bZBt3HDTcNFw" + "3XDLcDl/4nDXcNJw3nDgcNRwzXDFcMZwx3DacM5w4XBCcnhy////////////////////////////////////////////////" + "//////////////////////////////////////////93cnZyAHP6cvRy/nL2cvNy+3IBc9Nz2XPlc9ZzvHPnc+Nz6XPcc9Jz" + "23PUc91z2nPXc9hz6HPedN909HT1dCF1W3VfdbB1wXW7dcR1wHW/dbZ1unWKdsl2HXcbdxB3E3cSdyN3EXcVdxl3Gncidyd3" + "I3gseCJ4NXgveCh4LngreCF4KXgzeCp4MXhUeVt5T3lceVN5UnlReet57Hngee557Xnqedx53nndeYZ6iXqFeot6jHqKeod6" + "2HoQewR7E3sFew97CHsKew57CXsSe4R8kXyKfIx8iHyNfIV8Hn0dfRF9Dn0YfRZ9E30ffRJ9D30MfVx/YX9ef2B/XX9bf5Z/" + "kn/Df8J/wH8WgD6AOYD6gPKA+YD1gAGB+4AAgQGCL4IlgjODLYNEgxmDUYMlg1aDP4NBgyaDHIMig///////////////////" + "////////////////////////////////////////////////////////////////////////QoNOgxuDKoMIgzyDTYMWgySD" + "IIM3gy+DKYNHg0WDTINTgx6DLINLgyeDSINThlKGooaohpaGjYaRhp6Gh4aXhoaGi4aahoWGpYaZhqGGp4aVhpiGjoadhpCG" + "lIZDiESIbYh1iHaIcoiAiHGIf4hviIOIfoh0iHyIEopHjFeMe4ykjKOMdo14jbWNt422jdGO047+j/WPApD/j/uPBJD8j/aP" + "1pDgkNmQ2pDjkN+Q5ZDYkNuQ15DckOSQUJFOkU+R1ZHikdqRXJZflryW45jfmi+bf05wUGpQYVBeUGBQU1BLUF1QclBIUE1Q" + "QVBbUEpQYlAVUEVQX1BpUGtQY1BkUEZQQFBuUHNQV1BRUNBRa1JtUmxSblLWUtNSLVOcU3VVdlU8VU1VUFU0VSpVUVViVTZV" + "NVUwVVJVRVX/////////////////////////////////////////////////////////////////////////////////////" + "/////wxVMlVlVU5VOVVIVS1VO1VAVUtVClcHV/tXFFjiV/ZX3Ff0VwBY7Vf9VwhY+FcLWPNXz1cHWO5X41fyV+VX7FfhVw5Y" + "/FcQWOdXAVgMWPFX6VfwVw1YBFhcWWBaWFpVWmdaXlo4WjVabVpQWl9aZVpsWlNaZFpXWkNaXVpSWkRaW1pIWo5aPlpNWjla" + "TFpwWmlaR1pRWlZaQlpcWnJbblvBW8BbWVweXQtdHV0aXSBdDF0oXQ1dJl0lXQ9dMF0SXSNdH10uXT5eNF6xXrReuV6yXrNe" + "Nl84X5tfll+fX4pgkGCGYL5gsGC6YNNg1GDPYORg2WDdYMhgsWDbYLdgymC/YMNgzWDAYDJjZWOKY4JjfWO9Y55jrWOdY5dj" + "q2OOY29jh2OQY25jr2N1Y5xjbWOuY3xjpGM7Y59j////////////////////////////////////////////////////////" + "//////////////////////////////////94Y4VjgWORY41jcGNTZc1lZWZhZltmWWZcZmJmGGd5aIdokGicaG1obmiuaKto" + "VmlvaKNorGipaHVodGiyaI9od2iSaHxoa2hyaKpogGhxaH5om2iWaItooGiJaKRoeGh7aJFojGiKaH1oNmszazdrOGuRa49r" + "jWuOa4xrKmzAbatttG2zbXRurG3pbeJtt232bdRtAG7IbeBt323Wbb5t5W3cbd1t2230bcptvW3tbfBtum3VbcJtz23JbdBt" + "8m3Tbf1t123NbeNtu236cA1x93AXcfRwDHHwcARx83AQcfxw/3AGcRNxAHH4cPZwC3ECcQ5xfnJ7cnxyf3IdcxdzB3MRcxhz" + "CnMIc/9yD3Mec4hz9nP4c/VzBHQBdP1zB3QAdPpz/HP/cwx0C3T0cwh0ZHVjdc510nXPdf//////////////////////////" + "////////////////////////////////////////////////////////////////y3XMddF10HWPdol203Y5dy93LXcxdzJ3" + "NHczdz13JXc7dzV3SHhSeEl4TXhKeEx4JnhFeFB4ZHlneWl5anljeWt5YXm7efp5+Hn2efd5j3qUepB6NXtHezR7JXsweyJ7" + "JHszexh7KnsdezF7K3stey97Mns4exp7I3uUfJh8lnyjfDV9PX04fTZ9On1FfSx9KX1BfUd9Pn0/fUp9O30ofWN/lX+cf51/" + "m3/Kf8t/zX/Qf9F/x3/Pf8l/H4AegBuAR4BDgEiAGIElgRmBG4EtgR+BLIEegSGBFYEngR2BIoERgjiCM4I6gjSCMoJ0gpCD" + "o4Oog42DeoNzg6SDdIOPg4GDlYOZg3WDlIOpg32Dg4OMg52Dm4Oqg4uDfoOlg6+DiIOXg7CDf4Omg4eDroN2g5qDWYZWhr+G" + "t4b//////////////////////////////////////////////////////////////////////////////////////////8KG" + "wYbFhrqGsIbIhrmGs4a4hsyGtIa7hryGw4a9hr6GUoiJiJWIqIiiiKqImoiRiKGIn4iYiKeImYibiJeIpIisiIyIk4iOiIKJ" + "1onZidWJMIoniiyKHoo5jDuMXIxdjH2MpYx9jXuNeY28jcKNuY2/jcGN2I7ejt2O3I7XjuCO4Y4kkAuQEZAckAyQIZDvkOqQ" + "8JD0kPKQ85DUkOuQ7JDpkFaRWJFakVORVZHskfSR8ZHzkfiR5JH5keqR65H3keiR7pF6lYaViJV8lm2Wa5Zxlm+Wv5ZqlwSY" + "5ZiXmZtQlVCUUJ5Qi1CjUINQjFCOUJ1QaFCcUJJQglCHUF9R1FESUxFTpFOnU5FVqFWlVa1Vd1VFVqJVk1WIVY9VtVWBVaNV" + "klWkVX1VjFWmVX9VlVWhVY5VDFcpWDdY////////////////////////////////////////////////////////////////" + "//////////////////////////8ZWB5YJ1gjWChY9VdIWCVYHFgbWDNYP1g2WC5YOVg4WC1YLFg7WGFZr1qUWp9aelqiWp5a" + "eFqmWnxapVqsWpVarlo3WoRailqXWoNai1qpWntafVqMWpxaj1qTWp1a6lvNW8tb1FvRW8pbzlsMXDBcN11DXWtdQV1LXT9d" + "NV1RXU5dVV0zXTpdUl09XTFdWV1CXTldSV04XTxdMl02XUBdRV1EXkFeWF+mX6Vfq1/JYLlgzGDiYM5gxGAUYfJgCmEWYQVh" + "9WATYfhg/GD+YMFgA2EYYR1hEGH/YARhC2FKYpRjsWOwY85j5WPoY+9jw2OdZPNjymPgY/Zj1WPyY/VjYWTfY75j3WPcY8Rj" + "2GPTY8Jjx2PMY8tjyGPwY9dj2WMyZWdlamVkZVxlaGVlZYxlnWWeZa5l0GXSZf//////////////////////////////////" + "////////////////////////////////////////////////////////fGZsZntmgGZxZnlmamZyZgFnDGnTaARp3Ggqaexo" + "6mjxaA9p1mj3aOto5Gj2aBNpEGnzaOFoB2nMaAhpcGm0aBFp72jGaBRp+GjQaP1o/GjoaAtpCmkXac5oyGjdaN5o5mj0aNFo" + "BmnUaOloFWklacdoOWs7az9rPGuUa5drmWuVa71r8Gvya/NrMGz8bUZuR24fbkluiG48bj1uRW5ibituP25Bbl1uc24cbjNu" + "S25AblFuO24Dbi5uXm5oblxuYW4xbihuYG5xbmtuOW4ibjBuU25lbidueG5kbnduVW55blJuZm41bjZuWm4gcR5xL3H7cC5x" + "MXEjcSVxInEycR9xKHE6cRtxS3JacohyiXKGcoVyi3IScwtzMHMiczFzM3MnczJzLXMmcyNzNXMMcy50LHQwdCt0FnT/////" + "/////////////////////////////////////////////////////////////////////////////////////xp0IXQtdDF0" + "JHQjdB10KXQgdDJ0+3QvdW91bHXnddp14XXmdd1133Xkddd1lXaSdtp2RndHd0R3TXdFd0p3TndLd0x33nfsd2B4ZHhleFx4" + "bXhxeGp4bnhweGl4aHheeGJ4dHlzeXJ5cHkCegp6A3oMegR6mXrmeuR6Sns7e0R7SHtMe057QHtYe0V7onyefKh8oXxYfW99" + "Y31TfVZ9Z31qfU99bX1cfWt9Un1UfWl9UX1ffU59Pn8/f2V/Zn+if6B/oX/Xf1GAT4BQgP6A1IBDgUqBUoFPgUeBPYFNgTqB" + "5oHugfeB+IH5gQSCPII9gj+CdYI7g8+D+YMjhMCD6IMShOeD5IP8g/aDEITGg8iD64Pjg7+DAYTdg+WD2IP/g+GDy4POg9aD" + "9YPJgwmED4TegxGEBoTCg/OD////////////////////////////////////////////////////////////////////////" + "///////////////////Vg/qDx4PRg+qDE4TDg+yD7oPEg/uD14PigxuE24P+g9iG4obmhtOG44bahuqG3YbrhtyG7IbphteG" + "6IbRhkiIVohViLqI14i5iLiIwIi+iLaIvIi3iL2IsogBicmIlYmYiZeJ3YnaiduJTopNijmKWYpAileKWIpEikWKUopIilGK" + "SopMik+KX4yBjICMuoy+jLCMuYy1jISNgI2JjdiN043NjceN1o3cjc+N1Y3ZjciN143Fje+O9476jvmO5o7ujuWO9Y7njuiO" + "9o7rjvGO7I70jumOLZA0kC+QBpEskQSR/5D8kAiR+ZD7kAGRAJEHkQWRA5FhkWSRX5FikWCRAZIKkiWSA5IakiaSD5IMkgCS" + "EpL/kf2RBpIEkieSApIckiSSGZIXkgWSFpJ7lY2VjJWQlYeWfpaIlv//////////////////////////////////////////" + "////////////////////////////////////////////////iZaDloCWwpbIlsOW8ZbwlmyXcJdulweYqZjrmOac+Z6DToRO" + "tk69UL9QxlCuUMRQylC0UMhQwlCwUMFQulCxUMtQyVC2ULhQ11F6UnhSe1J8UsNV21XMVdBVy1XKVd1VwFXUVcRV6VW/VdJV" + "jVXPVdVV4lXWVchV8lXNVdlVwlUUV1NYaFhkWE9YTVhJWG9YVVhOWF1YWVhlWFtYPVhjWHFY/FjHWsRay1q6WrhasVq1WrBa" + "v1rIWrtaxlq3WsBaylq0WrZazVq5WpBa1lvYW9lbH1wzXHFdY11KXWVdcl1sXV5daF1nXWJd8F1PXk5eSl5NXktexV7MXsZe" + "y17HXkBfr1+tX/dgSWFKYSthRWE2YTJhLmFGYS9hT2EpYUBhIGJokSNiJWIkYsVj8WPrYxBkEmQJZCBkJGT/////////////" + "/////////////////////////////////////////////////////////////////////////////zNkQ2QfZBVkGGQ5ZDdk" + "ImQjZAxkJmQwZChkQWQ1ZC9kCmQaZEBkJWQnZAtk52MbZC5kIWQOZG9lkmXTZYZmjGaVZpBmi2aKZplmlGZ4ZiBnZmlfaThp" + "TmliaXFpP2lFaWppOWlCaVdpWWl6aUhpSWk1aWxpM2k9aWVp8Gh4aTRpaWlAaW9pRGl2aVhpQWl0aUxpO2lLaTdpXGlPaVFp" + "MmlSaS9pe2k8aUZrRWtDa0JrSGtBa5trDfr7a/xr+Wv3a/hrm27Wbshuj27Abp9uk26UbqBusW65bsZu0m69bsFunm7Jbrdu" + "sG7NbqZuz26ybr5uw27cbthumW6Sbo5ujW6kbqFuv26zbtBuym6Xbq5uo25HcVRxUnFjcWBxQXFdcWJxcnF4cWpxYXFCcVhx" + "Q3FLcXBxX3FQcVNx////////////////////////////////////////////////////////////////////////////////" + "//////////9EcU1xWnFPco1yjHKRcpByjnI8c0JzO3M6c0BzSnNJc0R0SnRLdFJ0UXRXdEB0T3RQdE50QnRGdE10VHThdP90" + "/nT9dB11eXV3dYNp73UPdgN293X+dfx1+XX4dRB2+3X2de119XX9dZl2tXbddlV3X3dgd1J3Vndad2l3Z3dUd1l3bXfgd4d4" + "mniUeI94hHiVeIV4hniheIN4eXiZeIB4lnh7eHx5gnl9eXl5EXoYehl6EnoXehV6InoTeht6EHqjeqJ6nnrremZ7ZHtte3R7" + "aXtye2V7c3txe3B7YXt4e3Z7Y3uyfLR8r3yIfYZ9gH2NfX99hX16fY59e32DfXx9jH2UfYR9fX2SfW1/a39nf2h/bH+mf6V/" + "p3/bf9x/IYBkgWCBd4FcgWmBW4FigXKBIWdegXaBZ4Fvgf//////////////////////////////////////////////////" + "////////////////////////////////////////RIFhgR2CSYJEgkCCQoJFgvGEP4RWhHaEeYSPhI2EZYRRhECEhoRnhDCE" + "TYR9hFqEWYR0hHOEXYQHhV6EN4Q6hDSEeoRDhHiEMoRFhCmE2YNLhC+EQoQthF+EcIQ5hE6ETIRShG+ExYSOhDuER4Q2hDOE" + "aIR+hESEK4RghFSEboRQhAuHBIf3hgyH+obWhvWGTYf4hg6HCYcBh/aGDYcFh9aIy4jNiM6I3ojbiNqIzIjQiIWJm4nfieWJ" + "5InhieCJ4oncieaJdoqGin+KYYo/ineKgoqEinWKg4qBinSKeoo8jEuMSoxljGSMZoyGjISMhYzMjGiNaY2RjYyNjo2PjY2N" + "k42UjZCNko3wjeCN7I3xje6N0I3pjeON4o3njfKN6430jQaP/44BjwCPBY8HjwiPAo8Lj1KQP5D/////////////////////" + "/////////////////////////////////////////////////////////////////////0SQSZA9kBCRDZEPkRGRFpEUkQuR" + "DpFukW+RSJJSkjCSOpJmkjOSZZJekoOSLpJKkkaSbZJskk+SYJJnkm+SNpJhknCSMZJUkmOSUJJykk6SU5JMklaSMpKflZyV" + "npWblZKWk5aRlpeWzpb6lv2W+Jb1lnOXd5d4l3KXD5gNmA6YrJj2mPmYr5mymbCZtZmtmquaW5vqnO2c55yAnv2e5lDUUNdQ" + "6FDzUNtQ6lDdUORQ01DsUPBQ71DjUOBQ2FGAUoFS6VLrUjBTrFMnVhVWDFYSVvxVD1YcVgFWE1YCVvpVHVYEVv9V+VWJWHxY" + "kFiYWIZYgVh/WHRYi1h6WIdYkViOWHZYgliIWHtYlFiPWP5Ya1ncWu5a5VrVWupa2lrtWuta81riWuBa21rsWt5a3VrZWuha" + "31p3W+Bb////////////////////////////////////////////////////////////////////////////////////////" + "///jW2Ncgl2AXX1dhl16XYFdd12KXYldiF1+XXxdjV15XX9dWF5ZXlNe2F7RXtdezl7cXtVe2V7SXtReRF9DX29ftl8sYShh" + "QWFeYXFhc2FSYVNhcmFsYYBhdGFUYXphW2FlYTthamFhYVZhKWInYitiK2RNZFtkXWR0ZHZkcmRzZH1kdWRmZKZkTmSCZF5k" + "XGRLZFNkYGRQZH9kP2RsZGtkWWRlZHdkc2WgZaFmoGafZgVnBGciZ7FptmnJaaBpzmmWabBprGm8aZFpmWmOaadpjWmpab5p" + "r2m/acRpvWmkadRpuWnKaZppz2mzaZNpqmmhaZ5p2WmXaZBpwmm1aaVpxmlKa01rS2uea59roGvDa8Rr/mvObvVu8W4DbyVv" + "+G43b/tuLm8Jb05vGW8abydvGG87bxJv7W4Kb///////////////////////////////////////////////////////////" + "////////////////////////////////Nm9zb/lu7m4tb0BvMG88bzVv624Hbw5vQ28Fb/1u9m45bxxv/G46bx9vDW8ebwhv" + "IW+HcZBxiXGAcYVxgnGPcXtxhnGBcZdxRHJTcpdylXKTckNzTXNRc0xzYnRzdHF0dXRydGd0bnQAdQJ1A3V9dZB1FnYIdgx2" + "FXYRdgp2FHa4doF3fHeFd4J3bneAd293fneDd7J4qni0eK14qHh+eKt4nnileKB4rHiieKR4mHmKeYt5lnmVeZR5k3mXeYh5" + "knmQeSt6Snowei96KHomeqh6q3qseu56iHuce4p7kXuQe5Z7jXuMe5t7jnuFe5h7hFKZe6R7gnu7fL98vHy6fKd9t33CfaN9" + "qn3BfcB9xX2dfc59xH3Gfct9zH2vfbl9ln28fZ99pn2ufal9oX3JfXN/4n/jf+V/3n//////////////////////////////" + "/////////////////////////////////////////////////////////////ySAXYBcgImBhoGDgYeBjYGMgYuBFYKXhKSE" + "oYSfhLqEzoTChKyEroSrhLmEtITBhM2EqoSahLGE0ISdhKeEu4SihJSEx4TMhJuEqYSvhKiE1oSYhLaEz4SghNeE1ITShNuE" + "sISRhGGGM4cjhyiHa4dAhy6HHochhxmHG4dDhyyHQYc+h0aHIIcyhyqHLYc8hxKHOocxhzWHQocmhyeHOIckhxqHMIcRh/eI" + "54jxiPKI+oj+iO6I/Ij2iPuI8IjsiOuInYmhiZ+JnonpieuJ6ImripmKi4qSio+Kloo9jGiMaYzVjM+M14yWjQmOAo7/jQ2O" + "/Y0KjgOOB44GjgWO/o0AjgSOEI8Rjw6PDY8jkRyRIJEikR+RHZEakSSRIZEbkXqRcpF5kXORpZKkknaSm5J6kqCSlJKqko2S" + "//////////////////////////////////////////////////////////////////////////////////////////+mkpqS" + "q5J5kpeSf5Kjku6SjpKCkpWSopJ9koiSoZKKkoaSjJKZkqeSfpKHkqmSnZKLki2Snpahlv+WWJd9l3qXfpeDl4CXgpd7l4SX" + "gZd/l86XzZcWmK2YrpgCmQCZB5mdmZyZw5m5mbuZupnCmb2Zx5mxmuOa55o+mz+bYJthm1+b8ZzynPWcp57/UANRMFH4UAZR" + "B1H2UP5QC1EMUf1QClGLUoxS8VLvUkhWQlZMVjVWQVZKVklWRlZYVlpWQFYzVj1WLFY+VjhWKlY6VhpXq1idWLFYoFijWK9Y" + "rFilWKFY/1j/WvRa/Vr3WvZaA1v4WgJb+VoBWwdbBVsPW2dcmV2XXZ9dkl2iXZNdlV2gXZxdoV2aXZ5daV5dXmBeXF7zfdte" + "3l7hXklfsl+LYYNheWGxYbBhomGJYf//////////////////////////////////////////////////////////////////" + "////////////////////////m2GTYa9hrWGfYZJhqmGhYY1hZmGzYS1ibmRwZJZkoGSFZJdknGSPZItkimSMZKNkn2RoZLFk" + "mGR2ZXpleWV7ZbJls2W1ZrBmqWayZrdmqmavZgBqBmoXauVp+GkVavFp5Gkgav9p7GniaRtqHWr+aSdq8mnuaRRq92nnaUBq" + "CGrmaftpDWr8aetpCWoEahhqJWoPavZpJmoHavRpFmpRa6Vro2uia6ZrAWwAbP9rAmxBbyZvfm+Hb8Zvkm+Nb4lvjG9ib09v" + "hW9ab5Zvdm9sb4JvVW9yb1JvUG9Xb5Rvk29dbwBvYW9rb31vZ2+Qb1Nvi29pb39vlW9jb3dvam97b7Jxr3GbcbBxoHGacalx" + "tXGdcaVxnnGkcaFxqnGccadxs3GYcppyWHNSc15zX3Ngc11zW3Nhc1pzWXP/////////////////////////////////////" + "/////////////////////////////////////////////////////2Jzh3SJdIp0hnSBdH10hXSIdHx0eXQIdQd1fnUldh52" + "GXYddhx2I3Yadih2G3acdp12nnabdo13j3eJd4h3zXi7eM94zHjReM541HjIeMN4xHjJeJp5oXmgeZx5onmbeXZrOXqyerR6" + "s3q3e8t7vnuse857r3u5e8p7tXvFfMh8zHzLfPd9233qfed9133hfQN++n3mffZ98X3wfe593312f6x/sH+tf+1/63/qf+x/" + "5n/of2SAZ4CjgZ+BnoGVgaKBmYGXgRaCT4JTglKCUIJOglGCJIU7hQ+FAIUphQ6FCYUNhR+FCoUnhRyF+4QrhfqECIUMhfSE" + "KoXyhBWF94TrhPOE/IQSheqE6YQWhf6EKIUdhS6FAoX9hB6F9oQxhSaF54TohPCE74T5hBiFIIUwhQuFGYUvhWKG////////" + "//////////////////////////////////////////////////////////////////////////////////9Wh2OHZId3h+GH" + "c4dYh1SHW4dSh2GHWodRh16HbYdqh1CHTodfh12Hb4dsh3qHbodch2WHT4d7h3WHYodnh2mHWogFiQyJFIkLiReJGIkZiQaJ" + "FokRiQ6JCYmiiaSJo4ntifCJ7InPisaKuIrTitGK1IrViruK14q+isCKxYrYisOKuoq9itmKPoxNjI+M5YzfjNmM6IzajN2M" + "54ygjZyNoY2bjSCOI44ljiSOLo4VjhuOFo4RjhmOJo4njhSOEo4YjhOOHI4XjhqOLI8kjxiPGo8gjyOPFo8Xj3OQcJBvkGeQ" + "a5AvkSuRKZEqkTKRJpEukYWRhpGKkYGRgpGEkYCR0JLDksSSwJLZkraSz5Lxkt+S2JLpkteS3ZLMku+SwpLoksqSyJLOkuaS" + "zZLVksmS4JLekueS0ZLTkv//////////////////////////////////////////////////////////////////////////" + "////////////////tZLhksaStJJ8layVq5WulbCVpJailtOWBZcIlwKXWpeKl46XiJfQl8+XHpgdmCaYKZgomCCYG5gnmLKY" + "CJn6mBGZFJkWmReZFZncmc2Zz5nTmdSZzpnJmdaZ2JnLmdeZzJmzmuya65rzmvKa8ZpGm0ObZ5t0m3GbZpt2m3WbcJtom2Sb" + "bJv8nPqc/Zz/nPecB50Anfmc+5wInQWdBJ2DntOeD58QnxxRE1EXURpREVHeUTRT4VNwVmBWblZzVmZWY1ZtVnJWXlZ3VhxX" + "G1fIWL1YyVi/WLpYwli8WMZYF1sZWxtbIVsUWxNbEFsWWyhbGlsgWx5b71usXbFdqV2nXbVdsF2uXapdqF2yXa1dr120XWde" + "aF5mXm9e6V7nXuZe6F7lXktfvF+dYahhlmHFYbRhxmHBYcxhumH/////////////////////////////////////////////" + "/////////////////////////////////////////////79huGGMYddk1mTQZM9kyWS9ZIlkw2TbZPNk2WQzZX9lfGWiZchm" + "vmbAZspmy2bPZr1mu2a6ZsxmI2c0amZqSWpnajJqaGo+al1qbWp2altqUWooalpqO2o/akFqampkalBqT2pUam9qaWpgajxq" + "XmpWalVqTWpOakZqVWtUa1Zrp2uqa6tryGvHawRsA2wGbK1vy2+jb8dvvG/Ob8hvXm/Eb71vnm/Kb6hvBHClb65vum+sb6pv" + "z2+/b7hvom/Jb6tvzW+vb7JvsG/FccJxv3G4cdZxwHHBcctx1HHKccdxz3G9cdhxvHHGcdpx23Gdcp5yaXNmc2dzbHNlc2tz" + "anN/dJp0oHSUdJJ0lXShdAt1gHUvdi12MXY9djN2PHY1djJ2MHa7duZ2mnedd6F3nHebd6J3o3eVd5l3////////////////" + "//////////////////////////////////////////////////////////////////////////+Xd9146XjleOp43njjeNt4" + "4XjieO1433jgeKR5RHpIekd6tnq4erV6sXq3et5743vne9171Xvle9p76Hv5e9R76nvie9x763vYe9970nzUfNd80HzRfBJ+" + "IX4Xfgx+H34gfhN+Dn4cfhV+Gn4ifgt+D34Wfg1+FH4lfiR+Q397f3x/en+xf+9/KoApgGyAsYGmga6BuYG1gauBsIGsgbSB" + "soG3gaeB8oFVglaCV4JWhUWFa4VNhVOFYYVYhUCFRoVkhUGFYoVEhVGFR4VjhT6FW4VxhU6FboV1hVWFZ4VghYyFZoVdhVSF" + "ZYVshWOGZYZkhpuHj4eXh5OHkoeIh4GHloeYh3mHh4ejh4WHkIeRh52HhIeUh5yHmoeJhx6JJokwiS2JLokniTGJIokpiSOJ" + "L4ksiR+J8Yngiv//////////////////////////////////////////////////////////////////////////////////" + "////////4oryivSK9YrdihSL5IrfivCKyIreiuGK6Ir/iu+K+4qRjJKMkIz1jO6M8YzwjPOMbI1ujaWNp40zjj6OOI5AjkWO" + "No48jj2OQY4wjj+OvY42jy6PNY8yjzmPN480j3aQeZB7kIaQ+pAzkTWRNpGTkZCRkZGNkY+RJ5MekwiTH5MGkw+TepM4kzyT" + "G5MjkxKTAZNGky2TDpMNk8uSHZP6kiWTE5P5kveSNJMCkyST/5IpkzmTNZMqkxSTDJMLk/6SCZMAk/uSFpO8lc2VvpW5lbqV" + "tpW/lbWVvZWpltSWC5cSlxCXmZeXl5SX8Jf4lzWYL5gymCSZH5knmSmZnpnumeyZ5ZnkmfCZ45nqmemZ55m5mr+atJq7mvaa" + "+pr5mveaM5uAm4Wbh5t8m36be5uCm5ObkpuQm3qblZv/////////////////////////////////////////////////////" + "/////////////////////////////////////32biJslnRedIJ0enRSdKZ0dnRidIp0QnRmdH52Inoaeh56unq2e1Z7Wnvqe" + "Ep89nyZRJVEiUSRRIFEpUfRSk1aMVo1WhlaEVoNWflaCVn9WgVbWWNRYz1jSWC1bJVsyWyNbLFsnWyZbL1suW3tb8VvyW7dd" + "bF5qXr5fu1/DYbVhvGHnYeBh5WHkYehh3mHvZOlk42TrZORk6GSBZYBltmXaZdJmjWqWaoFqpWqJap9qm2qhap5qh2qTao5q" + "lWqDaqhqpGqRan9qpmqaaoVqjGqSaltrrWsJbMxvqW/0b9Rv42/cb+1v52/mb95v8m/db+Jv6G/hcfFx6HHyceRx8HHicXNz" + "bnNvc5d0snSrdJB0qnStdLF0pXSvdBB1EXUSdQ91hHVDdkh2SXZHdqR26Xa1d6t3sne3d7Z3////////////////////////" + "//////////////////////////////////////////////////////////////////+0d7F3qHfwd/N4/XgCeft4/HjyeAV5" + "+Xj+eAR5q3moeVx6W3pWelh6VHpaer56wHrBegV8D3zyewB8/3v7ew589HsLfPN7AnwJfAN8AXz4e/17Bnzwe/F7EHwKfOh8" + "LX48fkJ+M35ImDh+Kn5JfkB+R34pfkx+MH47fjZ+RH46fkV/f39+f31/9H/yfyyAu4HEgcyByoHFgceBvIHpgVuCWoJcgoOF" + "gIWPhaeFlYWghYuFo4V7haSFmoWehXeFfIWJhaGFeoV4hVeFjoWWhYaFjYWZhZ2FgYWihYKFiIWFhXmFdoWYhZCFn4Vohr6H" + "qoeth8WHsIesh7mHtYe8h66HyYfDh8KHzIe3h6+HxIfKh7SHtoe/h7iHvYfeh7KHNYkziTyJPolBiVKJN4lCia2Jr4muifKJ" + "84kei///////////////////////////////////////////////////////////////////////////////////////////" + "GIsWixGLBYsLiyKLD4sSixWLB4sNiwiLBoscixOLGotPjHCMcoxxjG+MlYyUjPmMb41Ojk2OU45QjkyOR45Dj0CPhZB+kDiR" + "mpGikZuRmZGfkaGRnZGgkaGTg5Ovk2STVpNHk3yTWJNck3aTSZNQk1GTYJNtk4+TTJNqk3mTV5NVk1KTT5Nxk3eTe5Nhk16T" + "Y5Nnk4CTTpNZk8eVwJXJlcOVxZW3la6WsJasliCXH5cYlx2XGZeal6GXnJeel52X1ZfUl/GXQZhEmEqYSZhFmEOYJZkrmSyZ" + "KpkzmTKZL5ktmTGZMJmYmaOZoZkCmvqZ9Jn3mfmZ+Jn2mfuZ/Zn+mfyZA5q+mv6a/ZoBm/yaSJuam6ibnpubm6aboZulm6Sb" + "hpuim6Cbr5sznUGdZ502nS6dL50xnTidMJ3/////////////////////////////////////////////////////////////" + "/////////////////////////////0WdQp1DnT6dN51AnT2d9X8tnYqeiZ6NnrCeyJ7anvue/54knyOfIp9Un6CfMVEtUS5R" + "mFacVpdWmladVplWcFk8W2lcalzAXW1ebl7YYd9h7WHuYfFh6mHwYeth1mHpYf9kBGX9ZPhkAWUDZfxklGXbZdpm22bYZsVq" + "uWq9auFqxmq6arZqt2rHarRqrWpea8lrC2wHcAxwDXABcAVwFHAOcP9vAHD7byZw/G/3bwpwAXL/cflxA3L9cXZzuHTAdLV0" + "wXS+dLZ0u3TCdBR1E3VcdmR2WXZQdlN2V3ZadqZ2vXbsdsJ3unf/eAx5E3kUeQl5EHkSeRF5rXmseV96HHwpfBl8IHwffC18" + "HXwmfCh8InwlfDB8XH5QflZ+Y35YfmJ+X35RfmB+V35TfrV/s3/3f/h/dYDRgdKB////////////////////////////////" + "///////////////////////////////////////////////////////////QgV+CXoK0hcaFwIXDhcKFs4W1hb2Fx4XEhb+F" + "y4XOhciFxYWxhbaF0oUkhriFt4W+hWmG54fmh+KH24frh+qH5Yffh/OH5IfUh9yH04fth9iH44ekh9eH2YcBiPSH6Ifdh1OJ" + "S4lPiUyJRolQiVGJSYkqiyeLI4szizCLNYtHiy+LPIs+izGLJYs3iyaLNosuiySLO4s9izqLQox1jJmMmIyXjP6MBI0CjQCN" + "XI5ijmCOV45Wjl6OZY5njluOWo5hjl2OaY5UjkaPR49Ij0uPKJE6kTuRPpGokaWRp5GvkaqRtZOMk5KTt5Obk52TiZOnk46T" + "qpOek6aTlZOIk5mTn5ONk7GTkZOyk6STqJO0k6OTpZPSldOV0ZWzlteW2pbCXd+W2JbdliOXIpcll6yXrpeol6uXpJeql///" + "////////////////////////////////////////////////////////////////////////////////////////opell9eX" + "2ZfWl9iX+pdQmFGYUpi4mEGZPJk6mQ+aC5oJmg2aBJoRmgqaBZoHmgaawJrcmgibBJsFmymbNZtKm0ybS5vHm8abw5u/m8Gb" + "tZu4m9ObtpvEm7mbvZtcnVOdT51KnVudS51ZnVadTJ1XnVKdVJ1fnVidWp2Onoye354BnwCfFp8lnyufKp8pnyifTJ9VnzRR" + "NVGWUvdStFOrVq1WplanVqpWrFbaWN1Y21gSWT1bPls/W8NdcF6/X/thB2UQZQ1lCWUMZQ5lhGXeZd1l3mbnauBqzGrRatlq" + "y2rfatxq0Grras9qzWreamBrsGsMbBlwJ3AgcBZwK3AhcCJwI3ApcBdwJHAccCpwDHIKcgdyAnIFcqVypnKkcqNyoXLLdMV0" + "t3TDdBZ1YHbJd8p3xHfxdx15G3n/////////////////////////////////////////////////////////////////////" + "/////////////////////yF5HHkXeR55sHlnemh6M3w8fDl8LHw7fOx86nx2fnV+eH5wfnd+b356fnJ+dH5ofkt/Sn+Df4Z/" + "t3/9f/5/eIDXgdWBZIJhgmOC64Xxhe2F2YXhheiF2oXXheyF8oX4hdiF34XjhdyF0YXwheaF74XeheKFAIj6hwOI9of3hwmI" + "DIgLiAaI/IcIiP+HCogCiGKJWolbiVeJYYlciViJXYlZiYiJt4m2ifaJUItIi0qLQItTi1aLVItLi1WLUYtCi1KLV4tDjHeM" + "doyajAaNB40JjayNqo2tjauNbY54jnOOao5vjnuOwo5Sj1GPT49Qj1OPtI9AkT+RsJGtkd6Tx5PPk8KT2pPQk/mT7JPMk9mT" + "qZPmk8qT1JPuk+OT1ZPEk86TwJPSk+eTfZXalduV4ZYplyuXLJcolyaX////////////////////////////////////////" + "//////////////////////////////////////////////////+zl7eXtpfdl96X35dcmFmYXZhXmL+YvZi7mL6YSJlHmUOZ" + "ppmnmRqaFZolmh2aJJobmiKaIJonmiOaHpocmhSawpoLmwqbDpsMmzeb6pvrm+Cb3pvkm+ab4pvwm9Sb15vsm9yb2Zvlm9Wb" + "4Zvam3edgZ2KnYSdiJ1xnYCdeJ2GnYudjJ19nWuddJ11nXCdaZ2FnXOde52CnW+deZ1/nYedaJ2UnpGewJ78ni2fQJ9Bn02f" + "Vp9Xn1ifN1OyVrVWs1bjWEVbxl3HXe5e717AX8Ff+WEXZRZlFWUTZd9l6GbjZuRm82rwaupq6Gr5avFq7mrvajxwNXAvcDdw" + "NHAxcEJwOHA/cDpwOXBAcDtwM3BBcBNyFHKocn1zfHO6dKt2qna+du12zHfOd893zXfydyV5I3kneSh5JHkpef//////////" + "////////////////////////////////////////////////////////////////////////////////snluemx6bXr3ekl8" + "SHxKfEd8RXzufHt+fn6BfoB+un//f3mA24HZgQuCaIJpgiKG/4UBhv6FG4YAhvaFBIYJhgWGDIb9hRmIEIgRiBeIE4gWiGOJ" + "Zom5ifeJYItqi12LaItji2WLZ4tti66Nho6IjoSOWY9Wj1ePVY9Yj1qPjZBDkUGRt5G1kbKRs5ELlBOU+5MglA+UFJT+kxWU" + "EJQolBmUDZT1kwCU95MHlA6UFpQSlPqTCZT4kwqU/5P8kwyU9pMRlAaU3pXgld+VLpcvl7mXu5f9l/6XYJhimGOYX5jBmMKY" + "UJlOmVmZTJlLmVOZMpo0mjGaLJoqmjaaKZoumjiaLZrHmsqaxpoQmxKbEZsLnAic95sFnBKc+JtAnAecDpwGnBecFJwJnJ+d" + "mZ2knZ2dkp2YnZCdm53/////////////////////////////////////////////////////////////////////////////" + "/////////////6CdlJ2cnaqdl52hnZqdop2onZ6do52/namdlp2mnaedmZ6bnpqe5Z7knuee5p4wny6fW59gn16fXZ9Zn5Gf" + "OlE5UZhSl1LDVr1WvlZIW0dby13PXfFe/WEbZQJr/GoDa/hqAGtDcERwSnBIcElwRXBGcB1yGnIZcn5zF3VqdtB3LXkxeS95" + "VHxTfPJ8in6Hfoh+i36Gfo1+TX+7fzCA3YEYhiqGJoYfhiOGHIYZhieGLoYhhiCGKYYehiWGKYgdiBuIIIgkiByIK4hKiG2J" + "aYluiWuJ+ol5i3iLRYt6i3uLEI0Uja+Njo6Mjl6PW49dj0aRRJFFkbmRP5Q7lDaUKZQ9lDyUMJQ5lCqUN5QslECUMZTlleSV" + "45U1lzqXv5fhl2SYyZjGmMCYWJlWmTmaPZpGmkSaQppBmjqa////////////////////////////////////////////////" + "//////////////////////////////////////////8/ms2aFZsXmxibFps6m1KbK5wdnBycLJwjnCicKZwknCGct522nbyd" + "wZ3Hncqdz52+ncWdw527nbWdzp25nbqdrJ3InbGdrZ3MnbOdzZ2ynXqenJ7rnu6e7Z4bnxifGp8xn06fZZ9kn5KfuU7GVsVW" + "y1ZxWUtbTFvVXdFd8l4hZSBlJmUiZQtrCGsJaw1sVXBWcFdwUnAech9yqXJ/c9h01XTZdNd0bXatdjV5tHlwenF6V3xcfFl8" + "W3xafPR88XyRfk9/h3/egWuCNIY1hjOGLIYyhjaGLIgoiCaIKogliHGJv4m+ifuJfouEi4KLhouFi3+LFY2VjpSOmo6SjpCO" + "lo6XjmCPYo9HkUyUUJRKlEuUT5RHlEWUSJRJlEaUP5fjl2qYaZjLmFSZW5lOmlOaVJpMmk+aSJpKmv//////////////////" + "////////////////////////////////////////////////////////////////////////SZpSmlCa0JoZmyubO5tWm1Wb" + "RpxInD+cRJw5nDOcQZw8nDecNJwynD2cNpzbndKd3p3ancud0J3cndGd353pndmd2J3WnfWd1Z3dnbae8J41nzOfMp9Cn2uf" + "lZ+inz1RmVLoWOdYcllNW9hdL4hPXwFiA2IEYillJWWWZetmEWsSaw9rymtbcFpwInKCc4Fzg3NwdtR3Z3xmfJV+bII6hkCG" + "OYY8hjGGO4Y+hjCIMoguiDOIdol0iXOJ/omMi46Li4uIi0WMGY2YjmSPY4+8kWKUVZRdlFeUXpTEl8WXAJhWmlmaHpsfmyCb" + "UpxYnFCcSpxNnEucVZxZnEycTpz7nfed753jneud+J3knfad4Z3unead8p3wneKd7J30nfOd6J3tncKe0J7ynvOeBp8cnzif" + "N582n0OfT5//////////////////////////////////////////////////////////////////////////////////////" + "/////3GfcJ9un2+f01bNVk5bbVwtZe1m7mYTa19wYXBdcGBwI3LbdOV01Xc4ebd5tnlqfJd+iX9tgkOGOIg3iDWIS4iUi5WL" + "no6fjqCOnY6+kb2RwpFrlGiUaZTllkaXQ5dHl8eX5ZdemtWaWZtjnGecZpxinF6cYJwCnv6dB54DngaeBZ4AngGeCZ7/nf2d" + "BJ6gnh6fRp90n3Wfdp/UVi5luGUYaxlrF2saa2JwJnKqcth32Xc5eWl8a3z2fJp+mH6bfpl+4IHhgUaGR4ZIhnmJeol8iXuJ" + "/4mYi5mLpY6kjqOObpRtlG+UcZRzlEmXcphfmWicbpxtnAueDZ4Qng+eEp4RnqGe9Z4Jn0efeJ97n3qfeZ8eV2Zwb3w8iLKN" + "po7DkXSUeJR2lHWUYJp0nHOccZx1nBSeE572ngqf////////////////////////////////////////////////////////" + "//////////////////////////////////+kn2hwZXD3fGqGPog9iD+InoucjKmOyY5Ll3OYdJjMmGGZq5lkmmaaZ5okmxWe" + "F55InwdiHmsnckyGqI6ClICUgZRpmmiaLpsZnilyS4afi4OUeZy3nnV2a5p6nB2eaXBqcKSefp9Jn5if////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +BIG5_ENC_EXC = {0x5341: b'\xa4Q', 0x5345: b'\xa4\xca', 0xFF0F: b'\xa2A', 0xFF3C: b'\xa2B'} +BIG5_ENC_REJECT = frozenset() + +# ---- cp950 ---- +CP950_DEC = _g( + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "//////////////////////////////////////////////////////////////////////////8AMAz/ATACMA7/JyAb/xr/" + "H/8B/zD+JiAlIFD+Uf5S/rcAVP5V/lb+V/5c/xMgMf4UIDP+dCU0/k/+CP8J/zX+Nv5b/13/N/44/hQwFTA5/jr+EDARMDv+" + "PP4KMAswPf4+/ggwCTA//kD+DDANMEH+Qv4OMA8wQ/5E/ln+Wv7/////////////////////////////////////////////" + "/////////////////////////////////////////////1v+XP5d/l7+GCAZIBwgHSAdMB4wNSAyIAP/Bv8K/zsgpwADMMsl" + "zyWzJbIlziUGJgUmxyXGJaEloCW9JbwlozIFIa8A4/8//80CSf5K/k3+Tv5L/kz+X/5g/mH+C/8N/9cA9wCxABoiHP8e/x3/" + "ZiJnImAiHiJSImEiYv5j/mT+Zf5m/l7/KSIqIqUiICIfIr8i0jPRMysiLiI1IjQiQCZCJpUimSKRIZMhkCGSIZYhlyGZIZgh" + "JSIjIg//PP8VImj+BP/l/xIw4P/h/wX/IP8DIQkhaf5q/mv+1TOcM50znjPOM6EzjjOPM8QzsABZUVtRXlFdUWFRY1HnVel0" + "znyBJYIlgyWEJYUlhiWHJYgljyWOJY0ljCWLJYoliSU8JTQlLCUkJRwllCUAJQIllSUMJRAlFCUYJW0l////////////////" + "//////////////////////////////////////////////////////////////////////////9uJXAlbyVQJV4laiVhJeIl" + "4yXlJeQlcSVyJXMlEP8R/xL/E/8U/xX/Fv8X/xj/Gf9gIWEhYiFjIWQhZSFmIWchaCFpISEwIjAjMCQwJTAmMCcwKDApMEFT" + "RFNFUyH/Iv8j/yT/Jf8m/yf/KP8p/yr/K/8s/y3/Lv8v/zD/Mf8y/zP/NP81/zb/N/84/zn/Ov9B/0L/Q/9E/0X/Rv9H/0j/" + "Sf9K/0v/TP9N/07/T/9Q/1H/Uv9T/1T/Vf9W/1f/WP9Z/1r/kQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhA6MD" + "pAOlA6YDpwOoA6kDsQOyA7MDtAO1A7YDtwO4A7kDugO7A7wDvQO+A78DwAPBA8MDxAPFA8YDxwPIA8kDBTEGMQcxCDEJMQox" + "CzEMMQ0xDjEPMf//////////////////////////////////////////////////////////////////////////////////" + "////////EDERMRIxEzEUMRUxFjEXMRgxGTEaMRsxHDEdMR4xHzEgMSExIjEjMSQxJTEmMScxKDEpMdkCyQLKAscCywL/////" + "//////////////////////////////////////////////////////////////////////////////////+sIP//////////" + "//////////////////////////////////////////////////////////////////8ATllOAU4DTkNOXU6GToxOuk4/UWVR" + "a1HgUQBSAVKbUhVTQVNcU8hTCU4LTghOCk4rTjhO4VFFTkhOX05eTo5OoU5AUQNS+lJDU8lT41MfV+tYFVknWXNZUFtRW1Nb" + "+FsPXCJcOFxxXN1d5V3xXfJd813+XXJe/l4LXxNfTWL/////////////////////////////////////////////////////" + "/////////////////////////////////////xFOEE4NTi1OME45TktOOVyITpFOlU6STpROok7BTsBOw07GTsdOzU7KTstO" + "xE5DUUFRZ1FtUW5RbFGXUfZRBlIHUghS+1L+Uv9SFlM5U0hTR1NFU15ThFPLU8pTzVPsWClZK1kqWS1ZVFsRXCRcOlxvXPRd" + "e17/XhRfFV/DXwhiNmJLYk5iL2WHZZdlpGW5ZeVl8GYIZyhnIGtia3lry2vUa9trD2w0bGtwKnI2cjtyR3JZcltyrHKLcxlO" + "Fk4VThROGE47Tk1OT05OTuVO2E7UTtVO1k7XTuNO5E7ZTt5ORVFEUYlRilGsUflR+lH4UQpSoFKfUgVTBlMXUx1T305KU0lT" + "YVNgU29TblO7U+9T5FPzU+xT7lPpU+hT/FP4U/VT61PmU+pT8lPxU/BT5VPtU/tT21baVhZZ////////////////////////" + "//////////////////////////////////////////////////////////////////8uWTFZdFl2WVVbg1s8XOhd513mXQJe" + "A15zXnxeAV8YXxdfxV8KYlNiVGJSYlFipWXmZS5nLGcqZytnLWdja81rEWwQbDhsQWxAbD5sr3KEc4lz3HTmdBh1H3UodSl1" + "MHUxdTJ1M3WLdX12rna/du5223fid/N3Onm+eXR6y3oeTh9OUk5TTmlOmU6kTqZOpU7/TglPGU8KTxVPDU8QTxFPD0/yTvZO" + "+07wTvNO/U4BTwtPSVFHUUZRSFFoUXFRjVGwURdSEVISUg5SFlKjUghTIVMgU3BTcVMJVA9UDFQKVBBUAVQLVARUEVQNVAhU" + "A1QOVAZUElTgVt5W3VYzVzBXKFctVyxXL1cpVxlZGlk3WThZhFl4WYNZfVl5WYJZgVlXW1hbh1uIW4VbiVv6WxZceVzeXQZe" + "dl50Xv//////////////////////////////////////////////////////////////////////////////////////////" + "D18bX9lf1l8OYgxiDWIQYmNiW2JYYjZl6WXoZexl7WXyZvNmCWc9ZzRnMWc1ZyFrZGt7axZsXWxXbFlsX2xgbFBsVWxhbFts" + "TWxObHBwX3Jdcn52+XpzfPh8Nn+Kf71/AYADgAyAEoAzgH+AiYCLgIyA44HqgfOB/IEMghuCH4JugnKCfoJrhkCITIhjiH+J" + "IZYyTqhOTU9PT0dPV09eTzRPW09VTzBPUE9RTz1POk84T0NPVE88T0ZPY09cT2BPL09OTzZPWU9dT0hPWk9MUUtRTVF1UbZR" + "t1ElUiRSKVIqUihSq1KpUqpSrFIjU3NTdVMdVC1UHlQ+VCZUTlQnVEZUQ1QzVEhUQlQbVClUSlQ5VDtUOFQuVDVUNlQgVDxU" + "QFQxVCtUH1QsVOpW8FbkVutWSldRV0BXTVf/////////////////////////////////////////////////////////////" + "/////////////////////////////0dXTlc+V1BXT1c7V+9YPlmdWZJZqFmeWaNZmVmWWY1ZpFmTWYpZpVldW1xbWltbW4xb" + "i1uPWyxcQFxBXD9cPlyQXJFclFyMXOtdDF6PXodeil73XgRfH19kX2Jfd195X9hfzF/XX81f8V/rX/hf6l8SYhFihGKXYpZi" + "gGJ2YolibWKKYnxifmJ5YnNikmJvYphibmKVYpNikWKGYjllO2U4ZfFl9GZfZ05nT2dQZ1FnXGdWZ15nSWdGZ2BnU2dXZ2Vr" + "z2tCbF5smWyBbIhsiWyFbJtsamx6bJBscGyMbGhslmySbH1sg2xybH5sdGyGbHZsjWyUbJhsgmx2cHxwfXB4cGJyYXJgcsRy" + "wnKWcyx1K3U3dTh1gnbvduN3wXnAeb95dnr7fFV/loCTgJ2AmICbgJqAsoBvgpKC////////////////////////////////" + "//////////////////////////////////////////////////////////+Lgo2Ci4nSiQCKN4xGjFWMnYxkjXCNs42rjsqO" + "m4+wj8KPxo/Fj8SP4V2RkKKQqpCmkKOQSZHGkcyRMpYuljGWKpYsliZOVk5zTotOm06eTqtOrE5vT51PjU9zT39PbE+bT4tP" + "hk+DT3BPdU+IT2lPe0+WT35Pj0+RT3pPVFFSUVVRaVF3UXZReFG9Uf1RO1I4UjdSOlIwUi5SNlJBUr5Su1JSU1RTU1NRU2ZT" + "d1N4U3lT1lPUU9dTc1R1VJZUeFSVVIBUe1R3VIRUklSGVHxUkFRxVHZUjFSaVGJUaFSLVH1UjlT6VoNXd1dqV2lXYVdmV2RX" + "fFccWUlZR1lIWURZVFm+WbtZ1Fm5Wa5Z0VnGWdBZzVnLWdNZylmvWbNZ0lnFWV9bZFtjW5dbmluYW5xbmVubWxpcSFxFXP//" + "////////////////////////////////////////////////////////////////////////////////////////Rly3XKFc" + "uFypXKtcsVyzXBheGl4WXhVeG14RXnheml6XXpxelV6WXvZeJl8nXylfgF+BX39ffF/dX+Bf/V/1X/9fD2AUYC9gNWAWYCpg" + "FWAhYCdgKWArYBtgFmIVYj9iPmJAYn9iyWLMYsRiv2LCYrli0mLbYqti02LUYstiyGKoYr1ivGLQYtlix2LNYrVi2mKxYthi" + "1mLXYsZirGLOYj5lp2W8ZfplFGYTZgxmBmYCZg5mAGYPZhVmCmYHZg1nC2dtZ4tnlWdxZ5xnc2d3Z4dnnWeXZ29ncGd/Z4ln" + "fmeQZ3VnmmeTZ3xnamdyZyNrZmtna39rE2wbbONs6GzzbLFszGzlbLNsvWy+bLxs4myrbNVs02y4bMRsuWzBbK5s12zFbPFs" + "v2y7bOFs22zKbKxs72zcbNZs4Gz/////////////////////////////////////////////////////////////////////" + "/////////////////////5VwjnCScIpwmXAsci1yOHJIcmdyaXLAcs5y2XLXctByqXOoc59zq3Olcz11nXWZdZp1hHbCdvJ2" + "9Hbld/13PnlAeUF5yXnIeXp6eXr6ev58VH+Mf4t/BYC6gKWAooCxgKGAq4CpgLSAqoCvgOWB/oENgrOCnYKZgq2CvYKfgrmC" + "sYKsgqWCr4K4gqOCsIK+greCToZxhh1SaIjLjs6P1I/Rj7WQuJCxkLaQx5HRkXeVgJUclkCWP5Y7lkSWQpa5luiWUpdel59O" + "rU6uTuFPtU+vT79P4E/RT89P3U/DT7ZP2E/fT8pP10+uT9BPxE/CT9pPzk/eT7dPV1GSUZFRoFFOUkNSSlJNUkxSS1JHUsdS" + "yVLDUsFSDVNXU3tTmlPbU6xUwFSoVM5UyVS4VKZUs1THVMJUvVSqVMFU////////////////////////////////////////" + "///////////////////////////////////////////////////EVMhUr1SrVLFUu1SpVKdUv1T/VoJXi1egV6NXolfOV65X" + "k1dVWVFZT1lOWVBZ3FnYWf9Z41noWQNa5VnqWdpZ5lkBWvtZaVujW6ZbpFuiW6VbAVxOXE9cTVxLXNlc0lz3XR1eJV4fXn1e" + "oF6mXvpeCF8tX2VfiF+FX4pfi1+HX4xfiV8SYB1gIGAlYA5gKGBNYHBgaGBiYEZgQ2BsYGtgamBkYEFi3GIWYwlj/GLtYgFj" + "7mL9Ygdj8WL3Yu9i7GL+YvRiEWMCYz9lRWWrZb1l4mUlZi1mIGYnZi9mH2YoZjFmJGb3Zv9n02fxZ9Rn0GfsZ7Znr2f1Z+ln" + "72fEZ9FntGfaZ+VnuGfPZ95n82ewZ9ln4mfdZ9JnamuDa4ZrtWvSa9drH2zJbAttMm0qbUFtJW0MbTFtHm0Xbf//////////" + "////////////////////////////////////////////////////////////////////////////////O209bT5tNm0bbfVs" + "OW0nbThtKW0ubTVtDm0rbatwunCzcKxwr3CtcLhwrnCkcDBycnJvcnRy6XLgcuFyt3PKc7tzsnPNc8Bzs3MadS11T3VMdU51" + "S3WrdaR1pXWidaN1eHaGdod2iHbIdsZ2w3bFdgF3+Xb4dgl3C3f+dvx2B3fcdwJ4FHgMeA14RnlJeUh5R3m5ebp50XnSect5" + "f3qBev96/Xp9fAJ9BX0AfQl9B30EfQZ9OH+Of79/BIAQgA2AEYA2gNaA5YDagMOAxIDMgOGA24DOgN6A5IDdgPSBIoLnggOD" + "BYPjgtuC5oIEg+WCAoMJg9KC14LxggGD3ILUgtGC3oLTgt+C74IGg1CGeYZ7hnqGTYhriIGJ1IkIigKKA4qejKCMdI1zjbSN" + "zY7MjvCP5o/ij+qP5Y//////////////////////////////////////////////////////////////////////////////" + "/////////////+2P64/kj+iPypDOkMGQw5BLkUqRzZGClVCWS5ZMlk2WYpdpl8uX7ZfzlwGYqJjbmN+YlpmZmVhOs04MUA1Q" + "I1DvTyZQJVD4TylQFlAGUDxQH1AaUBJQEVD6TwBQFFAoUPFPIVALUBlQGFDzT+5PLVAqUP5PK1AJUHxRpFGlUaJRzVHMUcZR" + "y1FWUlxSVFJbUl1SKlN/U59TnVPfU+hUEFUBVTdV/FTlVPJUBlX6VBRV6VTtVOFUCVXuVOpU5lQnVQdV/VQPVQNXBFfCV9RX" + "y1fDVwlYD1lXWVhZWlkRWhhaHFofWhtaE1rsWSBaI1opWiVaDFoJWmtbWFywW7Nbtlu0W65btVu5W7hbBFxRXFVcUFztXP1c" + "+1zqXOhc8Fz2XAFd9FzuXS1eK16rXq1ep14xX5JfkV+QX1lg////////////////////////////////////////////////" + "//////////////////////////////////////////9jYGVgUGBVYG1gaWBvYIRgn2CaYI1glGCMYIVglmBHYvNiCGP/Yk5j" + "PmMvY1VjQmNGY09jSWM6Y1BjPWMqYytjKGNNY0xjSGVJZZllwWXFZUJmSWZPZkNmUmZMZkVmQWb4ZhRnFWcXZyFoOGhIaEZo" + "U2g5aEJoVGgpaLNoF2hMaFFoPWj0Z1BoQGg8aENoKmhFaBNoGGhBaIpriWu3ayNsJ2wobCZsJGzwbGptlW2IbYdtZm14bXdt" + "WW2TbWxtiW1ubVptdG1pbYxtim15bYVtZW2Ubcpw2HDkcNlwyHDPcDlyeXL8cvly/XL4cvdyhnPtcwl07nPgc+pz3nNUdV11" + "XHVadVl1vnXFdcd1snWzdb11vHW5dcJ1uHWLdrB2ynbNds52KXcfdyB3KHfpdzB4J3g4eB14NHg3eP//////////////////" + "////////////////////////////////////////////////////////////////////////JXgteCB4H3gyeFV5UHlgeV95" + "VnleeV15V3laeeR543nned955nnpedh5hHqIetl6BnsRe4l8IX0XfQt9Cn0gfSJ9FH0QfRV9Gn0cfQ19GX0bfTp/X3+Uf8V/" + "wX8GgBiAFYAZgBeAPYA/gPGAAoHwgAWB7YD0gAaB+IDzgAiB/YAKgfyA74DtgeyBAIIQgiqCK4IogiyCu4Irg1KDVINKgziD" + "UINJgzWDNINPgzKDOYM2gxeDQIMxgyiDQ4NUhoqGqoaThqSGqYaMhqOGnIZwiHeIgYiCiH2IeYgYihCKDooMihWKCooXihOK" + "FooPihGKSIx6jHmMoYyijHeNrI7SjtSOz46xjwGQBpD3jwCQ+o/0jwOQ/Y8FkPiPlZDhkN2Q4pBSkU2RTJHYkd2R15HckdmR" + "g5VilmOWYZb/////////////////////////////////////////////////////////////////////////////////////" + "/////1uWXZZklliWXpa7luKYrJmomtiaJZsymzybfk56UH1QXFBHUENQTFBaUElQZVB2UE5QVVB1UHRQd1BPUA9Qb1BtUFxR" + "lVHwUWpSb1LSUtlS2FLVUhBTD1MZUz9TQFM+U8NT/GZGVWpVZlVEVV5VYVVDVUpVMVVWVU9VVVUvVWRVOFUuVVxVLFVjVTNV" + "QVVXVQhXC1cJV99XBVgKWAZY4FfkV/pXAlg1WPdX+VcgWWJZNlpBWklaZlpqWkBaPFpiWlpaRlpKWnBbx1vFW8Rbwlu/W8Zb" + "CVwIXAdcYFxcXF1cB10GXQ5dG10WXSJdEV0pXRRdGV0kXSddF13iXTheNl4zXjdet164XrZetV6+XjVfN19XX2xfaV9rX5df" + "mV+eX5hfoV+gX5xff2CjYIlgoGCoYMtgtGDmYL1g////////////////////////////////////////////////////////" + "///////////////////////////////////FYLtgtWDcYLxg2GDVYMZg32C4YNpgx2AaYhtiSGKgY6djcmOWY6JjpWN3Y2dj" + "mGOqY3FjqWOJY4Njm2NrY6hjhGOIY5ljoWOsY5Jjj2OAY3tjaWNoY3pjXWVWZVFlWWVXZV9VT2VYZVVlVGWcZZtlrGXPZctl" + "zGXOZV1mWmZkZmhmZmZeZvlm11IbZ4For2iiaJNotWh/aHZosWinaJdosGiDaMRorWiGaIVolGidaKhon2ihaIJoMmu6a+tr" + "7GsrbI5tvG3zbdltsm3hbcxt5G37bfptBW7Hbcttr23Rba5t3m35bbht9231bcVt0m0abrVt2m3rbdht6m3xbe5t6G3GbcRt" + "qm3sbb9t5m35cAlxCnH9cO9wPXJ9coFyHHMbcxZzE3MZc4dzBXQKdAN0BnT+cw104HT2dP//////////////////////////" + "////////////////////////////////////////////////////////////////93QcdSJ1ZXVmdWJ1cHWPddR11XW1dcp1" + "zXWOdtR20nbbdjd3Pnc8dzZ3OHc6d2t4Q3hOeGV5aHlteft5knqVeiB7KHsbeyx7JnsZex57LnuSfJd8lXxGfUN9cX0ufTl9" + "PH1AfTB9M31EfS99Qn0yfTF9PX+ef5p/zH/Of9J/HIBKgEaAL4EWgSOBK4EpgTCBJIECgjWCN4I2gjmCjoOeg5iDeIOig5aD" + "vYOrg5KDioOTg4mDoIN3g3uDfIOGg6eDVYZqX8eGwIa2hsSGtYbGhsuGsYavhsmGU4ieiIiIq4iSiJaIjYiLiJOJj4kqih2K" + "I4olijGKLYofihuKIopJjFqMqYysjKuMqIyqjKeMZ41mjb6Nuo3bjt+OGZANkBqQF5AjkB+QHZAQkBWQHpAgkA+QIpAWkBuQ" + "FJD//////////////////////////////////////////////////////////////////////////////////////////+iQ" + "7ZD9kFeRzpH1keaR45Hnke2R6ZGJlWqWdZZzlniWcJZ0lnaWd5ZslsCW6pbpluB633oCmAOYWpvlnHWef56lnrueolCNUIVQ" + "mVCRUIBQllCYUJpQAGfxUXJSdFJ1UmlS3lLdUttSWlOlU3tVgFWnVXxVilWdVZhVglWcVapVlFWHVYtVg1WzVa5Vn1U+VbJV" + "mlW7VaxVsVV+VYlVq1WZVQ1XL1gqWDRYJFgwWDFYIVgdWCBY+Vj6WGBZd1qaWn9aklqbWqdac1txW9JbzFvTW9BbClwLXDFc" + "TF1QXTRdR139XUVePV5AXkNefl7KXsFewl7EXjxfbV+pX6pfqF/RYOFgsmC2YOBgHGEjYfpgFWHwYPtg9GBoYfFgDmH2YAlh" + "AGESYR9iSWKjY4xjz2PAY+ljyWPGY81j////////////////////////////////////////////////////////////////" + "///////////////////////////SY+Nj0GPhY9Zj7WPuY3Zj9GPqY9tjUmTaY/ljXmVmZWJlY2WRZZBlr2VuZnBmdGZ2Zm9m" + "kWZ6Zn5md2b+Zv9mH2cdZ/po1WjgaNho12gFad9o9WjuaOdo+WjSaPJo42jLaM1oDWkSaQ5pyWjaaG5p+2g+azprPWuYa5Zr" + "vGvvay5sL2wsbC9uOG5UbiFuMm5nbkpuIG4lbiNuG25bblhuJG5Wbm5uLW4mbm9uNG5NbjpuLG5Dbh1uPm7LboluGW5ObmNu" + "RG5ybmluX24ZcRpxJnEwcSFxNnFucRxxTHKEcoByNnMlczRzKXM6dCp0M3QidCV0NXQ2dDR0L3QbdCZ0KHQldSZ1a3VqdeJ1" + "23Xjddl12HXedeB1e3Z8dpZ2k3a0dtx2T3ftd114bHhveA16CHoLegV6AHqYev//////////////////////////////////" + "////////////////////////////////////////////////////////l3qWeuV643pJe1Z7RntQe1J7VHtNe0t7T3tRe598" + "pXxefVB9aH1VfSt9bn1yfWF9Zn1ifXB9c32EVdR/1X8LgFKAhYBVgVSBS4FRgU6BOYFGgT6BTIFTgXSBEoIcgumDA4T4gw2E" + "4IPFgwuEwYPvg/GD9INXhAqE8IMMhMyD/YPyg8qDOIQOhASE3IMHhNSD34Nbht+G2YbthtSG24bkhtCG3oZXiMGIwoixiIOJ" + "lok7imCKVYpeijyKQYpUiluKUIpGijSKOoo2ilaKYYyCjK+MvIyzjL2MwYy7jMCMtIy3jLaMv4y4jIqNhY2Bjc6N3Y3LjdqN" + "0Y3MjduNxo37jviO/I6cjy6QNZAxkDiQMpA2kAKR9ZAJkf6QY5Flkc+RFJIVkiOSCZIekg2SEJIHkhGSlJWPlYuVkZX/////" + "/////////////////////////////////////////////////////////////////////////////////////5OVkpWOlYqW" + "jpaLln2WhZaGlo2WcpaElsGWxZbElsaWx5bvlvKWzJcFmAaYCJjnmOqY75jpmPKY7Ziuma2Zw57NntGegk6tULVQslCzUMVQ" + "vlCsULdQu1CvUMdQf1J3Un1S31LmUuRS4lLjUi9T31XoVdNV5lXOVdxVx1XRVeNV5FXvVdpV4VXFVcZV5VXJVRJXE1deWFFY" + "WFhXWFpYVFhrWExYbVhKWGJYUlhLWGdZwVrJWsxavlq9Wrxas1rCWrJaaV1vXUxeeV7JXsheEl9ZX6xfrl8aYQ9hSGEfYfNg" + "G2H5YAFhCGFOYUxhRGFNYT5hNGEnYQ1hBmE3YSFiImITZD5kHmQqZC1kPWQsZA9kHGQUZA1kNmQWZBdkBmRsZZ9lsGWXZolm" + "h2aIZpZmhGaYZo1mA2eUaW1p////////////////////////////////////////////////////////////////////////" + "//////////////////9aaXdpYGlUaXVpMGmCaUppaGlraV5pU2l5aYZpXWljaVtpR2tya8Brv2vTa/1rom6vbtNutm7CbpBu" + "nW7HbsVupW6Ybrxuum6rbtFulm6cbsRu1G6qbqdutG5OcVlxaXFkcUlxZ3FccWxxZnFMcWVxXnFGcWhxVnE6clJyN3NFcz9z" + "PnNvdFp0VXRfdF50QXQ/dFl0W3RcdHZ1eHUAdvB1AXbydfF1+nX/dfR183Xedt92W3drd2Z3Xndjd3l3andsd1x3ZXdod2J3" + "7neOeLB4l3iYeIx4iXh8eJF4k3h/eHp5f3mBeSyEvXkcehp6IHoUeh96HnqfeqB6d3vAe2B7bntne7F8s3y1fJN9eX2RfYF9" + "j31bfW5/aX9qf3J/qX+of6R/VoBYgIaAhIBxgXCBeIFlgW6Bc4Frgf//////////////////////////////////////////" + "////////////////////////////////////////////////eYF6gWaBBYJHgoKEd4Q9hDGEdYRmhGuESYRshFuEPIQ1hGGE" + "Y4RphG2ERoRehlyGX4b5hhOHCIcHhwCH/ob7hgKHA4cGhwqHWYjfiNSI2YjciNiI3YjhiMqI1YjSiJyJ44lrinKKc4pmimmK" + "cIqHinyKY4qginGKhYptimKKbopsinmKe4o+imiKYoyKjImMyozHjMiMxIyyjMOMwozFjOGN343oje+N8436jeqN5I3mjbKO" + "A48Jj/6OCo+fj7KPS5BKkFOQQpBUkDyQVZBQkEeQT5BOkE2QUZA+kEGQEpEXkWyRapFpkcmRN5JXkjiSPZJAkj6SW5JLkmSS" + "UZI0kkmSTZJFkjmSP5JakpiVmJaUlpWWzZbLlsmWypb3lvuW+Zb2llaXdJd2lxCYEZgTmAqYEpgMmPyY9Jj/////////////" + "//////////////////////////////////////////////////////////////////////////////2Y/pizmbGZtJnhmumc" + "gp4OnxOfIJ/nUO5Q5VDWUO1Q2lDVUM9Q0VDxUM5Q6VBiUfNRg1KCUjFTrVP+VQBWG1YXVv1VFFYGVglWDVYOVvdVFlYfVghW" + "EFb2VRhXFld1WH5Yg1iTWIpYeViFWH1Y/VglWSJZJFlqWWlZ4VrmWula11rWWtha41p1W95b51vhW+Vb5lvoW+Jb5FvfWw1c" + "YlyEXYddW15jXlVeV15UXtNe1l4KX0ZfcF+5X0dhP2FLYXdhYmFjYV9hWmFYYXVhKmKHZFhkVGSkZHhkX2R6ZFFkZ2Q0ZG1k" + "e2RyZaFl12XWZaJmqGadZpxpqGmVacFprmnTactpm2m3abtpq2m0adBpzWmtacxppmnDaaNpSWtMazNsM28Ub/5uE2/0bilv" + "Pm8gbyxvD28CbyJv////////////////////////////////////////////////////////////////////////////////" + "////////////bu9uBm8xbzhvMm8jbxVvK28vb4hvKm/sbgFv8m7MbvdulHGZcX1xinGEcZJxPnKScpZyRHNQc2R0Y3RqdHB0" + "bXQEdZF1J3YNdgt2CXYTduF243aEd313f3dhd8F4n3ineLN4qXijeI55j3mNeS56MXqqeql67XrveqF7lXuLe3V7l3ude5R7" + "j3u4e4d7hHu5fL18vny7fbB9nH29fb59oH3KfbR9sn2xfbp9on2/fbV9uH2tfdJ9x32sfXB/4H/hf99/XoBagIeAUIGAgY+B" + "iIGKgX+BgoHngfqBB4IUgh6CS4LJhL+ExoTEhJmEnoSyhJyEy4S4hMCE04SQhLyE0YTKhD+HHIc7hyKHJYc0hxiHVYc3hymH" + "84gCifSI+Yj4iP2I6Igaie+IpoqMip6Ko4qNiqGKk4qkiv//////////////////////////////////////////////////" + "////////////////////////////////////////qoqliqiKmIqRipqKp4pqjI2MjIzTjNGM0oxrjZmNlY38jRSPEo8VjxOP" + "o49gkFiQXJBjkFmQXpBikF2QW5AZkRiRHpF1kXiRd5F0kXiSgJKFkpiSlpJ7kpOSnJKoknySkZKhlaiVqZWjlaWVpJWZlpyW" + "m5bMltKWAJd8l4WX9pcXmBiYr5ixmAOZBZkMmQmZwZmvmrCa5ppBm0Kb9Jz2nPOcvJ47n0qfBFEAUftQ9VD5UAJRCFEJUQVR" + "3FGHUohSiVKNUopS8FKyUy5WO1Y5VjJWP1Y0VilWU1ZOVldWdFY2Vi9WMFaAWJ9YnlizWJxYrlipWKZYbVkJW/taC1v1Wgxb" + "CFvuW+xb6VvrW2RcZVydXZRdYl5fXmFe4l7aXt9e3V7jXuBeSF9xX7dftV92YWdhbmFdYVVhgmH/////////////////////" + "/////////////////////////////////////////////////////////////////////3xhcGFrYX5hp2GQYathjmGsYZph" + "pGGUYa5hLmJpZG9keWSeZLJkiGSQZLBkpWSTZJVkqWSSZK5krWSrZJpkrGSZZKJks2R1ZXdleGWuZqtmtGaxZiNqH2roaQFq" + "HmoZav1pIWoTagpq82kCagVq7WkRalBrTmuka8Vrxms/b3xvhG9Rb2ZvVG+Gb21vW294b25vjm96b3BvZG+Xb1hv1W5vb2Bv" + "X2+fcaxxsXGocVZym3JOc1dzaXSLdIN0fnSAdH91IHYpdh92JHYmdiF2Inaadrp25HaOd4d3jHeRd4t3y3jFeLp4yni+eNV4" + "vHjQeD96PHpAej16N3o7eq96rnqte7F7xHu0e8Z7x3vBe6B7zHvKfOB99H3vfft92H3sfd196H3jfdp93n3pfZ592X3yffl9" + "dX93f69/////////////////////////////////////////////////////////////////////////////////////////" + "///pfyaAm4GcgZ2BoIGagZiBF4U9hRqF7oQshS2FE4URhSOFIYUUheyEJYX/hAaFgod0h3aHYIdmh3iHaIdZh1eHTIdTh1uI" + "XYgQiQeJEokTiRWJCom8itKKx4rEipWKy4r4irKKyYrCir+KsIrWis2Ktoq5ituKTIxOjGyM4IzejOaM5IzsjO2M4ozjjNyM" + "6ozhjG2Nn42jjSuOEI4djiKOD44pjh+OIY4ejrqOHY8bjx+PKY8mjyqPHI8ejyWPaZBukGiQbZB3kDCRLZEnkTGRh5GJkYuR" + "g5HFkruSt5LqkqyS5JLBkrOSvJLSkseS8JKykq2VsZUElwaXB5cJl2CXjZeLl4+XIZgrmByYs5gKmROZEpkYmd2Z0JnfmduZ" + "0ZnVmdKZ2Zm3mu6a75onm0WbRJt3m2+bBp0Jnf//////////////////////////////////////////////////////////" + "////////////////////////////////A52pnr6ezp6oWFKfElEYURRREFEVUYBRqlHdUZFSk1LzUllWa1Z5VmlWZFZ4VmpW" + "aFZlVnFWb1ZsVmJWdlbBWL5Yx1jFWG5ZHVs0W3hb8FsOXEpfsmGRYalhimHNYbZhvmHKYchhMGLFZMFky2S7ZLxk2mTEZMdk" + "wmTNZL9k0mTUZL5kdGXGZslmuWbEZsdmuGY9ajhqOmpZamtqWGo5akRqYmphaktqR2o1al9qSGpZa3drBWzCb7FvoW/Db6Rv" + "wW+nb7NvwG+5b7Zvpm+gb7RvvnHJcdBx0nHIcdVxuXHOcdlx3HHDccRxaHOcdKN0mHSfdJ504nQMdQ11NHY4djp253bldqB3" + "nnefd6V36HjaeOx453imeU16TnpGekx6S3q6etl7EXzJe+R723vhe+l75nvVfNZ8Cn7/////////////////////////////" + "/////////////////////////////////////////////////////////////xF+CH4bfiN+Hn4dfgl+EH55f7J/8H/xf+5/" + "KICzgamBqIH7gQiCWIJZgkqFWYVIhWiFaYVDhUmFbYVqhV6Fg4efh56HooeNh2GIKokyiSWJK4khiaqJponmivqK64rxigCL" + "3Irniu6K/ooBiwKL94rtivOK9or8imuMbYyTjPSMRI4xjjSOQo45jjWOO48vjziPM4+oj6aPdZB0kHiQcpB8kHqQNJGSkSCT" + "NpP4kjOTL5Mik/ySK5MEkxqTEJMmkyGTFZMukxmTu5WnlqiWqpbVlg6XEZcWlw2XE5cPl1uXXJdml5iXMJg4mDuYN5gtmDmY" + "JJgQmSiZHpkbmSGZGpntmeKZ8Zm4mrya+5rtmiibkZsVnSOdJp0onRKdG53YntSejZ+cnypRH1EhUTJR9VKOVoBWkFaFVodW" + "//////////////////////////////////////////////////////////////////////////////////////////+PVtVY" + "01jRWM5YMFsqWyRbels3XGhcvF26Xb1duF1rXkxfvV/JYcJhx2HmYcthMmI0Ys5kymTYZOBk8GTmZOxk8WTiZO1kgmWDZdlm" + "1maAapRqhGqiapxq22qjan5ql2qQaqBqXGuua9prCGzYb/Fv32/gb9tv5G/rb+9vgG/sb+Fv6W/Vb+5v8G/ncd9x7nHmceVx" + "7XHscfRx4HE1ckZycHNyc6l0sHSmdKh0RnZCdkx26nazd6p3sHesd6d3rXfvd/d4+nj0eO94AXmneap5V3q/egd8DXz+e/d7" + "DHzge+B83HzefOJ833zZfN18Ln4+fkZ+N34yfkN+K349fjF+RX5BfjR+OX5IfjV+P34vfkR/83/8f3GAcoBwgG+Ac4DGgcOB" + "uoHCgcCBv4G9gcmBvoHogQmCcYKqhf//////////////////////////////////////////////////////////////////" + "////////////////////////hIV+hZyFkYWUha+Fm4WHhaiFioVnhsCH0Yezh9KHxoerh7uHuofIh8uHO4k2iUSJOIk9iayJ" + "DosXixmLG4sKiyCLHYsEixCLQYw/jHOM+oz9jPyM+Iz7jKiNSY5LjkiOSo5Ejz6PQo9Fjz+Pf5B9kISQgZCCkICQOZGjkZ6R" + "nJFNk4KTKJN1k0qTZZNLkxiTfpNsk1uTcJNak1STypXLlcyVyJXGlbGWuJbWlhyXHpegl9OXRpi2mDWZAZr/ma6bq5uqm62b" + "O50/nYuez57entye3Z7bnj6fS5/iU5VWrlbZWNhYOFtdX+NhM2L0ZPJk/mQGZfpk+2T3ZLdl3GYmZ7NqrGrDartquGrCaq5q" + "r2pfa3hrr2sJcAtw/m8GcPpvEXAPcPtx/HH+cfhxd3N1c6d0v3QVdVZ2WHb/////////////////////////////////////" + "/////////////////////////////////////////////////////1J2vXe/d7t3vHcOea55YXpiemB6xHrFeit8J3wqfB58" + "I3whfOd8VH5Vfl5+Wn5hflJ+WX5If/l/+393gHaAzYHPgQqCz4Wphc2F0IXJhbCFuoW5haaF74fsh/KH4IeGibKJ9IkoizmL" + "LIsri1CMBY1ZjmOOZo5kjl+OVY7AjkmPTY+HkIOQiJCrkayR0JGUk4qTlpOik7OTrpOsk7CTmJOak5eT1JXWldCV1ZXiltyW" + "2Zbblt6WJJejl6aXrZf5l02YT5hMmE6YU5i6mD6ZP5k9mS6ZpZkOmsGaA5sGm0+bTptNm8qbyZv9m8ibwJtRnV2dYJ3gnhWf" + "LJ8zUaVW3ljfWOJY9VuQn+xe8mH3YfZh9WEAZQ9l4GbdZuVq3WraatNqG3AfcChwGnAdcBVwGHAGcg1yWHKicnhz////////" + "//////////////////////////////////////////////////////////////////////////////////96c710ynTjdId1" + "hnVfdmF2x3cZebF5a3ppej58P3w4fD18N3xAfGt+bX55fml+an6Ff3N+tn+5f7h/2IHphd2F6oXVheSF5YX3hfuHBYgNiPmH" + "/odgiV+JVoleiUGLXItYi0mLWotOi0+LRotZiwiNCo18jnKOh452jmyOeo50jlSPTo+tj4qQi5Cxka6R4ZPRk9+Tw5PIk9yT" + "3ZPWk+KTzZPYk+ST15Pok9yVtJbjliqXJ5dhl9yX+5demFiYW5i8mEWZSZkWmhmaDZvom+eb1pvbm4mdYZ1ynWqdbJ2Snpee" + "k560nvhSqFa3VrZWtFa8VuRYQFtDW31b9lvJXfhh+mEYZRRlGWXmZidn7Go+cDBwMnAQcntzz3RidmV2JnkqeSx5K3nHevZ6" + "THxDfE1873zwfK6PfX58fv//////////////////////////////////////////////////////////////////////////" + "////////////////gn5MfwCA2oFmgvuF+YURhvqFBoYLhgeGCoYUiBWIZIm6ifiJcItsi2aLb4tfi2uLD40NjYmOgY6FjoKO" + "tJHLkRiUA5T9k+GVMJfEmFKZUZmomSuaMJo3mjWaE5wNnHmetZ7oni+fX59jn2GfN1E4UcFWwFbCVhRZbFzNXfxh/mEdZRxl" + "lWXpZvtqBGv6arJrTHAbcqdy1nTUdGl203dQfI9+jH68fxeGLYYahiOIIoghiB+Iaolsib2JdIt3i32LE42Kjo2Oi45fj6+P" + "upEulDOUNZQ6lDiUMpQrlOKVOJc5lzKX/5dnmGWYV5lFmkOaQJo+ms+aVJtRmy2cJZyvnbSdwp24nZ2e754Zn1yfZp9nnzxR" + "O1HIVspWyVZ/W9Rd0l1OX/9hJGUKa2FrUXBYcIBz5HSKdW52bHb/////////////////////////////////////////////" + "/////////////////////////////////////////////7N5YHxffH6AfYDfgXKJb4n8iYCLFo0XjZGOk45hj0iRRJRRlFKU" + "PZc+l8OXwZdrmFWZVZpNmtKaGptJnDGcPpw7nNOd1500n2yfap+Un8xW1l0AYiNlK2UqZexmEGvadMp6ZHxjfGV8k36WfpR+" + "4oE4hj+GMYiKi5CQj5BjlGCUZJRol2+YXJlamluaV5rTmtSa0ZpUnFecVpzlnZ+e9J7RVulYLGVecHF2cnbXd1B/iH82iDmI" + "YoiTi5KLlot3ghuNwJFqlEKXSJdEl8aXcJhfmiKbWJtfnPmd+p18nn2eB593n3Kf814Wa2NwbHxufDuIwImhjsGRcpRwlHGY" + "XpnWmiObzJ5kcNp3mot3lMmXYpplmpx+nIuqjsWRfZR+lHyUd5x4nPeeVIx/lBqeKHJqmjGbG54ennJ8////////////////" + "///////////////////////////////////////////////////////////////////////////+MJ0wnjAFMEEwQjBDMEQw" + "RTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYwVzBYMFkwWjBbMFwwXTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgw" + "aTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHowezB8MH0wfjB/MIAwgTCCMIMwhDCFMIYwhzCIMIkwijCLMIww" + "jTCOMI8wkDCRMJIwkzChMKIwozCkMKUwpjCnMKgwqTCqMKswrDCtMK4wrzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0w" + "vjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w0DDRMNIw0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw" + "4jDjMOQw5TDmMP//////////////////////////////////////////////////////////////////////////////////" + "////////5zDoMOkw6jDrMOww7TDuMO8w8DDxMPIw8zD0MPUw9jAUBBUEAQQWBBcEGAQZBBoEGwQcBCMEJAQlBCYEJwQoBCkE" + "KgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUEUQQ2BDcEOAQ5BDoEOwQ8BD0EPgQ/BEAEQQRCBEMERARFBEYERwRIBEkESgRLBEwE" + "TQROBE8EYCRhJGIkYyRkJGUkZiRnJGgkaSR0JHUkdiR3JHgkeSR6JHskfCR9JP//////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "Qk5cTvVRGlOCUwdODE5HTo1O11YM+m5cc18PTodRDk4uTpNOwk7JTshOmFH8UmxTuVMgVwNZLFkQXP9d4WWza8xrFGw/cjFO" + "PE7oTtxO6U7hTt1O2k4MUhxTTFMiVyNXF1kvWYFbhFsSXDtcdFxzXARegF6CXslfCWJQYhVs////////////////////////" + "//////////////////////////////////////////////////////////////////82bENsP2w7bK5ysHKKc7h5ioAelg5P" + "GE8sT/VOFE/xTgBP904ITx1PAk8FTyJPE08ET/ROEk+xURNSCVIQUqZSIlMfU01TilMHVOFW31YuVypXNFc8WYBZfFmFWXtZ" + "fll3WX9ZVlsVXCVcfFx6XHtcflzfXXVehF4CXxpfdF/VX9Rfz19cYl5iZGJhYmZiYmJZYmBiWmJlYu9l7mU+ZzlnOGc7Zzpn" + "P2c8ZzNnGGxGbFJsXGxPbEpsVGxLbExscXBecrRytXKOcyp1f3Z1elF/eIJ8goCCfYJ/gk2GfomZkJeQmJCbkJSQIpYkliCW" + "I5ZWTztPYk9JT1NPZE8+T2dPUk9fT0FPWE8tTzNPP09hT49RuVEcUh5SIVKtUq5SCVNjU3JTjlOPUzBUN1QqVFRURVQZVBxU" + "JVQYVP//////////////////////////////////////////////////////////////////////////////////////////" + "PVRPVEFUKFQkVEdU7lbnVuVWQVdFV0xXSVdLV1JXBllAWaZZmFmgWZdZjlmiWZBZj1mnWaFZjluSWyhcKlyNXI9ciFyLXIlc" + "klyKXIZck1yVXOBdCl4OXoteiV6MXohejV4FXx1feF92X9Jf0V/QX+1f6F/uX/Nf4V/kX+Nf+l/vX/df+18AYPRfOmKDYoxi" + "jmKPYpRih2JxYntiemJwYoFiiGJ3Yn1icmJ0Yjdl8GX0ZfNl8mX1ZUVnR2dZZ1VnTGdIZ11nTWdaZ0tn0GsZbBpseGxnbGts" + "hGyLbI9scWxvbGlsmmxtbIdslWycbGZsc2xlbHtsjmx0cHpwY3K/cr1yw3LGcsFyunLFcpVzl3OTc5RzknM6dTl1lHWVdYF2" + "PXk0gJWAmYCQgJKAnICQgo+ChYKOgpGCk4L/////////////////////////////////////////////////////////////" + "/////////////////////////////4qCg4KEgniMyY+/j5+QoZClkJ6Qp5CgkDCWKJYvli2WM06YT3xPhU99T4BPh092T3RP" + "iU+ET3dPTE+XT2pPmk95T4FPeE+QT5xPlE+eT5JPgk+VT2tPbk+eUbxRvlE1UjJSM1JGUjFSvFIKUwtTPFOSU5RTh1R/VIFU" + "kVSCVIhUa1R6VH5UZVRsVHRUZlSNVG9UYVRgVJhUY1RnVGRU91b5Vm9XcldtV2tXcVdwV3ZXgFd1V3tXc1d0V2JXaFd9VwxZ" + "RVm1WbpZz1nOWbJZzFnBWbZZvFnDWdZZsVm9WcBZyFm0WcdZYltlW5NblVtEXEdcrlykXKBctVyvXKhcrFyfXKNcrVyiXKpc" + "p1ydXKVctlywXKZcF14UXhleKF8iXyNfJF9UX4Jffl99X95f5V8tYCZgGWAyYAtg////////////////////////////////" + "//////////////////////////////////////////////////////////80YApgF2AzYBpgHmAsYCJgDWAQYC5gE2ARYAxg" + "CWAcYBRiPWKtYrRi0WK+YqpitmLKYq5is2KvYrtiqWKwYrhiPWWoZbtlCWb8ZQRmEmYIZvtlA2YLZg1mBWb9ZRFmEGb2Zgpn" + "hWdsZ45nkmd2Z3tnmGeGZ4RndGeNZ4xnemefZ5FnmWeDZ31ngWd4Z3lnlGcla4Brfmveax1sk2zsbOts7mzZbLZs1GytbOds" + "t2zQbMJsumzDbMZs7WzybNJs3Wy0bIpsnWyAbN5swGwwbc1sx2ywbPlsz2zpbNFslHCYcIVwk3CGcIRwkXCWcIJwmnCDcGpy" + "1nLLcthyyXLcctJy1HLacsxy0XKkc6FzrXOmc6JzoHOsc51z3XTodD91QHU+dYx1mHWvdvN28XbwdvV2+Hf8d/l3+3f6d///" + "////////////////////////////////////////////////////////////////////////////////////////93dCeT95" + "xXl4ent6+3p1fP18NYCPgK6Ao4C4gLWArYAggqCCwIKrgpqCmIKbgrWCp4KugryCnoK6grSCqIKhgqmCwoKkgsOCtoKignCG" + "b4Zthm6GVozSj8uP04/Nj9aP1Y/Xj7KQtJCvkLOQsJA5lj2WPJY6lkOWzU/FT9NPsk/JT8tPwU/UT9xP2U+7T7NP20/HT9ZP" + "uk/AT7lP7E9EUklSwFLCUj1TfFOXU5ZTmVOYU7pUoVStVKVUz1TDVA2Dt1SuVNZUtlTFVMZUoFRwVLxUolS+VHJU3lSwVLVX" + "nlefV6RXjFeXV51Xm1eUV5hXj1eZV6VXmleVV/RYDVlTWeFZ3lnuWQBa8VndWfpZ/Vn8WfZZ5FnyWfdZ21npWfNZ9VngWf5Z" + "9FntWahbTFzQXNhczFzXXMtc21z/////////////////////////////////////////////////////////////////////" + "/////////////////////95c2lzJXMdcylzWXNNc1FzPXMhcxlzOXN9c+Fz5XSFeIl4jXiBeJF6wXqReol6bXqNepV4HXy5f" + "Vl+GXzdgOWBUYHJgXmBFYFNgR2BJYFtgTGBAYEJgX2AkYERgWGBmYG5gQmJDYs9iDWMLY/ViDmMDY+ti+WIPYwxj+GL2YgBj" + "E2MUY/piFWP7YvBiQWVDZaplv2U2ZiFmMmY1ZhxmJmYiZjNmK2Y6Zh1mNGY5Zi5mD2cQZ8Fn8mfIZ7pn3Ge7Z/hn2GfAZ7dn" + "xWfrZ+Rn32e1Z81ns2f3Z/Zn7mfjZ8JnuWfOZ+dn8GeyZ/xnxmftZ8xnrmfmZ9tn+mfJZ8pnw2fqZ8tnKGuCa4RrtmvWa9hr" + "4GsgbCFsKG00bS1tH208bT9tEm0KbdpsM20EbRltOm0abRFtAG0dbUJt////////////////////////////////////////" + "//////////////////////////////////////////////////8BbRhtN20DbQ9tQG0HbSBtLG0IbSJtCW0Qbbdwn3C+cLFw" + "sHChcLRwtXCpcEFySXJKcmxycHJzcm5yynLkcuhy63Lfcupy5nLjcoVzzHPCc8hzxXO5c7ZztXO0c+tzv3PHc75zw3PGc7hz" + "y3PsdO50LnVHdUh1p3WqdXl2xHYIdwN3BHcFdwp393b7dvp253fodwZ4EXgSeAV4EHgPeA54CXgDeBN4SnlMeUt5RXlEedV5" + "zXnPedZ5znmAen560XoAewF7enx4fHl8f3yAfIF8A30IfQF9WH+Rf41/vn8HgA6AD4AUgDeA2IDHgOCA0YDIgMKA0IDFgOOA" + "2YDcgMqA1YDJgM+A14DmgM2A/4EhgpSC2YL+gvmCB4PoggCD1YI6g+uC1oL0guyC4YLygvWCDIP7gvaC8ILqgv//////////" + "////////////////////////////////////////////////////////////////////////////////5ILggvqC84LtgneG" + "dIZ8hnOGQYhOiGeIaohpiNOJBIoHinKN44/hj+6P4I/xkL2Qv5DVkMWQvpDHkMuQyJDUkdORVJZPllGWU5ZKlk6WHlAFUAdQ" + "E1AiUDBQG1D1T/RPM1A3UCxQ9k/3TxdQHFAgUCdQNVAvUDFQDlBaUZRRk1HKUcRRxVHIUc5RYVJaUlJSXlJfUlVSYlLNUg5T" + "nlMmVeJUF1USVedU81TkVBpV/1QEVQhV61QRVQVV8VQKVftU91T4VOBUDlUDVQtVAVcCV8xXMljVV9JXulfGV71XvFe4V7ZX" + "v1fHV9BXuVfBVw5ZSlkZWhZaLVouWhVaD1oXWgpaHlozWmxbp1utW6xbA1xWXFRc7Fz/XO5c8Vz3XABd+VwpXiheqF6uXqpe" + "rF4zXzBfZ19dYFpgZ2D/////////////////////////////////////////////////////////////////////////////" + "/////////////0FgomCIYIBgkmCBYJ1gg2CVYJtgl2CHYJxgjmAZYkZi8mIQY1ZjLGNEY0VjNmNDY+RjOWNLY0pjPGMpY0Fj" + "NGNYY1RjWWMtY0djM2NaY1FjOGNXY0BjSGNKZUZlxmXDZcRlwmVKZl9mR2ZRZhJnE2cfaBpoSWgyaDNoO2hLaE9oFmgxaBxo" + "NWgraC1oL2hOaERoNGgdaBJoFGgmaChoLmhNaDpoJWggaCxrL2stazFrNGtta4KAiGvma+Rr6Gvja+Jr52slbHptY21kbXZt" + "DW1hbZJtWG1ibW1tb22RbY1t721/bYZtXm1nbWBtl21wbXxtX22CbZhtL21obYttfm2AbYRtFm2DbXttfW11bZBt3HDTcNFw" + "3XDLcDl/4nDXcNJw3nDgcNRwzXDFcMZwx3DacM5w4XBCcnhy////////////////////////////////////////////////" + "//////////////////////////////////////////93cnZyAHP6cvRy/nL2cvNy+3IBc9Nz2XPlc9ZzvHPnc+Nz6XPcc9Jz" + "23PUc91z2nPXc9hz6HPedN909HT1dCF1W3VfdbB1wXW7dcR1wHW/dbZ1unWKdsl2HXcbdxB3E3cSdyN3EXcVdxl3Gncidyd3" + "I3gseCJ4NXgveCh4LngreCF4KXgzeCp4MXhUeVt5T3lceVN5UnlReet57Hngee557Xnqedx53nndeYZ6iXqFeot6jHqKeod6" + "2HoQewR7E3sFew97CHsKew57CXsSe4R8kXyKfIx8iHyNfIV8Hn0dfRF9Dn0YfRZ9E30ffRJ9D30MfVx/YX9ef2B/XX9bf5Z/" + "kn/Df8J/wH8WgD6AOYD6gPKA+YD1gAGB+4AAgQGCL4IlgjODLYNEgxmDUYMlg1aDP4NBgyaDHIMig///////////////////" + "////////////////////////////////////////////////////////////////////////QoNOgxuDKoMIgzyDTYMWgySD" + "IIM3gy+DKYNHg0WDTINTgx6DLINLgyeDSINThlKGooaohpaGjYaRhp6Gh4aXhoaGi4aahoWGpYaZhqGGp4aVhpiGjoadhpCG" + "lIZDiESIbYh1iHaIcoiAiHGIf4hviIOIfoh0iHyIEopHjFeMe4ykjKOMdo14jbWNt422jdGO047+j/WPApD/j/uPBJD8j/aP" + "1pDgkNmQ2pDjkN+Q5ZDYkNuQ15DckOSQUJFOkU+R1ZHikdqRXJZflryW45jfmi+bf05wUGpQYVBeUGBQU1BLUF1QclBIUE1Q" + "QVBbUEpQYlAVUEVQX1BpUGtQY1BkUEZQQFBuUHNQV1BRUNBRa1JtUmxSblLWUtNSLVOcU3VVdlU8VU1VUFU0VSpVUVViVTZV" + "NVUwVVJVRVX/////////////////////////////////////////////////////////////////////////////////////" + "/////wxVMlVlVU5VOVVIVS1VO1VAVUtVClcHV/tXFFjiV/ZX3Ff0VwBY7Vf9VwhY+FcLWPNXz1cHWO5X41fyV+VX7FfhVw5Y" + "/FcQWOdXAVgMWPFX6VfwVw1YBFhcWWBaWFpVWmdaXlo4WjVabVpQWl9aZVpsWlNaZFpXWkNaXVpSWkRaW1pIWo5aPlpNWjla" + "TFpwWmlaR1pRWlZaQlpcWnJbblvBW8BbWVweXQtdHV0aXSBdDF0oXQ1dJl0lXQ9dMF0SXSNdH10uXT5eNF6xXrReuV6yXrNe" + "Nl84X5tfll+fX4pgkGCGYL5gsGC6YNNg1GDPYORg2WDdYMhgsWDbYLdgymC/YMNgzWDAYDJjZWOKY4JjfWO9Y55jrWOdY5dj" + "q2OOY29jh2OQY25jr2N1Y5xjbWOuY3xjpGM7Y59j////////////////////////////////////////////////////////" + "//////////////////////////////////94Y4VjgWORY41jcGNTZc1lZWZhZltmWWZcZmJmGGd5aIdokGicaG1obmiuaKto" + "VmlvaKNorGipaHVodGiyaI9od2iSaHxoa2hyaKpogGhxaH5om2iWaItooGiJaKRoeGh7aJFojGiKaH1oNmszazdrOGuRa49r" + "jWuOa4xrKmzAbatttG2zbXRurG3pbeJtt232bdRtAG7IbeBt323Wbb5t5W3cbd1t2230bcptvW3tbfBtum3VbcJtz23JbdBt" + "8m3Tbf1t123NbeNtu236cA1x93AXcfRwDHHwcARx83AQcfxw/3AGcRNxAHH4cPZwC3ECcQ5xfnJ7cnxyf3IdcxdzB3MRcxhz" + "CnMIc/9yD3Mec4hz9nP4c/VzBHQBdP1zB3QAdPpz/HP/cwx0C3T0cwh0ZHVjdc510nXPdf//////////////////////////" + "////////////////////////////////////////////////////////////////y3XMddF10HWPdol203Y5dy93LXcxdzJ3" + "NHczdz13JXc7dzV3SHhSeEl4TXhKeEx4JnhFeFB4ZHlneWl5anljeWt5YXm7efp5+Hn2efd5j3qUepB6NXtHezR7JXsweyJ7" + "JHszexh7KnsdezF7K3stey97Mns4exp7I3uUfJh8lnyjfDV9PX04fTZ9On1FfSx9KX1BfUd9Pn0/fUp9O30ofWN/lX+cf51/" + "m3/Kf8t/zX/Qf9F/x3/Pf8l/H4AegBuAR4BDgEiAGIElgRmBG4EtgR+BLIEegSGBFYEngR2BIoERgjiCM4I6gjSCMoJ0gpCD" + "o4Oog42DeoNzg6SDdIOPg4GDlYOZg3WDlIOpg32Dg4OMg52Dm4Oqg4uDfoOlg6+DiIOXg7CDf4Omg4eDroN2g5qDWYZWhr+G" + "t4b//////////////////////////////////////////////////////////////////////////////////////////8KG" + "wYbFhrqGsIbIhrmGs4a4hsyGtIa7hryGw4a9hr6GUoiJiJWIqIiiiKqImoiRiKGIn4iYiKeImYibiJeIpIisiIyIk4iOiIKJ" + "1onZidWJMIoniiyKHoo5jDuMXIxdjH2MpYx9jXuNeY28jcKNuY2/jcGN2I7ejt2O3I7XjuCO4Y4kkAuQEZAckAyQIZDvkOqQ" + "8JD0kPKQ85DUkOuQ7JDpkFaRWJFakVORVZHskfSR8ZHzkfiR5JH5keqR65H3keiR7pF6lYaViJV8lm2Wa5Zxlm+Wv5ZqlwSY" + "5ZiXmZtQlVCUUJ5Qi1CjUINQjFCOUJ1QaFCcUJJQglCHUF9R1FESUxFTpFOnU5FVqFWlVa1Vd1VFVqJVk1WIVY9VtVWBVaNV" + "klWkVX1VjFWmVX9VlVWhVY5VDFcpWDdY////////////////////////////////////////////////////////////////" + "//////////////////////////8ZWB5YJ1gjWChY9VdIWCVYHFgbWDNYP1g2WC5YOVg4WC1YLFg7WGFZr1qUWp9aelqiWp5a" + "eFqmWnxapVqsWpVarlo3WoRailqXWoNai1qpWntafVqMWpxaj1qTWp1a6lvNW8tb1FvRW8pbzlsMXDBcN11DXWtdQV1LXT9d" + "NV1RXU5dVV0zXTpdUl09XTFdWV1CXTldSV04XTxdMl02XUBdRV1EXkFeWF+mX6Vfq1/JYLlgzGDiYM5gxGAUYfJgCmEWYQVh" + "9WATYfhg/GD+YMFgA2EYYR1hEGH/YARhC2FKYpRjsWOwY85j5WPoY+9jw2OdZPNjymPgY/Zj1WPyY/VjYWTfY75j3WPcY8Rj" + "2GPTY8Jjx2PMY8tjyGPwY9dj2WMyZWdlamVkZVxlaGVlZYxlnWWeZa5l0GXSZf//////////////////////////////////" + "////////////////////////////////////////////////////////fGZsZntmgGZxZnlmamZyZgFnDGnTaARp3Ggqaexo" + "6mjxaA9p1mj3aOto5Gj2aBNpEGnzaOFoB2nMaAhpcGm0aBFp72jGaBRp+GjQaP1o/GjoaAtpCmkXac5oyGjdaN5o5mj0aNFo" + "BmnUaOloFWklacdoOWs7az9rPGuUa5drmWuVa71r8Gvya/NrMGz8bUZuR24fbkluiG48bj1uRW5ibituP25Bbl1uc24cbjNu" + "S25AblFuO24Dbi5uXm5oblxuYW4xbihuYG5xbmtuOW4ibjBuU25lbidueG5kbnduVW55blJuZm41bjZuWm4gcR5xL3H7cC5x" + "MXEjcSVxInEycR9xKHE6cRtxS3JacohyiXKGcoVyi3IScwtzMHMiczFzM3MnczJzLXMmcyNzNXMMcy50LHQwdCt0FnT/////" + "/////////////////////////////////////////////////////////////////////////////////////xp0IXQtdDF0" + "JHQjdB10KXQgdDJ0+3QvdW91bHXnddp14XXmdd1133Xkddd1lXaSdtp2RndHd0R3TXdFd0p3TndLd0x33nfsd2B4ZHhleFx4" + "bXhxeGp4bnhweGl4aHheeGJ4dHlzeXJ5cHkCegp6A3oMegR6mXrmeuR6Sns7e0R7SHtMe057QHtYe0V7onyefKh8oXxYfW99" + "Y31TfVZ9Z31qfU99bX1cfWt9Un1UfWl9UX1ffU59Pn8/f2V/Zn+if6B/oX/Xf1GAT4BQgP6A1IBDgUqBUoFPgUeBPYFNgTqB" + "5oHugfeB+IH5gQSCPII9gj+CdYI7g8+D+YMjhMCD6IMShOeD5IP8g/aDEITGg8iD64Pjg7+DAYTdg+WD2IP/g+GDy4POg9aD" + "9YPJgwmED4TegxGEBoTCg/OD////////////////////////////////////////////////////////////////////////" + "///////////////////Vg/qDx4PRg+qDE4TDg+yD7oPEg/uD14PigxuE24P+g9iG4obmhtOG44bahuqG3YbrhtyG7IbphteG" + "6IbRhkiIVohViLqI14i5iLiIwIi+iLaIvIi3iL2IsogBicmIlYmYiZeJ3YnaiduJTopNijmKWYpAileKWIpEikWKUopIilGK" + "SopMik+KX4yBjICMuoy+jLCMuYy1jISNgI2JjdiN043NjceN1o3cjc+N1Y3ZjciN143Fje+O9476jvmO5o7ujuWO9Y7njuiO" + "9o7rjvGO7I70jumOLZA0kC+QBpEskQSR/5D8kAiR+ZD7kAGRAJEHkQWRA5FhkWSRX5FikWCRAZIKkiWSA5IakiaSD5IMkgCS" + "EpL/kf2RBpIEkieSApIckiSSGZIXkgWSFpJ7lY2VjJWQlYeWfpaIlv//////////////////////////////////////////" + "////////////////////////////////////////////////iZaDloCWwpbIlsOW8ZbwlmyXcJdulweYqZjrmOac+Z6DToRO" + "tk69UL9QxlCuUMRQylC0UMhQwlCwUMFQulCxUMtQyVC2ULhQ11F6UnhSe1J8UsNV21XMVdBVy1XKVd1VwFXUVcRV6VW/VdJV" + "jVXPVdVV4lXWVchV8lXNVdlVwlUUV1NYaFhkWE9YTVhJWG9YVVhOWF1YWVhlWFtYPVhjWHFY/FjHWsRay1q6WrhasVq1WrBa" + "v1rIWrtaxlq3WsBaylq0WrZazVq5WpBa1lvYW9lbH1wzXHFdY11KXWVdcl1sXV5daF1nXWJd8F1PXk5eSl5NXktexV7MXsZe" + "y17HXkBfr1+tX/dgSWFKYSthRWE2YTJhLmFGYS9hT2EpYUBhIGJokSNiJWIkYsVj8WPrYxBkEmQJZCBkJGT/////////////" + "/////////////////////////////////////////////////////////////////////////////zNkQ2QfZBVkGGQ5ZDdk" + "ImQjZAxkJmQwZChkQWQ1ZC9kCmQaZEBkJWQnZAtk52MbZC5kIWQOZG9lkmXTZYZmjGaVZpBmi2aKZplmlGZ4ZiBnZmlfaThp" + "TmliaXFpP2lFaWppOWlCaVdpWWl6aUhpSWk1aWxpM2k9aWVp8Gh4aTRpaWlAaW9pRGl2aVhpQWl0aUxpO2lLaTdpXGlPaVFp" + "MmlSaS9pe2k8aUZrRWtDa0JrSGtBa5trDfr7a/xr+Wv3a/hrm27Wbshuj27Abp9uk26UbqBusW65bsZu0m69bsFunm7Jbrdu" + "sG7NbqZuz26ybr5uw27cbthumW6Sbo5ujW6kbqFuv26zbtBuym6Xbq5uo25HcVRxUnFjcWBxQXFdcWJxcnF4cWpxYXFCcVhx" + "Q3FLcXBxX3FQcVNx////////////////////////////////////////////////////////////////////////////////" + "//////////9EcU1xWnFPco1yjHKRcpByjnI8c0JzO3M6c0BzSnNJc0R0SnRLdFJ0UXRXdEB0T3RQdE50QnRGdE10VHThdP90" + "/nT9dB11eXV3dYNp73UPdgN293X+dfx1+XX4dRB2+3X2de119XX9dZl2tXbddlV3X3dgd1J3Vndad2l3Z3dUd1l3bXfgd4d4" + "mniUeI94hHiVeIV4hniheIN4eXiZeIB4lnh7eHx5gnl9eXl5EXoYehl6EnoXehV6InoTeht6EHqjeqJ6nnrremZ7ZHtte3R7" + "aXtye2V7c3txe3B7YXt4e3Z7Y3uyfLR8r3yIfYZ9gH2NfX99hX16fY59e32DfXx9jH2UfYR9fX2SfW1/a39nf2h/bH+mf6V/" + "p3/bf9x/IYBkgWCBd4FcgWmBW4FigXKBIWdegXaBZ4Fvgf//////////////////////////////////////////////////" + "////////////////////////////////////////RIFhgR2CSYJEgkCCQoJFgvGEP4RWhHaEeYSPhI2EZYRRhECEhoRnhDCE" + "TYR9hFqEWYR0hHOEXYQHhV6EN4Q6hDSEeoRDhHiEMoRFhCmE2YNLhC+EQoQthF+EcIQ5hE6ETIRShG+ExYSOhDuER4Q2hDOE" + "aIR+hESEK4RghFSEboRQhAuHBIf3hgyH+obWhvWGTYf4hg6HCYcBh/aGDYcFh9aIy4jNiM6I3ojbiNqIzIjQiIWJm4nfieWJ" + "5InhieCJ4oncieaJdoqGin+KYYo/ineKgoqEinWKg4qBinSKeoo8jEuMSoxljGSMZoyGjISMhYzMjGiNaY2RjYyNjo2PjY2N" + "k42UjZCNko3wjeCN7I3xje6N0I3pjeON4o3njfKN6430jQaP/44BjwCPBY8HjwiPAo8Lj1KQP5D/////////////////////" + "/////////////////////////////////////////////////////////////////////0SQSZA9kBCRDZEPkRGRFpEUkQuR" + "DpFukW+RSJJSkjCSOpJmkjOSZZJekoOSLpJKkkaSbZJskk+SYJJnkm+SNpJhknCSMZJUkmOSUJJykk6SU5JMklaSMpKflZyV" + "npWblZKWk5aRlpeWzpb6lv2W+Jb1lnOXd5d4l3KXD5gNmA6YrJj2mPmYr5mymbCZtZmtmquaW5vqnO2c55yAnv2e5lDUUNdQ" + "6FDzUNtQ6lDdUORQ01DsUPBQ71DjUOBQ2FGAUoFS6VLrUjBTrFMnVhVWDFYSVvxVD1YcVgFWE1YCVvpVHVYEVv9V+VWJWHxY" + "kFiYWIZYgVh/WHRYi1h6WIdYkViOWHZYgliIWHtYlFiPWP5Ya1ncWu5a5VrVWupa2lrtWuta81riWuBa21rsWt5a3VrZWuha" + "31p3W+Bb////////////////////////////////////////////////////////////////////////////////////////" + "///jW2Ncgl2AXX1dhl16XYFdd12KXYldiF1+XXxdjV15XX9dWF5ZXlNe2F7RXtdezl7cXtVe2V7SXtReRF9DX29ftl8sYShh" + "QWFeYXFhc2FSYVNhcmFsYYBhdGFUYXphW2FlYTthamFhYVZhKWInYitiK2RNZFtkXWR0ZHZkcmRzZH1kdWRmZKZkTmSCZF5k" + "XGRLZFNkYGRQZH9kP2RsZGtkWWRlZHdkc2WgZaFmoGafZgVnBGciZ7FptmnJaaBpzmmWabBprGm8aZFpmWmOaadpjWmpab5p" + "r2m/acRpvWmkadRpuWnKaZppz2mzaZNpqmmhaZ5p2WmXaZBpwmm1aaVpxmlKa01rS2uea59roGvDa8Rr/mvObvVu8W4DbyVv" + "+G43b/tuLm8Jb05vGW8abydvGG87bxJv7W4Kb///////////////////////////////////////////////////////////" + "////////////////////////////////Nm9zb/lu7m4tb0BvMG88bzVv624Hbw5vQ28Fb/1u9m45bxxv/G46bx9vDW8ebwhv" + "IW+HcZBxiXGAcYVxgnGPcXtxhnGBcZdxRHJTcpdylXKTckNzTXNRc0xzYnRzdHF0dXRydGd0bnQAdQJ1A3V9dZB1FnYIdgx2" + "FXYRdgp2FHa4doF3fHeFd4J3bneAd293fneDd7J4qni0eK14qHh+eKt4nnileKB4rHiieKR4mHmKeYt5lnmVeZR5k3mXeYh5" + "knmQeSt6Snowei96KHomeqh6q3qseu56iHuce4p7kXuQe5Z7jXuMe5t7jnuFe5h7hFKZe6R7gnu7fL98vHy6fKd9t33CfaN9" + "qn3BfcB9xX2dfc59xH3Gfct9zH2vfbl9ln28fZ99pn2ufal9oX3JfXN/4n/jf+V/3n//////////////////////////////" + "/////////////////////////////////////////////////////////////ySAXYBcgImBhoGDgYeBjYGMgYuBFYKXhKSE" + "oYSfhLqEzoTChKyEroSrhLmEtITBhM2EqoSahLGE0ISdhKeEu4SihJSEx4TMhJuEqYSvhKiE1oSYhLaEz4SghNeE1ITShNuE" + "sISRhGGGM4cjhyiHa4dAhy6HHochhxmHG4dDhyyHQYc+h0aHIIcyhyqHLYc8hxKHOocxhzWHQocmhyeHOIckhxqHMIcRh/eI" + "54jxiPKI+oj+iO6I/Ij2iPuI8IjsiOuInYmhiZ+JnonpieuJ6ImripmKi4qSio+Kloo9jGiMaYzVjM+M14yWjQmOAo7/jQ2O" + "/Y0KjgOOB44GjgWO/o0AjgSOEI8Rjw6PDY8jkRyRIJEikR+RHZEakSSRIZEbkXqRcpF5kXORpZKkknaSm5J6kqCSlJKqko2S" + "//////////////////////////////////////////////////////////////////////////////////////////+mkpqS" + "q5J5kpeSf5Kjku6SjpKCkpWSopJ9koiSoZKKkoaSjJKZkqeSfpKHkqmSnZKLki2Snpahlv+WWJd9l3qXfpeDl4CXgpd7l4SX" + "gZd/l86XzZcWmK2YrpgCmQCZB5mdmZyZw5m5mbuZupnCmb2Zx5mxmuOa55o+mz+bYJthm1+b8ZzynPWcp57/UANRMFH4UAZR" + "B1H2UP5QC1EMUf1QClGLUoxS8VLvUkhWQlZMVjVWQVZKVklWRlZYVlpWQFYzVj1WLFY+VjhWKlY6VhpXq1idWLFYoFijWK9Y" + "rFilWKFY/1j/WvRa/Vr3WvZaA1v4WgJb+VoBWwdbBVsPW2dcmV2XXZ9dkl2iXZNdlV2gXZxdoV2aXZ5daV5dXmBeXF7zfdte" + "3l7hXklfsl+LYYNheWGxYbBhomGJYf//////////////////////////////////////////////////////////////////" + "////////////////////////m2GTYa9hrWGfYZJhqmGhYY1hZmGzYS1ibmRwZJZkoGSFZJdknGSPZItkimSMZKNkn2RoZLFk" + "mGR2ZXpleWV7ZbJls2W1ZrBmqWayZrdmqmavZgBqBmoXauVp+GkVavFp5Gkgav9p7GniaRtqHWr+aSdq8mnuaRRq92nnaUBq" + "CGrmaftpDWr8aetpCWoEahhqJWoPavZpJmoHavRpFmpRa6Vro2uia6ZrAWwAbP9rAmxBbyZvfm+Hb8Zvkm+Nb4lvjG9ib09v" + "hW9ab5Zvdm9sb4JvVW9yb1JvUG9Xb5Rvk29dbwBvYW9rb31vZ2+Qb1Nvi29pb39vlW9jb3dvam97b7Jxr3GbcbBxoHGacalx" + "tXGdcaVxnnGkcaFxqnGccadxs3GYcppyWHNSc15zX3Ngc11zW3Nhc1pzWXP/////////////////////////////////////" + "/////////////////////////////////////////////////////2Jzh3SJdIp0hnSBdH10hXSIdHx0eXQIdQd1fnUldh52" + "GXYddhx2I3Yadih2G3acdp12nnabdo13j3eJd4h3zXi7eM94zHjReM541HjIeMN4xHjJeJp5oXmgeZx5onmbeXZrOXqyerR6" + "s3q3e8t7vnuse857r3u5e8p7tXvFfMh8zHzLfPd9233qfed9133hfQN++n3mffZ98X3wfe593312f6x/sH+tf+1/63/qf+x/" + "5n/of2SAZ4CjgZ+BnoGVgaKBmYGXgRaCT4JTglKCUIJOglGCJIU7hQ+FAIUphQ6FCYUNhR+FCoUnhRyF+4QrhfqECIUMhfSE" + "KoXyhBWF94TrhPOE/IQSheqE6YQWhf6EKIUdhS6FAoX9hB6F9oQxhSaF54TohPCE74T5hBiFIIUwhQuFGYUvhWKG////////" + "//////////////////////////////////////////////////////////////////////////////////9Wh2OHZId3h+GH" + "c4dYh1SHW4dSh2GHWodRh16HbYdqh1CHTodfh12Hb4dsh3qHbodch2WHT4d7h3WHYodnh2mHWogFiQyJFIkLiReJGIkZiQaJ" + "FokRiQ6JCYmiiaSJo4ntifCJ7InPisaKuIrTitGK1IrViruK14q+isCKxYrYisOKuoq9itmKPoxNjI+M5YzfjNmM6IzajN2M" + "54ygjZyNoY2bjSCOI44ljiSOLo4VjhuOFo4RjhmOJo4njhSOEo4YjhOOHI4XjhqOLI8kjxiPGo8gjyOPFo8Xj3OQcJBvkGeQ" + "a5AvkSuRKZEqkTKRJpEukYWRhpGKkYGRgpGEkYCR0JLDksSSwJLZkraSz5Lxkt+S2JLpkteS3ZLMku+SwpLoksqSyJLOkuaS" + "zZLVksmS4JLekueS0ZLTkv//////////////////////////////////////////////////////////////////////////" + "////////////////tZLhksaStJJ8layVq5WulbCVpJailtOWBZcIlwKXWpeKl46XiJfQl8+XHpgdmCaYKZgomCCYG5gnmLKY" + "CJn6mBGZFJkWmReZFZncmc2Zz5nTmdSZzpnJmdaZ2JnLmdeZzJmzmuya65rzmvKa8ZpGm0ObZ5t0m3GbZpt2m3WbcJtom2Sb" + "bJv8nPqc/Zz/nPecB50Anfmc+5wInQWdBJ2DntOeD58QnxxRE1EXURpREVHeUTRT4VNwVmBWblZzVmZWY1ZtVnJWXlZ3VhxX" + "G1fIWL1YyVi/WLpYwli8WMZYF1sZWxtbIVsUWxNbEFsWWyhbGlsgWx5b71usXbFdqV2nXbVdsF2uXapdqF2yXa1dr120XWde" + "aF5mXm9e6V7nXuZe6F7lXktfvF+dYahhlmHFYbRhxmHBYcxhumH/////////////////////////////////////////////" + "/////////////////////////////////////////////79huGGMYddk1mTQZM9kyWS9ZIlkw2TbZPNk2WQzZX9lfGWiZchm" + "vmbAZspmy2bPZr1mu2a6ZsxmI2c0amZqSWpnajJqaGo+al1qbWp2altqUWooalpqO2o/akFqampkalBqT2pUam9qaWpgajxq" + "XmpWalVqTWpOakZqVWtUa1Zrp2uqa6tryGvHawRsA2wGbK1vy2+jb8dvvG/Ob8hvXm/Eb71vnm/Kb6hvBHClb65vum+sb6pv" + "z2+/b7hvom/Jb6tvzW+vb7JvsG/FccJxv3G4cdZxwHHBcctx1HHKccdxz3G9cdhxvHHGcdpx23Gdcp5yaXNmc2dzbHNlc2tz" + "anN/dJp0oHSUdJJ0lXShdAt1gHUvdi12MXY9djN2PHY1djJ2MHa7duZ2mnedd6F3nHebd6J3o3eVd5l3////////////////" + "//////////////////////////////////////////////////////////////////////////+Xd9146XjleOp43njjeNt4" + "4XjieO1433jgeKR5RHpIekd6tnq4erV6sXq3et5743vne9171Xvle9p76Hv5e9R76nvie9x763vYe9970nzUfNd80HzRfBJ+" + "IX4Xfgx+H34gfhN+Dn4cfhV+Gn4ifgt+D34Wfg1+FH4lfiR+Q397f3x/en+xf+9/KoApgGyAsYGmga6BuYG1gauBsIGsgbSB" + "soG3gaeB8oFVglaCV4JWhUWFa4VNhVOFYYVYhUCFRoVkhUGFYoVEhVGFR4VjhT6FW4VxhU6FboV1hVWFZ4VghYyFZoVdhVSF" + "ZYVshWOGZYZkhpuHj4eXh5OHkoeIh4GHloeYh3mHh4ejh4WHkIeRh52HhIeUh5yHmoeJhx6JJokwiS2JLokniTGJIokpiSOJ" + "L4ksiR+J8Yngiv//////////////////////////////////////////////////////////////////////////////////" + "////////4oryivSK9YrdihSL5IrfivCKyIreiuGK6Ir/iu+K+4qRjJKMkIz1jO6M8YzwjPOMbI1ujaWNp40zjj6OOI5AjkWO" + "No48jj2OQY4wjj+OvY42jy6PNY8yjzmPN480j3aQeZB7kIaQ+pAzkTWRNpGTkZCRkZGNkY+RJ5MekwiTH5MGkw+TepM4kzyT" + "G5MjkxKTAZNGky2TDpMNk8uSHZP6kiWTE5P5kveSNJMCkyST/5IpkzmTNZMqkxSTDJMLk/6SCZMAk/uSFpO8lc2VvpW5lbqV" + "tpW/lbWVvZWpltSWC5cSlxCXmZeXl5SX8Jf4lzWYL5gymCSZH5knmSmZnpnumeyZ5ZnkmfCZ45nqmemZ55m5mr+atJq7mvaa" + "+pr5mveaM5uAm4Wbh5t8m36be5uCm5ObkpuQm3qblZv/////////////////////////////////////////////////////" + "/////////////////////////////////////32biJslnRedIJ0enRSdKZ0dnRidIp0QnRmdH52Inoaeh56unq2e1Z7Wnvqe" + "Ep89nyZRJVEiUSRRIFEpUfRSk1aMVo1WhlaEVoNWflaCVn9WgVbWWNRYz1jSWC1bJVsyWyNbLFsnWyZbL1suW3tb8VvyW7dd" + "bF5qXr5fu1/DYbVhvGHnYeBh5WHkYehh3mHvZOlk42TrZORk6GSBZYBltmXaZdJmjWqWaoFqpWqJap9qm2qhap5qh2qTao5q" + "lWqDaqhqpGqRan9qpmqaaoVqjGqSaltrrWsJbMxvqW/0b9Rv42/cb+1v52/mb95v8m/db+Jv6G/hcfFx6HHyceRx8HHicXNz" + "bnNvc5d0snSrdJB0qnStdLF0pXSvdBB1EXUSdQ91hHVDdkh2SXZHdqR26Xa1d6t3sne3d7Z3////////////////////////" + "//////////////////////////////////////////////////////////////////+0d7F3qHfwd/N4/XgCeft4/HjyeAV5" + "+Xj+eAR5q3moeVx6W3pWelh6VHpaer56wHrBegV8D3zyewB8/3v7ew589HsLfPN7AnwJfAN8AXz4e/17Bnzwe/F7EHwKfOh8" + "LX48fkJ+M35ImDh+Kn5JfkB+R34pfkx+MH47fjZ+RH46fkV/f39+f31/9H/yfyyAu4HEgcyByoHFgceBvIHpgVuCWoJcgoOF" + "gIWPhaeFlYWghYuFo4V7haSFmoWehXeFfIWJhaGFeoV4hVeFjoWWhYaFjYWZhZ2FgYWihYKFiIWFhXmFdoWYhZCFn4Vohr6H" + "qoeth8WHsIesh7mHtYe8h66HyYfDh8KHzIe3h6+HxIfKh7SHtoe/h7iHvYfeh7KHNYkziTyJPolBiVKJN4lCia2Jr4muifKJ" + "84kei///////////////////////////////////////////////////////////////////////////////////////////" + "GIsWixGLBYsLiyKLD4sSixWLB4sNiwiLBoscixOLGotPjHCMcoxxjG+MlYyUjPmMb41Ojk2OU45QjkyOR45Dj0CPhZB+kDiR" + "mpGikZuRmZGfkaGRnZGgkaGTg5Ovk2STVpNHk3yTWJNck3aTSZNQk1GTYJNtk4+TTJNqk3mTV5NVk1KTT5Nxk3eTe5Nhk16T" + "Y5Nnk4CTTpNZk8eVwJXJlcOVxZW3la6WsJasliCXH5cYlx2XGZeal6GXnJeel52X1ZfUl/GXQZhEmEqYSZhFmEOYJZkrmSyZ" + "KpkzmTKZL5ktmTGZMJmYmaOZoZkCmvqZ9Jn3mfmZ+Jn2mfuZ/Zn+mfyZA5q+mv6a/ZoBm/yaSJuam6ibnpubm6aboZulm6Sb" + "hpuim6Cbr5sznUGdZ502nS6dL50xnTidMJ3/////////////////////////////////////////////////////////////" + "/////////////////////////////0WdQp1DnT6dN51AnT2d9X8tnYqeiZ6NnrCeyJ7anvue/54knyOfIp9Un6CfMVEtUS5R" + "mFacVpdWmladVplWcFk8W2lcalzAXW1ebl7YYd9h7WHuYfFh6mHwYeth1mHpYf9kBGX9ZPhkAWUDZfxklGXbZdpm22bYZsVq" + "uWq9auFqxmq6arZqt2rHarRqrWpea8lrC2wHcAxwDXABcAVwFHAOcP9vAHD7byZw/G/3bwpwAXL/cflxA3L9cXZzuHTAdLV0" + "wXS+dLZ0u3TCdBR1E3VcdmR2WXZQdlN2V3ZadqZ2vXbsdsJ3unf/eAx5E3kUeQl5EHkSeRF5rXmseV96HHwpfBl8IHwffC18" + "HXwmfCh8InwlfDB8XH5QflZ+Y35YfmJ+X35RfmB+V35TfrV/s3/3f/h/dYDRgdKB////////////////////////////////" + "///////////////////////////////////////////////////////////QgV+CXoK0hcaFwIXDhcKFs4W1hb2Fx4XEhb+F" + "y4XOhciFxYWxhbaF0oUkhriFt4W+hWmG54fmh+KH24frh+qH5Yffh/OH5IfUh9yH04fth9iH44ekh9eH2YcBiPSH6Ifdh1OJ" + "S4lPiUyJRolQiVGJSYkqiyeLI4szizCLNYtHiy+LPIs+izGLJYs3iyaLNosuiySLO4s9izqLQox1jJmMmIyXjP6MBI0CjQCN" + "XI5ijmCOV45Wjl6OZY5njluOWo5hjl2OaY5UjkaPR49Ij0uPKJE6kTuRPpGokaWRp5GvkaqRtZOMk5KTt5Obk52TiZOnk46T" + "qpOek6aTlZOIk5mTn5ONk7GTkZOyk6STqJO0k6OTpZPSldOV0ZWzlteW2pbCXd+W2JbdliOXIpcll6yXrpeol6uXpJeql///" + "////////////////////////////////////////////////////////////////////////////////////////opell9eX" + "2ZfWl9iX+pdQmFGYUpi4mEGZPJk6mQ+aC5oJmg2aBJoRmgqaBZoHmgaawJrcmgibBJsFmymbNZtKm0ybS5vHm8abw5u/m8Gb" + "tZu4m9ObtpvEm7mbvZtcnVOdT51KnVudS51ZnVadTJ1XnVKdVJ1fnVidWp2Onoye354BnwCfFp8lnyufKp8pnyifTJ9VnzRR" + "NVGWUvdStFOrVq1WplanVqpWrFbaWN1Y21gSWT1bPls/W8NdcF6/X/thB2UQZQ1lCWUMZQ5lhGXeZd1l3mbnauBqzGrRatlq" + "y2rfatxq0Grras9qzWreamBrsGsMbBlwJ3AgcBZwK3AhcCJwI3ApcBdwJHAccCpwDHIKcgdyAnIFcqVypnKkcqNyoXLLdMV0" + "t3TDdBZ1YHbJd8p3xHfxdx15G3n/////////////////////////////////////////////////////////////////////" + "/////////////////////yF5HHkXeR55sHlnemh6M3w8fDl8LHw7fOx86nx2fnV+eH5wfnd+b356fnJ+dH5ofkt/Sn+Df4Z/" + "t3/9f/5/eIDXgdWBZIJhgmOC64Xxhe2F2YXhheiF2oXXheyF8oX4hdiF34XjhdyF0YXwheaF74XeheKFAIj6hwOI9of3hwmI" + "DIgLiAaI/IcIiP+HCogCiGKJWolbiVeJYYlciViJXYlZiYiJt4m2ifaJUItIi0qLQItTi1aLVItLi1WLUYtCi1KLV4tDjHeM" + "doyajAaNB40JjayNqo2tjauNbY54jnOOao5vjnuOwo5Sj1GPT49Qj1OPtI9AkT+RsJGtkd6Tx5PPk8KT2pPQk/mT7JPMk9mT" + "qZPmk8qT1JPuk+OT1ZPEk86TwJPSk+eTfZXalduV4ZYplyuXLJcolyaX////////////////////////////////////////" + "//////////////////////////////////////////////////+zl7eXtpfdl96X35dcmFmYXZhXmL+YvZi7mL6YSJlHmUOZ" + "ppmnmRqaFZolmh2aJJobmiKaIJonmiOaHpocmhSawpoLmwqbDpsMmzeb6pvrm+Cb3pvkm+ab4pvwm9Sb15vsm9yb2Zvlm9Wb" + "4Zvam3edgZ2KnYSdiJ1xnYCdeJ2GnYudjJ19nWuddJ11nXCdaZ2FnXOde52CnW+deZ1/nYedaJ2UnpGewJ78ni2fQJ9Bn02f" + "Vp9Xn1ifN1OyVrVWs1bjWEVbxl3HXe5e717AX8Ff+WEXZRZlFWUTZd9l6GbjZuRm82rwaupq6Gr5avFq7mrvajxwNXAvcDdw" + "NHAxcEJwOHA/cDpwOXBAcDtwM3BBcBNyFHKocn1zfHO6dKt2qna+du12zHfOd893zXfydyV5I3kneSh5JHkpef//////////" + "////////////////////////////////////////////////////////////////////////////////snluemx6bXr3ekl8" + "SHxKfEd8RXzufHt+fn6BfoB+un//f3mA24HZgQuCaIJpgiKG/4UBhv6FG4YAhvaFBIYJhgWGDIb9hRmIEIgRiBeIE4gWiGOJ" + "Zom5ifeJYItqi12LaItji2WLZ4tti66Nho6IjoSOWY9Wj1ePVY9Yj1qPjZBDkUGRt5G1kbKRs5ELlBOU+5MglA+UFJT+kxWU" + "EJQolBmUDZT1kwCU95MHlA6UFpQSlPqTCZT4kwqU/5P8kwyU9pMRlAaU3pXgld+VLpcvl7mXu5f9l/6XYJhimGOYX5jBmMKY" + "UJlOmVmZTJlLmVOZMpo0mjGaLJoqmjaaKZoumjiaLZrHmsqaxpoQmxKbEZsLnAic95sFnBKc+JtAnAecDpwGnBecFJwJnJ+d" + "mZ2knZ2dkp2YnZCdm53/////////////////////////////////////////////////////////////////////////////" + "/////////////6CdlJ2cnaqdl52hnZqdop2onZ6do52/namdlp2mnaedmZ6bnpqe5Z7knuee5p4wny6fW59gn16fXZ9Zn5Gf" + "OlE5UZhSl1LDVr1WvlZIW0dby13PXfFe/WEbZQJr/GoDa/hqAGtDcERwSnBIcElwRXBGcB1yGnIZcn5zF3VqdtB3LXkxeS95" + "VHxTfPJ8in6Hfoh+i36Gfo1+TX+7fzCA3YEYhiqGJoYfhiOGHIYZhieGLoYhhiCGKYYehiWGKYgdiBuIIIgkiByIK4hKiG2J" + "aYluiWuJ+ol5i3iLRYt6i3uLEI0Uja+Njo6Mjl6PW49dj0aRRJFFkbmRP5Q7lDaUKZQ9lDyUMJQ5lCqUN5QslECUMZTlleSV" + "45U1lzqXv5fhl2SYyZjGmMCYWJlWmTmaPZpGmkSaQppBmjqa////////////////////////////////////////////////" + "//////////////////////////////////////////8/ms2aFZsXmxibFps6m1KbK5wdnBycLJwjnCicKZwknCGct522nbyd" + "wZ3Hncqdz52+ncWdw527nbWdzp25nbqdrJ3InbGdrZ3MnbOdzZ2ynXqenJ7rnu6e7Z4bnxifGp8xn06fZZ9kn5KfuU7GVsVW" + "y1ZxWUtbTFvVXdFd8l4hZSBlJmUiZQtrCGsJaw1sVXBWcFdwUnAech9yqXJ/c9h01XTZdNd0bXatdjV5tHlwenF6V3xcfFl8" + "W3xafPR88XyRfk9/h3/egWuCNIY1hjOGLIYyhjaGLIgoiCaIKogliHGJv4m+ifuJfouEi4KLhouFi3+LFY2VjpSOmo6SjpCO" + "lo6XjmCPYo9HkUyUUJRKlEuUT5RHlEWUSJRJlEaUP5fjl2qYaZjLmFSZW5lOmlOaVJpMmk+aSJpKmv//////////////////" + "////////////////////////////////////////////////////////////////////////SZpSmlCa0JoZmyubO5tWm1Wb" + "RpxInD+cRJw5nDOcQZw8nDecNJwynD2cNpzbndKd3p3ancud0J3cndGd353pndmd2J3WnfWd1Z3dnbae8J41nzOfMp9Cn2uf" + "lZ+inz1RmVLoWOdYcllNW9hdL4hPXwFiA2IEYillJWWWZetmEWsSaw9rymtbcFpwInKCc4Fzg3NwdtR3Z3xmfJV+bII6hkCG" + "OYY8hjGGO4Y+hjCIMoguiDOIdol0iXOJ/omMi46Li4uIi0WMGY2YjmSPY4+8kWKUVZRdlFeUXpTEl8WXAJhWmlmaHpsfmyCb" + "UpxYnFCcSpxNnEucVZxZnEycTpz7nfed753jneud+J3knfad4Z3unead8p3wneKd7J30nfOd6J3tncKe0J7ynvOeBp8cnzif" + "N582n0OfT5//////////////////////////////////////////////////////////////////////////////////////" + "/////3GfcJ9un2+f01bNVk5bbVwtZe1m7mYTa19wYXBdcGBwI3LbdOV01Xc4ebd5tnlqfJd+iX9tgkOGOIg3iDWIS4iUi5WL" + "no6fjqCOnY6+kb2RwpFrlGiUaZTllkaXQ5dHl8eX5ZdemtWaWZtjnGecZpxinF6cYJwCnv6dB54DngaeBZ4AngGeCZ7/nf2d" + "BJ6gnh6fRp90n3Wfdp/UVi5luGUYaxlrF2saa2JwJnKqcth32Xc5eWl8a3z2fJp+mH6bfpl+4IHhgUaGR4ZIhnmJeol8iXuJ" + "/4mYi5mLpY6kjqOObpRtlG+UcZRzlEmXcphfmWicbpxtnAueDZ4Qng+eEp4RnqGe9Z4Jn0efeJ97n3qfeZ8eV2Zwb3w8iLKN" + "po7DkXSUeJR2lHWUYJp0nHOccZx1nBSeE572ngqf////////////////////////////////////////////////////////" + "//////////////////////////////////+kn2hwZXD3fGqGPog9iD+InoucjKmOyY5Ll3OYdJjMmGGZq5lkmmaaZ5okmxWe" + "F55InwdiHmsnckyGqI6ClICUgZRpmmiaLpsZnilyS4afi4OUeZy3nnV2a5p6nB2eaXBqcKSefp9Jn5ifgXi5ks+Iu1hSYKd8" + "+lpUJWYlVyVgJWwlYyVaJWklXSVSJWQlVSVeJWolYSVYJWclWyVTJWUlViVfJWslYiVZJWglXCVRJVAlbSVuJXAlbyWTJf//" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////" +) +CP950_ENC_EXC = {0xA2: b'\xa2F', 0xA3: b'\xa2G', 0xA5: b'\xa2D', 0x2022: b'\xa1E', 0x203E: b'\xa1\xc2', 0x223C: b'\xa1\xe3', 0x2609: b'\xa1\xf3', 0x2641: b'\xa1\xf2', 0x5341: b'\xa4Q', 0x5345: b'\xa4\xca', 0xFF64: b'\xa1N'} +CP950_ENC_REJECT = frozenset() + +# ---- big5hkscs ---- +BIG5HKSCS_DEC = _g( + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////8EMAMkwAA0YApkUAeEUAZ3IC" + "d00As0UAsXwC4kwAxXwClTsANkcAREcAR0wAQEwAv0ICFzYCUnMCi24C0nACV0wAUaMCT0cA2kUAhUwAbHwCB00ApEoAoUYA" + "I2sCJXIAVFoCYxoCBj4CYT8CTWYA+1YA////lX0AHVkAuYsC9D0ANJcA73sC21sAXh0CpFoAJTYAsJ4C0VoAt1sA/FwAbmcA" + "k4UARZkCYXQAnXQA////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////wDEAwTEAwjEAwzEAxDEADAECxTEA" + "0QACzQACxjEAxzEAywAC6B8CyDEAygACyTEAyjEAyzEAzDEADgECzTEAzjEAAAEAwQAAzQEAwAAAEgEAyQAAGgEAyAAATAEA" + "0wAA0QEA0gAA/v//vh4A/v//wB4AygAAAQEA4QAAzgEA4AAAUQIAEwEA6QAAGwEA6AAAKwEA7QAA0AEA7AAATQEA8wAA0gEA" + "8gAAawEA+gAA1AEA+QAA1gEA2AEA2gEA////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////3AEA/AAA/v//vx4A/v//wR4A" + "6gAAYQIA2iMA2yMA////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////qaMCRREC////CmUA////////PU4A3W4A" + "Tp0A35EA////////NXcCkWQAGk8AKE8AqE8AVlEAdFEAnFEA5FEAoVIAqFIAO1MATlMA0VMA2FMA4lYA8FgABFkAB1kAMlkA" + "NFkAZlsAnlsAn1sAmlwAhl4AO2AAiWUA/mcABGgAZWgATm0AvHAANXUApH4ArH4Aun4Ax34Az34A334ABn8AN38AeoIAz4IA" + "b4MAxokAvosA4osAZo8AZ48Abo8A////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////EXQA/HwAzX0ARmkAyXoAJ1IA////" + "////////////jJEAuHgAXpEAvIAA////C40A9oAA5wkC////////n4AAx54AzUwAyZ0ADJ4APkwA9p0CDnACCp4AM6ECwTUA" + "////mm4APoIAGXUA////EUkAbJoAj5oAmZ8Ah3kAbIQCyh0C0AUC5ioCJE4AgU4AgE4Ah04Av04A604AN08ATDQAvU8ASD4A" + "A1AAiFAAfTQAkzQApTQAhlEABVkA21EA/FEABVIAiU4AeVIAkFIAJ1MAxzUAqVMAUTUAsFMAUzUAwlMAI1QAbTUAcjUAgTYA" + "k1QAo1QAtFQAuVQA0FQA71QAGFUAI1UAKFUAmDUAP1UApTUAvzUA11UAxTUAhH0CJVUA////QgwCFQ0CK1ECkFUAxiwC7DkA" + "QQMCRo4AuE0C5ZQCU0AAvoACencAOCwCNDoA1UcAXYEC8mkC6k0C3WQAfA0CtA8C1QwC9BACjWQAfo4Alg4CCwwCZA8CqSwC" + "VoIC00QC////Rg0CTZoC6YAC9EcAp04CwiwCspoAZzoA9JUC7T8ABjUAx1IC1JcCyHgCRC0Cbp0AFZgA////2UMApWACtGQA" + "41QATC0CyisCdxAC+zkAbxAC////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////2mYCFmcCoHkC6mQAUlACQwwCaI4AoSEC" + "TIsCMQcC////C0gAqQEC+j8Ac1gAjS0C////yEUC/AQCl2ACTA8Clg0CeVUAu0AAukMA////tEoAZioCnRACqoEA9ZgAnA0C" + "eWMA/jkAdScCwI0AoVYAfGQAQz4A////AaYCCQ4CzyoCySwC////yBACwjkCkjkABjoAm4ICeDUASV4CxyACUlYAMQ8CsiwC" + "IJcCvDQAPWwAO04C////////dHUCiy4CCCICW6YCzYwCeg4CNAwCHGgCk38AzxACAygCOSkC+zUA41ECjA4CjQ8Cqg4Ckz8A" + "MA8CRw0CTxECTA4C////qw4CqQsCSA0CwBACPREC+T8AliYCMmQArQ8C9DMCOXYCzisCfg0Cfw0CUSwCVSwCGDoAmA4CxxAC" + "Lg8CMqYCUGsC0owCmY0CyowCqpUAzFQAxIIAuVUA////w54CJpwAtpoAXncC7i0CQHEAbYEA7IAAHFwAcmUCNIEAlzcAX1MA" + "vYACtpEA+g4CDw4Cdw4C+w4C3TUA600CCTYA1gwCr1YAtScCyRACEA4CeA4CeBACSBECB4ICVRQCeQ4CUE4CpC0CVFoAHRAC" + "HhAC9RAC9hACnFcAEQ4C////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////lHYCzYICtQ8Cew4CflECAzcAtg8CgBEC2FIC" + "vaIC2kkCOhgCd0ECfIICmVgAaFIAGjYAPVcCsnsAaFsAAEgALEsAJ58A50kAH5wAjZsAdFsCPTEC+1UA8jUAiVYAKE4AAlkA" + "wRsCePgCUZcAhgACW04Au04APjUAI1wAUV8AxF8A+jgATGIANWUAemsANWwAOmwAbHAAK3IALE4ArXIA6UgCUn8AO3kA+XwA" + "U38AamICwTQA////S2MCAoAAgIAAEmYCUWkCXVMAZIgAwYkAsngCoIsAHY0AhZQAeJUAf5UA6JUAD44C5pcAdZgAzpgA3pgA" + "Y5kAEJgCfJwAH54AxJ4Ab2sAB/kAN04AhwACHZYAN2IAopQA////O1AA/m0Ac5wCpp8AyT0Aj4gATkECd3AA9VwAIEsAzVEC" + "WTUAMF0CImEAMooCp48A9pEAkXEAGWcAunMAgTICB6ECizwAgBkCEEsA5HgAAnQArlEAD4cCCUAAY2oAuqICI0IAD4YAbwoC" + "KnoAR5kC6ooCVZcATXAAJFMAfiAC9JMA2XYA44kCp58A3XcAo04A8E8AvFAAL04AF08AqJ8ANFQAi30AklgA0FgAth0Ckl4A" + "mV4Awl8AEicCi2UA////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////+TMCGWkAQ2oAYzwC/2wA////AHIABUUCjHMA2z4A" + "E0oCFVsAuXQAg4sApFwClVYCk3oA7HsAw3wAbH4A+IIAl4UAqZ8AkIgAqp8AuY4Aq58Az48AX4UA4JkAIZIArJ8AuY0CPxQC" + "cUAAokIAGloA////////////aJgAa2cAdkIAPVcA////1oUAe0kCv4IADXECgUwAdG0Ce10AFWsCvm8CrZ8Arp8AllsAr58A" + "52YAW34AV24AynkAiD0Aw0QAVjIClicCmkMANkUA////1VwAGjsC+YoAeFwAEj0AUTUCeF0Asp8AV3EAWEUA7EACIx4Cd0wA" + "eDkASjQApAECQWwCzIoAtE8AOQICv1kAbIEAVpgA+pgCO18AnwsC////wSECbYkCAkEAu0YAeZACBz8As58AtaEC+EAA1jcA" + "90YARmwCfEEAsoYC/3MCbUUA1DgAmlQCYUUAG0UAiU0Ae0wAdk0A6kUAyD8AD0sCYTYA3kQAvUQA7UEAPl0ASF0AVl0A/D0A" + "DzgApF0AuV0AIDgAODgAQl4AvV4AJV8Ag18ACDkAFDkAPzkATTkA12AAPWEA5VwAiTkAt2EAuWEAz2EAuDkALGIAkGIA5WIA" + "GGMA+DkAsVYA////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////AzoA4mMA+2MAB2QAWmQASzoAwGQAFV0AIVYAn58AlzoA" + "hmUAvToA/2UAU2YA8joAkmYAIjsAFmcAQjsApGcAAGgAWDsASmgAhGgAcjsAcTsAezsACWkAQ2kAXHIAZGkAn2kAhWkAvDsA" + "1mkA3TsAZWoAdGoAcWoAgmoA7DsAmWoA8jsAq2oAtWoA1GoA9moAgWsAwWsA6msAdWwAqmwAyzwAAm0ABm0AJm0AgW0A7zwA" + "pG0AsW0AFW4AGG4AKW4Ahm4AwIkCu24A4m4A2m4Af58A6G4A6W4AJG8ANG8ARj0AQT8CgW8Avm8Aaj0AdT0At3EAmVwAij0A" + "LHAAkT0AUHAAVHAAb3AAf3AAiXAAJQMCwUMA8TUA2A4C1z4CvlcA024CPnEA4FcCTjYAomkA6YsCdFsASXoA4VgC2ZQCZXoA" + "fXoArFkCu3oAsHoAwnoAw3oA0XEAjWQCykEA2noA3XoA6noA70EAslQAAVwCC3sAVXsAKXsADlMC/lwConsAb3sAnIMAtFsC" + "f2wC0HsAIYQAknsA////IF0CrT0AZVwCkoQA+nsA////NXwAwVwCRHwAg3wAgkgCpnwAfWYAeEUCyXwAx3wA5nwAdHwA83wA" + "9XwA////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////Z34AHUUARG4CXX0A1m4CjXQAiX0Aq30ANXEAs30A////V0AC" + "KWAC5H0AEz0A9X0A+RcC5X0AbYMC////IWECWmECbn4Akn4AK0MAbJQAJ34AQH8AQX8AR38ANnkA0GIC4ZkAl38AUWMCo38A" + "YRYCaAACXEUAZjcCA0UAOoMC+n8AiWQC////CIAAHYAA////L4AAh6ACw2wCO4AAPIAAYYAAFCcCiUkAJmYC4z0C6GYCJWcA" + "p4AASIoCB4EAGoEAsFgA9iYCf2wAmGQCuE8C52QAihQCGIIAXhgCU2oAZUoClUoCekQAKYIADQsCUmoCfj0C+U8A/RQC4oQA" + "YoMACmsCp0kCMDUCcxcC+D0CqoIAG2kAlPkC20EAS4UA0IIAGoMAFg4CtBcCwTYAfTECWjUCe4IA4oIAGIMAiz4Co20CBWsC" + "l2sCzjUCvz0AHYMA7FUAhYMAC0UApW0CrIMA////04MAfjQA1G4CV2oAWoUAljQAQm4C7y4CWIQA5FsCcYQA0z0A5EQAp2oA" + "SoQAtTwCWHkA////lmsCd24CQ24C3oQA////kYMAoEQAk4QA5IQAkVwCQEIAwFwCQ0UANIUA8loAmW4CJ0UAc4UAFkUAv2cA" + "FoYA////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////JYYCO4YCwYUAiHACAoYAghUCzXACsvkCakUAKIYASDYAohgC91MA" + "mnMCfoYAcYcA+KAC7ocAJywCsYcA2ocAD4gAYVYAbIYAVmgAD0YARYgARogA4HUCuT0C5HUCXogAnIgAW0YAtIgAtYgAwWMA" + "xYgAd3cAD3cCh4kAiokA////////p4kAvIkAJYoC54kAJHkCvXoCnIoAk3cA/pEAkIoAWXoC6XoAOnsCjz8CE0cAOHsCfHEA" + "DIsAH4sAMFQCZVUCP4sATIsATYsAqYoAekoCkIsAm4sAr4oA3xYCFUYAT4gAm4wAVH0Cj30C1PkCJTcAU30C1owAmH0CvX0C" + "Eo0AA40AEBkC24wAXHAAEY0AyUwC0D4A////qY0AAoACFBACikkCfDsAvIECDHEC53oArY4Ato4Aw44A1JIAGY8ALY8AZYMC" + "EoQCpY8AA5MAn6ICUAoCs48AKkkA3okCPYUCuz0C+F4AYjIC+Y8AFKACvIYCAYUCJSMCgDkA124CN5AAPIUCvnoCYZAAbIUC" + "C4YCqJAAE4cCxJAA5oYCrpAA////Z5EA8DoAqZEAxJEArHwAM4kCiR4CDpIAn2wAQZIAYpIAuVUC////xooCmzwCDIsC21UC" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////MQ0CLJMAa5MA4YoC64sCj3AAw1oA4ooC5YoCZUkARJIA7IsCOYwC/4sC" + "c5MAW5QAvI4AhZUAppUAJpQAoJUA9m8AuUIAeiYC2IYCfBICLj4C30kAHGwAe5YAlpYAbEEAo5YA1W4C2mEAtpYA9XgA4IoC" + "vZYAzFMAoUkAuGwCdAICEGQCr5AC5ZAC0UoCFRkCCjMCMZcAQoYANpcAD0oAPUUAhUUA6UoCdXAAQVsAG5cA////1ZECV5cA" + "SlsA65ECX5cAJZQA0FAAtzACvDACiZcAn5cAsZcAvpcAwJcA0pcA4JcAbFQC7pcAHHQAM5QC////9ZcAHZQCenkC0UoANJgA" + "M5gAS5gAZpgADjsAdXECUT0AMAYCXEECBlcCypgAt5gAyJgAx5gA/0oAJ20C0xYCsFUA4ZgA5pgA7JgAeJMAOZkAKUoCcksA" + "V5gCBZkC9ZkADJoAO5oAEJoAWJoAJVcCxDYAsZAC1ZsC4JoA4poABZsC9JoADkwAFJsALZsAAIYCNFAANJsAqGkCwzgAfTAC" + "UJsAQJsAPp0CRVoAYxgCjpsAS0ICApwA/5sADJwAaJ4C1J0At58CkqECq6EC4aACI6EC36ECfp0Ag50ANKECDp4AiGgA////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////xJ0AWyECk6ECIKICOxkCM6ICOZ0AuaACtKICkJ4AlZ4Anp4Aop4ANE0Aqp4A" + "r54AZEMCwZ4AYDsA5TkAHT0AMk8AvjcAK4wCAp8ACJ8AlksAJJQAom0CF58A////OZ8An1YAilYARZ8AuJkAi5AC8pcAf4QA" + "Yp8AaZ8A3HoAjp8AFnIAvksAdUkCu0kCd3EA+EkCSEMCUUoCnnMA2osC+hgCn3kAfokCNo4CaZMA85MARIoC7JIAgZMAy5MA" + "bIkCuUQCF3IA6z4AcncAQ3oA0HAAc0QC+EMCfnEA7xcCo3AAvhgCmTUCxz4AhRgCL1QC+BcCIjcA+xYCORgC4TYAdBcC0RgC" + "S18CIzcAwBYCW1cAJUoC/hMCqBICxhMCthQCA4UApjYC////VYQAlEkCZXECMT4CXFUC+z4CUnAC9EQA7jYCnZkCJm8C+WcA" + "MzcAFTwA5z0AbFgAIhkCEGgAV0AAPzcC4UACi0ACD0ECIWwCy1QAnlYAsWYCklYA3w8CqAsCDQ4CxpMAE4sCnJMA+E4AK1EA" + "GTgANkQCvE4AZQQCfwMCS08Aik8AUVYCaFoAqwECywMCmTkACgMCFAQCNTQAKU8AwAICs44CdQIC2ooADAICmE4A////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////zVAADVEAok8AA08ADkoCij4CQk8ALlAAbFAAgVAAzE8A5U8AWFAA/FAA////////" + "////////dm4AlTUCOT4Cvz4Ccm0AhBgCiT4CqFEAw1EA4AUC3UQAowQCkgQCkQQCeo0AnIoCDgcCWVIApFIAcwgC4VIA////" + "ekYAjHEAjEMCIAwCrEkC5BAC0WkAHQ4C////3j4AmXQAFHQAVnQAmHMAjksAvEoCjUAC0FMAhDUAD3IAyUACtFUARQMCzVQA" + "xgsCHVcAXZIA9JYAZpMA3VcAjVcAf1cAPjYAy1gAmVoARooC+hYCbxcCEBcCLFoAuFkAj5IAfloAz1oAEloARlkC8xkCYRgC" + "lUIC9TYABW0AQ3QAIVoAg14CgVoA14sCEwQC4JMAjHQAAxMCBXEAckkACJQA+4kCvZMAoDcAHlwAnlwAXl4ASF4AlhkCfBkC" + "7joCzV4AT1sAAxkCBBkCATcAoBgC3TYA/hYC0zYAKoEAR4oCuh0CcjQCqIkCDF8ADl8AJxkCqxcCa1oAOxcCRFsAFIYA/XUC" + "YIgAfmAAYCgCKyYC218AuD4AryUCviUCiJACc28CwGEAPgACRgACGyYCmWEAmGEAdWAAmywCBy0C1EYCTZEC////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////cWQAZUYCaisCKToAIisCUDQC6pgCeC4CN2MAW6QCtmQAMWMA0WMA40kCZy0CpGIAoSwC" + "O2QAa2UAcmkA9DsAjjACrTICiUkCqzICDVUA4DIC2RgCP5QCzmYAiTICszEC4DoAkEEAhFUCIosCj1UC/BYCW1UCJVQC7ngA" + "AzECKhgCNDICZDQADzICgjECyUICjmYAJG0Ca2YAk0sAMGYAcHgC6x0CY2YA0jIC4TICHmYAclgC0TgAOjgCvDcCmTsAojcC" + "/jMC0HQAljsAj2cAKkYCtmgAHmgAxDsAvmoAYzgA1TcCh0QCM2oAUmoAyWoABWsAEhkCEWUAmGgATGoA1zsAemoAV2sAwD8C" + "mjwCoJMA8pIA6osCy4oCiZIAHoAC3IkCZ5QApW0AC28A7EkC////fz8Cjz0ABG4APEACPVoACm4AR1gAJG0AQngAO3EAGkMC" + "dkIC8XAAUHIAh3IAlHIAj0cCJUcCeVEApEoC6wUCenQA+D4CXzYCSkoCF0kC4V8CBj8AsT4A30oCI4wCNT8Cp2AA8z4AzHQA" + "PHQAh5MAN3QAn0QA6m0CUUUAg3UAYz8A2UwCBk0CWD8AVXUAc3YAxqUCGTsAaHQAzIoCq0kCjkkC+zoA////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////zT0ATkoC/z4AxUkC80gC+pEAMlcAQpMA44oCZBgC31AAIVIC51ECeHcAMjICDncAD3cAe3cA" + "l0YCgTcCXjoA8EgCOHQAm3QAvz4AukoCx0oCyEAAlkoCrmECB5MAgVUCHngAjXgAiHgA0ngA0HMAWXkAQXcC41YCDkEA////" + "loQApXkALWoA+j4COnoA9HkAbkEA5hYCMkEANZIA8XkATA0CjEkCmQICuj0CbhcClzUAa1UAcDUAqjYA1AECDQwC4noAWVoA" + "9SYCr1oCnFoCDVoAWwIC8HgAKloAxlsC/noA+UEAXXwAbXwAEUIAs1sCvF4Cpl4CzXwA+UkCsBcCjnwAfHwArnwAsmoA3H0A" + "B34A030ATn8AYWICXGECSHsCl30Agl4CakIAdWsCFgkC1mcATgACzzUCxFcAEmQC+GMCYkkC3X8AJ3sALAgC6VoCQ10CDHsA" + "Dl4C5pkARYYAY5oAHGoAPzQC4jkA90kCrWUCH5oAoGUCgIQAJ3EC0WwC6kQAN4EAAkQAxoAACYEAQoEAtGcCw5gAQmoCYoIA" + "ZYIAUWoCU4QAp20CEIYAG3IChloAf0EAQBgCK1sAoRgC5FoA2BgCoIYAvPkCjz0CLYgAInQCAloA////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////bogARU8Ah4gAv4gA5ogAZYkATYkAg1YCVIkAhXcChHcC9YsC2YsCnIsC+YkCrT4Ao4QA9UYAz0YA" + "8jcAPYoAHIoASJQCTV8AK5IAhEIC1GUAKXEAxHAARRgCbZ0An4wA6YwA3H0CmlkAw3cA8FkAbkMA1DYAKo4Ap44ACUwCMI8A" + "So8A9EIAWGwAu28AISMCm0gAeW8Ai24A2hcC6ZsAtTYAL0kCu5AA////cVUABkkAu5EABJQAS4oCYkAA/IoCJ5QAHYwCO4wC" + "5YQAK4oAmZUAp5UAl5UAlpUANI0CRXQAwj4A/0gCQkoC6kMC5z4AJTICj5YA544CZo4CZY4CzD4A7UkCeEoC7j8CEnQAa3QA" + "/D4AQZcAsJACR2gAHUoAk5AC31cC////aJMAiYkCJowCL4sCvmMCupIAEVsAaYsAPEkA+XMAG0ICm5cAcZcAOJkAJg8CwV0A" + "xYsCskoCH5gA2pQC9pIA15UC5ZEAwEQAUIsCZ0oCZIsC3JgARYoCAD8AKpIAJUkAFIQAO5kATZkABnsC/T0Am5kAb0sAqpkA" + "XJoAZYsCyFgCj2oAIZoA/loAL5oA8ZgCkEsASJkCvJkAvUsAl0sAfZMAclgAAhMCIlgAuEkC////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////6BQCRHgAHycCuD0CxWgAfT0AWJQAJzkAUGEAgScCaykCB2EAT5wAU5wAe5wANZwAEJwAf5sAz5sALZ4C" + "n5sA9aEC/qACIZ0ArkwABEECGJ4AsEwADJ0AtKEC7aAC86ACL5kCpZ0AvYQAEm4C328CgmsC/IUAM0UApG0ChG4C8G0CIIQA" + "7oUAAG4C1zcCZGAC4nkAnDUCQDYCLUkA3kkCYj0A25MAvpIASJMAvwICuXgAd5IATZQA5E8AQDQAZJAAXVUCPXgAVHgAtngA" + "S3gAVxcCyTECQUkCmjYAck8A2m8A2W8A////HnAAFFQAtUECu1cA81gAilcAFp0A11cANHEArzQArEEC63EAQGwCl08C////" + "tRcCSYoCDGEAzloAC1oAvEIAiEQCLDcAe0sA/IkCu5MAuJMA1hgCHQ8CcoQAwGwCExQC+kICJiwCwUMClFkAtz0CQWcCqH0A" + "W2ECpGACuUkCi0kC+okC5ZIA4nMA6T4AtHQAY4sCnxgC4T4As0oC2GoA83MA+3MA1j4APkoClEoC2RcCZkoCpwMCJBQC5UkC" + "SHQAFkkCpXAAdkkChJIA5nMAX5MA/gQCMZMAzooCFooChpMA54sC1VUCNUkAgooCa3EA////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////Q0kC/wwCpFYAGgYC6wsCuAwCAlUAxHkA+hcC/n0AwhYCUEoCUhgCLkUAAZQACjcAwIoCrUkCsFkAvxgCgxgC" + "hHQCoVoA4jYAWz0CsDYAX5IAeVoAgYoCYhgCdJMAzTwAtAoClkoAijkA9FAAaT0ATD0AnBMCdXEA+0IAGIICD24A5JAC60QA" + "V20AT34CZ3AAr2wA1jwA7T8CLT4CAm4ADG8Abz0A9QMCUXUAvDYAyDQAgEYA2j4AcUgAxFkAbpIAPkkAQY8AHIwCwGsCElgA" + "yFcA1jYAUhQC/nAAYkMCcUoC4y8CsBICvSMCuWgAZ2kAmBMC5TQC9HsC3zYCg4oC1jcC+jMCn0wCGmoArTYCt2wCPoQA30QA" + "zkQAJm0CUW0CgmwC3m8CF28ACXECPYMAOhcC7YMAgGwCU3AC2xcCiVkAgloAsxcCYVoAcVoABRkC/EECLTcA71kAPBcCxzYA" + "jnEAkJMAmmYApUICbloAK1oAk0ICK2oA+T4CNncCW0QCykICHXEAWUIC4YkCsE8AKG0CwlwAzkQCTX4CvUMCDGoAVkICBBMC" + "pnAAM3EA6UMCpT0A32wAJfgCT0oCZX4A61kAL10A8z0AXF8AXUoC3xcCpH0AJoQA////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////hVQA+joCADMCFAICflcA1QgCGQYC5T8Anh8CtqICA3AAW5ECcF0Aj3MA03wAWYoCIJQCyE8A538AzXIAEHMA9HoC" + "OHMAOXMA9lYCQXMASHMAqT4AGHsCbJAA9XEA8kgC4XMA9oEAyj4ADHcA0T4AomwA/VYAGXQAHnQAH3QA4j4A8D4A9D4A+j4A" + "03QADj8AUz8AQnUAbXUAcnUAjXUAfD8AyHUA3HUAwD8ATXYA1z8AdHYA3D8AenYAXE8CiHEAI1YAgIkAaVgAHUAAQ3cAOUAA" + "YWcARUAA2zUAmHcAakAAb0AAXlwAvncAy3cA8lgAGHgAuXAAHHgAqEAAOXgAR3gAUXgAZngASIQANVUCM3kAA2gAMnkAA0EA" + "CUEAkXkAmXkAu48ABnoAvI8AZ0EAkXoAskEAvHoAeYIAxEEAz3oA23oAz0EAIU4AYnsAbHsAe3sAEnwAG3wAYEIAekIAe3wA" + "nHwAjEIAuHwAlEIA7XwAk48AwHAAzwwCz30A1H0A0H0A/X0Arn8AtH8An3IAl0MAIIAAJYAAOXsALoAAMYAAVIAAzD0AtFcA" + "oHAAt4AA6YAA7UMADIEAKnMADoEAEoEAYHUAFIEAAUQAOTsAVoEAWYEAWoEA////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////E0QAOlgAfIEAhIEAJUQAk4EALUQApYEA71cAwYEA5IEAVIIAj0QApoIAdoIAyoIA2IIA/4IAsEQAV4MAaZYAimkABYQA" + "9XAAZIQA42AAiIQABEUAvoQA4YQA+IQAEIUAOIUAUoUAO0UAb4UAcIUA4IUAd0UAcoYAkoYAsoYA74YARZYAi4cABkYAF0YA" + "rogA/4gAJIkAR4kAkYkAZ3kCKYoAOIoAlIoAtIoAUYwA1IwA8owAHI0AmEcAX1gAw40A7UcA7k4AOo4A2FUAVFcAcY4A9VUA" + "sI4AN0gAzo4A4o4A5I4A7Y4A8o4At48AwY8Ayo8AzI8AM5AAxJkArUgA4JgAE5IAHkkAKJIAWJIAa5IAsZIArpIAv5IA45IA" + "65IA85IA9JIA/ZIAQ5MAhJMArZMARUkAUUkAv54AF5QAAVMAHZQALZQAPpQAakkAVJQAeZQALZUAopUAp0kA9JUAM5YA5UkA" + "oGcAJEoAQJcANUoAspcAwpcAVFYA5EoA6GAAuZgAGUsA8ZgARFgADpkAGZkAtFEAHJkAN5kAQpkAXZkAYpkAcEsAxZkAnUsA" + "PJoAD5sAg3oAaZsAgZsA3ZsA8ZsA9JsAbUwAIJwAbzcAwhsCSZ0AOpwA////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "/p4AUFYAk50AvZ0AwJ0A/J0A9pQAto8Ae54ArJ4AsZ4AvZ4Axp4A3JQA4p4A8Z4A+J4AyHoARJ8AlAACtwICoAMCGmkAw5QA" + "rFkA1wQCQFgAwZQAuTcA1QUCFQYCdgYCuhYCV1cAc3EAwgoCzQoCvwsCalQAO/gCywsCnlQA+wsCOwwCUwwCZQwCfAwC52AA" + "jQwCelYAtQwC3QwC7QwCbw0Csg0CyA0CVWkAL5wApYcABA4CDg4C1w4CkA8CLQ8Ccw4CIFwAvA8CC14AXBACTxACdhACHmcA" + "exACiBAClhACRzYAvxAC0xACLxECOxECZFMArYQA4xICdRMCNhMCgYsAdxUCGRYCwxcCxxcCeE4Au3AALRgCahkCLRoCRRoC" + "KhwCcBwCrBwCyB4Cw2IA1R4CFR8CmHEAVWgARSAC6WkAyDYAfCIC1yMC+iMCKicCcSgCTykC/YIAZykCkykC1SoCpYkA6CoC" + "oI8ADisCuJcAPysCR5gAvZoATCwC////iCwCtywC6FsCCC0CEi0Cty0ClS0CQi4CdC8CzC8CMzACZjACHzMC3jMCsV8ASGYA" + "v2YAeXoCZzUC8zUC////ukkC////GjYCFjcC////RgMCtVgADmcA////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////GGkA" + "pzoCV3YC4l8CET4CuT4C/nUCmiAC0EgAuEoAGUECmooC7kICDUMCO0ACNEMClkMCRUoCygUC0lEAEQYCn1kAqB4CvjsA/zwC" + "BEQC1kQCiFcAdEYCmzkAL0cC6IUCyZkCYjcAwyECXosATosC////EkgC+0gCFUoCCXIAwEoCeAwCZVkApU4Chk8CeQcC2o4A" + "LFACj1IAP1cAcXEAmVICGVQCSj8Cp0oCvFUARlQCblQCUmsC////czQAP1UCMnYCXlUCGEcAYlUCZlUCx1cCP0kCXVgCZlAA" + "+zQAzDMC////A1kCfEcASIkCrloCiVsCBlwCkB0CoVcAUXEA////AmECEnwCVpAAsmECmk8CYosAAmQCSmQCW10A92sC////" + "hGQCHBkC6ooA9kkCiGQC7z8CEmUCwEsAv2UCtWYCGycCZZQA4VcClWEAJ1oAzfgC////uVYAIUUC/GYCak4ANEkCVpYAj20A" + "vWwCGDYAd4kAmWcCbmgCEWQCXmgC////x2gCQnsAwJACEQoCJmkC////OWkCRXoA////+mkCJpoALWoCXzYAaWQCIQACg3kA" + "NGoCW2sCLF0AGTUC////nWsC0EYApGwCO3UAZYgArm0CtlgA////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////HDcAjSUC" + "S3ACzXECVDwAgHIChXICgZIAeiECi3ICMJMA5nIC0EkCOWwAn5QAUHQC+A4CJ4gA9YgAJikCc4QCsRcCuG4AKkoCIBgCpDkA" + "uTYA////////P0UAtmYArZwCpJgCQ4kAzHcCWHgC1lYA30AAChYCoTkALzcC6IACxRMCrXEAZoMA3XkCqJEC////t0wAr3AC" + "q4kC/XkCCnoCC3sCZn0CekECQ3sAfnkACYACtW8A36ICA2oAGIMColMAB24Cv5MANmgAXZcAb4ECI4ACtWkC7RMCLzICSIAC" + "hV0AMIwCg4ACFVcAI5gASYkCq10AiEkCvmUA1WkA0lMApUoCgT8CETwANmcAkIAC9IACLoECoR8CT4ECiYECr4ECGoICBoMC" + "L4MCioMCyjUAaIQCqoYC+kgA5mMAVokCCHgAVZIAuIkC8kMA54kC30MA6IkCRosC1IsC+FkACYwC////xY8C7JAC////EJEC" + "PJEC9z0AXpECykoC0I8Aj3IAi1YA55QC6ZUCsJUCuJUCMpcC0ZgCSZkCapkCw5kCKJoCDpsCWp0Cm50Cn34A+J4CI58CpEwA" + "R5UAk6IConEA/6ICkU0AEpAAy6UCnE0AnAwCvo8AwVUA////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////uo8AsCQCuY8A" + "k0oCCUUAf34AVm8AsWoA6k4A5DQALIsCnXgCOjcAgI4A9RcCJIACbIsCmYsCPnoCr2YC6z0AVXYCtzwCNVYCVlkCmk4AgV4C" + "WGICv1YAbQ4CDo4AbVsAiD4CnkwC3mMA////9hcCexgCMGUALVYASlwCGlQAEVMCxj0AmJ0CfUwAIlYAHlYASX8A2F4CdVkA" + "QD0CcIcAHE4A6g8CSQ0CujYCF4EAXp0AGI0AO3YARZwATnYAuXcARZMAMlQASIEA94IAJVYAMoEAGIQAvYAA6lUAYnkAQ1YA" + "FlQAnQ4CzjUABVYA8VUA8WYA4oICLTYANHUA8FUAulUAl1QAclUAQQwClgwC0F4ASFECdg4CYiwCog4Cq54AWn0A3lUAdRAC" + "nWIAbZcAlFQAzYwA9nEAdpEA/GMAuWMA/mMAaVUAQysCcpwAsy4CmlEA3zQApw0Cp1EATVQAHlUAE1UAZnYALY4AimgCsXUA" + "toAABIgAhocAx4gAtoEAHIQAwRAC7EQABHMABkcCkFsAC4MAk2gCe1YA9CYCL30Co0ECc30C0G4CtnICcJEA2RECCJIA/DwC" + "qaYCrA4C+Q4CZnIAohwCTkcAwk8C+X8C6w8C+kAA////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////XZwAH2UAoC0C80gA" + "4EcCfJ0C7A8CCg4C////o3UC7Q8C////SGAChxECo3EAjn4AUJ0AGk4ABE4AdzUADVsAsmwAZ1MArDYA3DkAfVMApTYAGEYC" + "mlgAbksCLYIAS1QAqlcAlVoCeQkC////UjoAZSQCdHMArJ4CCU0A7ZsA/jwCMJ8CW0wAqU8CnpUC3p8CXIQAtj0CsnICs2cC" + "IDcCLmMAJX0A9z4CLD4CKjoACJAAzFIAdD4AejYA6UUAjgQCQHYA8FoAtg4CengALn8Cp1gAv0AAfFYAi5sAdF0AVHYANKQC" + "hZ4A4UwA////+zcAGWEA2jAC8kMC////XVYAqRICp1cAY0kCBp4CNFIArnACrTUA////fJ0AVnwAOZsA3lcAbBcCU1wA02QA" + "0JQCNWMCZHECrYYAKA0CIm0C4koCcQ0C/////lEADx8Cjl0AA5cA0R0CgZ4ATJAAH3sAApsA0VwAo3sAaGIANWMA/5oAz3sA" + "KpsAfnwA////QnwAhnwAFZwA/HsACZsA////G5wAPkkCWp8Ac1UAw1sA/U8AmJ4A8k8AYFIABj4A0VIAZ1cAVlAAt1kAEl4A" + "yJcAq50AXI8AaVQAtJcAQJkAupcALFMAMGEA////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////LGkA2lMACpwAAp0AO0wA" + "QZYAgGkAplAARnUAbRcC2pkAc1IA////WZEAgZYAXJEA////UZEAl44Cf2MAI20CymoAEVYAjpEAenUAhWIA/AMCT3MAcHwA" + "IVwC/TwC////GUkC1nYAnZsAKk4A1AwCvoMAQogA////SlwAwGkA////elcAH1IA9V0Azk4AMWwA8gECOU8AnFQA2lQAmlIA" + "go0A/jUA////8zUA////UmsAfJEApZ8Al5sALpgAtJgAupoAqJ4AhJ4AenEAFHsA////+msAGIgAeH8A////IFYASqYCd44A" + "U58A////1I0AT44AHJ4AAY4AgmIAfYMCKI4AdY4A03oAd0oCPnoA2HgA6mwAZ4oAB3YAWooCJp8AzmwA1ocAw3UAsqICU3gA" + "QPgCDI0A4nIAcXMALYsAAnMA8XQA64wAu0oCL4YAul8AoIgAt0QA////OxgCBW4C////fooAGyUC/////WAAZ3YA15oARJ0A" + "bpMAj5sA9YcA////////94wALHMAIZcAsJsA1jUAsnIAB0wAUXwASpkAWWECWWEABEwAlp4AfWEA////X1cAb2EApmIAOWIA" + "////XDoA4mEAqlMA9TMCZGMAAmgA0jUA////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////V10AwosC2o8AOY4C////2VAA" + "Rh0CBnkAMlMAOJYAOw8CZUAA/////ncA////wnwAGl8C2nwALXoAZoAAY4AATX0ABXUA8nQAlIkAGoIADGcAYoAAhnQCW4AA" + "8HQAA4EAJHcAiYkAzGcCU3UA0W4CqYcAzocAyIEAjIcASYoArYwAQ4sAK3cA+HQA2oQANTYAsmkApo0A////qYkA////uW0A" + "wYcAEUAC53QA2z0AdnEApGAAnGEA0TwA////d2AA////cX8ALYsC////6WAAfksAIFIAGDwAxzwC114CVnYCMVUCRBkC/hIC" + "A5kC3G0CrXACwVwArWECD4oCdzYC7gACRmgCDk8CYkUAH1sATGMCUJ8App4Aa2ICADAADP8AATAAAjAADv8AIiAAG/8AGv8A" + "H/8AAf8AMP4AJiAAJSAAUP4AZP8AUv4AtwAAVP4AVf4AVv4AV/4AXP8AEyAAMf4AFCAAM/4AdCUANP4AT/4ACP8ACf8ANf4A" + "Nv4AW/8AXf8AN/4AOP4AFDAAFTAAOf4AOv4AEDAAETAAO/4APP4ACjAACzAAPf4APv4ACDAACTAAP/4AQP4ADDAADTAAQf4A" + "Qv4ADjAADzAAQ/4ARP4AWf4AWv4A////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////W/4AXP4AXf4AXv4AGCAAGSAAHCAA" + "HSAAHTAAHjAANSAAMiAAA/8ABv8ACv8AOyAApwAAAzAAyyUAzyUAsyUAsiUAziUABiYABSYAxyUAxiUAoSUAoCUAvSUAvCUA" + "ozIABSEAPiAA4/8AP/8AzQIASf4ASv4ATf4ATv4AS/4ATP4AX/4AYP4AYf4AC/8ADf8A1wAA9wAAsQAAGiIAHP8AHv8AHf8A" + "ZiIAZyIAYCIAHiIAUiIAYSIAYv4AY/4AZP4AZf4AZv4APCIAKSIAKiIApSIAICIAHyIAvyIA0jMA0TMAKyIALiIANSIANCIA" + "QCYAQiYAQSYACSYAkSEAkyEAkCEAkiEAliEAlyEAmSEAmCEAJSIAIyIAD/8APP8AD/8APP8ABP8ApQAAEjAAogAAowAABf8A" + "IP8AAyEACSEAaf4Aav4Aa/4A1TMAnDMAnTMAnjMAzjMAoTMAjjMAjzMAxDMAsAAAWVEAW1EAXlEAXVEAYVEAY1EA51UA6XQA" + "znwAgSUAgiUAgyUAhCUAhSUAhiUAhyUAiCUAjyUAjiUAjSUAjCUAiyUAiiUAiSUAPCUANCUALCUAJCUAHCUAlCUAACUAAiUA" + "lSUADCUAECUAFCUAGCUAbSUA////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////biUAcCUAbyUAUCUAXiUAaiUAYSUA4iUA" + "4yUA5SUA5CUAcSUAciUAcyUAEP8AEf8AEv8AE/8AFP8AFf8AFv8AF/8AGP8AGf8AYCEAYSEAYiEAYyEAZCEAZSEAZiEAZyEA" + "aCEAaSEAITAAIjAAIzAAJDAAJTAAJjAAJzAAKDAAKTAAQVMARFMARVMAIf8AIv8AI/8AJP8AJf8AJv8AJ/8AKP8AKf8AKv8A" + "K/8ALP8ALf8ALv8AL/8AMP8AMf8AMv8AM/8ANP8ANf8ANv8AN/8AOP8AOf8AOv8AQf8AQv8AQ/8ARP8ARf8ARv8AR/8ASP8A" + "Sf8ASv8AS/8ATP8ATf8ATv8AT/8AUP8AUf8AUv8AU/8AVP8AVf8AVv8AV/8AWP8AWf8AWv8AkQMAkgMAkwMAlAMAlQMAlgMA" + "lwMAmAMAmQMAmgMAmwMAnAMAnQMAngMAnwMAoAMAoQMAowMApAMApQMApgMApwMAqAMAqQMAsQMAsgMAswMAtAMAtQMAtgMA" + "twMAuAMAuQMAugMAuwMAvAMAvQMAvgMAvwMAwAMAwQMAwwMAxAMAxQMAxgMAxwMAyAMAyQMABTEABjEABzEACDEACTEACjEA" + "CzEADDEADTEADjEADzEA////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////EDEAETEAEjEAEzEAFDEAFTEAFjEAFzEAGDEA" + "GTEAGjEAGzEAHDEAHTEAHjEAHzEAIDEAITEAIjEAIzEAJDEAJTEAJjEAJzEAKDEAKTEA2QIAyQIAygIAxwIAywIA////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////AE4AWU4AAU4AA04AQ04AXU4Ahk4AjE4Auk4AP1EAZVEA" + "a1EA4FEAAFIAAVIAm1IAFVMAQVMAXFMAyFMACU4AC04ACE4ACk4AK04AOE4A4VEARU4ASE4AX04AXk4Ajk4AoU4AQFEAA1IA" + "+lIAQ1MAyVMA41MAH1cA61gAFVkAJ1kAc1kAUFsAUVsAU1sA+FsAD1wAIlwAOFwAcVwA3V0A5V0A8V0A8l0A810A/l0Acl4A" + "/l4AC18AE18ATWIA////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////EU4AEE4ADU4ALU4AME4AOU4AS04AOVwAiE4AkU4A" + "lU4Akk4AlE4Aok4AwU4AwE4Aw04Axk4Ax04AzU4Ayk4Ay04AxE4AQ1EAQVEAZ1EAbVEAblEAbFEAl1EA9lEABlIAB1IACFIA" + "+1IA/lIA/1IAFlMAOVMASFMAR1MARVMAXlMAhFMAy1MAylMAzVMA7FgAKVkAK1kAKlkALVkAVFsAEVwAJFwAOlwAb1wA9F0A" + "e14A/14AFF8AFV8Aw18ACGIANmIAS2IATmIAL2UAh2UAl2UApGUAuWUA5WUA8GYACGcAKGcAIGsAYmsAeWsAy2sA1GsA22sA" + "D2wANGwAa3AAKnIANnIAO3IAR3IAWXIAW3IArHIAi3MAGU4AFk4AFU4AFE4AGE4AO04ATU4AT04ATk4A5U4A2E4A1E4A1U4A" + "1k4A104A404A5E4A2U4A3k4ARVEARFEAiVEAilEArFEA+VEA+lEA+FEAClIAoFIAn1IABVMABlMAF1MAHVMA304ASlMASVMA" + "YVMAYFMAb1MAblMAu1MA71MA5FMA81MA7FMA7lMA6VMA6FMA/FMA+FMA9VMA61MA5lMA6lMA8lMA8VMA8FMA5VMA7VMA+1MA" + "21YA2lYAFlkA////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////LlkAMVkAdFkAdlkAVVsAg1sAPFwA6F0A510A5l0AAl4A" + "A14Ac14AfF4AAV8AGF8AF18AxV8ACmIAU2IAVGIAUmIAUWIApWUA5mUALmcALGcAKmcAK2cALWcAY2sAzWsAEWwAEGwAOGwA" + "QWwAQGwAPmwAr3IAhHMAiXMA3HQA5nQAGHUAH3UAKHUAKXUAMHUAMXUAMnUAM3UAi3UAfXYArnYAv3YA7nYA23cA4ncA83cA" + "OnkAvnkAdHoAy3oAHk4AH04AUk4AU04AaU4AmU4ApE4Apk4ApU4A/04ACU8AGU8ACk8AFU8ADU8AEE8AEU8AD08A8k4A9k4A" + "+04A8E4A804A/U4AAU8AC08ASVEAR1EARlEASFEAaFEAcVEAjVEAsFEAF1IAEVIAElIADlIAFlIAo1IACFMAIVMAIFMAcFMA" + "cVMACVQAD1QADFQAClQAEFQAAVQAC1QABFQAEVQADVQACFQAA1QADlQABlQAElQA4FYA3lYA3VYAM1cAMFcAKFcALVcALFcA" + "L1cAKVcAGVkAGlkAN1kAOFkAhFkAeFkAg1kAfVkAeVkAglkAgVkAV1sAWFsAh1sAiFsAhVsAiVsA+lsAFlwAeVwA3l0ABl4A" + "dl4AdF4A////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////D18AG18A2V8A1l8ADmIADGIADWIAEGIAY2IAW2IAWGIANmUA" + "6WUA6GUA7GUA7WUA8mYA82YACWcAPWcANGcAMWcANWcAIWsAZGsAe2sAFmwAXWwAV2wAWWwAX2wAYGwAUGwAVWwAYWwAW2wA" + "TWwATmwAcHAAX3IAXXIAfnYA+XoAc3wA+HwANn8Ain8AvX8AAYAAA4AADIAAEoAAM4AAf4AAiYAAi4AAjIAA44EA6oEA84EA" + "/IEADIIAG4IAH4IAboIAcoIAfoIAa4YAQIgATIgAY4gAf4kAIZYAMk4AqE4ATU8AT08AR08AV08AXk8ANE8AW08AVU8AME8A" + "UE8AUU8APU8AOk8AOE8AQ08AVE8APE8ARk8AY08AXE8AYE8AL08ATk8ANk8AWU8AXU8ASE8AWk8ATFEAS1EATVEAdVEAtlEA" + "t1EAJVIAJFIAKVIAKlIAKFIAq1IAqVIAqlIArFIAI1MAc1MAdVMAHVQALVQAHlQAPlQAJlQATlQAJ1QARlQAQ1QAM1QASFQA" + "QlQAG1QAKVQASlQAOVQAO1QAOFQALlQANVQANlQAIFQAPFQAQFQAMVQAK1QAH1QALFQA6lYA8FYA5FYA61YASlcAUVcAQFcA" + "TVcA////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////R1cATlcAPlcAUFcAT1cAO1cA71gAPlkAnVkAklkAqFkAnlkAo1kA" + "mVkAllkAjVkApFkAk1kAilkApVkAXVsAXFsAWlsAW1sAjFsAi1sAj1sALFwAQFwAQVwAP1wAPlwAkFwAkVwAlFwAjFwA610A" + "DF4Aj14Ah14Ail4A914ABF8AH18AZF8AYl8Ad18AeV8A2F8AzF8A118AzV8A8V8A618A+F8A6l8AEmIAEWIAhGIAl2IAlmIA" + "gGIAdmIAiWIAbWIAimIAfGIAfmIAeWIAc2IAkmIAb2IAmGIAbmIAlWIAk2IAkWIAhmIAOWUAO2UAOGUA8WUA9GYAX2cATmcA" + "T2cAUGcAUWcAXGcAVmcAXmcASWcARmcAYGcAU2cAV2cAZWsAz2sAQmwAXmwAmWwAgWwAiGwAiWwAhWwAm2wAamwAemwAkGwA" + "cGwAjGwAaGwAlmwAkmwAfWwAg2wAcmwAfmwAdGwAhmwAdmwAjWwAlGwAmGwAgmwAdnAAfHAAfXAAeHAAYnIAYXIAYHIAxHIA" + "wnIAlnMALHUAK3UAN3UAOHUAgnYA73YA43cAwXkAwHkAv3kAdnoA+3wAVX8AloAAk4AAnYAAmIAAm4AAmoAAsoAAb4IAkoIA" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////i4IAjYIAi4kA0okAAIoAN4wARowAVYwAnYwAZI0AcI0As40Aq44Ayo4A" + "m48AsI8Awo8Axo8AxY8AxI8A4V0AkZAAopAAqpAAppAAo5AASZEAxpEAzJEAMpYALpYAMZYAKpYALJYAJk4AVk4Ac04Ai04A" + "m04Ank4Aq04ArE4Ab08AnU8AjU8Ac08Af08AbE8Am08Ai08Ahk8Ag08AcE8AdU8AiE8AaU8Ae08Alk8Afk8Aj08AkU8Aek8A" + "VFEAUlEAVVEAaVEAd1EAdlEAeFEAvVEA/VEAO1IAOFIAN1IAOlIAMFIALlIANlIAQVIAvlIAu1IAUlMAVFMAU1MAUVMAZlMA" + "d1MAeFMAeVMA1lMA1FMA11MAc1QAdVQAllQAeFQAlVQAgFQAe1QAd1QAhFQAklQAhlQAfFQAkFQAcVQAdlQAjFQAmlQAYlQA" + "aFQAi1QAfVQAjlQA+lYAg1cAd1cAalcAaVcAYVcAZlcAZFcAfFcAHFkASVkAR1kASFkARFkAVFkAvlkAu1kA1FkAuVkArlkA" + "0VkAxlkA0FkAzVkAy1kA01kAylkAr1kAs1kA0lkAxVkAX1sAZFsAY1sAl1sAmlsAmFsAnFsAmVsAm1sAGlwASFwARVwA////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////RlwAt1wAoVwAuFwAqVwAq1wAsVwAs1wAGF4AGl4AFl4AFV4AG14AEV4AeF4A" + "ml4Al14AnF4AlV4All4A9l4AJl8AJ18AKV8AgF8AgV8Af18AfF8A3V8A4F8A/V8A9V8A/18AD2AAFGAAL2AANWAAFmAAKmAA" + "FWAAIWAAJ2AAKWAAK2AAG2AAFmIAFWIAP2IAPmIAQGIAf2IAyWIAzGIAxGIAv2IAwmIAuWIA0mIA22IAq2IA02IA1GIAy2IA" + "yGIAqGIAvWIAvGIA0GIA2WIAx2IAzWIAtWIA2mIAsWIA2GIA1mIA12IAxmIArGIAzmIAPmUAp2UAvGUA+mUAFGYAE2YADGYA" + "BmYAAmYADmYAAGYAD2YAFWYACmYAB2YADWcAC2cAbWcAi2cAlWcAcWcAnGcAc2cAd2cAh2cAnWcAl2cAb2cAcGcAf2cAiWcA" + "fmcAkGcAdWcAmmcAk2cAfGcAamcAcmcAI2sAZmsAZ2sAf2sAE2wAG2wA42wA6GwA82wAsWwAzGwA5WwAs2wAvWwAvmwAvGwA" + "4mwAq2wA1WwA02wAuGwAxGwAuWwAwWwArmwA12wAxWwA8WwAv2wAu2wA4WwA22wAymwArGwA72wA3GwA1mwA4GwA////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////lXAAjnAAknAAinAAmXAALHIALXIAOHIASHIAZ3IAaXIAwHIAznIA2XIA13IA0HIA" + "qXMAqHMAn3MAq3MApXMAPXUAnXUAmXUAmnUAhHYAwnYA8nYA9HYA5XcA/XcAPnkAQHkAQXkAyXkAyHkAenoAeXoA+noA/nwA" + "VH8AjH8Ai38ABYAAuoAApYAAooAAsYAAoYAAq4AAqYAAtIAAqoAAr4AA5YEA/oEADYIAs4IAnYIAmYIArYIAvYIAn4IAuYIA" + "sYIArIIApYIAr4IAuIIAo4IAsIIAvoIAt4IAToYAcYYAHVIAaIgAy44Azo8A1I8A0Y8AtZAAuJAAsZAAtpAAx5EA0ZEAd5UA" + "gJUAHJYAQJYAP5YAO5YARJYAQpYAuZYA6JYAUpcAXpcAn04ArU4Ark4A4U8AtU8Ar08Av08A4E8A0U8Az08A3U8Aw08Atk8A" + "2E8A308Ayk8A108Ark8A0E8AxE8Awk8A2k8Azk8A3k8At08AV1EAklEAkVEAoFEATlIAQ1IASlIATVIATFIAS1IAR1IAx1IA" + "yVIAw1IAwVIADVMAV1MAe1MAmlMA21MArFQAwFQAqFQAzlQAyVQAuFQAplQAs1QAx1QAwlQAvVQAqlQAwVQA////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////xFQAyFQAr1QAq1QAsVQAu1QAqVQAp1QAv1QA/1YAglcAi1cAoFcAo1cAolcAzlcArlcA" + "k1cAVVkAUVkAT1kATlkAUFkA3FkA2FkA/1kA41kA6FkAA1oA5VkA6lkA2lkA5lkAAVoA+1kAaVsAo1sAplsApFsAolsApVsA" + "AVwATlwAT1wATVwAS1wA2VwA0lwA910AHV4AJV4AH14AfV4AoF4Apl4A+l4ACF8ALV8AZV8AiF8AhV8Ail8Ai18Ah18AjF8A" + "iV8AEmAAHWAAIGAAJWAADmAAKGAATWAAcGAAaGAAYmAARmAAQ2AAbGAAa2AAamAAZGAAQWIA3GIAFmMACWMA/GIA7WIAAWMA" + "7mIA/WIAB2MA8WIA92IA72IA7GIA/mIA9GIAEWMAAmMAP2UARWUAq2UAvWUA4mUAJWYALWYAIGYAJ2YAL2YAH2YAKGYAMWYA" + "JGYA92YA/2cA02cA8WcA1GcA0GcA7GcAtmcAr2cA9WcA6WcA72cAxGcA0WcAtGcA2mcA5WcAuGcAz2cA3mcA82cAsGcA2WcA" + "4mcA3WcA0mcAamsAg2sAhmsAtWsA0msA12sAH2wAyWwAC20AMm0AKm0AQW0AJW0ADG0AMW0AHm0AF20A////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////O20APW0APm0ANm0AG20A9WwAOW0AJ20AOG0AKW0ALm0ANW0ADm0AK20Aq3AAunAAs3AArHAA" + "r3AArXAAuHAArnAApHAAMHIAcnIAb3IAdHIA6XIA4HIA4XIAt3MAynMAu3MAsnMAzXMAwHMAs3MAGnUALXUAT3UATHUATnUA" + "S3UAq3UApHUApXUAonUAo3UAeHYAhnYAh3YAiHYAyHYAxnYAw3YAxXYAAXcA+XYA+HYACXcAC3cA/nYA/HYAB3cA3HcAAngA" + "FHgADHgADXgARnkASXkASHkAR3kAuXkAunkA0XkA0nkAy3kAf3oAgXoA/3oA/XoAfXwAAn0ABX0AAH0ACX0AB30ABH0ABn0A" + "OH8Ajn8Av38ABIAAEIAADYAAEYAANoAA1oAA5YAA2oAAw4AAxIAAzIAA4YAA24AAzoAA3oAA5IAA3YAA9IEAIoIA54IAA4MA" + "BYMA44IA24IA5oIABIMA5YIAAoMACYMA0oIA14IA8YIAAYMA3IIA1IIA0YIA3oIA04IA34IA74IABoMAUIYAeYYAe4YAeoYA" + "TYgAa4gAgYkA1IkACIoAAooAA4oAnowAoIwAdI0Ac40AtI0AzY4AzI4A8I8A5o8A4o8A6o8A5Y8A////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////7Y8A648A5I8A6I8AypAAzpAAwZAAw5AAS5EASpEAzZEAgpUAUJYAS5YATJYATZYAYpcAaZcAy5cA" + "7ZcA85cAAZgAqJgA25gA35gAlpkAmZkAWE4As04ADFAADVAAI1AA708AJlAAJVAA+E8AKVAAFlAABlAAPFAAH1AAGlAAElAA" + "EVAA+k8AAFAAFFAAKFAA8U8AIVAAC1AAGVAAGFAA808A7k8ALVAAKlAA/k8AK1AACVAAfFEApFEApVEAolEAzVEAzFEAxlEA" + "y1EAVlIAXFIAVFIAW1IAXVIAKlMAf1MAn1MAnVMA31MA6FQAEFUAAVUAN1UA/FQA5VQA8lQABlUA+lQAFFUA6VQA7VQA4VQA" + "CVUA7lQA6lQA5lQAJ1UAB1UA/VQAD1UAA1cABFcAwlcA1FcAy1cAw1cACVgAD1kAV1kAWFkAWlkAEVoAGFoAHFoAH1oAG1oA" + "E1oA7FkAIFoAI1oAKVoAJVoADFoACVoAa1sAWFwAsFsAs1sAtlsAtFsArlsAtVsAuVsAuFsABFwAUVwAVVwAUFwA7VwA/VwA" + "+1wA6lwA6FwA8FwA9lwAAV0A9FwA7l0ALV4AK14Aq14ArV4Ap14AMV8Akl8AkV8AkF8AWWAA////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////Y2AAZWAAUGAAVWAAbWAAaWAAb2AAhGAAn2AAmmAAjWAAlGAAjGAAhWAAlmAAR2IA82IACGMA/2IATmMA" + "PmMAL2MAVWMAQmMARmMAT2MASWMAOmMAUGMAPWMAKmMAK2MAKGMATWMATGMASGUASWUAmWUAwWUAxWUAQmYASWYAT2YAQ2YA" + "UmYATGYARWYAQWYA+GYAFGcAFWcAF2cAIWgAOGgASGgARmgAU2gAOWgAQmgAVGgAKWgAs2gAF2gATGgAUWgAPWgA9GcAUGgA" + "QGgAPGgAQ2gAKmgARWgAE2gAGGgAQWgAimsAiWsAt2sAI2wAJ2wAKGwAJmwAJGwA8GwAam0AlW0AiG0Ah20AZm0AeG0Ad20A" + "WW0Ak20AbG0AiW0Abm0AWm0AdG0AaW0AjG0Aim0AeW0AhW0AZW0AlG0AynAA2HAA5HAA2XAAyHAAz3AAOXIAeXIA/HIA+XIA" + "/XIA+HIA93IAhnMA7XMACXQA7nMA4HMA6nMA3nMAVHUAXXUAXHUAWnUAWXUAvnUAxXUAx3UAsnUAs3UAvXUAvHUAuXUAwnUA" + "uHUAi3YAsHYAynYAzXYAznYAKXcAH3cAIHcAKHcA6XcAMHgAJ3gAOHgAHXgANHgAN3gA////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////JXgALXgAIHgAH3gAMngAVXkAUHkAYHkAX3kAVnkAXnkAXXkAV3kAWnkA5HkA43kA53kA33kA5nkA6XkA2HkA" + "hHoAiHoA2XoABnsAEXsAiXwAIX0AF30AC30ACn0AIH0AIn0AFH0AEH0AFX0AGn0AHH0ADX0AGX0AG30AOn8AX38AlH8AxX8A" + "wX8ABoAAGIAAFYAAGYAAF4AAPYAAP4AA8YAAAoEA8IAABYEA7YAA9IAABoEA+IAA84AACIEA/YAACoEA/IAA74AA7YEA7IEA" + "AIIAEIIAKoIAK4IAKIIALIIAu4IAK4MAUoMAVIMASoMAOIMAUIMASYMANYMANIMAT4MAMoMAOYMANoMAF4MAQIMAMYMAKIMA" + "Q4MAVIYAioYAqoYAk4YApIYAqYYAjIYAo4YAnIYAcIgAd4gAgYgAgogAfYgAeYgAGIoAEIoADooADIoAFYoACooAF4oAE4oA" + "FooAD4oAEYoASIwAeowAeYwAoYwAoowAd40ArI4A0o4A1I4Az44AsY8AAZAABpAA948AAJAA+o8A9I8AA5AA/Y8ABZAA+I8A" + "lZAA4ZAA3ZAA4pAAUpEATZEATJEA2JEA3ZEA15EA3JEA2ZEAg5UAYpYAY5YAYZYA////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////W5YAXZYAZJYAWJYAXpYAu5YA4pgArJkAqJoA2JoAJZsAMpsAPJsAfk4AelAAfVAAXFAAR1AAQ1AATFAAWlAASVAA" + "ZVAAdlAATlAAVVAAdVAAdFAAd1AAT1AAD1AAb1AAbVAAXFEAlVEA8FEAalIAb1IA0lIA2VIA2FIA1VIAEFMAD1MAGVMAP1MA" + "QFMAPlMAw1MA/GYARlUAalUAZlUARFUAXlUAYVUAQ1UASlUAMVUAVlUAT1UAVVUAL1UAZFUAOFUALlUAXFUALFUAY1UAM1UA" + "QVUAV1UACFcAC1cACVcA31cABVgAClgABlgA4FcA5FcA+lcAAlgANVgA91cA+VcAIFkAYlkANloAQVoASVoAZloAaloAQFoA" + "PFoAYloAWloARloASloAcFsAx1sAxVsAxFsAwlsAv1sAxlsACVwACFwAB1wAYFwAXFwAXVwAB10ABl0ADl0AG10AFl0AIl0A" + "EV0AKV0AFF0AGV0AJF0AJ10AF10A4l0AOF4ANl4AM14AN14At14AuF4Atl4AtV4Avl4ANV8AN18AV18AbF8AaV8Aa18Al18A" + "mV8Anl8AmF8AoV8AoF8AnF8Af2AAo2AAiWAAoGAAqGAAy2AAtGAA5mAAvWAA////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////xWAAu2AAtWAA3GAAvGAA2GAA1WAAxmAA32AAuGAA2mAAx2AAGmIAG2IASGIAoGMAp2MAcmMAlmMAomMApWMAd2MAZ2MA" + "mGMAqmMAcWMAqWMAiWMAg2MAm2MAa2MAqGMAhGMAiGMAmWMAoWMArGMAkmMAj2MAgGMAe2MAaWMAaGMAemMAXWUAVmUAUWUA" + "WWUAV2UAX1UAT2UAWGUAVWUAVGUAnGUAm2UArGUAz2UAy2UAzGUAzmUAXWYAWmYAZGYAaGYAZmYAXmYA+WYA11IAG2cAgWgA" + "r2gAomgAk2gAtWgAf2gAdmgAsWgAp2gAl2gAsGgAg2gAxGgArWgAhmgAhWgAlGgAnWgAqGgAn2gAoWgAgmgAMmsAumsA62sA" + "7GsAK2wAjm0AvG0A820A2W0Asm0A4W0AzG0A5G0A+20A+m0ABW4Ax20Ay20Ar20A0W0Arm0A3m0A+W0AuG0A920A9W0AxW0A" + "0m0AGm4AtW0A2m0A620A2G0A6m0A8W0A7m0A6G0Axm0AxG0Aqm0A7G0Av20A5m0A+XAACXEACnEA/XAA73AAPXIAfXIAgXIA" + "HHMAG3MAFnMAE3MAGXMAh3MABXQACnQAA3QABnQA/nMADXQA4HQA9nQA////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "93QAHHUAInUAZXUAZnUAYnUAcHUAj3UA1HUA1XUAtXUAynUAzXUAjnYA1HYA0nYA23YAN3cAPncAPHcANncAOHcAOncAa3gA" + "Q3gATngAZXkAaHkAbXkA+3kAknoAlXoAIHsAKHsAG3sALHsAJnsAGXsAHnsALnsAknwAl3wAlXwARn0AQ30AcX0ALn0AOX0A" + "PH0AQH0AMH0AM30ARH0AL30AQn0AMn0AMX0APX8Ann8Amn8AzH8Azn8A0n8AHIAASoAARoAAL4EAFoEAI4EAK4EAKYEAMIEA" + "JIEAAoIANYIAN4IANoIAOYIAjoMAnoMAmIMAeIMAooMAloMAvYMAq4MAkoMAioMAk4MAiYMAoIMAd4MAe4MAfIMAhoMAp4MA" + "VYYAal8Ax4YAwIYAtoYAxIYAtYYAxoYAy4YAsYYAr4YAyYYAU4gAnogAiIgAq4gAkogAlogAjYgAi4gAk4kAj4kAKooAHYoA" + "I4oAJYoAMYoALYoAH4oAG4oAIooASYwAWowAqYwArIwAq4wAqIwAqowAp4wAZ40AZo0Avo0Auo0A244A344AGZAADZAAGpAA" + "F5AAI5AAH5AAHZAAEJAAFZAAHpAAIJAAD5AAIpAAFpAAG5AAFJAA////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////6JAA" + "7ZAA/ZAAV5EAzpEA9ZEA5pEA45EA55EA7ZEA6ZEAiZUAapYAdZYAc5YAeJYAcJYAdJYAdpYAd5YAbJYAwJYA6pYA6ZYA4HoA" + "33oAApgAA5gAWpsA5ZwAdZ4Af54ApZ4Au54AolAAjVAAhVAAmVAAkVAAgFAAllAAmFAAmlAAAGcA8VEAclIAdFIAdVIAaVIA" + "3lIA3VIA21IAWlMApVMAe1UAgFUAp1UAfFUAilUAnVUAmFUAglUAnFUAqlUAlFUAh1UAi1UAg1UAs1UArlUAn1UAPlUAslUA" + "mlUAu1UArFUAsVUAflUAiVUAq1UAmVUADVcAL1gAKlgANFgAJFgAMFgAMVgAIVgAHVgAIFgA+VgA+lgAYFkAd1oAmloAf1oA" + "kloAm1oAp1oAc1sAcVsA0lsAzFsA01sA0FsAClwAC1wAMVwATF0AUF0ANF0AR10A/V0ARV4APV4AQF4AQ14Afl4Ayl4AwV4A" + "wl4AxF4APF8AbV8AqV8Aql8AqF8A0WAA4WAAsmAAtmAA4GAAHGEAI2EA+mAAFWEA8GAA+2AA9GAAaGEA8WAADmEA9mAACWEA" + "AGEAEmEAH2IASWIAo2MAjGMAz2MAwGMA6WMAyWMAxmMAzWMA////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////0mMA42MA" + "0GMA4WMA1mMA7WMA7mMAdmMA9GMA6mMA22MAUmQA2mMA+WMAXmUAZmUAYmUAY2UAkWUAkGUAr2UAbmYAcGYAdGYAdmYAb2YA" + "kWYAemYAfmYAd2YA/mYA/2YAH2cAHWcA+mgA1WgA4GgA2GgA12gABWkA32gA9WgA7mgA52gA+WgA0mgA8mgA42gAy2gAzWgA" + "DWkAEmkADmkAyWgA2mgAbmkA+2gAPmsAOmsAPWsAmGsAlmsAvGsA72sALmwAL2wALGwAL24AOG4AVG4AIW4AMm4AZ24ASm4A" + "IG4AJW4AI24AG24AW24AWG4AJG4AVm4Abm4ALW4AJm4Ab24ANG4ATW4AOm4ALG4AQ24AHW4APm4Ay24AiW4AGW4ATm4AY24A" + "RG4Acm4AaW4AX24AGXEAGnEAJnEAMHEAIXEANnEAbnEAHHEATHIAhHIAgHIANnMAJXMANHMAKXMAOnQAKnQAM3QAInQAJXQA" + "NXQANnQANHQAL3QAG3QAJnQAKHQAJXUAJnUAa3UAanUA4nUA23UA43UA2XUA2HUA3nUA4HUAe3YAfHYAlnYAk3YAtHYA3HYA" + "T3cA7XcAXXgAbHgAb3gADXoACHoAC3oABXoAAHoAmHoA////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////l3oAlnoA5XoA" + "43oASXsAVnsARnsAUHsAUnsAVHsATXsAS3sAT3sAUXsAn3wApXwAXn0AUH0AaH0AVX0AK30Abn0Acn0AYX0AZn0AYn0AcH0A" + "c30AhFUA1H8A1X8AC4AAUoAAhYAAVYEAVIEAS4EAUYEAToEAOYEARoEAPoEATIEAU4EAdIEAEoIAHIIA6YMAA4QA+IMADYQA" + "4IMAxYMAC4QAwYMA74MA8YMA9IMAV4QACoQA8IMADIQAzIMA/YMA8oMAyoMAOIQADoQABIQA3IMAB4QA1IMA34MAW4YA34YA" + "2YYA7YYA1IYA24YA5IYA0IYA3oYAV4gAwYgAwogAsYgAg4kAlokAO4oAYIoAVYoAXooAPIoAQYoAVIoAW4oAUIoARooANIoA" + "OooANooAVooAYYwAgowAr4wAvIwAs4wAvYwAwYwAu4wAwIwAtIwAt4wAtowAv4wAuIwAio0AhY0AgY0Azo0A3Y0Ay40A2o0A" + "0Y0AzI0A240Axo0A+44A+I4A/I4AnI8ALpAANZAAMZAAOJAAMpAANpAAApEA9ZAACZEA/pAAY5EAZZEAz5EAFJIAFZIAI5IA" + "CZIAHpIADZIAEJIAB5IAEZIAlJUAj5UAi5UAkZUA////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////k5UAkpUAjpUAipYA" + "jpYAi5YAfZYAhZYAhpYAjZYAcpYAhJYAwZYAxZYAxJYAxpYAx5YA75YA8pYAzJcABZgABpgACJgA55gA6pgA75gA6ZgA8pgA" + "7ZgArpkArZkAw54AzZ4A0Z4Agk4ArVAAtVAAslAAs1AAxVAAvlAArFAAt1AAu1AAr1AAx1AAf1IAd1IAfVIA31IA5lIA5FIA" + "4lIA41IAL1MA31UA6FUA01UA5lUAzlUA3FUAx1UA0VUA41UA5FUA71UA2lUA4VUAxVUAxlUA5VUAyVUAElcAE1cAXlgAUVgA" + "WFgAV1gAWlgAVFgAa1gATFgAbVgASlgAYlgAUlgAS1gAZ1kAwVoAyVoAzFoAvloAvVoAvFoAs1oAwloAsloAaV0Ab10ATF4A" + "eV4AyV4AyF4AEl8AWV8ArF8Arl8AGmEAD2EASGEAH2EA82AAG2EA+WAAAWEACGEATmEATGEARGEATWEAPmEANGEAJ2EADWEA" + "BmEAN2EAIWIAImIAE2QAPmQAHmQAKmQALWQAPWQALGQAD2QAHGQAFGQADWQANmQAFmQAF2QABmQAbGUAn2UAsGUAl2YAiWYA" + "h2YAiGYAlmYAhGYAmGYAjWYAA2cAlGkAbWkA////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////WmkAd2kAYGkAVGkAdWkA" + "MGkAgmkASmkAaGkAa2kAXmkAU2kAeWkAhmkAXWkAY2kAW2kAR2sAcmsAwGsAv2sA02sA/WsAom4Ar24A024Atm4Awm4AkG4A" + "nW4Ax24AxW4ApW4AmG4AvG4Aum4Aq24A0W4Alm4AnG4AxG4A1G4Aqm4Ap24AtG4ATnEAWXEAaXEAZHEASXEAZ3EAXHEAbHEA" + "ZnEATHEAZXEAXnEARnEAaHEAVnEAOnIAUnIAN3MARXMAP3MAPnMAb3QAWnQAVXQAX3QAXnQAQXQAP3QAWXQAW3QAXHQAdnUA" + "eHUAAHYA8HUAAXYA8nUA8XUA+nUA/3UA9HUA83UA3nYA33YAW3cAa3cAZncAXncAY3cAeXcAancAbHcAXHcAZXcAaHcAYncA" + "7ncAjngAsHgAl3gAmHgAjHgAiXgAfHgAkXgAk3gAf3gAenkAf3kAgXkALIQAvXkAHHoAGnoAIHoAFHoAH3oAHnoAn3oAoHoA" + "d3sAwHsAYHsAbnsAZ3sAsXwAs3wAtXwAk30AeX0AkX0AgX0Aj30AW30Abn8AaX8Aan8Acn8AqX8AqH8ApH8AVoAAWIAAhoAA" + "hIAAcYEAcIEAeIEAZYEAboEAc4EAa4EA////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////eYEAeoEAZoEABYIAR4IAgoQA" + "d4QAPYQAMYQAdYQAZoQAa4QASYQAbIQAW4QAPIQANYQAYYQAY4QAaYQAbYQARoQAXoYAXIYAX4YA+YYAE4cACIcAB4cAAIcA" + "/oYA+4YAAocAA4cABocACocAWYgA34gA1IgA2YgA3IgA2IgA3YgA4YgAyogA1YgA0ogAnIkA44kAa4oAcooAc4oAZooAaYoA" + "cIoAh4oAfIoAY4oAoIoAcYoAhYoAbYoAYooAbooAbIoAeYoAe4oAPooAaIoAYowAiowAiYwAyowAx4wAyIwAxIwAsowAw4wA" + "wowAxYwA4Y0A340A6I0A740A840A+o0A6o0A5I0A5o0Aso4AA48ACY8A/o4ACo8An48Aso8AS5AASpAAU5AAQpAAVJAAPJAA" + "VZAAUJAAR5AAT5AATpAATZAAUZAAPpAAQZAAEpEAF5EAbJEAapEAaZEAyZEAN5IAV5IAOJIAPZIAQJIAPpIAW5IAS5IAZJIA" + "UZIANJIASZIATZIARZIAOZIAP5IAWpIAmJUAmJYAlJYAlZYAzZYAy5YAyZYAypYA95YA+5YA+ZYA9pYAVpcAdJcAdpcAEJgA" + "EZgAE5gACpgAEpgADJgA/JgA9JgA////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////////ZgA/pgAs5kAsZkAtJkA4ZoA6ZwA" + "gp4ADp8AE58AIJ8A51AA7lAA5VAA1lAA7VAA2lAA1VAAz1AA0VAA8VAAzlAA6VAAYlEA81EAg1IAglIAMVMArVMA/lUAAFYA" + "G1YAF1YA/VUAFFYABlYACVYADVYADlYA91UAFlYAH1YACFYAEFYA9lUAGFcAFlcAdVgAflgAg1gAk1gAilgAeVgAhVgAfVgA" + "/VgAJVkAIlkAJFkAalkAaVkA4VoA5loA6VoA11oA1loA2FoA41oAdVsA3lsA51sA4VsA5VsA5lsA6FsA4lsA5FsA31sADVwA" + "YlwAhF0Ah10AW14AY14AVV4AV14AVF4A014A1l4ACl8ARl8AcF8AuV8AR2EAP2EAS2EAd2EAYmEAY2EAX2EAWmEAWGEAdWEA" + "KmIAh2QAWGQAVGQApGQAeGQAX2QAemQAUWQAZ2QANGQAbWQAe2QAcmUAoWUA12UA1mUAomYAqGYAnWYAnGkAqGkAlWkAwWkA" + "rmkA02kAy2kAm2kAt2kAu2kAq2kAtGkA0GkAzWkArWkAzGkApmkAw2kAo2kASWsATGsAM2wAM28AFG8A/m4AE28A9G4AKW8A" + "Pm8AIG8ALG8AD28AAm8AIm8A////////////////////////////////////////////////////////////////////////" + "/////////////////////////////////////////////////////////////////24A724ABm8AMW8AOG8AMm8AI28AFW8A" + "K28AL28AiG8AKm8A7G4AAW8A8m4AzG4A924AlHEAmXEAfXEAinEAhHEAknEAPnIAknIAlnIARHMAUHMAZHQAY3QAanQAcHQA" + "bXQABHUAkXUAJ3YADXYAC3YACXYAE3YA4XYA43YAhHcAfXcAf3cAYXcAwXgAn3gAp3gAs3gAqXgAo3gAjnkAj3kAjXkALnoA" + "MXoAqnoAqXoA7XoA73oAoXsAlXsAi3sAdXsAl3sAnXsAlHsAj3sAuHsAh3sAhHsAuXwAvXwAvnwAu30AsH0AnH0AvX0Avn0A" + "oH0Ayn0AtH0Asn0AsX0Aun0Aon0Av30AtX0AuH0ArX0A0n0Ax30ArH0AcH8A4H8A4X8A338AXoAAWoAAh4AAUIEAgIEAj4EA" + "iIEAioEAf4EAgoEA54EA+oEAB4IAFIIAHoIAS4IAyYQAv4QAxoQAxIQAmYQAnoQAsoQAnIQAy4QAuIQAwIQA04QAkIQAvIQA" + "0YQAyoQAP4cAHIcAO4cAIocAJYcANIcAGIcAVYcAN4cAKYcA84gAAokA9IgA+YgA+IgA/YgA6IgAGokA74gApooAjIoAnooA" + "o4oAjYoAoYoAk4oApIoA////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////qooApYoAqIoAmIoAkYoAmooAp4oAaowAjYwA" + "jIwA04wA0YwA0owAa40AmY0AlY0A/I0AFI8AEo8AFY8AE48Ao48AYJAAWJAAXJAAY5AAWZAAXpAAYpAAXZAAW5AAGZEAGJEA" + "HpEAdZEAeJEAd5EAdJEAeJIAgJIAhZIAmJIAlpIAe5IAk5IAnJIAqJIAfJIAkZIAoZUAqJUAqZUAo5UApZUApJUAmZYAnJYA" + "m5YAzJYA0pYAAJcAfJcAhZcA9pcAF5gAGJgAr5gAsZgAA5kABZkADJkACZkAwZkAr5oAsJoA5poAQZsAQpsA9JwA9pwA85wA" + "vJ4AO58ASp8ABFEAAFEA+1AA9VAA+VAAAlEACFEACVEABVEA3FEAh1IAiFIAiVIAjVIAilIA8FIAslMALlYAO1YAOVYAMlYA" + "P1YANFYAKVYAU1YATlYAV1YAdFYANlYAL1YAMFYAgFgAn1gAnlgAs1gAnFgArlgAqVgAplgAbVkACVsA+1oAC1sA9VoADFsA" + "CFsA7lsA7FsA6VsA61sAZFwAZVwAnV0AlF0AYl4AX14AYV4A4l4A2l4A314A3V4A414A4F4ASF8AcV8At18AtV8AdmEAZ2EA" + "bmEAXWEAVWEAgmEA////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////fGEAcGEAa2EAfmEAp2EAkGEAq2EAjmEArGEAmmEA" + "pGEAlGEArmEALmIAaWQAb2QAeWQAnmQAsmQAiGQAkGQAsGQApWQAk2QAlWQAqWQAkmQArmQArWQAq2QAmmQArGQAmWQAomQA" + "s2QAdWUAd2UAeGUArmYAq2YAtGYAsWYAI2oAH2oA6GkAAWoAHmoAGWoA/WkAIWoAE2oACmoA82kAAmoABWoA7WkAEWoAUGsA" + "TmsApGsAxWsAxmsAP28AfG8AhG8AUW8AZm8AVG8Ahm8AbW8AW28AeG8Abm8Ajm8Aem8AcG8AZG8Al28AWG8A1W4Ab28AYG8A" + "X28An3EArHEAsXEAqHEAVnIAm3IATnMAV3MAaXQAi3QAg3QAfnQAgHQAf3UAIHYAKXYAH3YAJHYAJnYAIXYAInYAmnYAunYA" + "5HYAjncAh3cAjHcAkXcAi3cAy3gAxXgAungAyngAvngA1XgAvHgA0HgAP3oAPHoAQHoAPXoAN3oAO3oAr3oArnoArXsAsXsA" + "xHsAtHsAxnsAx3sAwXsAoHsAzHsAynwA4H0A9H0A730A+30A2H0A7H0A3X0A6H0A430A2n0A3n0A6X0Ann0A2X0A8n0A+X0A" + "dX8Ad38Ar38A////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////6X8AJoAAm4EAnIEAnYEAoIEAmoEAmIEAF4UAPYUAGoUA" + "7oQALIUALYUAE4UAEYUAI4UAIYUAFIUA7IQAJYUA/4QABoUAgocAdIcAdocAYIcAZocAeIcAaIcAWYcAV4cATIcAU4cAW4gA" + "XYgAEIkAB4kAEokAE4kAFYkACokAvIoA0ooAx4oAxIoAlYoAy4oA+IoAsooAyYoAwooAv4oAsIoA1ooAzYoAtooAuYoA24oA" + "TIwATowAbIwA4IwA3owA5owA5IwA7IwA7YwA4owA44wA3IwA6owA4YwAbY0An40Ao40AK44AEI4AHY4AIo4AD44AKY4AH44A" + "IY4AHo4Auo4AHY8AG48AH48AKY8AJo8AKo8AHI8AHo8AJY8AaZAAbpAAaJAAbZAAd5AAMJEALZEAJ5EAMZEAh5EAiZEAi5EA" + "g5EAxZIAu5IAt5IA6pIArJIA5JIAwZIAs5IAvJIA0pIAx5IA8JIAspIArZUAsZUABJcABpcAB5cACZcAYJcAjZcAi5cAj5cA" + "IZgAK5gAHJgAs5gACpkAE5kAEpkAGJkA3ZkA0JkA35kA25kA0ZkA1ZkA0pkA2ZkAt5oA7poA75oAJ5sARZsARJsAd5sAb5sA" + "Bp0ACZ0A////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////A50AqZ4Avp4Azp4AqFgAUp8AElEAGFEAFFEAEFEAFVEAgFEA" + "qlEA3VEAkVIAk1IA81IAWVYAa1YAeVYAaVYAZFYAeFYAalYAaFYAZVYAcVYAb1YAbFYAYlYAdlYAwVgAvlgAx1gAxVgAblkA" + "HVsANFsAeFsA8FsADlwASl8AsmEAkWEAqWEAimEAzWEAtmEAvmEAymEAyGEAMGIAxWQAwWQAy2QAu2QAvGQA2mQAxGQAx2QA" + "wmQAzWQAv2QA0mQA1GQAvmQAdGUAxmYAyWYAuWYAxGYAx2YAuGYAPWoAOGoAOmoAWWoAa2oAWGoAOWoARGoAYmoAYWoAS2oA" + "R2oANWoAX2oASGoAWWsAd2sABWwAwm8AsW8AoW8Aw28ApG8AwW8Ap28As28AwG8AuW8Atm8Apm8AoG8AtG8AvnEAyXEA0HEA" + "0nEAyHEA1XEAuXEAznEA2XEA3HEAw3EAxHEAaHMAnHQAo3QAmHQAn3QAnnQA4nQADHUADXUANHYAOHYAOnYA53YA5XYAoHcA" + "nncAn3cApXcA6HgA2ngA7HgA53gApnkATXoATnoARnoATHoAS3oAunoA2XsAEXwAyXsA5HsA23sA4XsA6XsA5nsA1XwA1nwA" + "Cn4A////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////EX4ACH4AG34AI34AHn4AHX4ACX4AEH4AeX8Asn8A8H8A8X8A7n8A" + "KIAAs4EAqYEAqIEA+4EACIIAWIIAWYIASoUAWYUASIUAaIUAaYUAQ4UASYUAbYUAaoUAXoUAg4cAn4cAnocAoocAjYcAYYgA" + "KokAMokAJYkAK4kAIYkAqokApokA5ooA+ooA64oA8YoAAIsA3IoA54oA7ooA/ooAAYsAAosA94oA7YoA84oA9ooA/IoAa4wA" + "bYwAk4wA9IwARI4AMY4ANI4AQo4AOY4ANY4AO48AL48AOI8AM48AqI8Apo8AdZAAdJAAeJAAcpAAfJAAepAANJEAkpEAIJMA" + "NpMA+JIAM5MAL5MAIpMA/JIAK5MABJMAGpMAEJMAJpMAIZMAFZMALpMAGZMAu5UAp5YAqJYAqpYA1ZYADpcAEZcAFpcADZcA" + "E5cAD5cAW5cAXJcAZpcAmJcAMJgAOJgAO5gAN5gALZgAOZgAJJgAEJkAKJkAHpkAG5kAIZkAGpkA7ZkA4pkA8ZkAuJoAvJoA" + "+5oA7ZoAKJsAkZsAFZ0AI50AJp0AKJ0AEp0AG50A2J4A1J4AjZ8AnJ8AKlEAH1EAIVEAMlEA9VIAjlYAgFYAkFYAhVYAh1YA" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////j1YA1VgA01gA0VgAzlgAMFsAKlsAJFsAelsAN1wAaFwAvF0Aul0AvV0A" + "uF0Aa14ATF8AvV8AyWEAwmEAx2EA5mEAy2EAMmIANGIAzmQAymQA2GQA4GQA8GQA5mQA7GQA8WQA4mQA7WQAgmUAg2UA2WYA" + "1mYAgGoAlGoAhGoAomoAnGoA22oAo2oAfmoAl2oAkGoAoGoAXGsArmsA2msACGwA2G8A8W8A328A4G8A228A5G8A628A728A" + "gG8A7G8A4W8A6W8A1W8A7m8A8G8A53EA33EA7nEA5nEA5XEA7XEA7HEA9HEA4HEANXIARnIAcHMAcnMAqXQAsHQApnQAqHQA" + "RnYAQnYATHYA6nYAs3cAqncAsHcArHcAp3cArXcA73cA93gA+ngA9HgA73gAAXkAp3kAqnkAV3oAv3oAB3wADXwA/nsA93sA" + "DHwA4HsA4HwA3HwA3nwA4nwA33wA2XwA3XwALn4APn4ARn4AN34AMn4AQ34AK34APX4AMX4ARX4AQX4ANH4AOX4ASH4ANX4A" + "P34AL34ARH8A838A/H8AcYAAcoAAcIAAb4AAc4AAxoEAw4EAuoEAwoEAwIEAv4EAvYEAyYEAvoEA6IEACYIAcYIAqoUA////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////hIUAfoUAnIUAkYUAlIUAr4UAm4UAh4UAqIUAioUAZ4YAwIcA0YcAs4cA0ocA" + "xocAq4cAu4cAuocAyIcAy4cAO4kANokARIkAOIkAPYkArIkADosAF4sAGYsAG4sACosAIIsAHYsABIsAEIsAQYwAP4wAc4wA" + "+owA/YwA/IwA+IwA+4wAqI0ASY4AS44ASI4ASo4ARI8APo8AQo8ARY8AP48Af5AAfZAAhJAAgZAAgpAAgJAAOZEAo5EAnpEA" + "nJEATZMAgpMAKJMAdZMASpMAZZMAS5MAGJMAfpMAbJMAW5MAcJMAWpMAVJMAypUAy5UAzJUAyJUAxpUAsZYAuJYA1pYAHJcA" + "HpcAoJcA05cARpgAtpgANZkAAZoA/5kArpsAq5sAqpsArZsAO50AP50Ai54Az54A3p4A3J4A3Z4A254APp8AS58A4lMAlVYA" + "rlYA2VgA2FgAOFsAXV8A42EAM2IA9GQA8mQA/mQABmUA+mQA+2QA92QAt2UA3GYAJmcAs2oArGoAw2oAu2oAuGoAwmoArmoA" + "r2oAX2sAeGsAr2sACXAAC3AA/m8ABnAA+m8AEXAAD3AA+3EA/HEA/nEA+HEAd3MAdXMAp3QAv3QAFXUAVnYAWHYA////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////UnYAvXcAv3cAu3cAvHcADnkArnkAYXoAYnoAYHoAxHoAxXoAK3wAJ3wAKnwAHnwA" + "I3wAIXwA53wAVH4AVX4AXn4AWn4AYX4AUn4AWX4ASH8A+X8A+38Ad4AAdoAAzYEAz4EACoIAz4UAqYUAzYUA0IUAyYUAsIUA" + "uoUAuYUApoUA74cA7IcA8ocA4IcAhokAsokA9IkAKIsAOYsALIsAK4sAUIwABY0AWY4AY44AZo4AZI4AX44AVY4AwI4ASY8A" + "TY8Ah5AAg5AAiJAAq5EArJEA0JEAlJMAipMAlpMAopMAs5MArpMArJMAsJMAmJMAmpMAl5MA1JUA1pUA0JUA1ZUA4pYA3JYA" + "2ZYA25YA3pYAJJcAo5cAppcArZcA+ZcATZgAT5gATJgATpgAU5gAupgAPpkAP5kAPZkALpkApZkADpoAwZoAA5sABpsAT5sA" + "TpsATZsAypsAyZsA/ZsAyJsAwJsAUZ0AXZ0AYJ0A4J4AFZ8ALJ8AM1EApVYA3lgA31gA4lgA9VsAkJ8A7F4A8mEA92EA9mEA" + "9WEAAGUAD2UA4GYA3WYA5WoA3WoA2moA02oAG3AAH3AAKHAAGnAAHXAAFXAAGHAABnIADXIAWHIAonIAeHMA////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////enMAvXQAynQA43QAh3UAhnUAX3YAYXYAx3cAGXkAsXkAa3oAaXoAPnwAP3wAOHwAPXwA" + "N3wAQHwAa34AbX4AeX4AaX4Aan4AhX8Ac34Atn8AuX8AuH8A2IEA6YUA3YUA6oUA1YUA5IUA5YUA94UA+4cABYgADYgA+YcA" + "/ocAYIkAX4kAVokAXokAQYsAXIsAWIsASYsAWosATosAT4sARosAWYsACI0ACo0AfI4Aco4Ah44Ado4AbI4Aeo4AdI4AVI8A" + "To8ArY8AipAAi5AAsZEArpEA4ZMA0ZMA35MAw5MAyJMA3JMA3ZMA1pMA4pMAzZMA2JMA5JMA15MA6JMA3JUAtJYA45YAKpcA" + "J5cAYZcA3JcA+5cAXpgAWJgAW5gAvJgARZkASZkAFpoAGZoADZsA6JsA55sA1psA25sAiZ0AYZ0Acp0Aap0AbJ0Akp4Al54A" + "k54AtJ4A+FIAqFYAt1YAtlYAtFYAvFYA5FgAQFsAQ1sAfVsA9lsAyV0A+GEA+mEAGGUAFGUAGWUA5mYAJ2cA7GoAPnAAMHAA" + "MnAAEHIAe3MAz3QAYnYAZXYAJnkAKnkALHkAK3kAx3oA9noATHwAQ3wATXwA73wA8HwAro8AfX4AfH4A////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////gn4ATH8AAIAA2oEAZoIA+4UA+YUAEYYA+oUABoYAC4YAB4YACoYAFIgAFYgAZIkAuokA+IkA" + "cIsAbIsAZosAb4sAX4sAa4sAD40ADY0AiY4AgY4AhY4Ago4AtJEAy5EAGJQAA5QA/ZMA4ZUAMJcAxJgAUpkAUZkAqJkAK5oA" + "MJoAN5oANZoAE5wADZwAeZ4AtZ4A6J4AL58AX58AY58AYZ8AN1EAOFEAwVYAwFYAwlYAFFkAbFwAzV0A/GEA/mEAHWUAHGUA" + "lWUA6WYA+2oABGsA+moAsmsATHAAG3IAp3IA1nQA1HQAaXYA03cAUHwAj34AjH4AvH8AF4YALYYAGoYAI4gAIogAIYgAH4gA" + "aokAbIkAvYkAdIsAd4sAfYsAE40Aio4AjY4Ai44AX48Ar48AupEALpQAM5QANZQAOpQAOJQAMpQAK5QA4pUAOJcAOZcAMpcA" + "/5cAZ5gAZZgAV5kARZoAQ5oAQJoAPpoAz5oAVJsAUZsALZwAJZwAr50AtJ0Awp0AuJ0AnZ4A754AGZ8AXJ8AZp8AZ58APFEA" + "O1EAyFYAylYAyVYAf1sA1F0A0l0ATl8A/2EAJGUACmsAYWsAUXAAWHAAgHMA5HQAinUAbnYAbHYA////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////s3kAYHwAX3wAfoAAfYAA34EAcokAb4kA/IkAgIsAFo0AF40AkY4Ak44AYY8ASJEARJQAUZQAUpQA" + "PZcAPpcAw5cAwZcAa5gAVZkAVZoATZoA0poAGpsASZwAMZwAPpwAO5wA050A150ANJ8AbJ8Aap8AlJ8AzFYA1l0AAGIAI2UA" + "K2UAKmUA7GYAEGsA2nQAynoAZHwAY3wAZXwAk34Aln4AlH4A4oEAOIYAP4YAMYgAiosAkJAAj5AAY5QAYJQAZJQAaJcAb5gA" + "XJkAWpoAW5oAV5oA05oA1JoA0ZoAVJwAV5wAVpwA5Z0An54A9J4A0VYA6VgALGUAXnAAcXYAcnYA13cAUH8AiH8ANogAOYgA" + "YogAk4sAkosAlosAd4IAG40AwJEAapQAQpcASJcARJcAxpcAcJgAX5oAIpsAWJsAX5wA+Z0A+p0AfJ4AfZ4AB58Ad58Acp8A" + "814AFmsAY3AAbHwAbnwAO4gAwIkAoY4AwZEAcpQAcJQAcZgAXpkA1poAI5sAzJ4AZHAA2ncAmosAd5QAyZcAYpoAZZoAnH4A" + "nIsAqo4AxZEAfZQAfpQAfJQAd5wAeJwA954AVIwAf5QAGp4AKHIAapoAMZsAG54AHp4AcnwA////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////YCQAYSQAYiQAYyQAZCQAZSQAZiQAZyQAaCQAaSQAdCQAdSQAdiQAdyQAeCQAeSQAeiQAeyQAfCQAfSQA" + "cCEAcSEAciEAcyEAdCEAdSEAdiEAdyEAeCEAeSEANk4AP04AhU4AoE4AglEAllEAq1EA+VIAOFMAaVMAtlMAClkAgFsA210A" + "My8Af14A////UF8AYV8ANGUA////knUA////tY8A////qAAAxgIA/TAA/jAAnTAAnjAA////////BTAABjAABzAA/DAAO/8A" + "Pf8APScAQTAAQjAAQzAARDAARTAARjAARzAASDAASTAASjAASzAATDAATTAATjAATzAAUDAAUTAAUjAAUzAAVDAAVTAAVjAA" + "VzAAWDAAWTAAWjAAWzAAXDAAXTAAXjAAXzAAYDAAYTAAYjAAYzAAZDAAZTAAZjAAZzAAaDAAaTAAajAAazAAbDAAbTAAbjAA" + "bzAAcDAAcTAAcjAAczAAdDAAdTAAdjAAdzAAeDAAeTAAejAAezAAfDAAfTAAfjAAfzAAgDAAgTAAgjAAgzAAhDAAhTAAhjAA" + "hzAAiDAAiTAAijAAizAAjDAAjTAAjjAAjzAAkDAAkTAAkjAAkzAAoTAAojAAozAApDAA////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////pTAApjAApzAAqDAAqTAAqjAAqzAArDAArTAArjAArzAAsDAAsTAAsjAAszAAtDAAtTAAtjAAtzAAuDAAuTAA" + "ujAAuzAAvDAAvTAAvjAAvzAAwDAAwTAAwjAAwzAAxDAAxTAAxjAAxzAAyDAAyTAAyjAAyzAAzDAAzTAAzjAAzzAA0DAA0TAA" + "0jAA0zAA1DAA1TAA1jAA1zAA2DAA2TAA2jAA2zAA3DAA3TAA3jAA3zAA4DAA4TAA4jAA4zAA5DAA5TAA5jAA5zAA6DAA6TAA" + "6jAA6zAA7DAA7TAA7jAA7zAA8DAA8TAA8jAA8zAA9DAA9TAA9jAAEAQAEQQAEgQAEwQAFAQAFQQAAQQAFgQAFwQAGAQAGQQA" + "GgQAGwQAHAQAHQQAHgQAHwQAIAQAIQQAIgQAIwQAJAQAJQQAJgQAJwQAKAQAKQQAKgQAKwQALAQALQQALgQALwQAMAQAMQQA" + "MgQAMwQANAQANQQAUQQANgQANwQAOAQAOQQAOgQAOwQAPAQAPQQAPgQAPwQAQAQAQQQAQgQAQwQARAQARQQARgQARwQASAQA" + "SQQASgQASwQATAQATQQATgQATwQA5yEAuCEAuSEAzzEAzAACWk4AigACAlIAkUQA////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////sJ8AiFEAsZ8AB3YC////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////4v8A5P8A" + "B/8AAv8AMTIAFiEAISEAmzAAnDAAgC4AhC4Ahi4Ahy4AiC4Aii4AjC4AjS4AlS4AnC4AnS4ApS4Apy4Aqi4ArC4Ari4Ati4A" + "vC4Avi4Axi4Ayi4AzC4AzS4Azy4A1i4A1y4A3i4A4y4A////////////gwIAUAIAWwIAVAIAdQIAUwEA+AAASwEAigIAagIA" + "Qk4AXE4A9VEAGlMAglMAB04ADE4AR04AjU4A11YADPoAblwAc18AD04Ah1EADk4ALk4Ak04Awk4AyU4AyE4AmFEA/FIAbFMA" + "uVMAIFcAA1kALFkAEFwA/10A4WUAs2sAzGsAFGwAP3IAMU4APE4A6E4A3E4A6U4A4U4A3U4A2k4ADFIAHFMATFMAIlcAI1cA" + "F1kAL1kAgVsAhFsAElwAO1wAdFwAc1wABF4AgF4Agl4AyV8ACWIAUGIAFWwA////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////NmwAQ2wAP2wAO2wArnIAsHIAinMAuHkAioAAHpYADk8AGE8ALE8A9U4AFE8A8U4AAE8A904ACE8AHU8AAk8ABU8AIk8A" + "E08ABE8A9E4AEk8AsVEAE1IACVIAEFIAplIAIlMAH1MATVMAilMAB1QA4VYA31YALlcAKlcANFcAPFkAgFkAfFkAhVkAe1kA" + "flkAd1kAf1kAVlsAFVwAJVwAfFwAelwAe1wAflwA310AdV4AhF4AAl8AGl8AdF8A1V8A1F8Az18AXGIAXmIAZGIAYWIAZmIA" + "YmIAWWIAYGIAWmIAZWIA72UA7mUAPmcAOWcAOGcAO2cAOmcAP2cAPGcAM2cAGGwARmwAUmwAXGwAT2wASmwAVGwAS2wATGwA" + "cXAAXnIAtHIAtXIAjnMAKnUAf3YAdXoAUX8AeIIAfIIAgIIAfYIAf4IATYYAfokAmZAAl5AAmJAAm5AAlJAAIpYAJJYAIJYA" + "I5YAVk8AO08AYk8ASU8AU08AZE8APk8AZ08AUk8AX08AQU8AWE8ALU8AM08AP08AYU8Aj1EAuVEAHFIAHlIAIVIArVIArlIA" + "CVMAY1MAclMAjlMAj1MAMFQAN1QAKlQAVFQARVQAGVQAHFQAJVQAGFQA////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "PVQAT1QAQVQAKFQAJFQAR1QA7lYA51YA5VYAQVcARVcATFcASVcAS1cAUlcABlkAQFkAplkAmFkAoFkAl1kAjlkAolkAkFkA" + "j1kAp1kAoVkAjlsAklsAKFwAKlwAjVwAj1wAiFwAi1wAiVwAklwAilwAhlwAk1wAlVwA4F0ACl4ADl4Ai14AiV4AjF4AiF4A" + "jV4ABV8AHV8AeF8Adl8A0l8A0V8A0F8A7V8A6F8A7l8A818A4V8A5F8A418A+l8A718A918A+18AAGAA9F8AOmIAg2IAjGIA" + "jmIAj2IAlGIAh2IAcWIAe2IAemIAcGIAgWIAiGIAd2IAfWIAcmIAdGIAN2UA8GUA9GUA82UA8mUA9WUARWcAR2cAWWcAVWcA" + "TGcASGcAXWcATWcAWmcAS2cA0GsAGWwAGmwAeGwAZ2wAa2wAhGwAi2wAj2wAcWwAb2wAaWwAmmwAbWwAh2wAlWwAnGwAZmwA" + "c2wAZWwAe2wAjmwAdHAAenAAY3IAv3IAvXIAw3IAxnIAwXIAunIAxXIAlXMAl3MAk3MAlHMAknMAOnUAOXUAlHUAlXUAgXYA" + "PXkANIAAlYAAmYAAkIAAkoAAnIAAkIIAj4IAhYIAjoIAkYIAk4IA////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////ioIA" + "g4IAhIIAeIwAyY8Av48An5AAoZAApZAAnpAAp5AAoJAAMJYAKJYAL5YALZYAM04AmE8AfE8AhU8AfU8AgE8Ah08Adk8AdE8A" + "iU8AhE8Ad08ATE8Al08Aak8Amk8AeU8AgU8AeE8AkE8AnE8AlE8Ank8Akk8Agk8AlU8Aa08Abk8AnlEAvFEAvlEANVIAMlIA" + "M1IARlIAMVIAvFIAClMAC1MAPFMAklMAlFMAh1QAf1QAgVQAkVQAglQAiFQAa1QAelQAflQAZVQAbFQAdFQAZlQAjVQAb1QA" + "YVQAYFQAmFQAY1QAZ1QAZFQA91YA+VYAb1cAclcAbVcAa1cAcVcAcFcAdlcAgFcAdVcAe1cAc1cAdFcAYlcAaFcAfVcADFkA" + "RVkAtVkAulkAz1kAzlkAslkAzFkAwVkAtlkAvFkAw1kA1lkAsVkAvVkAwFkAyFkAtFkAx1kAYlsAZVsAk1sAlVsARFwAR1wA" + "rlwApFwAoFwAtVwAr1wAqFwArFwAn1wAo1wArVwAolwAqlwAp1wAnVwApVwAtlwAsFwAplwAF14AFF4AGV4AKF8AIl8AI18A" + "JF8AVF8Agl8Afl8AfV8A3l8A5V8ALWAAJmAAGWAAMmAAC2AA////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////NGAACmAA" + "F2AAM2AAGmAAHmAALGAAImAADWAAEGAALmAAE2AAEWAADGAACWAAHGAAFGIAPWIArWIAtGIA0WIAvmIAqmIAtmIAymIArmIA" + "s2IAr2IAu2IAqWIAsGIAuGIAPWUAqGUAu2UACWYA/GUABGYAEmYACGYA+2UAA2YAC2YADWYABWYA/WUAEWYAEGYA9mYACmcA" + "hWcAbGcAjmcAkmcAdmcAe2cAmGcAhmcAhGcAdGcAjWcAjGcAemcAn2cAkWcAmWcAg2cAfWcAgWcAeGcAeWcAlGcAJWsAgGsA" + "fmsA3msAHWwAk2wA7GwA62wA7mwA2WwAtmwA1GwArWwA52wAt2wA0GwAwmwAumwAw2wAxmwA7WwA8mwA0mwA3WwAtGwAimwA" + "nWwAgGwA3mwAwGwAMG0AzWwAx2wAsGwA+WwAz2wA6WwA0WwAlHAAmHAAhXAAk3AAhnAAhHAAkXAAlnAAgnAAmnAAg3AAanIA" + "1nIAy3IA2HIAyXIA3HIA0nIA1HIA2nIAzHIA0XIApHMAoXMArXMApnMAonMAoHMArHMAnXMA3XQA6HQAP3UAQHUAPnUAjHUA" + "mHUAr3YA83YA8XYA8HYA9XYA+HcA/HcA+XcA+3cA+ncA////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////93cAQnkAP3kA" + "xXkAeHoAe3oA+3oAdXwA/XwANYAAj4AAroAAo4AAuIAAtYAArYAAIIIAoIIAwIIAq4IAmoIAmIIAm4IAtYIAp4IAroIAvIIA" + "noIAuoIAtIIAqIIAoYIAqYIAwoIApIIAw4IAtoIAooIAcIYAb4YAbYYAboYAVowA0o8Ay48A048AzY8A1o8A1Y8A148AspAA" + "tJAAr5AAs5AAsJAAOZYAPZYAPJYAOpYAQ5YAzU8AxU8A008Ask8AyU8Ay08AwU8A1E8A3E8A2U8Au08As08A208Ax08A1k8A" + "uk8AwE8AuU8A7E8ARFIASVIAwFIAwlIAPVMAfFMAl1MAllMAmVMAmFMAulQAoVQArVQApVQAz1QAw1QADYMAt1QArlQA1lQA" + "tlQAxVQAxlQAoFQAcFQAvFQAolQAvlQAclQA3lQAsFQAtVcAnlcAn1cApFcAjFcAl1cAnVcAm1cAlFcAmFcAj1cAmVcApVcA" + "mlcAlVcA9FgADVkAU1kA4VkA3lkA7lkAAFoA8VkA3VkA+lkA/VkA/FkA9lkA5FkA8lkA91kA21kA6VkA81kA9VkA4FkA/lkA" + "9FkA7VkAqFsATFwA0FwA2FwAzFwA11wAy1wA21wA////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////3lwA2lwAyVwAx1wA" + "ylwA1lwA01wA1FwAz1wAyFwAxlwAzlwA31wA+FwA+V0AIV4AIl4AI14AIF4AJF4AsF4ApF4Aol4Am14Ao14ApV4AB18ALl8A" + "Vl8Ahl8AN2AAOWAAVGAAcmAAXmAARWAAU2AAR2AASWAAW2AATGAAQGAAQmAAX2AAJGAARGAAWGAAZmAAbmAAQmIAQ2IAz2IA" + "DWMAC2MA9WIADmMAA2MA62IA+WIAD2MADGMA+GIA9mIAAGMAE2MAFGMA+mIAFWMA+2IA8GIAQWUAQ2UAqmUAv2UANmYAIWYA" + "MmYANWYAHGYAJmYAImYAM2YAK2YAOmYAHWYANGYAOWYALmYAD2cAEGcAwWcA8mcAyGcAumcA3GcAu2cA+GcA2GcAwGcAt2cA" + "xWcA62cA5GcA32cAtWcAzWcAs2cA92cA9mcA7mcA42cAwmcAuWcAzmcA52cA8GcAsmcA/GcAxmcA7WcAzGcArmcA5mcA22cA" + "+mcAyWcAymcAw2cA6mcAy2cAKGsAgmsAhGsAtmsA1msA2GsA4GsAIGwAIWwAKG0ANG0ALW0AH20APG0AP20AEm0ACm0A2mwA" + "M20ABG0AGW0AOm0AGm0AEW0AAG0AHW0AQm0A////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////AW0AGG0AN20AA20AD20A" + "QG0AB20AIG0ALG0ACG0AIm0ACW0AEG0At3AAn3AAvnAAsXAAsHAAoXAAtHAAtXAAqXAAQXIASXIASnIAbHIAcHIAc3IAbnIA" + "ynIA5HIA6HIA63IA33IA6nIA5nIA43IAhXMAzHMAwnMAyHMAxXMAuXMAtnMAtXMAtHMA63MAv3MAx3MAvnMAw3MAxnMAuHMA" + "y3MA7HQA7nQALnUAR3UASHUAp3UAqnUAeXYAxHYACHcAA3cABHcABXcACncA93YA+3YA+nYA53cA6HcABngAEXgAEngABXgA" + "EHgAD3gADngACXgAA3gAE3gASnkATHkAS3kARXkARHkA1XkAzXkAz3kA1nkAznkAgHoAfnoA0XoAAHsAAXsAenwAeHwAeXwA" + "f3wAgHwAgXwAA30ACH0AAX0AWH8AkX8AjX8Avn8AB4AADoAAD4AAFIAAN4AA2IAAx4AA4IAA0YAAyIAAwoAA0IAAxYAA44AA" + "2YAA3IAAyoAA1YAAyYAAz4AA14AA5oAAzYAA/4EAIYIAlIIA2YIA/oIA+YIAB4MA6IIAAIMA1YIAOoMA64IA1oIA9IIA7IIA" + "4YIA8oIA9YIADIMA+4IA9oIA8IIA6oIA////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////5IIA4IIA+oIA84IA7YIAd4YA" + "dIYAfIYAc4YAQYgATogAZ4gAaogAaYgA04kABIoAB4oAco0A448A4Y8A7o8A4I8A8ZAAvZAAv5AA1ZAAxZAAvpAAx5AAy5AA" + "yJAA1JEA05EAVJYAT5YAUZYAU5YASpYATpYAHlAABVAAB1AAE1AAIlAAMFAAG1AA9U8A9E8AM1AAN1AALFAA9k8A908AF1AA" + "HFAAIFAAJ1AANVAAL1AAMVAADlAAWlEAlFEAk1EAylEAxFEAxVEAyFEAzlEAYVIAWlIAUlIAXlIAX1IAVVIAYlIAzVIADlMA" + "nlMAJlUA4lQAF1UAElUA51QA81QA5FQAGlUA/1QABFUACFUA61QAEVUABVUA8VQAClUA+1QA91QA+FQA4FQADlUAA1UAC1UA" + "AVcAAlcAzFcAMlgA1VcA0lcAulcAxlcAvVcAvFcAuFcAtlcAv1cAx1cA0FcAuVcAwVcADlkASlkAGVoAFloALVoALloAFVoA" + "D1oAF1oACloAHloAM1oAbFsAp1sArVsArFsAA1wAVlwAVFwA7FwA/1wA7lwA8VwA91wAAF0A+VwAKV4AKF4AqF4Arl4Aql4A" + "rF4AM18AMF8AZ18AXWAAWmAAZ2AA////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////QWAAomAAiGAAgGAAkmAAgWAAnWAA" + "g2AAlWAAm2AAl2AAh2AAnGAAjmAAGWIARmIA8mIAEGMAVmMALGMARGMARWMANmMAQ2MA5GMAOWMAS2MASmMAPGMAKWMAQWMA" + "NGMAWGMAVGMAWWMALWMAR2MAM2MAWmMAUWMAOGMAV2MAQGMASGMASmUARmUAxmUAw2UAxGUAwmUASmYAX2YAR2YAUWYAEmcA" + "E2cAH2gAGmgASWgAMmgAM2gAO2gAS2gAT2gAFmgAMWgAHGgANWgAK2gALWgAL2gATmgARGgANGgAHWgAEmgAFGgAJmgAKGgA" + "LmgATWgAOmgAJWgAIGgALGsAL2sALWsAMWsANGsAbWsAgoAAiGsA5msA5GsA6GsA42sA4msA52sAJWwAem0AY20AZG0Adm0A" + "DW0AYW0Akm0AWG0AYm0AbW0Ab20AkW0AjW0A720Af20Ahm0AXm0AZ20AYG0Al20AcG0AfG0AX20Agm0AmG0AL20AaG0Ai20A" + "fm0AgG0AhG0AFm0Ag20Ae20AfW0AdW0AkG0A3HAA03AA0XAA3XAAy3AAOX8A4nAA13AA0nAA3nAA4HAA1HAAzXAAxXAAxnAA" + "x3AA2nAAznAA4XAAQnIAeHIA////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////d3IAdnIAAHMA+nIA9HIA/nIA9nIA83IA" + "+3IAAXMA03MA2XMA5XMA1nMAvHMA53MA43MA6XMA3HMA0nMA23MA1HMA3XMA2nMA13MA2HMA6HMA3nQA33QA9HQA9XQAIXUA" + "W3UAX3UAsHUAwXUAu3UAxHUAwHUAv3UAtnUAunUAinYAyXYAHXcAG3cAEHcAE3cAEncAI3cAEXcAFXcAGXcAGncAIncAJ3cA" + "I3gALHgAIngANXgAL3gAKHgALngAK3gAIXgAKXgAM3gAKngAMXgAVHkAW3kAT3kAXHkAU3kAUnkAUXkA63kA7HkA4HkA7nkA" + "7XkA6nkA3HkA3nkA3XkAhnoAiXoAhXoAi3oAjHoAinoAh3oA2HoAEHsABHsAE3sABXsAD3sACHsACnsADnsACXsAEnsAhHwA" + "kXwAinwAjHwAiHwAjXwAhXwAHn0AHX0AEX0ADn0AGH0AFn0AE30AH30AEn0AD30ADH0AXH8AYX8AXn8AYH8AXX8AW38Aln8A" + "kn8Aw38Awn8AwH8AFoAAPoAAOYAA+oAA8oAA+YAA9YAAAYEA+4AAAIEAAYIAL4IAJYIAM4MALYMARIMAGYMAUYMAJYMAVoMA" + "P4MAQYMAJoMAHIMAIoMA////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////QoMAToMAG4MAKoMACIMAPIMATYMAFoMAJIMA" + "IIMAN4MAL4MAKYMAR4MARYMATIMAU4MAHoMALIMAS4MAJ4MASIMAU4YAUoYAooYAqIYAloYAjYYAkYYAnoYAh4YAl4YAhoYA" + "i4YAmoYAhYYApYYAmYYAoYYAp4YAlYYAmIYAjoYAnYYAkIYAlIYAQ4gARIgAbYgAdYgAdogAcogAgIgAcYgAf4gAb4gAg4gA" + "fogAdIgAfIgAEooAR4wAV4wAe4wApIwAo4wAdo0AeI0AtY0At40Ato0A0Y4A044A/o8A9Y8AApAA/48A+48ABJAA/I8A9o8A" + "1pAA4JAA2ZAA2pAA45AA35AA5ZAA2JAA25AA15AA3JAA5JAAUJEATpEAT5EA1ZEA4pEA2pEAXJYAX5YAvJYA45gA35oAL5sA" + "f04AcFAAalAAYVAAXlAAYFAAU1AAS1AAXVAAclAASFAATVAAQVAAW1AASlAAYlAAFVAARVAAX1AAaVAAa1AAY1AAZFAARlAA" + "QFAAblAAc1AAV1AAUVAA0FEAa1IAbVIAbFIAblIA1lIA01IALVMAnFMAdVUAdlUAPFUATVUAUFUANFUAKlUAUVUAYlUANlUA" + "NVUAMFUAUlUARVUA////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////DFUAMlUAZVUATlUAOVUASFUALVUAO1UAQFUAS1UA" + "ClcAB1cA+1cAFFgA4lcA9lcA3FcA9FcAAFgA7VcA/VcACFgA+FcAC1gA81cAz1cAB1gA7lcA41cA8lcA5VcA7FcA4VcADlgA" + "/FcAEFgA51cAAVgADFgA8VcA6VcA8FcADVgABFgAXFkAYFoAWFoAVVoAZ1oAXloAOFoANVoAbVoAUFoAX1oAZVoAbFoAU1oA" + "ZFoAV1oAQ1oAXVoAUloARFoAW1oASFoAjloAPloATVoAOVoATFoAcFoAaVoAR1oAUVoAVloAQloAXFoAclsAblsAwVsAwFsA" + "WVwAHl0AC10AHV0AGl0AIF0ADF0AKF0ADV0AJl0AJV0AD10AMF0AEl0AI10AH10ALl0APl4ANF4AsV4AtF4AuV4Asl4As14A" + "Nl8AOF8Am18All8An18AimAAkGAAhmAAvmAAsGAAumAA02AA1GAAz2AA5GAA2WAA3WAAyGAAsWAA22AAt2AAymAAv2AAw2AA" + "zWAAwGAAMmMAZWMAimMAgmMAfWMAvWMAnmMArWMAnWMAl2MAq2MAjmMAb2MAh2MAkGMAbmMAr2MAdWMAnGMAbWMArmMAfGMA" + "pGMAO2MAn2MA////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////eGMAhWMAgWMAkWMAjWMAcGMAU2UAzWUAZWYAYWYAW2YA" + "WWYAXGYAYmYAGGcAeWgAh2gAkGgAnGgAbWgAbmgArmgAq2gAVmkAb2gAo2gArGgAqWgAdWgAdGgAsmgAj2gAd2gAkmgAfGgA" + "a2gAcmgAqmgAgGgAcWgAfmgAm2gAlmgAi2gAoGgAiWgApGgAeGgAe2gAkWgAjGgAimgAfWgANmsAM2sAN2sAOGsAkWsAj2sA" + "jWsAjmsAjGsAKmwAwG0Aq20AtG0As20AdG4ArG0A6W0A4m0At20A9m0A1G0AAG4AyG0A4G0A320A1m0Avm0A5W0A3G0A3W0A" + "220A9G0Aym0AvW0A7W0A8G0Aum0A1W0Awm0Az20AyW0A0G0A8m0A020A/W0A120AzW0A420Au20A+nAADXEA93AAF3EA9HAA" + "DHEA8HAABHEA83AAEHEA/HAA/3AABnEAE3EAAHEA+HAA9nAAC3EAAnEADnEAfnIAe3IAfHIAf3IAHXMAF3MAB3MAEXMAGHMA" + "CnMACHMA/3IAD3MAHnMAiHMA9nMA+HMA9XMABHQAAXQA/XMAB3QAAHQA+nMA/HMA/3MADHQAC3QA9HMACHQAZHUAY3UAznUA" + "0nUAz3UA////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////y3UAzHUA0XUA0HUAj3YAiXYA03YAOXcAL3cALXcAMXcAMncA" + "NHcAM3cAPXcAJXcAO3cANXcASHgAUngASXgATXgASngATHgAJngARXgAUHgAZHkAZ3kAaXkAankAY3kAa3kAYXkAu3kA+nkA" + "+HkA9nkA93kAj3oAlHoAkHoANXsAR3sANHsAJXsAMHsAInsAJHsAM3sAGHsAKnsAHXsAMXsAK3sALXsAL3sAMnsAOHsAGnsA" + "I3sAlHwAmHwAlnwAo3wANX0APX0AOH0ANn0AOn0ARX0ALH0AKX0AQX0AR30APn0AP30ASn0AO30AKH0AY38AlX8AnH8AnX8A" + "m38Ayn8Ay38AzX8A0H8A0X8Ax38Az38AyX8AH4AAHoAAG4AAR4AAQ4AASIAAGIEAJYEAGYEAG4EALYEAH4EALIEAHoEAIYEA" + "FYEAJ4EAHYEAIoEAEYIAOIIAM4IAOoIANIIAMoIAdIIAkIMAo4MAqIMAjYMAeoMAc4MApIMAdIMAj4MAgYMAlYMAmYMAdYMA" + "lIMAqYMAfYMAg4MAjIMAnYMAm4MAqoMAi4MAfoMApYMAr4MAiIMAl4MAsIMAf4MApoMAh4MAroMAdoMAmoMAWYYAVoYAv4YA" + "t4YA////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////woYAwYYAxYYAuoYAsIYAyIYAuYYAs4YAuIYAzIYAtIYAu4YAvIYA" + "w4YAvYYAvoYAUogAiYgAlYgAqIgAoogAqogAmogAkYgAoYgAn4gAmIgAp4gAmYgAm4gAl4gApIgArIgAjIgAk4gAjogAgokA" + "1okA2YkA1YkAMIoAJ4oALIoAHooAOYwAO4wAXIwAXYwAfYwApYwAfY0Ae40AeY0AvI0Awo0AuY0Av40AwY0A2I4A3o4A3Y4A" + "3I4A144A4I4A4Y4AJJAAC5AAEZAAHJAADJAAIZAA75AA6pAA8JAA9JAA8pAA85AA1JAA65AA7JAA6ZAAVpEAWJEAWpEAU5EA" + "VZEA7JEA9JEA8ZEA85EA+JEA5JEA+ZEA6pEA65EA95EA6JEA7pEAepUAhpUAiJUAfJYAbZYAa5YAcZYAb5YAv5YAapcABJgA" + "5ZgAl5kAm1AAlVAAlFAAnlAAi1AAo1AAg1AAjFAAjlAAnVAAaFAAnFAAklAAglAAh1AAX1EA1FEAElMAEVMApFMAp1MAkVUA" + "qFUApVUArVUAd1UARVYAolUAk1UAiFUAj1UAtVUAgVUAo1UAklUApFUAfVUAjFUAplUAf1UAlVUAoVUAjlUADFcAKVgAN1gA" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////GVgAHlgAJ1gAI1gAKFgA9VcASFgAJVgAHFgAG1gAM1gAP1gANlgALlgA" + "OVgAOFgALVgALFgAO1gAYVkAr1oAlFoAn1oAeloAoloAnloAeFoAploAfFoApVoArFoAlVoArloAN1oAhFoAiloAl1oAg1oA" + "i1oAqVoAe1oAfVoAjFoAnFoAj1oAk1oAnVoA6lsAzVsAy1sA1FsA0VsAylsAzlsADFwAMFwAN10AQ10Aa10AQV0AS10AP10A" + "NV0AUV0ATl0AVV0AM10AOl0AUl0APV0AMV0AWV0AQl0AOV0ASV0AOF0APF0AMl0ANl0AQF0ARV0ARF4AQV4AWF8Apl8ApV8A" + "q18AyWAAuWAAzGAA4mAAzmAAxGAAFGEA8mAACmEAFmEABWEA9WAAE2EA+GAA/GAA/mAAwWAAA2EAGGEAHWEAEGEA/2AABGEA" + "C2EASmIAlGMAsWMAsGMAzmMA5WMA6GMA72MAw2MAnWQA82MAymMA4GMA9mMA1WMA8mMA9WMAYWQA32MAvmMA3WMA3GMAxGMA" + "2GMA02MAwmMAx2MAzGMAy2MAyGMA8GMA12MA2WMAMmUAZ2UAamUAZGUAXGUAaGUAZWUAjGUAnWUAnmUArmUA0GUA0mUA////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////fGYAbGYAe2YAgGYAcWYAeWYAamYAcmYAAWcADGkA02gABGkA3GgAKmkA7GgA" + "6mgA8WgAD2kA1mgA92gA62gA5GgA9mgAE2kAEGkA82gA4WgAB2kAzGgACGkAcGkAtGgAEWkA72gAxmgAFGkA+GgA0GgA/WgA" + "/GgA6GgAC2kACmkAF2kAzmgAyGgA3WgA3mgA5mgA9GgA0WgABmkA1GgA6WgAFWkAJWkAx2gAOWsAO2sAP2sAPGsAlGsAl2sA" + "mWsAlWsAvWsA8GsA8msA82sAMGwA/G0ARm4AR24AH24ASW4AiG4APG4APW4ARW4AYm4AK24AP24AQW4AXW4Ac24AHG4AM24A" + "S24AQG4AUW4AO24AA24ALm4AXm4AaG4AXG4AYW4AMW4AKG4AYG4AcW4Aa24AOW4AIm4AMG4AU24AZW4AJ24AeG4AZG4Ad24A" + "VW4AeW4AUm4AZm4ANW4ANm4AWm4AIHEAHnEAL3EA+3AALnEAMXEAI3EAJXEAInEAMnEAH3EAKHEAOnEAG3EAS3IAWnIAiHIA" + "iXIAhnIAhXIAi3IAEnMAC3MAMHMAInMAMXMAM3MAJ3MAMnMALXMAJnMAI3MANXMADHMALnQALHQAMHQAK3QAFnQA////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////GnQAIXQALXQAMXQAJHQAI3QAHXQAKXQAIHQAMnQA+3QAL3UAb3UAbHUA53UA2nUA" + "4XUA5nUA3XUA33UA5HUA13UAlXYAknYA2nYARncAR3cARHcATXcARXcASncATncAS3cATHcA3ncA7HcAYHgAZHgAZXgAXHgA" + "bXgAcXgAangAbngAcHgAaXgAaHgAXngAYngAdHkAc3kAcnkAcHkAAnoACnoAA3oADHoABHoAmXoA5noA5HoASnsAO3sARHsA" + "SHsATHsATnsAQHsAWHsARXsAonwAnnwAqHwAoXwAWH0Ab30AY30AU30AVn0AZ30Aan0AT30AbX0AXH0Aa30AUn0AVH0AaX0A" + "UX0AX30ATn0APn8AP38AZX8AZn8Aon8AoH8AoX8A138AUYAAT4AAUIAA/oAA1IAAQ4EASoEAUoEAT4EAR4EAPYEATYEAOoEA" + "5oEA7oEA94EA+IEA+YEABIIAPIIAPYIAP4IAdYIAO4MAz4MA+YMAI4QAwIMA6IMAEoQA54MA5IMA/IMA9oMAEIQAxoMAyIMA" + "64MA44MAv4MAAYQA3YMA5YMA2IMA/4MA4YMAy4MAzoMA1oMA9YMAyYMACYQAD4QA3oMAEYQABoQAwoMA84MA////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////1YMA+oMAx4MA0YMA6oMAE4QAw4MA7IMA7oMAxIMA+4MA14MA4oMAG4QA24MA/oMA2IYA" + "4oYA5oYA04YA44YA2oYA6oYA3YYA64YA3IYA7IYA6YYA14YA6IYA0YYASIgAVogAVYgAuogA14gAuYgAuIgAwIgAvogAtogA" + "vIgAt4gAvYgAsogAAYkAyYgAlYkAmIkAl4kA3YkA2okA24kATooATYoAOYoAWYoAQIoAV4oAWIoARIoARYoAUooASIoAUYoA" + "SooATIoAT4oAX4wAgYwAgIwAuowAvowAsIwAuYwAtYwAhI0AgI0AiY0A2I0A040AzY0Ax40A1o0A3I0Az40A1Y0A2Y0AyI0A" + "140AxY0A744A944A+o4A+Y4A5o4A7o4A5Y4A9Y4A544A6I4A9o4A644A8Y4A7I4A9I4A6Y4ALZAANJAAL5AABpEALJEABJEA" + "/5AA/JAACJEA+ZAA+5AAAZEAAJEAB5EABZEAA5EAYZEAZJEAX5EAYpEAYJEAAZIACpIAJZIAA5IAGpIAJpIAD5IADJIAAJIA" + "EpIA/5EA/ZEABpIABJIAJ5IAApIAHJIAJJIAGZIAF5IABZIAFpIAe5UAjZUAjJUAkJUAh5YAfpYAiJYA////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////iZYAg5YAgJYAwpYAyJYAw5YA8ZYA8JYAbJcAcJcAbpcAB5gAqZgA65gA5pwA+Z4Ag04AhE4A" + "tk4AvVAAv1AAxlAArlAAxFAAylAAtFAAyFAAwlAAsFAAwVAAulAAsVAAy1AAyVAAtlAAuFAA11EAelIAeFIAe1IAfFIAw1UA" + "21UAzFUA0FUAy1UAylUA3VUAwFUA1FUAxFUA6VUAv1UA0lUAjVUAz1UA1VUA4lUA1lUAyFUA8lUAzVUA2VUAwlUAFFcAU1gA" + "aFgAZFgAT1gATVgASVgAb1gAVVgATlgAXVgAWVgAZVgAW1gAPVgAY1gAcVgA/FgAx1oAxFoAy1oAuloAuFoAsVoAtVoAsFoA" + "v1oAyFoAu1oAxloAt1oAwFoAyloAtFoAtloAzVoAuVoAkFoA1lsA2FsA2VsAH1wAM1wAcV0AY10ASl0AZV0Acl0AbF0AXl0A" + "aF0AZ10AYl0A8F0AT14ATl4ASl4ATV4AS14AxV4AzF4Axl4Ay14Ax14AQF8Ar18ArV8A92AASWEASmEAK2EARWEANmEAMmEA" + "LmEARmEAL2EAT2EAKWEAQGEAIGIAaJEAI2IAJWIAJGIAxWMA8WMA62MAEGQAEmQACWQAIGQAJGQA////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////M2QAQ2QAH2QAFWQAGGQAOWQAN2QAImQAI2QADGQAJmQAMGQAKGQAQWQANWQAL2QACmQAGmQAQGQA" + "JWQAJ2QAC2QA52MAG2QALmQAIWQADmQAb2UAkmUA02UAhmYAjGYAlWYAkGYAi2YAimYAmWYAlGYAeGYAIGcAZmkAX2kAOGkA" + "TmkAYmkAcWkAP2kARWkAamkAOWkAQmkAV2kAWWkAemkASGkASWkANWkAbGkAM2kAPWkAZWkA8GgAeGkANGkAaWkAQGkAb2kA" + "RGkAdmkAWGkAQWkAdGkATGkAO2kAS2kAN2kAXGkAT2kAUWkAMmkAUmkAL2kAe2kAPGkARmsARWsAQ2sAQmsASGsAQWsAm2sA" + "DfoA+2sA/GsA+WsA92sA+GsAm24A1m4AyG4Aj24AwG4An24Ak24AlG4AoG4AsW4AuW4Axm4A0m4AvW4AwW4Anm4AyW4At24A" + "sG4AzW4Apm4Az24Asm4Avm4Aw24A3G4A2G4AmW4Akm4Ajm4AjW4ApG4AoW4Av24As24A0G4Aym4Al24Arm4Ao24AR3EAVHEA" + "UnEAY3EAYHEAQXEAXXEAYnEAcnEAeHEAanEAYXEAQnEAWHEAQ3EAS3EAcHEAX3EAUHEAU3EA////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////RHEATXEAWnEAT3IAjXIAjHIAkXIAkHIAjnIAPHMAQnMAO3MAOnMAQHMASnMASXMARHQASnQAS3QAUnQA" + "UXQAV3QAQHQAT3QAUHQATnQAQnQARnQATXQAVHQA4XQA/3QA/nQA/XQAHXUAeXUAd3UAg2kA73UAD3YAA3YA93UA/nUA/HUA" + "+XUA+HUAEHYA+3UA9nUA7XUA9XUA/XUAmXYAtXYA3XYAVXcAX3cAYHcAUncAVncAWncAaXcAZ3cAVHcAWXcAbXcA4HcAh3gA" + "mngAlHgAj3gAhHgAlXgAhXgAhngAoXgAg3gAeXgAmXgAgHgAlngAe3gAfHkAgnkAfXkAeXkAEXoAGHoAGXoAEnoAF3oAFXoA" + "InoAE3oAG3oAEHoAo3oAonoAnnoA63oAZnsAZHsAbXsAdHsAaXsAcnsAZXsAc3sAcXsAcHsAYXsAeHsAdnsAY3sAsnwAtHwA" + "r3wAiH0Ahn0AgH0AjX0Af30AhX0Aen0Ajn0Ae30Ag30AfH0AjH0AlH0AhH0AfX0Akn0AbX8Aa38AZ38AaH8AbH8Apn8ApX8A" + "p38A238A3H8AIYAAZIEAYIEAd4EAXIEAaYEAW4EAYoEAcoEAIWcAXoEAdoEAZ4EAb4EA////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////RIEAYYEAHYIASYIARIIAQIIAQoIARYIA8YQAP4QAVoQAdoQAeYQAj4QAjYQAZYQAUYQAQIQAhoQAZ4QAMIQA" + "TYQAfYQAWoQAWYQAdIQAc4QAXYQAB4UAXoQAN4QAOoQANIQAeoQAQ4QAeIQAMoQARYQAKYQA2YMAS4QAL4QAQoQALYQAX4QA" + "cIQAOYQAToQATIQAUoQAb4QAxYQAjoQAO4QAR4QANoQAM4QAaIQAfoQARIQAK4QAYIQAVIQAboQAUIQAC4cABIcA94YADIcA" + "+oYA1oYA9YYATYcA+IYADocACYcAAYcA9oYADYcABYcA1ogAy4gAzYgAzogA3ogA24gA2ogAzIgA0IgAhYkAm4kA34kA5YkA" + "5IkA4YkA4IkA4okA3IkA5okAdooAhooAf4oAYYoAP4oAd4oAgooAhIoAdYoAg4oAgYoAdIoAeooAPIwAS4wASowAZYwAZIwA" + "ZowAhowAhIwAhYwAzIwAaI0AaY0AkY0AjI0Ajo0Aj40AjY0Ak40AlI0AkI0Ako0A8I0A4I0A7I0A8Y0A7o0A0I0A6Y0A440A" + "4o0A540A8o0A640A9I0ABo8A/44AAY8AAI8ABY8AB48ACI8AAo8AC48AUpAAP5AA////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////RJAASZAAPZAAEJEADZEAD5EAEZEAFpEAFJEAC5EADpEAbpEAb5EASJIAUpIAMJIAOpIAZpIAM5IAZZIAXpIAg5IA" + "LpIASpIARpIAbZIAbJIAT5IAYJIAZ5IAb5IANpIAYZIAcJIAMZIAVJIAY5IAUJIAcpIATpIAU5IATJIAVpIAMpIAn5UAnJUA" + "npUAm5UAkpYAk5YAkZYAl5YAzpYA+pYA/ZYA+JYA9ZYAc5cAd5cAeJcAcpcAD5gADZgADpgArJgA9pgA+ZgAr5kAspkAsJkA" + "tZkArZoAq5oAW5sA6pwA7ZwA55wAgJ4A/Z4A5lAA1FAA11AA6FAA81AA21AA6lAA3VAA5FAA01AA7FAA8FAA71AA41AA4FAA" + "2FEAgFIAgVIA6VIA61IAMFMArFMAJ1YAFVYADFYAElYA/FUAD1YAHFYAAVYAE1YAAlYA+lUAHVYABFYA/1UA+VUAiVgAfFgA" + "kFgAmFgAhlgAgVgAf1gAdFgAi1gAelgAh1gAkVgAjlgAdlgAglgAiFgAe1gAlFgAj1gA/lgAa1kA3FoA7loA5VoA1VoA6loA" + "2loA7VoA61oA81oA4loA4FoA21oA7FoA3loA3VoA2VoA6FoA31oAd1sA4FsA////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////41sAY1wAgl0AgF0AfV0Ahl0Ael0AgV0Ad10Ail0AiV0AiF0Afl0AfF0AjV0AeV0Af10AWF4AWV4AU14A2F4A0V4A114A" + "zl4A3F4A1V4A2V4A0l4A1F4ARF8AQ18Ab18Atl8ALGEAKGEAQWEAXmEAcWEAc2EAUmEAU2EAcmEAbGEAgGEAdGEAVGEAemEA" + "W2EAZWEAO2EAamEAYWEAVmEAKWIAJ2IAK2IAK2QATWQAW2QAXWQAdGQAdmQAcmQAc2QAfWQAdWQAZmQApmQATmQAgmQAXmQA" + "XGQAS2QAU2QAYGQAUGQAf2QAP2QAbGQAa2QAWWQAZWQAd2QAc2UAoGUAoWYAoGYAn2YABWcABGcAImcAsWkAtmkAyWkAoGkA" + "zmkAlmkAsGkArGkAvGkAkWkAmWkAjmkAp2kAjWkAqWkAvmkAr2kAv2kAxGkAvWkApGkA1GkAuWkAymkAmmkAz2kAs2kAk2kA" + "qmkAoWkAnmkA2WkAl2kAkGkAwmkAtWkApWkAxmkASmsATWsAS2sAnmsAn2sAoGsAw2sAxGsA/msAzm4A9W4A8W4AA28AJW8A" + "+G4AN28A+24ALm8ACW8ATm8AGW8AGm8AJ28AGG8AO28AEm8A7W4ACm8A////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "Nm8Ac28A+W4A7m4ALW8AQG8AMG8APG8ANW8A624AB28ADm8AQ28ABW8A/W4A9m4AOW8AHG8A/G4AOm8AH28ADW8AHm8ACG8A" + "IW8Ah3EAkHEAiXEAgHEAhXEAgnEAj3EAe3EAhnEAgXEAl3EARHIAU3IAl3IAlXIAk3IAQ3MATXMAUXMATHMAYnQAc3QAcXQA" + "dXQAcnQAZ3QAbnQAAHUAAnUAA3UAfXUAkHUAFnYACHYADHYAFXYAEXYACnYAFHYAuHYAgXcAfHcAhXcAgncAbncAgHcAb3cA" + "fncAg3cAsngAqngAtHgArXgAqHgAfngAq3gAnngApXgAoHgArHgAongApHgAmHkAinkAi3kAlnkAlXkAlHkAk3kAl3kAiHkA" + "knkAkHkAK3oASnoAMHoAL3oAKHoAJnoAqHoAq3oArHoA7noAiHsAnHsAinsAkXsAkHsAlnsAjXsAjHsAm3sAjnsAhXsAmHsA" + "hFIAmXsApHsAgnsAu3wAv3wAvHwAunwAp30At30Awn0Ao30Aqn0AwX0AwH0AxX0AnX0Azn0AxH0Axn0Ay30AzH0Ar30AuX0A" + "ln0AvH0An30Apn0Arn0AqX0AoX0AyX0Ac38A4n8A438A5X8A3n8A////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////JIAA" + "XYAAXIAAiYEAhoEAg4EAh4EAjYEAjIEAi4EAFYIAl4QApIQAoYQAn4QAuoQAzoQAwoQArIQAroQAq4QAuYQAtIQAwYQAzYQA" + "qoQAmoQAsYQA0IQAnYQAp4QAu4QAooQAlIQAx4QAzIQAm4QAqYQAr4QAqIQA1oQAmIQAtoQAz4QAoIQA14QA1IQA0oQA24QA" + "sIQAkYQAYYYAM4cAI4cAKIcAa4cAQIcALocAHocAIYcAGYcAG4cAQ4cALIcAQYcAPocARocAIIcAMocAKocALYcAPIcAEocA" + "OocAMYcANYcAQocAJocAJ4cAOIcAJIcAGocAMIcAEYcA94gA54gA8YgA8ogA+ogA/ogA7ogA/IgA9ogA+4gA8IgA7IgA64gA" + "nYkAoYkAn4kAnokA6YkA64kA6IkAq4oAmYoAi4oAkooAj4oAlooAPYwAaIwAaYwA1YwAz4wA14wAlo0ACY4AAo4A/40ADY4A" + "/Y0ACo4AA44AB44ABo4ABY4A/o0AAI4ABI4AEI8AEY8ADo8ADY8AI5EAHJEAIJEAIpEAH5EAHZEAGpEAJJEAIZEAG5EAepEA" + "cpEAeZEAc5EApZIApJIAdpIAm5IAepIAoJIAlJIAqpIAjZIA////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////ppIAmpIA" + "q5IAeZIAl5IAf5IAo5IA7pIAjpIAgpIAlZIAopIAfZIAiJIAoZIAipIAhpIAjJIAmZIAp5IAfpIAh5IAqZIAnZIAi5IALZIA" + "npYAoZYA/5YAWJcAfZcAepcAfpcAg5cAgJcAgpcAe5cAhJcAgZcAf5cAzpcAzZcAFpgArZgArpgAApkAAJkAB5kAnZkAnJkA" + "w5kAuZkAu5kAupkAwpkAvZkAx5kAsZoA45oA55oAPpsAP5sAYJsAYZsAX5sA8ZwA8pwA9ZwAp54A/1AAA1EAMFEA+FAABlEA" + "B1EA9lAA/lAAC1EADFEA/VAAClEAi1IAjFIA8VIA71IASFYAQlYATFYANVYAQVYASlYASVYARlYAWFYAWlYAQFYAM1YAPVYA" + "LFYAPlYAOFYAKlYAOlYAGlcAq1gAnVgAsVgAoFgAo1gAr1gArFgApVgAoVgA/1gA/1oA9FoA/VoA91oA9loAA1sA+FoAAlsA" + "+VoAAVsAB1sABVsAD1sAZ1wAmV0Al10An10Akl0Aol0Ak10AlV0AoF0AnF0AoV0Aml0Anl0AaV4AXV4AYF4AXF4A830A214A" + "3l4A4V4ASV8Asl8Ai2EAg2EAeWEAsWEAsGEAomEAiWEA////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////m2EAk2EAr2EA" + "rWEAn2EAkmEAqmEAoWEAjWEAZmEAs2EALWIAbmQAcGQAlmQAoGQAhWQAl2QAnGQAj2QAi2QAimQAjGQAo2QAn2QAaGQAsWQA" + "mGQAdmUAemUAeWUAe2UAsmUAs2UAtWYAsGYAqWYAsmYAt2YAqmYAr2YAAGoABmoAF2oA5WkA+GkAFWoA8WkA5GkAIGoA/2kA" + "7GkA4mkAG2oAHWoA/mkAJ2oA8mkA7mkAFGoA92kA52kAQGoACGoA5mkA+2kADWoA/GkA62kACWoABGoAGGoAJWoAD2oA9mkA" + "JmoAB2oA9GkAFmoAUWsApWsAo2sAomsApmsAAWwAAGwA/2sAAmwAQW8AJm8Afm8Ah28Axm8Akm8AjW8AiW8AjG8AYm8AT28A" + "hW8AWm8Alm8Adm8AbG8Agm8AVW8Acm8AUm8AUG8AV28AlG8Ak28AXW8AAG8AYW8Aa28AfW8AZ28AkG8AU28Ai28AaW8Af28A" + "lW8AY28Ad28Aam8Ae28AsnEAr3EAm3EAsHEAoHEAmnEAqXEAtXEAnXEApXEAnnEApHEAoXEAqnEAnHEAp3EAs3EAmHIAmnIA" + "WHMAUnMAXnMAX3MAYHMAXXMAW3MAYXMAWnMAWXMA////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////YnMAh3QAiXQAinQA" + "hnQAgXQAfXQAhXQAiHQAfHQAeXQACHUAB3UAfnUAJXYAHnYAGXYAHXYAHHYAI3YAGnYAKHYAG3YAnHYAnXYAnnYAm3YAjXcA" + "j3cAiXcAiHcAzXgAu3gAz3gAzHgA0XgAzngA1HgAyHgAw3gAxHgAyXgAmnkAoXkAoHkAnHkAonkAm3kAdmsAOXoAsnoAtHoA" + "s3oAt3sAy3sAvnsArHsAznsAr3sAuXsAynsAtXsAxXwAyHwAzHwAy3wA930A230A6n0A530A130A4X0AA34A+n0A5n0A9n0A" + "8X0A8H0A7n0A330Adn8ArH8AsH8ArX8A7X8A638A6n8A7H8A5n8A6H8AZIAAZ4AAo4EAn4EAnoEAlYEAooEAmYEAl4EAFoIA" + "T4IAU4IAUoIAUIIAToIAUYIAJIUAO4UAD4UAAIUAKYUADoUACYUADYUAH4UACoUAJ4UAHIUA+4QAK4UA+oQACIUADIUA9IQA" + "KoUA8oQAFYUA94QA64QA84QA/IQAEoUA6oQA6YQAFoUA/oQAKIUAHYUALoUAAoUA/YQAHoUA9oQAMYUAJoUA54QA6IQA8IQA" + "74QA+YQAGIUAIIUAMIUAC4UAGYUAL4UAYoYA////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////VocAY4cAZIcAd4cA4YcA" + "c4cAWIcAVIcAW4cAUocAYYcAWocAUYcAXocAbYcAaocAUIcATocAX4cAXYcAb4cAbIcAeocAbocAXIcAZYcAT4cAe4cAdYcA" + "YocAZ4cAaYcAWogABYkADIkAFIkAC4kAF4kAGIkAGYkABokAFokAEYkADokACYkAookApIkAo4kA7YkA8IkA7IkAz4oAxooA" + "uIoA04oA0YoA1IoA1YoAu4oA14oAvooAwIoAxYoA2IoAw4oAuooAvYoA2YoAPowATYwAj4wA5YwA34wA2YwA6IwA2owA3YwA" + "54wAoI0AnI0AoY0Am40AII4AI44AJY4AJI4ALo4AFY4AG44AFo4AEY4AGY4AJo4AJ44AFI4AEo4AGI4AE44AHI4AF44AGo4A" + "LI8AJI8AGI8AGo8AII8AI48AFo8AF48Ac5AAcJAAb5AAZ5AAa5AAL5EAK5EAKZEAKpEAMpEAJpEALpEAhZEAhpEAipEAgZEA" + "gpEAhJEAgJEA0JIAw5IAxJIAwJIA2ZIAtpIAz5IA8ZIA35IA2JIA6ZIA15IA3ZIAzJIA75IAwpIA6JIAypIAyJIAzpIA5pIA" + "zZIA1ZIAyZIA4JIA3pIA55IA0ZIA05IA////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////tZIA4ZIAxpIAtJIAfJUArJUA" + "q5UArpUAsJUApJYAopYA05YABZcACJcAApcAWpcAipcAjpcAiJcA0JcAz5cAHpgAHZgAJpgAKZgAKJgAIJgAG5gAJ5gAspgA" + "CJkA+pgAEZkAFJkAFpkAF5kAFZkA3JkAzZkAz5kA05kA1JkAzpkAyZkA1pkA2JkAy5kA15kAzJkAs5oA7JoA65oA85oA8poA" + "8ZoARpsAQ5sAZ5sAdJsAcZsAZpsAdpsAdZsAcJsAaJsAZJsAbJsA/JwA+pwA/ZwA/5wA95wAB50AAJ0A+ZwA+5wACJ0ABZ0A" + "BJ0Ag54A054AD58AEJ8AHFEAE1EAF1EAGlEAEVEA3lEANFMA4VMAcFYAYFYAblYAc1YAZlYAY1YAbVYAclYAXlYAd1YAHFcA" + "G1cAyFgAvVgAyVgAv1gAulgAwlgAvFgAxlgAF1sAGVsAG1sAIVsAFFsAE1sAEFsAFlsAKFsAGlsAIFsAHlsA71sArF0AsV0A" + "qV0Ap10AtV0AsF0Arl0Aql0AqF0Asl0ArV0Ar10AtF0AZ14AaF4AZl4Ab14A6V4A514A5l4A6F4A5V4AS18AvF8AnWEAqGEA" + "lmEAxWEAtGEAxmEAwWEAzGEAumEA////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////v2EAuGEAjGEA12QA1mQA0GQAz2QA" + "yWQAvWQAiWQAw2QA22QA82QA2WQAM2UAf2UAfGUAomUAyGYAvmYAwGYAymYAy2YAz2YAvWYAu2YAumYAzGYAI2cANGoAZmoA" + "SWoAZ2oAMmoAaGoAPmoAXWoAbWoAdmoAW2oAUWoAKGoAWmoAO2oAP2oAQWoAamoAZGoAUGoAT2oAVGoAb2oAaWoAYGoAPGoA" + "XmoAVmoAVWoATWoATmoARmoAVWsAVGsAVmsAp2sAqmsAq2sAyGsAx2sABGwAA2wABmwArW8Ay28Ao28Ax28AvG8Azm8AyG8A" + "Xm8AxG8AvW8Anm8Aym8AqG8ABHAApW8Arm8Aum8ArG8Aqm8Az28Av28AuG8Aom8AyW8Aq28AzW8Ar28Asm8AsG8AxXEAwnEA" + "v3EAuHEA1nEAwHEAwXEAy3EA1HEAynEAx3EAz3EAvXEA2HEAvHEAxnEA2nEA23EAnXIAnnIAaXMAZnMAZ3MAbHMAZXMAa3MA" + "anMAf3QAmnQAoHQAlHQAknQAlXQAoXQAC3UAgHUAL3YALXYAMXYAPXYAM3YAPHYANXYAMnYAMHYAu3YA5nYAmncAnXcAoXcA" + "nHcAm3cAoncAo3cAlXcAmXcA////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////l3cA3XgA6XgA5XgA6ngA3ngA43gA23gA" + "4XgA4ngA7XgA33gA4HgApHkARHoASHoAR3oAtnoAuHoAtXoAsXoAt3oA3nsA43sA53sA3XsA1XsA5XsA2nsA6HsA+XsA1HsA" + "6nsA4nsA3HsA63sA2HsA33sA0nwA1HwA13wA0HwA0XwAEn4AIX4AF34ADH4AH34AIH4AE34ADn4AHH4AFX4AGn4AIn4AC34A" + "D34AFn4ADX4AFH4AJX4AJH4AQ38Ae38AfH8Aen8AsX8A738AKoAAKYAAbIAAsYEApoEAroEAuYEAtYEAq4EAsIEArIEAtIEA" + "soEAt4EAp4EA8oEAVYIAVoIAV4IAVoUARYUAa4UATYUAU4UAYYUAWIUAQIUARoUAZIUAQYUAYoUARIUAUYUAR4UAY4UAPoUA" + "W4UAcYUAToUAboUAdYUAVYUAZ4UAYIUAjIUAZoUAXYUAVIUAZYUAbIUAY4YAZYYAZIYAm4cAj4cAl4cAk4cAkocAiIcAgYcA" + "locAmIcAeYcAh4cAo4cAhYcAkIcAkYcAnYcAhIcAlIcAnIcAmocAiYcAHokAJokAMIkALYkALokAJ4kAMYkAIokAKYkAI4kA" + "L4kALIkAH4kA8YkA4IoA////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////4ooA8ooA9IoA9YoA3YoAFIsA5IoA34oA8IoA" + "yIoA3ooA4YoA6IoA/4oA74oA+4oAkYwAkowAkIwA9YwA7owA8YwA8IwA84wAbI0Abo0ApY0Ap40AM44APo4AOI4AQI4ARY4A" + "No4API4APY4AQY4AMI4AP44AvY4ANo8ALo8ANY8AMo8AOY8AN48ANI8AdpAAeZAAe5AAhpAA+pAAM5EANZEANpEAk5EAkJEA" + "kZEAjZEAj5EAJ5MAHpMACJMAH5MABpMAD5MAepMAOJMAPJMAG5MAI5MAEpMAAZMARpMALZMADpMADZMAy5IAHZMA+pIAJZMA" + "E5MA+ZIA95IANJMAApMAJJMA/5IAKZMAOZMANZMAKpMAFJMADJMAC5MA/pIACZMAAJMA+5IAFpMAvJUAzZUAvpUAuZUAupUA" + "tpUAv5UAtZUAvZUAqZYA1JYAC5cAEpcAEJcAmZcAl5cAlJcA8JcA+JcANZgAL5gAMpgAJJkAH5kAJ5kAKZkAnpkA7pkA7JkA" + "5ZkA5JkA8JkA45kA6pkA6ZkA55kAuZoAv5oAtJoAu5oA9poA+poA+ZoA95oAM5sAgJsAhZsAh5sAfJsAfpsAe5sAgpsAk5sA" + "kpsAkJsAepsAlZsA////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////fZsAiJsAJZ0AF50AIJ0AHp0AFJ0AKZ0AHZ0AGJ0A" + "Ip0AEJ0AGZ0AH50AiJ4Ahp4Ah54Arp4ArZ4A1Z4A1p4A+p4AEp8APZ8AJlEAJVEAIlEAJFEAIFEAKVEA9FIAk1YAjFYAjVYA" + "hlYAhFYAg1YAflYAglYAf1YAgVYA1lgA1FgAz1gA0lgALVsAJVsAMlsAI1sALFsAJ1sAJlsAL1sALlsAe1sA8VsA8lsAt10A" + "bF4Aal4Avl8Au18Aw2EAtWEAvGEA52EA4GEA5WEA5GEA6GEA3mEA72QA6WQA42QA62QA5GQA6GQAgWUAgGUAtmUA2mUA0mYA" + "jWoAlmoAgWoApWoAiWoAn2oAm2oAoWoAnmoAh2oAk2oAjmoAlWoAg2oAqGoApGoAkWoAf2oApmoAmmoAhWoAjGoAkmoAW2sA" + "rWsACWwAzG8AqW8A9G8A1G8A428A3G8A7W8A528A5m8A3m8A8m8A3W8A4m8A6G8A4XEA8XEA6HEA8nEA5HEA8HEA4nEAc3MA" + "bnMAb3MAl3QAsnQAq3QAkHQAqnQArXQAsXQApXQAr3QAEHUAEXUAEnUAD3UAhHUAQ3YASHYASXYAR3YApHYA6XYAtXcAq3cA" + "sncAt3cAtncA////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////tHcAsXcAqHcA8HcA83gA/XgAAnkA+3gA/HgA8ngABXkA" + "+XgA/ngABHkAq3kAqHkAXHoAW3oAVnoAWHoAVHoAWnoAvnoAwHoAwXoABXwAD3wA8nsAAHwA/3sA+3sADnwA9HsAC3wA83sA" + "AnwACXwAA3wAAXwA+HsA/XsABnwA8HsA8XsAEHwACnwA6HwALX4APH4AQn4AM34ASJgAOH4AKn4ASX4AQH4AR34AKX4ATH4A" + "MH4AO34ANn4ARH4AOn4ARX8Af38Afn8AfX8A9H8A8n8ALIAAu4EAxIEAzIEAyoEAxYEAx4EAvIEA6YEAW4IAWoIAXIIAg4UA" + "gIUAj4UAp4UAlYUAoIUAi4UAo4UAe4UApIUAmoUAnoUAd4UAfIUAiYUAoYUAeoUAeIUAV4UAjoUAloUAhoUAjYUAmYUAnYUA" + "gYUAooUAgoUAiIUAhYUAeYUAdoUAmIUAkIUAn4UAaIYAvocAqocArYcAxYcAsIcArIcAuYcAtYcAvIcArocAyYcAw4cAwocA" + "zIcAt4cAr4cAxIcAyocAtIcAtocAv4cAuIcAvYcA3ocAsocANYkAM4kAPIkAPokAQYkAUokAN4kAQokArYkAr4kArokA8okA" + "84kAHosA////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////////GIsAFosAEYsABYsAC4sAIosAD4sAEosAFYsAB4sADYsACIsA" + "BosAHIsAE4sAGosAT4wAcIwAcowAcYwAb4wAlYwAlIwA+YwAb40ATo4ATY4AU44AUI4ATI4AR44AQ48AQI8AhZAAfpAAOJEA" + "mpEAopEAm5EAmZEAn5EAoZEAnZEAoJEAoZMAg5MAr5MAZJMAVpMAR5MAfJMAWJMAXJMAdpMASZMAUJMAUZMAYJMAbZMAj5MA" + "TJMAapMAeZMAV5MAVZMAUpMAT5MAcZMAd5MAe5MAYZMAXpMAY5MAZ5MAgJMATpMAWZMAx5UAwJUAyZUAw5UAxZUAt5UArpYA" + "sJYArJYAIJcAH5cAGJcAHZcAGZcAmpcAoZcAnJcAnpcAnZcA1ZcA1JcA8ZcAQZgARJgASpgASZgARZgAQ5gAJZkAK5kALJkA" + "KpkAM5kAMpkAL5kALZkAMZkAMJkAmJkAo5kAoZkAApoA+pkA9JkA95kA+ZkA+JkA9pkA+5kA/ZkA/pkA/JkAA5oAvpoA/poA" + "/ZoAAZsA/JoASJsAmpsAqJsAnpsAm5sAppsAoZsApZsApJsAhpsAopsAoJsAr5sAM50AQZ0AZ50ANp0ALp0AL50AMZ0AOJ0A" + "MJ0A////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////////RZ0AQp0AQ50APp0AN50AQJ0APZ0A9X8ALZ0Aip4AiZ4AjZ4AsJ4A" + "yJ4A2p4A+54A/54AJJ8AI58AIp8AVJ8AoJ8AMVEALVEALlEAmFYAnFYAl1YAmlYAnVYAmVYAcFkAPFsAaVwAalwAwF0AbV4A" + "bl4A2GEA32EA7WEA7mEA8WEA6mEA8GEA62EA1mEA6WEA/2QABGUA/WQA+GQAAWUAA2UA/GQAlGUA22UA2mYA22YA2GYAxWoA" + "uWoAvWoA4WoAxmoAumoAtmoAt2oAx2oAtGoArWoAXmsAyWsAC2wAB3AADHAADXAAAXAABXAAFHAADnAA/28AAHAA+28AJnAA" + "/G8A928ACnAAAXIA/3EA+XEAA3IA/XEAdnMAuHQAwHQAtXQAwXQAvnQAtnQAu3QAwnQAFHUAE3UAXHYAZHYAWXYAUHYAU3YA" + "V3YAWnYApnYAvXYA7HYAwncAuncA/3gADHkAE3kAFHkACXkAEHkAEnkAEXkArXkArHkAX3oAHHwAKXwAGXwAIHwAH3wALXwA" + "HXwAJnwAKHwAInwAJXwAMHwAXH4AUH4AVn4AY34AWH4AYn4AX34AUX4AYH4AV34AU34AtX8As38A938A+H8AdYAA0YEA0oEA" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////////0IEAX4IAXoIAtIUAxoUAwIUAw4UAwoUAs4UAtYUAvYUAx4UAxIUAv4UA" + "y4UAzoUAyIUAxYUAsYUAtoUA0oUAJIYAuIUAt4UAvoUAaYYA54cA5ocA4ocA24cA64cA6ocA5YcA34cA84cA5IcA1IcA3IcA" + "04cA7YcA2IcA44cApIcA14cA2YcAAYgA9IcA6IcA3YcAU4kAS4kAT4kATIkARokAUIkAUYkASYkAKosAJ4sAI4sAM4sAMIsA" + "NYsAR4sAL4sAPIsAPosAMYsAJYsAN4sAJosANosALosAJIsAO4sAPYsAOosAQowAdYwAmYwAmIwAl4wA/owABI0AAo0AAI0A" + "XI4AYo4AYI4AV44AVo4AXo4AZY4AZ44AW44AWo4AYY4AXY4AaY4AVI4ARo8AR48ASI8AS48AKJEAOpEAO5EAPpEAqJEApZEA" + "p5EAr5EAqpEAtZMAjJMAkpMAt5MAm5MAnZMAiZMAp5MAjpMAqpMAnpMAppMAlZMAiJMAmZMAn5MAjZMAsZMAkZMAspMApJMA" + "qJMAtJMAo5MApZMA0pUA05UA0ZUAs5YA15YA2pYAwl0A35YA2JYA3ZYAI5cAIpcAJZcArJcArpcAqJcAq5cApJcAqpcA////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////////opcApZcA15cA2ZcA1pcA2JcA+pcAUJgAUZgAUpgAuJgAQZkAPJkAOpkAD5oA" + "C5oACZoADZoABJoAEZoACpoABZoAB5oABpoAwJoA3JoACJsABJsABZsAKZsANZsASpsATJsAS5sAx5sAxpsAw5sAv5sAwZsA" + "tZsAuJsA05sAtpsAxJsAuZsAvZsAXJ0AU50AT50ASp0AW50AS50AWZ0AVp0ATJ0AV50AUp0AVJ0AX50AWJ0AWp0Ajp4AjJ4A" + "354AAZ8AAJ8AFp8AJZ8AK58AKp8AKZ8AKJ8ATJ8AVZ8ANFEANVEAllIA91IAtFMAq1YArVYAplYAp1YAqlYArFYA2lgA3VgA" + "21gAElkAPVsAPlsAP1sAw10AcF4Av18A+2EAB2UAEGUADWUACWUADGUADmUAhGUA3mUA3WUA3mYA52oA4GoAzGoA0WoA2WoA" + "y2oA32oA3GoA0GoA62oAz2oAzWoA3moAYGsAsGsADGwAGXAAJ3AAIHAAFnAAK3AAIXAAInAAI3AAKXAAF3AAJHAAHHAAKnAA" + "DHIACnIAB3IAAnIABXIApXIApnIApHIAo3IAoXIAy3QAxXQAt3QAw3QAFnUAYHYAyXcAyncAxHcA8XcAHXkAG3kA////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////////IXkAHHkAF3kAHnkAsHkAZ3oAaHoAM3wAPHwAOXwALHwAO3wA7HwA6nwAdn4AdX4A" + "eH4AcH4Ad34Ab34Aen4Acn4AdH4AaH4AS38ASn8Ag38Ahn8At38A/X8A/n8AeIAA14EA1YEAZIIAYYIAY4IA64UA8YUA7YUA" + "2YUA4YUA6IUA2oUA14UA7IUA8oUA+IUA2IUA34UA44UA3IUA0YUA8IUA5oUA74UA3oUA4oUAAIgA+ocAA4gA9ocA94cACYgA" + "DIgAC4gABogA/IcACIgA/4cACogAAogAYokAWokAW4kAV4kAYYkAXIkAWIkAXYkAWYkAiIkAt4kAtokA9okAUIsASIsASosA" + "QIsAU4sAVosAVIsAS4sAVYsAUYsAQosAUosAV4sAQ4wAd4wAdowAmowABo0AB40ACY0ArI0Aqo0ArY0Aq40AbY4AeI4Ac44A" + "ao4Ab44Ae44Awo4AUo8AUY8AT48AUI8AU48AtI8AQJEAP5EAsJEArZEA3pMAx5MAz5MAwpMA2pMA0JMA+ZMA7JMAzJMA2ZMA" + "qZMA5pMAypMA1JMA7pMA45MA1ZMAxJMAzpMAwJMA0pMA55MAfZUA2pUA25UA4ZYAKZcAK5cALJcAKJcAJpcA////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////////s5cAt5cAtpcA3ZcA3pcA35cAXJgAWZgAXZgAV5gAv5gAvZgAu5gAvpgASJkAR5kAQ5kA" + "ppkAp5kAGpoAFZoAJZoAHZoAJJoAG5oAIpoAIJoAJ5oAI5oAHpoAHJoAFJoAwpoAC5sACpsADpsADJsAN5sA6psA65sA4JsA" + "3psA5JsA5psA4psA8JsA1JsA15sA7JsA3JsA2ZsA5ZsA1ZsA4ZsA2psAd50AgZ0Aip0AhJ0AiJ0AcZ0AgJ0AeJ0Ahp0Ai50A" + "jJ0AfZ0Aa50AdJ0AdZ0AcJ0AaZ0AhZ0Ac50Ae50Agp0Ab50AeZ0Af50Ah50AaJ0AlJ4AkZ4AwJ4A/J4ALZ8AQJ8AQZ8ATZ8A" + "Vp8AV58AWJ8AN1MAslYAtVYAs1YA41gARVsAxl0Ax10A7l4A714AwF8AwV8A+WEAF2UAFmUAFWUAE2UA32UA6GYA42YA5GYA" + "82oA8GoA6moA6GoA+WoA8WoA7moA72oAPHAANXAAL3AAN3AANHAAMXAAQnAAOHAAP3AAOnAAOXAAQHAAO3AAM3AAQXAAE3IA" + "FHIAqHIAfXMAfHMAunQAq3YAqnYAvnYA7XYAzHcAzncAz3cAzXcA8ncAJXkAI3kAJ3kAKHkAJHkAKXkA////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////////snkAbnoAbHoAbXoA93oASXwASHwASnwAR3wARXwA7nwAe34Afn4AgX4AgH4Aun8A/38AeYAA" + "24EA2YEAC4IAaIIAaYIAIoYA/4UAAYYA/oUAG4YAAIYA9oUABIYACYYABYYADIYA/YUAGYgAEIgAEYgAF4gAE4gAFogAY4kA" + "ZokAuYkA94kAYIsAaosAXYsAaIsAY4sAZYsAZ4sAbYsAro0Aho4AiI4AhI4AWY8AVo8AV48AVY8AWI8AWo8AjZAAQ5EAQZEA" + "t5EAtZEAspEAs5EAC5QAE5QA+5MAIJQAD5QAFJQA/pMAFZQAEJQAKJQAGZQADZQA9ZMAAJQA95MAB5QADpQAFpQAEpQA+pMA" + "CZQA+JMACpQA/5MA/JMADJQA9pMAEZQABpQA3pUA4JUA35UALpcAL5cAuZcAu5cA/ZcA/pcAYJgAYpgAY5gAX5gAwZgAwpgA" + "UJkATpkAWZkATJkAS5kAU5kAMpoANJoAMZoALJoAKpoANpoAKZoALpoAOJoALZoAx5oAypoAxpoAEJsAEpsAEZsAC5wACJwA" + "95sABZwAEpwA+JsAQJwAB5wADpwABpwAF5wAFJwACZwAn50AmZ0ApJ0AnZ0Akp0AmJ0AkJ0Am50A////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////////oJ0AlJ0AnJ0Aqp0Al50AoZ0Amp0Aop0AqJ0Anp0Ao50Av50AqZ0Alp0App0Ap50AmZ4Am54Amp4A" + "5Z4A5J4A554A5p4AMJ8ALp8AW58AYJ8AXp8AXZ8AWZ8AkZ8AOlEAOVEAmFIAl1IAw1YAvVYAvlYASFsAR1sAy10Az10A8V4A" + "/WEAG2UAAmsA/GoAA2sA+GoAAGsAQ3AARHAASnAASHAASXAARXAARnAAHXIAGnIAGXIAfnMAF3UAanYA0HcALXkAMXkAL3kA" + "VHwAU3wA8nwAin4Ah34AiH4Ai34Ahn4AjX4ATX8Au38AMIAA3YEAGIYAKoYAJoYAH4YAI4YAHIYAGYYAJ4YALoYAIYYAIIYA" + "KYYAHoYAJYYAKYgAHYgAG4gAIIgAJIgAHIgAK4gASogAbYkAaYkAbokAa4kA+okAeYsAeIsARYsAeosAe4sAEI0AFI0Ar40A" + "jo4AjI4AXo8AW48AXY8ARpEARJEARZEAuZEAP5QAO5QANpQAKZQAPZQAPJQAMJQAOZQAKpQAN5QALJQAQJQAMZQA5ZUA5JUA" + "45UANZcAOpcAv5cA4ZcAZJgAyZgAxpgAwJgAWJkAVpkAOZoAPZoARpoARJoAQpoAQZoAOpoA////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////////P5oAzZoAFZsAF5sAGJsAFpsAOpsAUpsAK5wAHZwAHJwALJwAI5wAKJwAKZwAJJwAIZwAt50Atp0AvJ0A" + "wZ0Ax50Ayp0Az50Avp0AxZ0Aw50Au50AtZ0Azp0AuZ0Aup0ArJ0AyJ0AsZ0ArZ0AzJ0As50AzZ0Asp0Aep4AnJ4A654A7p4A" + "7Z4AG58AGJ8AGp8AMZ8ATp8AZZ8AZJ8Akp8AuU4AxlYAxVYAy1YAcVkAS1sATFsA1V0A0V0A8l4AIWUAIGUAJmUAImUAC2sA" + "CGsACWsADWwAVXAAVnAAV3AAUnAAHnIAH3IAqXIAf3MA2HQA1XQA2XQA13QAbXYArXYANXkAtHkAcHoAcXoAV3wAXHwAWXwA" + "W3wAWnwA9HwA8XwAkX4AT38Ah38A3oEAa4IANIYANYYAM4YALIYAMoYANoYALIgAKIgAJogAKogAJYgAcYkAv4kAvokA+4kA" + "fosAhIsAgosAhosAhYsAf4sAFY0AlY4AlI4Amo4Ako4AkI4Alo4Al44AYI8AYo8AR5EATJQAUJQASpQAS5QAT5QAR5QARZQA" + "SJQASZQARpQAP5cA45cAapgAaZgAy5gAVJkAW5kATpoAU5oAVJoATJoAT5oASJoASpoA////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////////SZoAUpoAUJoA0JoAGZsAK5sAO5sAVpsAVZsARpwASJwAP5wARJwAOZwAM5wAQZwAPJwAN5wANJwAMpwAPZwA" + "NpwA250A0p0A3p0A2p0Ay50A0J0A3J0A0Z0A350A6Z0A2Z0A2J0A1p0A9Z0A1Z0A3Z0Atp4A8J4ANZ8AM58AMp8AQp8Aa58A" + "lZ8Aop8APVEAmVIA6FgA51gAclkATVsA2F0AL4gAT18AAWIAA2IABGIAKWUAJWUAlmUA62YAEWsAEmsAD2sAymsAW3AAWnAA" + "InIAgnMAgXMAg3MAcHYA1HcAZ3wAZnwAlX4AbIIAOoYAQIYAOYYAPIYAMYYAO4YAPoYAMIgAMogALogAM4gAdokAdIkAc4kA" + "/okAjIsAjosAi4sAiIsARYwAGY0AmI4AZI8AY48AvJEAYpQAVZQAXZQAV5QAXpQAxJcAxZcAAJgAVpoAWZoAHpsAH5sAIJsA" + "UpwAWJwAUJwASpwATZwAS5wAVZwAWZwATJwATpwA+50A950A750A450A650A+J0A5J0A9p0A4Z0A7p0A5p0A8p0A8J0A4p0A" + "7J0A9J0A850A6J0A7Z0Awp4A0J4A8p4A854ABp8AHJ8AOJ8AN58ANp8AQ58AT58A////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////////cZ8AcJ8Abp8Ab58A01YAzVYATlsAbVwALWUA7WYA7mYAE2sAX3AAYXAAXXAAYHAAI3IA23QA5XQA1XcAOHkAt3kA" + "tnkAanwAl34AiX8AbYIAQ4YAOIgAN4gANYgAS4gAlIsAlYsAno4An44AoI4AnY4AvpEAvZEAwpEAa5QAaJQAaZQA5ZYARpcA" + "Q5cAR5cAx5cA5ZcAXpoA1ZoAWZsAY5wAZ5wAZpwAYpwAXpwAYJwAAp4A/p0AB54AA54ABp4ABZ4AAJ4AAZ4ACZ4A/50A/Z0A" + "BJ4AoJ4AHp8ARp8AdJ8AdZ8Adp8A1FYALmUAuGUAGGsAGWsAF2sAGmsAYnAAJnIAqnIA2HcA2XcAOXkAaXwAa3wA9nwAmn4A" + "mH4Am34AmX4A4IEA4YEARoYAR4YASIYAeYkAeokAfIkAe4kA/4kAmIsAmYsApY4ApI4Ao44AbpQAbZQAb5QAcZQAc5QASZcA" + "cpgAX5kAaJwAbpwAbZwAC54ADZ4AEJ4AD54AEp4AEZ4AoZ4A9Z4ACZ8AR58AeJ8Ae58Aep8AeZ8AHlcAZnAAb3wAPIgAso0A" + "po4Aw5EAdJQAeJQAdpQAdZQAYJoAdJwAc5wAcZwAdZwAFJ4AE54A9p4ACp8A////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "////pJ8AaHAAZXAA93wAaoYAPogAPYgAP4gAnosAnIwAqY4AyY4AS5cAc5gAdJgAzJgAYZkAq5kAZJoAZpoAZ5oAJJsAFZ4A" + "F54ASJ8AB2IAHmsAJ3IATIYAqI4AgpQAgJQAgZQAaZoAaJoALpsAGZ4AKXIAS4YAn4sAg5QAeZwAt54AdXYAa5oAepwAHZ4A" + "aXAAanAApJ4Afp8ASZ8AmJ8AgXgAuZIAz4gAu1gAUmAAp3wA+loAVCUAZiUAVyUAYCUAbCUAYyUAWiUAaSUAXSUAUiUAZCUA" + "VSUAXiUAaiUAYSUAWCUAZyUAWyUAUyUAZSUAViUAXyUAayUAYiUAWSUAaCUAXCUAUSUAUCUAbSUAbiUAcCUAbyUA7f8ARwUC" + "25IA3wUCxT8CTIUAtUIA73MAtVEASTYAQkkC5IkCRJMA2xkC7oIAyDwCPHgARGcA32IAM0kCqokCoAICs2sCBRMCq08A7SQC" + "CFAAKW0ChHoCADYCsUoCEyUC////fgMCpF8AgAMCRwMC224AHwQC////AVEAejQADlEAbJgAQzcAFoQApEkChwQCYFEAtDMC" + "alEA/wsC/CAC5QICMCUCjgUCMzICgxkCglsAfYcAswUCmTwCslEAuFEA////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////////" + "NJ0AyVEAz1EA0VEA3DwA01EApkoCs1EA4lEAQlMA7VEAzYMAPmkALTcCe18AC1IAJlIAPFIAtVIAV1IAlFIAuVIAxVIAFXwA" + "QoUA4FIADYYAE2sC////3ooCSVUA2W4AgD8CVAkC7D8CM1MA////4gsCy2wAJhcCG2gA1XMASmAAqj4AzDgA6BYC3XEAokQA" + "bVMAdFMAq4YCflMA////lhUCExYC5ncAk1MAm4oCoFMAq1MArlMAp3MAclcCWT8AnHMAwVMAxVMASWwASU4A/lcA2VMAqzoA" + "jwsC4FMA6z8Coy0C9lMAdwwCE1QAeXAAK1UAV2YAW20AbVQAU2sCdA0CXVUAj1QApFQApkcADRcC3Q4CtD0ATQ0CvIkCmCYC" + "R1UA7UwAL1QAF3QAhlUAqVUA////1xgCOkACUkUANUQCs2YAtBACN1YAzWYAijICpGYArWYATVYAT1YA8XgA8VYAh5cA/lMA" + "AFcA71YA7VYAZosCIzYATxICRlcApUECbmwAi3AAQlcAsTYAfmwC5lcAFhQCA1gAVBQCY0MCJlgA9UsCXFgAqlgAYTUA4FgA" + "3FgAPBIC+1gA/1sAQ1cAUKECeEIC05MAoTUAH1kApmgAwzYAWW4A////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////////PhYC" + "JFoAU1UAkhYCBYUAyVkATg0CgWwCKm0C3BcC2VkA+xcCshcCpm0CcW0AKBgC1RYC+VkARW4Cq1oAY1oA5jYAqUkC////CDcA" + "lloAZXQA01oAoW8CVCUChT0AERkCMjcAuBYCg14A0FIAdlsAiGUAfFsADnoCBEAAXUgABAIC1VsAYGEANBoCzFkCpQUC81sA" + "nVsAEE0ABVwARBsCE1wAznMAFFwApRwCKGsCSVwA3UgAhVwA6VwA71wAi10A+R0CNx4CEF0AGF0ARl0ApB4CulwA110A/IIA" + "LTgAAUkCSSACcyECh4IANjgAwjsALl4AimoA////el4AvEQC0wwCplMAt04A////qFMAcRcCCV4A9F4AgoQC+V4A+14AoDgA" + "/F4APmgAG5QADV8AwQEClPgC3joArkgAOhMCOl8AiGgC0CMC////cSQCY18AvZcAbm4Ccl8AQJMANooCp18Atl0AXz0AUFIC" + "ah8C+HACaCYC1pEAngICKYoCMWAAhWYAdxgCYzkAxz0AOTYAkFcAtCcCcXkAQD4AnmAA////s2AAgkkCj0kCU3oCpHQA4VAA" + "oFoAZGEAJIQAQmEApvgC0m4CgWEA9FEAVgYCh2EAqlsAtz8C////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////////XygC02EA" + "nYsCXZkC0GEAMjkAgCkCwSgCI2AAXGEAHmUAi2MAGAECxWIAcBcC1WIADS4CbGMA30kCFzoAOGQA+GMAjhMC/BcC////im8A" + "Ni4CFJgAjEACHVcC4WQA5WQAe5QAZjoAOmQAVzoATWUAFm8AKEoCI0oChWUAbWUAX2UAfjACtWUAQEkCN0sA0WUA2EAAKRgC" + "4GUA42UA318AADQCGGYA9zEC+DECRGYApDECpTECS2YAdQ4CZ2YA5lECc2YA////PR4CMTIC9IUCyDECE1MCxXcA9ygCpJkA" + "AmcAnEMCIUoCKzsA+mkAwjcC////Z2cAYmcAzUEC7ZAC12cA6UQAImgAUG4APJIAAWgA5jMCoG0CXWgAbzQC4WkAC2oA34oC" + "c2kAw2gAzTUCAWkAAGkAMj0AAToAPDYCgDsArGcAYWkASooC/EIANmkAmGkAoTsAyQMCY4MAkFAA+WkAWTYCKiECRWoAAzcC" + "nWoA8zsAsWcAyGoAnJECDTwAHWsAIwkC3mAANWsAdGsAzScCtW4A2zoCtQMCWBkCQDcAIVQAWjsC4WsA/D4C3GsAN2wAiyQC" + "8UgCUWsCWmwAJoIAeWwAvD0CxUQAvT0CpEECDEkCAEkC////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////////yTwC5TYA6zwA" + "Mg0Cg5sA+TECkSQCj38AN2gAJW0CoW0C620Clm0AXG0AfG4ABG8Af0kChUACcm4CM4UAdG8Cx1EA////////LoQAIYsC////" + "Lz4CU3QAgj8CzHkAT24AkVoASzAC+G8ADTcAnW8AMD4C+m4AlxQCPUACVUUA8JMARG8AXG8ATj0AdG8AcJECOz0An28AREEC" + "028AkUACVUECOUAC8D8CtD8CP0EC31EAVkECV0ECQEEC3WECS3AAfnAAp3AAgXAAzHAA1XAA1nAA33AABEEA6D0AtHEAlnEA" + "d0ICK3EARXEAiFoASnEA////nFwAZUMCT3EAYpMAwUICLHEAWkQCJ0oCIkoCunEA6IsCvXAADnIAQpQAFXIAEVkAQ5QAJHIA" + "QZMABVYCLnIAQHIAdEkCvWgAVXIAV3IAVT4ARDACDWgAPW8AgnIA////K3MAI0gCK4gC7UgABIgCKHMALnMAz3MAqnMAOgwC" + "LmoCyXMASXQA4kEC5xYCJEoCI2YAxTYAt0kCjUkC+0kC93MAFXQAA2kAJkoCOXQAwwUC1z4A////rSgCYHQAso4CR3QA5HMA" + "dnQAuYMAbHQAMDcAdHQA8ZMALGoAgnQAU0kAjEoC////////////////////////////////////////////////////////" + "////////////////////////////////////////////////////////////////////////////////X0ECeUoCj4sCRlsA" + "A4wCnhgCyHQAiBkCDnUA////HnUA2Y4CSxoC11sArI4ChZMATXUASnUAZ3UAbnUAgk8CBD8AE00CjnUAXXQAnnUAtHUAAnYA" + "LHYAUXYAT3YAb3YAdnYA9WMCkHYA74EA+DcAEWkCDmkCoXYApXYAt3YAzHYAn28CYoQAnVACfVECHB4CHncAJncAQHcAr2QA" + "IFICWHcArDICr3cAZIkCaIkCwRYC9HcA////dhMCEkoCymgAr3gAx3gA03gApZYALnkA4FUC13gANHkAsXgADHYCuI8AhIgA" + "K4sCg2ACHCYChnkAAIkAAmkAgHkAV1gCnXkAOXsCPHkAqXkAKm4AJnECqD4AxnkADZEC1HkA" +) +BIG5HKSCS_DEC_PAIRS = {(0x88, 0x62): (0xCA, 0x304), (0x88, 0x64): (0xCA, 0x30C), (0x88, 0xA3): (0xEA, 0x304), (0x88, 0xA5): (0xEA, 0x30C)} +BIG5HKSCS_ENC_EXC = {0x2550: b'\xf9\xf9', 0x255E: b'\xf9\xe9', 0x2561: b'\xf9\xeb', 0x256A: b'\xf9\xea', 0x256D: b'\xf9\xfa', 0x256E: b'\xf9\xfb', 0x256F: b'\xf9\xfd', 0x2570: b'\xf9\xfc', 0x5341: b'\xa4Q', 0x5345: b'\xa4\xca', 0xFF0F: b'\xa2A', 0xFF3C: b'\xa2B'} +BIG5HKSCS_ENC_REJECT = frozenset() + diff --git a/crates/weavepy-vm/src/stdlib/python/_codec_cjk_dbcs.py b/crates/weavepy-vm/src/stdlib/python/_codec_cjk_dbcs.py new file mode 100644 index 0000000..5b8d685 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/_codec_cjk_dbcs.py @@ -0,0 +1,611 @@ +"""WeavePy frozen port of CPython's stateless CJK DBCS codecs. + +Covers the double/multi-byte codecs CPython implements in +``Modules/cjkcodecs`` whose mapping tables live in `_cjk_tables` (generated +by probing CPython 3.13 itself): ``euc_kr``, ``cp949``, ``euc_jp``, +``cp932``, ``shift_jis``, ``gb2312``, ``gbk``, ``gb18030``, ``big5``, +``cp950`` and ``big5hkscs``. + +The state machines are line-by-line ports of ``_codecs_kr.c`` +(EUC-KR 8-byte jamo make-up sequences), ``_codecs_jp.c`` (SS2/SS3 planes, +JIS X 0201 layers, cp932 PUA rows), ``_codecs_cn.c`` (GB18030 4-byte +linear forms) and ``_codecs_hk.c`` (HKSCS combining pairs — the one codec +here with a *stateful* encoder). Every cjkcodecs decode/encode error flags +exactly one byte/char (`return 1` throughout the C), except truncated +multi-byte tails at flush which span the remaining bytes with CPython's +"incomplete multibyte sequence" reason. +""" + +from codecs import ( + CodecInfo, + IncrementalEncoder, + IncrementalDecoder, + StreamReader, + StreamWriter, +) + +import _cjk_tables as _t +from _cjk_common import ( + ErrorsProperty, + MbDecStateMixin, + MbEncStateMixin, + MbStreamReaderMixin, + dec_handle as _dec_handle, + enc_handle as _enc_handle, +) + +_REASON = "illegal multibyte sequence" +_REASON_INCOMPLETE = "incomplete multibyte sequence" + +_U16_UNDEF = 0xFFFF +_U24_UNDEF = 0xFFFFFF +_U24_PAIR = 0xFFFFFE + + +# --------------------------------------------------------------------------- +# packed-grid access + encode-map reconstruction +# --------------------------------------------------------------------------- + +def _cell16(grid, lead, trail): + if not (0x81 <= lead <= 0xFE and 0x40 <= trail <= 0xFE): + return None + off = ((lead - 0x81) * 191 + (trail - 0x40)) << 1 + v = grid[off] | (grid[off + 1] << 8) + return None if v == _U16_UNDEF else v + + +def _cell24(grid, lead, trail): + if not (0x81 <= lead <= 0xFE and 0x40 <= trail <= 0xFE): + return None + off = ((lead - 0x81) * 191 + (trail - 0x40)) * 3 + v = grid[off] | (grid[off + 1] << 8) | (grid[off + 2] << 16) + return None if v == _U24_UNDEF else v + + +_ENC_MAPS = {} + + +def _enc_map(name): + """{codepoint: bytes} — the *lowest (lead, trail)* preimage of the + decode grid (the rule `tools/gen_cjk_dbcs_tables.py` diffed against), + patched by the probed exceptions dict.""" + m = _ENC_MAPS.get(name) + if m is not None: + return m + up = name.upper() + grid = getattr(_t, up + "_DEC") + cell = 3 if name == "big5hkscs" else 2 + m = {} + idx = 0 + for li in range(126): + for ti in range(191): + if cell == 2: + v = grid[idx] | (grid[idx + 1] << 8) + undef = _U16_UNDEF + else: + v = grid[idx] | (grid[idx + 1] << 8) | (grid[idx + 2] << 16) + undef = _U24_UNDEF + idx += cell + if v != undef and v != _U24_PAIR and v not in m: + m[v] = bytes((0x81 + li, 0x40 + ti)) + ss3 = getattr(_t, up + "_DEC_SS3", None) + if ss3 is not None: + idx = 0 + for c2 in range(0xA1, 0xFF): + for c3 in range(0xA1, 0xFF): + v = ss3[idx] | (ss3[idx + 1] << 8) + idx += 2 + if v != _U16_UNDEF and v not in m: + m[v] = bytes((0x8F, c2, c3)) + m.update(getattr(_t, up + "_ENC_EXC")) + for cp in getattr(_t, up + "_ENC_REJECT"): + m.pop(cp, None) + _ENC_MAPS[name] = m + return m + + +# --------------------------------------------------------------------------- +# generic decode / encode cores +# --------------------------------------------------------------------------- + +def _mb_decode(name, data, errors, final, single, needs2, cell2, special=None): + """Port shape shared by every cjkcodecs DECODER: ASCII passthrough, + optional single-byte layer, optional multi-byte special form, then the + 2-byte cell lookup. All error spans are 1 byte (the C `return 1`).""" + out = [] + i = 0 + n = len(data) + while i < n: + c = data[i] + if c < 0x80: + out.append(chr(c)) + i += 1 + continue + if single is not None: + s = single(c) + if s is not None: + out.append(s) + i += 1 + continue + if special is not None: + r = special(data, i, n) + if r is not None: + kind = r[0] + if kind == "toofew": + if not final: + break + rep, i = _dec_handle(name, errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + if kind == "out": + out.append(r[1]) + i += r[2] + continue + rep, i = _dec_handle(name, errors, data, i, i + r[1], _REASON) + out.append(rep) + continue + if not needs2(c): + rep, i = _dec_handle(name, errors, data, i, i + 1, _REASON) + out.append(rep) + continue + if i + 1 >= n: + if not final: + break + rep, i = _dec_handle(name, errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + decoded = cell2(c, data[i + 1]) + if decoded is None: + rep, i = _dec_handle(name, errors, data, i, i + 1, _REASON) + out.append(rep) + continue + out.append(decoded) + i += 2 + return ("".join(out), i) + + +def _mb_encode(name, s, errors, final, enc_char): + """enc_char(c, c2, final) -> (bytes, chars_consumed), "toofew" or None.""" + out = bytearray() + pending = "" + i = 0 + n = len(s) + while i < n: + c = ord(s[i]) + if c < 0x80: + out.append(c) + i += 1 + continue + c2 = ord(s[i + 1]) if i + 1 < n else None + r = enc_char(c, c2, final) + if r == "toofew": + pending = s[i:] + break + if r is None: + rep, newpos = _enc_handle(name, errors, s, i, i + 1) + if isinstance(rep, bytes): + out += rep + i = newpos + continue + if rep: + sub, _ = _mb_encode(name, rep, "strict", True, enc_char) + out += sub + i = newpos + continue + out += r[0] + i += r[1] + return (bytes(out), pending) + + +def _always2(c): + return True + + +# --------------------------------------------------------------------------- +# EUC-KR (jamo make-up sequences) / CP949 +# --------------------------------------------------------------------------- + +_NONE = 127 +_U2CGK_CHO = ( + 0xA1, 0xA2, 0xA4, 0xA7, 0xA8, 0xA9, 0xB1, 0xB2, + 0xB3, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, + 0xBC, 0xBD, 0xBE, +) +_U2CGK_JUNG = ( + 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, + 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, + 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, +) +_U2CGK_JONG = ( + 0xD4, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, + 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, + 0xB1, 0xB2, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xBA, + 0xBB, 0xBC, 0xBD, 0xBE, +) +_CGK2U_CHO = ( + 0, 1, _NONE, 2, _NONE, _NONE, 3, 4, + 5, _NONE, _NONE, _NONE, _NONE, _NONE, _NONE, _NONE, + 6, 7, 8, _NONE, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, +) +_CGK2U_JONG = ( + 1, 2, 3, 4, 5, 6, 7, _NONE, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, _NONE, 18, 19, 20, 21, 22, + _NONE, 23, 24, 25, 26, 27, +) + + +def _euckr_special(data, i, n): + """KS X 1001:1998 make-up sequence: A4 D4 A4 cho A4 jung A4 jong.""" + if data[i] != 0xA4 or i + 1 >= n or data[i + 1] != 0xD4: + return None + if i + 8 > n: + return ("toofew",) + if data[i + 2] != 0xA4 or data[i + 4] != 0xA4 or data[i + 6] != 0xA4: + return ("err", 1) + c = data[i + 3] + cho = _CGK2U_CHO[c - 0xA1] if 0xA1 <= c <= 0xBE else _NONE + c = data[i + 5] + jung = (c - 0xBF) if 0xBF <= c <= 0xD3 else _NONE + c = data[i + 7] + if c == 0xD4: + jong = 0 + elif 0xA1 <= c <= 0xBE: + jong = _CGK2U_JONG[c - 0xA1] + else: + jong = _NONE + if cho == _NONE or jung == _NONE or jong == _NONE: + return ("err", 1) + return ("out", chr(0xAC00 + cho * 588 + jung * 28 + jong), 8) + + +def _euckr_enc_char(c, c2, final): + b = _enc_map("euc_kr").get(c) + if b is not None: + return (b, 1) + if 0xAC00 <= c <= 0xD7A3: + # CP949-extension syllable -> 8-byte jamo make-up sequence. + v = c - 0xAC00 + return ( + bytes( + ( + 0xA4, 0xD4, + 0xA4, _U2CGK_CHO[v // 588], + 0xA4, _U2CGK_JUNG[(v // 28) % 21], + 0xA4, _U2CGK_JONG[v % 28], + ) + ), + 1, + ) + return None + + +# --------------------------------------------------------------------------- +# EUC-JP (SS3 plane) / Shift_JIS / CP932 +# --------------------------------------------------------------------------- + +def _eucjp_special(data, i, n): + if data[i] != 0x8F: + return None + if i + 3 > n: + return ("toofew",) + c2, c3 = data[i + 1], data[i + 2] + if 0xA1 <= c2 <= 0xFE and 0xA1 <= c3 <= 0xFE: + off = ((c2 - 0xA1) * 94 + (c3 - 0xA1)) << 1 + ss3 = _t.EUC_JP_DEC_SS3 + v = ss3[off] | (ss3[off + 1] << 8) + if v != _U16_UNDEF: + return ("out", chr(v), 3) + return ("err", 1) + + +def _sjis_single(c): + if 0xA1 <= c <= 0xDF: + return chr(0xFEC0 + c) + return None + + +def _sjis_needs2(c): + return (0x81 <= c <= 0x9F) or (0xE0 <= c <= 0xEA) + + +def _sjis_enc_char(c, c2, final): + if 0xFF61 <= c <= 0xFF9F: + return (bytes((c - 0xFEC0,)), 1) + b = _enc_map("shift_jis").get(c) + return (b, 1) if b is not None else None + + +def _cp932_single(c): + if c == 0x80: + return "\x80" + if c == 0xA0: + return "\uf8f0" + if 0xA1 <= c <= 0xDF: + return chr(0xFEC0 + c) + if c >= 0xFD: + return chr(0xF8F1 - 0xFD + c) + return None + + +def _cp932_enc_char(c, c2, final): + if c == 0x80: + return (b"\x80", 1) + if 0xFF61 <= c <= 0xFF9F: + return (bytes((c - 0xFEC0,)), 1) + if c == 0xF8F0: + return (b"\xa0", 1) + if 0xF8F1 <= c <= 0xF8F3: + return (bytes((c - 0xF8F1 + 0xFD,)), 1) + b = _enc_map("cp932").get(c) + if b is not None: + return (b, 1) + if 0xE000 <= c < 0xE758: + c1 = (c - 0xE000) // 188 + t = (c - 0xE000) % 188 + return (bytes((c1 + 0xF0, t + 0x40 if t < 0x3F else t + 0x41)), 1) + return None + + +# --------------------------------------------------------------------------- +# GB18030 4-byte linear forms +# --------------------------------------------------------------------------- + +def _gb18030_special(data, i, n): + if i + 1 >= n: + return None # generic path: needs2 -> toofew + c2 = data[i + 1] + if not (0x30 <= c2 <= 0x39): + return None + if i + 4 > n: + return ("toofew",) + c, c3, c4 = data[i], data[i + 2], data[i + 3] + if not (0x81 <= c <= 0xFE and 0x81 <= c3 <= 0xFE and 0x30 <= c4 <= 0x39): + return ("err", 1) + a = c - 0x81 + if a < 4: # U+0080 - U+FFFF + lseq = ((a * 10 + (c2 - 0x30)) * 1260 + (c3 - 0x81) * 10 + (c4 - 0x30)) + if lseq < 39420: + for first, last, base in _t.GB18030_RANGES: + if base <= lseq <= base + (last - first): + return ("out", chr(first - base + lseq), 4) + elif a >= 15: # U+10000 - U+10FFFF + lseq = 0x10000 + ((a - 15) * 10 + (c2 - 0x30)) * 1260 \ + + (c3 - 0x81) * 10 + (c4 - 0x30) + if lseq <= 0x10FFFF: + return ("out", chr(lseq), 4) + return ("err", 1) + + +def _gb18030_enc_char(c, c2, final): + b = _enc_map("gb18030").get(c) + if b is not None: + return (b, 1) + if c >= 0x10000: + tc = c - 0x10000 + b4 = tc % 10 + 0x30 + tc //= 10 + b3 = tc % 126 + 0x81 + tc //= 126 + b2 = tc % 10 + 0x30 + tc //= 10 + return (bytes((tc + 0x90, b2, b3, b4)), 1) + if c >= 0xD800 and c <= 0xDFFF: + return None + for first, last, base in _t.GB18030_RANGES: + if first <= c <= last: + tc = c - first + base + b4 = tc % 10 + 0x30 + tc //= 10 + b3 = tc % 126 + 0x81 + tc //= 126 + b2 = tc % 10 + 0x30 + tc //= 10 + return (bytes((tc + 0x81, b2, b3, b4)), 1) + return None + + +# --------------------------------------------------------------------------- +# BIG5HKSCS (combining pairs; the encoder is stateful) +# --------------------------------------------------------------------------- + +_HK_PAIRENC = { # ((c >> 4) | (c2 >> 3)) & 3 -> DBCS code + (0x00CA, 0x0304): b"\x88\x62", + (0x00CA, 0x030C): b"\x88\x64", + (0x00EA, 0x0304): b"\x88\xa3", + (0x00EA, 0x030C): b"\x88\xa5", +} + + +def _hk_cell2(c, c2): + v = _cell24(_t.BIG5HKSCS_DEC, c, c2) + if v is None: + return None + if v == _U24_PAIR: + a, b = _t.BIG5HKSCS_DEC_PAIRS[(c, c2)] + return chr(a) + chr(b) + return chr(v) + + +def _hk_enc_char(c, c2, final): + if c in (0x00CA, 0x00EA): + if c2 is None and not final: + return "toofew" + if c2 in (0x0304, 0x030C): + return (_HK_PAIRENC[(c, c2)], 2) + return (b"\x88\x66" if c == 0x00CA else b"\x88\xa7", 1) + b = _enc_map("big5hkscs").get(c) + return (b, 1) if b is not None else None + + +# --------------------------------------------------------------------------- +# codec registry +# --------------------------------------------------------------------------- + +def _table_enc_char(name): + m = _enc_map(name) + + def enc_char(c, c2, final, _m=m): + b = _m.get(c) + return (b, 1) if b is not None else None + + return enc_char + + +def _grid_cell2(name): + grid = getattr(_t, name.upper() + "_DEC") + + def cell2(c, c2, _grid=grid): + v = _cell16(_grid, c, c2) + return chr(v) if v is not None else None + + return cell2 + + +def _codec_spec(name): + """(single, needs2, cell2, special, enc_char) for `name`.""" + if name in ("euc_kr", "cp949", "gb2312", "gbk", "big5", "cp950"): + single = None + needs2 = _always2 + cell2 = _grid_cell2(name) + special = _euckr_special if name == "euc_kr" else None + enc_char = _euckr_enc_char if name == "euc_kr" else _table_enc_char(name) + return (single, needs2, cell2, special, enc_char) + if name == "euc_jp": + return (None, _always2, _grid_cell2(name), _eucjp_special, + _table_enc_char(name)) + if name == "shift_jis": + return (_sjis_single, _sjis_needs2, _grid_cell2(name), None, + _sjis_enc_char) + if name == "cp932": + return (_cp932_single, _always2, _grid_cell2(name), None, + _cp932_enc_char) + if name == "gb18030": + return (None, _always2, _grid_cell2(name), _gb18030_special, + _gb18030_enc_char) + if name == "big5hkscs": + return (None, _always2, _hk_cell2, None, _hk_enc_char) + raise LookupError("unknown encoding: " + name) + + +def _check_decode_input(name, input): + if not isinstance(input, (bytes, bytearray, memoryview)): + raise TypeError( + "decode() argument 'data' must be a bytes-like object, not %s" + % type(input).__name__ + ) + return bytes(input) + + +_REGENTRY_CACHE = {} + + +def getregentry(name): + info = _REGENTRY_CACHE.get(name) + if info is not None: + return info + + single, needs2, cell2, special, enc_char = _codec_spec(name) + + def encode(input, errors="strict", _name=name): + out, _pending = _mb_encode(_name, input, errors, True, enc_char) + return (out, len(input)) + + def decode(input, errors="strict", _name=name): + data = _check_decode_input(_name, input) + text, _consumed = _mb_decode( + _name, data, errors, True, single, needs2, cell2, special + ) + return (text, len(data)) + + class _IncEnc(ErrorsProperty, MbEncStateMixin, IncrementalEncoder): + # Only big5hkscs is genuinely stateful (pair lookahead); the + # pending-tail pattern is a no-op for every other codec. + def __init__(self, errors="strict"): + super().__init__(errors) + self._pending = "" + + def encode(self, input, final=False): + out, self._pending = _mb_encode( + name, self._pending + input, self.errors, final, enc_char + ) + return out + + def reset(self): + self._pending = "" + + class _IncDec(ErrorsProperty, MbDecStateMixin, IncrementalDecoder): + def __init__(self, errors="strict"): + super().__init__(errors) + self._buffer = b"" + self._flags = 0 + + def decode(self, input, final=False): + data = self._buffer + bytes(input) + result, consumed = _mb_decode( + name, data, self.errors, final, single, needs2, cell2, special + ) + self._buffer = data[consumed:] + return result + + def reset(self): + self._buffer = b"" + + class _Writer(StreamWriter): + def __init__(self, stream, errors="strict"): + super().__init__(stream, errors) + self._encoder = _IncEnc(errors) + + def encode(self, input, errors="strict"): + self._encoder.errors = errors + return (self._encoder.encode(input, False), len(input)) + + def reset(self): + super().reset() + enc = getattr(self, "_encoder", None) + if enc is not None: + try: + tail = enc.encode("", True) + except UnicodeEncodeError: + tail = b"" + if tail: + self.stream.write(tail) + enc.reset() + + class _Reader(MbStreamReaderMixin, StreamReader): + def __init__(self, stream, errors="strict"): + super().__init__(stream, errors) + self._decoder = _IncDec(errors) + + def decode(self, input, errors="strict"): + self._decoder.errors = errors + text = self._decoder.decode(bytes(input), False) + # Unconsumed tail bytes are buffered inside the incremental + # decoder, so report the full input as consumed. + return (text, len(input)) + + def reset(self): + super().reset() + dec = getattr(self, "_decoder", None) + if dec is not None: + dec.reset() + + _IncEnc.__name__ = "_IncEnc_" + name + _IncDec.__name__ = "_IncDec_" + name + _IncDec.name = name + _Writer.__name__ = "_StreamWriter_" + name + _Reader.__name__ = "_StreamReader_" + name + + info = CodecInfo( + encode=encode, + decode=decode, + incrementalencoder=_IncEnc, + incrementaldecoder=_IncDec, + streamreader=_Reader, + streamwriter=_Writer, + name=name, + _is_text_encoding=True, + ) + _REGENTRY_CACHE[name] = info + return info diff --git a/crates/weavepy-vm/src/stdlib/python/_codec_cjk_ext.py b/crates/weavepy-vm/src/stdlib/python/_codec_cjk_ext.py new file mode 100644 index 0000000..9199c39 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/_codec_cjk_ext.py @@ -0,0 +1,1615 @@ +"""WeavePy frozen port of CPython's stateful CJK escape codecs. + +Covers the codecs CPython implements in ``Modules/cjkcodecs`` that have no +``encoding_rs`` backend: ``hz``, the seven ``iso2022_*`` variants, ``johab``, +and ``shift_jis_2004``/``shift_jisx0213``. + +The double-byte charsets are bridged onto codecs WeavePy already carries: + +- JIS X 0208 -> ``euc_jp`` (two-byte cells, both bytes | 0x80) +- KS X 1001 -> ``euc_kr`` (same EUC bridging; UHC-only cells rejected) +- GB 2312 -> ``gb2312`` (same; GBK-only cells rejected) +- JIS X 0213 planes 1/2 and JIS X 0212 -> the packed tables in + ``_codec_euc_jis_2004`` (plane 2 rows split by row number: JIS X 0213 + plane 2 owns rows 1,3-5,8,12-15,78-94; JIS X 0212 owns the complement). + +State machines (ISO-2022 designations/shifts, HZ ~{..~} runs, Shift_JIS +lead-byte splits) are line-by-line ports of ``_codecs_iso2022.c``, +``_codecs_cn.c``, ``_codecs_kr.c`` and ``_codecs_jp.c``. +""" + +from codecs import ( + CodecInfo, + IncrementalEncoder, + IncrementalDecoder, + StreamReader, + StreamWriter, +) + +import _codec_euc_jis_2004 as _jis +from _cjk_common import ( + ErrorsProperty, + MbDecStateMixin, + MbEncStateMixin, + MbStreamReaderMixin, + dec_handle, + dec_setstate as _dec_setstate, + enc_getstate as _enc_getstate, + enc_handle, + enc_setstate as _enc_setstate, +) + +_ESC = 0x1B +_SO = 0x0E +_SI = 0x0F +_LF = 0x0A + +_REASON = "illegal multibyte sequence" +_REASON_INCOMPLETE = "incomplete multibyte sequence" + +# JIS X 0213:2000 emulation (emu_jisx0213_2000.h): characters added in the +# 2004 revision must be rejected, and U+9B1D moved plane between revisions. +_EMU2000_ENC_REJECT = frozenset( + (0x9B1C, 0x4FF1, 0x525D, 0x541E, 0x5653, 0x59F8, 0x5C5B, 0x5E77, 0x7626, 0x7E6B) +) +_EMU2000_DEC_REJECT_P1 = frozenset( + ((0x2E, 0x21), (0x2F, 0x7E), (0x4F, 0x54), (0x4F, 0x7E), (0x74, 0x27), + (0x7E, 0x7A), (0x7E, 0x7B), (0x7E, 0x7C), (0x7E, 0x7D), (0x7E, 0x7E)) +) + +# JIS X 0213 plane 2 rows (1,3,4,5,8,12,13,14,15,78-94 -> +0x20); every other +# row of the merged euc_jis_2004 plane-2 table belongs to JIS X 0212. +_X0213_2_ROWS = frozenset((0x21, 0x23, 0x24, 0x25, 0x28, 0x2C, 0x2D, 0x2E, 0x2F)) +_X0213_2_ROWS = _X0213_2_ROWS | frozenset(range(0x6E, 0x7F)) + + +# Error-handler plumbing lives in `_cjk_common` (the exact +# multibytecodec.c encerror/decerror protocol). +_enc_handle = enc_handle +_dec_handle = dec_handle + + +# --------------------------------------------------------------------------- +# charset bridges +# --------------------------------------------------------------------------- + +def _euc_cell_enc(ch, backend, rows=None): + """Encode one char through an EUC-style backend; accept only a proper + two-byte 94x94 cell (both bytes >= 0xA1). Returns (lead, trail) in the + 0x21..0x7E range or None.""" + try: + b = ch.encode(backend) + except ValueError: # UnicodeEncodeError or the engine's ValueError + return None + if len(b) == 2 and b[0] >= 0xA1 and b[1] >= 0xA1: + cell = (b[0] & 0x7F, b[1] & 0x7F) + if rows is not None and cell[0] not in rows: + return None + return cell + return None + + +def _euc_cell_dec(c1, c2, backend, rows=None): + """Decode a 94x94 cell through an EUC-style backend -> str or None.""" + if rows is not None and c1 not in rows: + return None + try: + s = bytes((c1 | 0x80, c2 | 0x80)).decode(backend) + except ValueError: + return None + return s if len(s) == 1 else None + + +# CPython's jisx0208 map covers only the rows JIS X 0208 itself defines +# (1-8 symbols/kana, 16-84 kanji); the WHATWG index behind the euc_jp +# backend additionally carries the NEC row-13 and IBM row-89..92 extensions, +# which must stay invisible here. +_JISX0208_ROWS = frozenset(range(0x21, 0x29)) | frozenset(range(0x30, 0x75)) +# GB 2312 defines rows 1-9 and 16-87; the gbk backend knows more. +_GB2312_ROWS = frozenset(range(0x21, 0x2A)) | frozenset(range(0x30, 0x78)) + + +# --- JIS X 0213 tables (shared with the euc_jis_2004 frozen port) ---------- + +_P1_ENC = None # {codepoint: (l, t)} plane 1 (merged 0208+0213-1) +_P2_ENC = None # {codepoint: (l, t)} plane 2 (0213-2 rows only) +_X0212_ENC = None # {codepoint: (l, t)} JIS X 0212 rows of the plane-2 table +_PAIR_ENC = None # {(base, mark): (l, t)} combining pairs (plane 1) +_BASE_LONE = None # {base: (l, t)} lone cell for each combining base + + +def _build_tables(): + global _P1_ENC, _P2_ENC, _X0212_ENC, _PAIR_ENC, _BASE_LONE + if _P1_ENC is not None: + return + p1 = {} + dec1 = _jis._DEC1 + for idx in range(len(dec1)): + v = dec1[idx] + if v >= 0x110000: + continue + cell = (0x21 + idx // 94, 0x21 + idx % 94) + if cell == (0x22, 0x32): + # euc_jis_2004 decodes 1-2-18 as U+FF5E; the layered + # jisx0208/jisx0213 view used by iso2022/shift_jis gives U+007E, + # and neither maps FF5E back on encode. + continue + p1.setdefault(v, cell) + p2 = {} + x0212 = {} + dec2 = _jis._DEC2 + for idx in range(len(dec2)): + v = dec2[idx] + if v >= 0x110000: + continue + cell = (0x21 + idx // 94, 0x21 + idx % 94) + if cell[0] in _X0213_2_ROWS: + p2.setdefault(v, cell) + else: + x0212.setdefault(v, cell) + pair = {} + lone = {} + for k, cp_pair in _jis._COMB.items(): + cell = (0x21 + k // 94, 0x21 + k % 94) + pair[cp_pair] = cell + for base in _jis._COMB_BASES: + b = _jis._ENC.get(chr(base)) + if b is not None and len(b) == 2: + lone[base] = (b[0] & 0x7F, b[1] & 0x7F) + _P1_ENC, _P2_ENC, _X0212_ENC, _PAIR_ENC, _BASE_LONE = p1, p2, x0212, pair, lone + + +def _x0213_p1_dec(c1, c2, y2000): + """JIS X 0213 plane-1 layered decode (jisx0208 first) -> str or None.""" + if y2000 and (c1, c2) in _EMU2000_DEC_REJECT_P1: + return None + if c1 == 0x22 and c2 == 0x32: + return "\x7e" + if not (0x21 <= c1 <= 0x7E and 0x21 <= c2 <= 0x7E): + return None + idx = (c1 - 0x21) * 94 + (c2 - 0x21) + v = _jis._DEC1[idx] + if v == 0xFFFFFE: + a, b = _jis._COMB[idx] + return chr(a) + chr(b) + if v >= 0x110000: + return None + return chr(v) + + +def _x0213_p2_dec(c1, c2, y2000): + """JIS X 0213 plane-2 decode -> str or None (0212 rows excluded).""" + if y2000 and c1 == 0x7D and c2 == 0x3B: + return "\u9b1d" + if c1 not in _X0213_2_ROWS or not (0x21 <= c2 <= 0x7E): + return None + v = _jis._DEC2[(c1 - 0x21) * 94 + (c2 - 0x21)] + if v >= 0x110000: + return None + return chr(v) + + +def _x0212_dec(c1, c2): + if c1 in _X0213_2_ROWS or not (0x21 <= c1 <= 0x7E and 0x21 <= c2 <= 0x7E): + return None + v = _jis._DEC2[(c1 - 0x21) * 94 + (c2 - 0x21)] + if v >= 0x110000: + return None + return chr(v) + + +# --------------------------------------------------------------------------- +# ISO-2022 designation charsets +# --------------------------------------------------------------------------- +# +# Each charset is a tuple: (dbcs, letter, width, encoder, decoder) +# encoder(c, c2, final) -> None (unmappable), "toofew", +# (cell, 1) or (cell, 2) -- cell is an int byte (width 1) or +# an (l, t) tuple (width 2); the second item is chars consumed. +# decoder(bytes...) -> str or None. ``None`` encoder/decoder marks a +# decode-only (G2) or dummy charset. + +def _cs_ascii_dummy(): + return (False, "B", 1, None, None) + + +def _enc_jisx0208(c, c2, final): + if c > 0xFFFF: + return None + cell = _euc_cell_enc(chr(c), "euc_jp", _JISX0208_ROWS) + return (cell, 1) if cell is not None else None + + +def _dec_jisx0208(c1, c2): + return _euc_cell_dec(c1, c2, "euc_jp", _JISX0208_ROWS) + + +def _enc_jisx0212(c, c2, final): + if c > 0xFFFF: + return None + _build_tables() + cell = _X0212_ENC.get(c) + return (cell, 1) if cell is not None else None + + +def _dec_jisx0212(c1, c2): + return _x0212_dec(c1, c2) + + +def _enc_ksx1001(c, c2, final): + if c > 0xFFFF: + return None + cell = _euc_cell_enc(chr(c), "euc_kr") + return (cell, 1) if cell is not None else None + + +def _dec_ksx1001(c1, c2): + return _euc_cell_dec(c1, c2, "euc_kr") + + +def _enc_gb2312(c, c2, final): + if c > 0xFFFF: + return None + cell = _euc_cell_enc(chr(c), "gb2312", _GB2312_ROWS) + return (cell, 1) if cell is not None else None + + +def _dec_gb2312(c1, c2): + return _euc_cell_dec(c1, c2, "gb2312", _GB2312_ROWS) + + +def _enc_jisx0201_r(c, c2, final): + if c == 0x00A5: + return (0x5C, 1) + if c == 0x203E: + return (0x7E, 1) + return None + + +def _dec_jisx0201_r(c1): + if c1 == 0x5C: + return "\u00a5" + if c1 == 0x7E: + return "\u203e" + if c1 <= 0x7F: + return chr(c1) + return None + + +def _enc_jisx0201_k(c, c2, final): + if 0xFF61 <= c <= 0xFF9F: + return (c - 0xFEC0 - 0x80, 1) + return None + + +def _dec_jisx0201_k(c1): + if 0x21 <= c1 <= 0x5F: + return chr(0xFF40 + c1) + return None + + +def _x0213_encoder(c, c2, final, y2000, plane, paironly): + """Port of jisx0213_encoder + the plane/paironly wrappers.""" + _build_tables() + if c > 0xFFFF: + if paironly or (c >> 16) != 0x2: + return None + if y2000 and c == 0x20B9F: + return None + cell = (_P1_ENC if plane == 1 else _P2_ENC).get(c) + return (cell, 1) if cell is not None else None + if y2000: + if c in _EMU2000_ENC_REJECT: + return None + if c == 0x9B1D: + return ((0x7D, 0x3B), 1) if plane == 2 else None + if c in _jis._COMB_BASES: + if c2 is None: + if not final: + return "toofew" + # flush: paironly never encodes a lone base (ilength == -1 path) + if paironly or plane != 1: + return None + cell = _BASE_LONE.get(c) + return (cell, 1) if cell is not None else None + cell = _PAIR_ENC.get((c, c2)) + if cell is not None: + return (cell, 2) if plane == 1 else None + if paironly or plane != 1: + return None + cell = _BASE_LONE.get(c) + return (cell, 1) if cell is not None else None + if paironly: + return None + cell = (_P1_ENC if plane == 1 else _P2_ENC).get(c) + return (cell, 1) if cell is not None else None + + +def _mk_x0213_charset(letter, y2000, plane, paironly): + def enc(c, c2, final): + return _x0213_encoder(c, c2, final, y2000, plane, paironly) + + def dec(c1, c2): + if plane == 1: + return _x0213_p1_dec(c1, c2, y2000) + return _x0213_p2_dec(c1, c2, y2000) + + return (True, letter, 2, enc, dec) + + +_CS_JISX0208 = (True, "B", 2, _enc_jisx0208, _dec_jisx0208) +_CS_JISX0208_O = (True, "@", 2, _enc_jisx0208, _dec_jisx0208) +_CS_JISX0212 = (True, "D", 2, _enc_jisx0212, _dec_jisx0212) +_CS_KSX1001 = (True, "C", 2, _enc_ksx1001, _dec_ksx1001) +_CS_GB2312 = (True, "A", 2, _enc_gb2312, _dec_gb2312) +_CS_JISX0201_R = (False, "J", 1, _enc_jisx0201_r, _dec_jisx0201_r) +_CS_JISX0201_K = (False, "I", 1, _enc_jisx0201_k, _dec_jisx0201_k) +_CS_ISO8859_1 = (False, "A", 1, None, None) +_CS_ISO8859_7 = (False, "F", 1, None, None) +_CS_X0213_2000_1 = _mk_x0213_charset("O", True, 1, False) +_CS_X0213_2000_1_PAIR = _mk_x0213_charset("O", True, 1, True) +_CS_X0213_2000_2 = _mk_x0213_charset("P", True, 2, False) +_CS_X0213_2004_1 = _mk_x0213_charset("Q", False, 1, False) +_CS_X0213_2004_1_PAIR = _mk_x0213_charset("Q", False, 1, True) +_CS_X0213_2004_2 = _mk_x0213_charset("P", False, 2, False) + +# iso2022_config flags +_NO_SHIFT = 0x01 +_USE_G2 = 0x02 +_USE_JISX0208_EXT = 0x04 + +# name -> (flags, ((charset, plane), ...)) +_ISO2022_CONFIGS = { + "iso2022_kr": (0, ((_CS_KSX1001, 1),)), + "iso2022_jp": ( + _NO_SHIFT | _USE_JISX0208_EXT, + ((_CS_JISX0208, 0), (_CS_JISX0201_R, 0), (_CS_JISX0208_O, 0)), + ), + "iso2022_jp_1": ( + _NO_SHIFT | _USE_JISX0208_EXT, + ((_CS_JISX0208, 0), (_CS_JISX0212, 0), (_CS_JISX0201_R, 0), + (_CS_JISX0208_O, 0)), + ), + "iso2022_jp_2": ( + _NO_SHIFT | _USE_G2 | _USE_JISX0208_EXT, + ((_CS_JISX0208, 0), (_CS_JISX0212, 0), (_CS_KSX1001, 0), + (_CS_GB2312, 0), (_CS_JISX0201_R, 0), (_CS_JISX0208_O, 0), + (_CS_ISO8859_1, 2), (_CS_ISO8859_7, 2)), + ), + "iso2022_jp_2004": ( + _NO_SHIFT | _USE_JISX0208_EXT, + ((_CS_X0213_2004_1_PAIR, 0), (_CS_JISX0208, 0), + (_CS_X0213_2004_1, 0), (_CS_X0213_2004_2, 0)), + ), + "iso2022_jp_3": ( + _NO_SHIFT | _USE_JISX0208_EXT, + ((_CS_X0213_2000_1_PAIR, 0), (_CS_JISX0208, 0), + (_CS_X0213_2000_1, 0), (_CS_X0213_2000_2, 0)), + ), + "iso2022_jp_ext": ( + _NO_SHIFT | _USE_JISX0208_EXT, + ((_CS_JISX0208, 0), (_CS_JISX0212, 0), (_CS_JISX0201_R, 0), + (_CS_JISX0201_K, 0), (_CS_JISX0208_O, 0)), + ), +} + +_ASCII_MARK = (False, "B") + + +def _charset_key(cs): + return (cs[0], cs[1]) + + +# --------------------------------------------------------------------------- +# ISO-2022 encoder / decoder cores +# --------------------------------------------------------------------------- + +class _Iso2022State: + """Mutable G0..G3 designations + shift/esc-throughout flags. + + ``getstate`` packs each designation slot into one byte exactly like + ``_codecs_iso2022.c``: the designation final character, OR'd with 0x80 + for a multibyte charset; 0 means "never designated" (which is why a + fresh *encoder* re-emits ``ESC ( B`` after ``setstate(0)`` even though + its natural initial G0 is ASCII).""" + + __slots__ = ("g", "shifted", "escthrough") + + def __init__(self, decoder=False): + # ENCODER_INIT designates G0/G1 only; DECODER_INIT also sets G2. + self.g = [ + _ASCII_MARK, + _ASCII_MARK, + _ASCII_MARK if decoder else None, + None, + ] + self.shifted = False + self.escthrough = False + + +def _mark_byte(mark): + if mark is None: + return 0 + return ord(mark[1]) | (0x80 if mark[0] else 0) + + +def _byte_mark(b): + if b == 0: + return None + return (bool(b & 0x80), chr(b & 0x7F)) + + +def _iso2022_encode_core(name, s, errors, final, state): + flags, desigs = _ISO2022_CONFIGS[name] + out = bytearray() + pending = "" + chars = s + i = 0 + n = len(chars) + while i < n: + c = ord(chars[i]) + if c < 0x80: + if state.g[0] != _ASCII_MARK: + out += b"\x1b(B" + state.g[0] = _ASCII_MARK + if state.shifted: + out.append(_SI) + state.shifted = False + out.append(c) + i += 1 + continue + + c2 = ord(chars[i + 1]) if i + 1 < n else None + encoded = None + consumed = 1 + hit = None + toofew = False + for cs, plane in desigs: + enc = cs[3] + if enc is None: + continue + r = enc(c, c2, final) + if r == "toofew": + toofew = True + break + if r is not None: + encoded, consumed = r + hit = (cs, plane) + break + if toofew: + pending = chars[i:] + break + if hit is None: + end = i + 1 + rep, newpos = _enc_handle(name, errors, chars, i, end) + if isinstance(rep, bytes): + out += rep + i = newpos + continue + if rep: + # Replacement text is encoded through this same state machine + # with strict errors (CPython re-encodes the callback result + # via the codec and errors out if it is unencodable). + sub, _ = _iso2022_encode_core(name, rep, "strict", True, state) + out += sub + i = newpos + continue + + cs, plane = hit + dbcs, letter, width = cs[0], cs[1], cs[2] + mark = (dbcs, letter) + if plane == 0: + if state.shifted: + out.append(_SI) + state.shifted = False + if state.g[0] != mark: + if width == 1: + out += b"\x1b(" + letter.encode("ascii") + elif mark == (True, "B"): + out += b"\x1b$B" + else: + out += b"\x1b$(" + letter.encode("ascii") + state.g[0] = mark + else: # plane 1 (iso2022_kr) + if state.g[1] != mark: + if width == 1: + out += b"\x1b)" + letter.encode("ascii") + else: + out += b"\x1b$)" + letter.encode("ascii") + state.g[1] = mark + if not state.shifted: + out.append(_SO) + state.shifted = True + + if width == 1: + out.append(encoded) + else: + out.append(encoded[0]) + out.append(encoded[1]) + i += consumed + + if final: + if state.shifted: + out.append(_SI) + state.shifted = False + if state.g[0] != _ASCII_MARK: + out += b"\x1b(B" + state.g[0] = _ASCII_MARK + return (bytes(out), pending) + + +_IS_ESCEND = frozenset(range(ord("A"), ord("Z") + 1)) | {ord("@")} +_ISO2022ESC_2ND = frozenset(b"()$.&") + + +def _iso2022_process_esc(name, data, i, final, state): + """Port of iso2022processesc. Returns ('ok', consumed), ('toofew', 0) or + ('err', length).""" + flags, desigs = _ISO2022_CONFIGS[name] + n = len(data) + esclen = 0 + j = 1 + while j < 16: + if i + j >= n: + if not final: + return ("toofew", 0) + return ("err", n - i) + b = data[i + j] + if b in _IS_ESCEND: + esclen = j + 1 + break + if (flags & _USE_JISX0208_EXT) and i + j + 1 < n \ + and b == 0x26 and data[i + j + 1] == 0x40: + j += 2 + j += 1 + + if esclen == 0: + return ("err", 1) + if esclen == 3: + if data[i + 1] == 0x24: # '$' + charset = (True, chr(data[i + 2])) + slot = 0 + else: + charset = (False, chr(data[i + 2])) + if data[i + 1] == 0x28: + slot = 0 + elif data[i + 1] == 0x29: + slot = 1 + elif (flags & _USE_G2) and data[i + 1] == 0x2E: + slot = 2 + else: + return ("err", 3) + elif esclen == 4: + if data[i + 1] != 0x24: + return ("err", 4) + charset = (True, chr(data[i + 3])) + if data[i + 2] == 0x28: + slot = 0 + elif data[i + 2] == 0x29: + slot = 1 + else: + return ("err", 4) + elif esclen == 6: + if (flags & _USE_JISX0208_EXT) and data[i + 3] == _ESC \ + and data[i + 4] == 0x24 and data[i + 5] == 0x42: + charset = (True, "B") + slot = 0 + else: + return ("err", 6) + else: + return ("err", esclen) + + if charset != _ASCII_MARK: + for cs, _plane in desigs: + if _charset_key(cs) == charset: + break + else: + return ("err", esclen) + state.g[slot] = charset + return ("ok", esclen) + + +def _iso2022_process_g2(data, i, state): + """Port of iso2022processg2 (SS2, ESC N x). Returns str or None.""" + b = data[i + 2] + g2 = state.g[2] + if g2 == (False, "A"): # iso8859-1 + if b < 0x80: + return chr(b + 0x80) + return None + if g2 == (False, "F"): # iso8859-7 + try: + return bytes((b | 0x80,)).decode("iso8859_7") + except UnicodeDecodeError: + return None + if g2 == _ASCII_MARK: + if b & 0x80: + return None + return chr(b) + return None + + +def _iso2022_decode_core(name, data, errors, final, state): + flags, desigs = _ISO2022_CONFIGS[name] + out = [] + i = 0 + n = len(data) + while i < n: + c = data[i] + + if state.escthrough: + # Non-iso2022 escape sequence: pass bytes through until the + # sequence terminator. + out.append(chr(c)) + i += 1 + if c in _IS_ESCEND: + state.escthrough = False + continue + + if c == _ESC: + if i + 1 >= n: + if not final: + break + rep, i = _dec_handle(name, errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + if data[i + 1] in _ISO2022ESC_2ND: + status, length = _iso2022_process_esc(name, data, i, final, state) + if status == "toofew": + break + if status == "err": + rep, i = _dec_handle(name, errors, data, i, i + length, _REASON) + out.append(rep) + continue + i += length + continue + if (flags & _USE_G2) and data[i + 1] == 0x4E: # 'N' (SS2) + if i + 2 >= n: + if not final: + break + rep, i = _dec_handle(name, errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + decoded = _iso2022_process_g2(data, i, state) + if decoded is None: + rep, i = _dec_handle(name, errors, data, i, i + 3, _REASON) + out.append(rep) + continue + out.append(decoded) + i += 3 + continue + out.append("\x1b") + state.escthrough = True + i += 1 + continue + + if c == _SI and not (flags & _NO_SHIFT): + state.shifted = False + i += 1 + continue + if c == _SO and not (flags & _NO_SHIFT): + state.shifted = True + i += 1 + continue + if c == _LF: + state.shifted = False + out.append("\n") + i += 1 + continue + if c < 0x20: + out.append(chr(c)) + i += 1 + continue + if c >= 0x80: + rep, i = _dec_handle(name, errors, data, i, i + 1, _REASON) + out.append(rep) + continue + + charset = state.g[1] if state.shifted else state.g[0] + if charset == _ASCII_MARK: + out.append(chr(c)) + i += 1 + continue + + for cs, _plane in desigs: + if _charset_key(cs) == charset: + break + else: # pragma: no cover - designation validation forbids this + rep, i = _dec_handle(name, errors, data, i, i + 1, _REASON) + out.append(rep) + continue + + width = cs[2] + dec = cs[4] + if i + width > n: + if not final: + break + rep, i = _dec_handle(name, errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + if dec is None: + decoded = None + elif width == 2: + decoded = dec(data[i], data[i + 1]) + else: + decoded = dec(data[i]) + if decoded is None: + rep, i = _dec_handle(name, errors, data, i, i + width, _REASON) + out.append(rep) + continue + out.append(decoded) + i += width + + return ("".join(out), i) + + +# --------------------------------------------------------------------------- +# HZ (HZ-GB-2312) encoder / decoder cores +# --------------------------------------------------------------------------- + +def _hz_encode_core(s, errors, final, state): + """state: [in_gb_mode]""" + out = bytearray() + i = 0 + n = len(s) + while i < n: + c = ord(s[i]) + if c < 0x80: + if state[0]: + out += b"~}" + state[0] = 0 + out.append(c) + if c == 0x7E: + out.append(0x7E) + i += 1 + continue + cell = _euc_cell_enc(s[i], "gb2312", _GB2312_ROWS) if c <= 0xFFFF else None + if cell is None: + rep, newpos = _enc_handle("hz", errors, s, i, i + 1) + if isinstance(rep, bytes): + out += rep + i = newpos + continue + if rep: + sub, _ = _hz_encode_core(rep, "strict", True, state) + out += sub + i = newpos + continue + if not state[0]: + out += b"~{" + state[0] = 1 + out.append(cell[0]) + out.append(cell[1]) + i += 1 + if final and state[0]: + out += b"~}" + state[0] = 0 + return (bytes(out), "") + + +def _hz_decode_core(data, errors, final, state): + out = [] + i = 0 + n = len(data) + while i < n: + c = data[i] + if c == 0x7E: # '~' + if i + 1 >= n: + if not final: + break + rep, i = _dec_handle("hz", errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + c2 = data[i + 1] + if c2 == 0x7E and not state[0]: + out.append("~") + elif c2 == 0x7B and not state[0]: + state[0] = 1 + elif c2 == 0x0A and not state[0]: + pass # line continuation + elif c2 == 0x7D and state[0]: + state[0] = 0 + else: + rep, i = _dec_handle("hz", errors, data, i, i + 1, _REASON) + out.append(rep) + continue + i += 2 + continue + if c & 0x80: + rep, i = _dec_handle("hz", errors, data, i, i + 1, _REASON) + out.append(rep) + continue + if not state[0]: + out.append(chr(c)) + i += 1 + continue + if i + 1 >= n: + if not final: + break + rep, i = _dec_handle("hz", errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + decoded = _euc_cell_dec(c, data[i + 1], "gb2312", _GB2312_ROWS) + if decoded is None: + # cjkcodecs decoders flag one byte per error (`return 1`) + rep, i = _dec_handle("hz", errors, data, i, i + 1, _REASON) + out.append(rep) + continue + out.append(decoded) + i += 2 + return ("".join(out), i) + + +# --------------------------------------------------------------------------- +# JOHAB encoder / decoder (stateless; port of _codecs_kr.c) +# --------------------------------------------------------------------------- + +_JOHAB_U2IDX_CHO = ( + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, +) +_JOHAB_U2IDX_JUNG = ( + 0x03, 0x04, 0x05, 0x06, 0x07, + 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1A, 0x1B, 0x1C, 0x1D, +) +_JOHAB_U2IDX_JONG = ( + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, +) +_JOHAB_U2JAMO = ( + 0x8841, 0x8C41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441, + 0x9841, 0x9C41, 0x844A, 0x844B, 0x844C, 0x844D, 0x844E, 0x844F, + 0x8450, 0xA041, 0xA441, 0xA841, 0x8454, 0xAC41, 0xB041, 0xB441, + 0xB841, 0xBC41, 0xC041, 0xC441, 0xC841, 0xCC41, 0xD041, 0x8461, + 0x8481, 0x84A1, 0x84C1, 0x84E1, 0x8541, 0x8561, 0x8581, 0x85A1, + 0x85C1, 0x85E1, 0x8641, 0x8661, 0x8681, 0x86A1, 0x86C1, 0x86E1, + 0x8741, 0x8761, 0x8781, 0x87A1, +) + +_J_FILL = 0xFD +_J_NONE = 0xFF +_JOHAB_IDX_CHO = ( + _J_NONE, _J_FILL, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, + 0x0E, 0x0F, 0x10, 0x11, 0x12, _J_NONE, _J_NONE, _J_NONE, + _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, +) +_JOHAB_IDX_JUNG = ( + _J_NONE, _J_NONE, _J_FILL, 0x00, 0x01, 0x02, 0x03, 0x04, + _J_NONE, _J_NONE, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + _J_NONE, _J_NONE, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, + _J_NONE, _J_NONE, 0x11, 0x12, 0x13, 0x14, _J_NONE, _J_NONE, +) +_JOHAB_IDX_JONG = ( + _J_NONE, _J_FILL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, _J_NONE, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, _J_NONE, _J_NONE, +) +_JOHAB_JAMO_CHO = ( + _J_NONE, _J_FILL, 0x31, 0x32, 0x34, 0x37, 0x38, 0x39, + 0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, _J_NONE, _J_NONE, _J_NONE, + _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, _J_NONE, +) +_JOHAB_JAMO_JUNG = ( + _J_NONE, _J_NONE, _J_FILL, 0x4F, 0x50, 0x51, 0x52, 0x53, + _J_NONE, _J_NONE, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + _J_NONE, _J_NONE, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, + _J_NONE, _J_NONE, 0x60, 0x61, 0x62, 0x63, _J_NONE, _J_NONE, +) +_JOHAB_JAMO_JONG = ( + _J_NONE, _J_FILL, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x40, 0x41, _J_NONE, 0x42, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, _J_NONE, _J_NONE, +) + + +def _johab_encode_char(c): + """-> (b1, b2) or None.""" + if 0xAC00 <= c <= 0xD7A3: + v = c - 0xAC00 + code = ( + 0x8000 + | (_JOHAB_U2IDX_CHO[v // 588] << 10) + | (_JOHAB_U2IDX_JUNG[(v // 28) % 21] << 5) + | _JOHAB_U2IDX_JONG[v % 28] + ) + return (code >> 8, code & 0xFF) + if 0x3131 <= c <= 0x3163: + code = _JOHAB_U2JAMO[c - 0x3131] + return (code >> 8, code & 0xFF) + if c > 0xFFFF: + return None + cell = _euc_cell_enc(chr(c), "euc_kr") + if cell is None: + return None + c1, c2 = cell + if ((0x21 <= c1 <= 0x2C) or (0x4A <= c1 <= 0x7D)) and 0x21 <= c2 <= 0x7E: + t1 = (c1 - 0x21 + 0x1B2) if c1 < 0x4A else (c1 - 0x21 + 0x197) + t2 = ((0x5E if (t1 & 1) else 0) + (c2 - 0x21)) & 0xFF + b1 = t1 >> 1 + b2 = t2 + 0x31 if t2 < 0x4E else t2 + 0x43 + return (b1 & 0xFF, b2 & 0xFF) + return None + + +def _johab_decode_cell(c, c2): + """-> str or None (c is the lead byte, 0x80..0xFF).""" + if c < 0xD8: + c_cho = (c >> 2) & 0x1F + c_jung = ((c << 3) | (c2 >> 5)) & 0x1F + c_jong = c2 & 0x1F + i_cho = _JOHAB_IDX_CHO[c_cho] + i_jung = _JOHAB_IDX_JUNG[c_jung] + i_jong = _JOHAB_IDX_JONG[c_jong] + if _J_NONE in (i_cho, i_jung, i_jong): + return None + if i_cho == _J_FILL: + if i_jung == _J_FILL: + if i_jong == _J_FILL: + return "\u3000" + return chr(0x3100 | _JOHAB_JAMO_JONG[c_jong]) + if i_jong == _J_FILL: + return chr(0x3100 | _JOHAB_JAMO_JUNG[c_jung]) + return None + if i_jung == _J_FILL: + if i_jong == _J_FILL: + return chr(0x3100 | _JOHAB_JAMO_CHO[c_cho]) + return None + return chr( + 0xAC00 + i_cho * 588 + i_jung * 28 + (0 if i_jong == _J_FILL else i_jong) + ) + # KS X 1001 non-hangul area + if (c == 0xDF or c > 0xF9 or c2 < 0x31 + or (0x80 <= c2 < 0x91) or (c2 & 0x7F) == 0x7F + or (c == 0xDA and 0xA1 <= c2 <= 0xD3)): + return None + t1 = (2 * (c - 0xD9)) & 0xFF if c < 0xE0 else (2 * c - 0x197) & 0xFF + t2 = (c2 - 0x31) & 0xFF if c2 < 0x91 else (c2 - 0x43) & 0xFF + t1 = (t1 + (0 if t2 < 0x5E else 1) + 0x21) & 0xFF + t2 = ((t2 if t2 < 0x5E else t2 - 0x5E) + 0x21) & 0xFF + return _euc_cell_dec(t1, t2, "euc_kr") + + +def _johab_encode_core(s, errors, final, state): + out = bytearray() + i = 0 + n = len(s) + while i < n: + c = ord(s[i]) + if c < 0x80: + out.append(c) + i += 1 + continue + pair = _johab_encode_char(c) + if pair is None: + rep, newpos = _enc_handle("johab", errors, s, i, i + 1) + if isinstance(rep, bytes): + out += rep + i = newpos + continue + if rep: + sub, _ = _johab_encode_core(rep, "strict", True, state) + out += sub + i = newpos + continue + out.append(pair[0]) + out.append(pair[1]) + i += 1 + return (bytes(out), "") + + +def _johab_decode_core(data, errors, final, state): + out = [] + i = 0 + n = len(data) + while i < n: + c = data[i] + if c < 0x80: + out.append(chr(c)) + i += 1 + continue + if i + 1 >= n: + if not final: + break + rep, i = _dec_handle("johab", errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + decoded = _johab_decode_cell(c, data[i + 1]) + if decoded is None: + # cjkcodecs decoders flag one byte per error (`return 1`) + rep, i = _dec_handle("johab", errors, data, i, i + 1, _REASON) + out.append(rep) + continue + out.append(decoded) + i += 2 + return ("".join(out), i) + + +# --------------------------------------------------------------------------- +# Shift_JIS-2004 / Shift_JISX0213 (port of _codecs_jp.c shift_jis_2004) +# --------------------------------------------------------------------------- + +def _sjis2004_cell_to_bytes(plane, c1, c2): + """Pack a plane/cell into the Shift_JIS lead/trail byte pair.""" + c2 -= 0x21 + if plane == 2: + c1 |= 0x80 + if c1 >= 0xEE: + c1 -= 0x87 + elif c1 >= 0xAC or c1 == 0xA8: + c1 -= 0x49 + else: + c1 -= 0x43 + else: + c1 -= 0x21 + if c1 & 1: + c2 += 0x5E + c1 >>= 1 + b1 = c1 + (0x81 if c1 < 0x1F else 0xC1) + b2 = c2 + (0x40 if c2 < 0x3F else 0x41) + return (b1, b2) + + +def _sjis2004_encode_char(c, c2, final, y2000): + """-> ('single', byte), ('cell', plane, c1, c2, consumed), 'toofew', + or None.""" + _build_tables() + # JIS X 0201 layer + if c < 0x80 and c != 0x5C and c != 0x7E: + return ("single", c) + if c == 0x00A5: + return ("single", 0x5C) + if c == 0x203E: + return ("single", 0x7E) + if 0xFF61 <= c <= 0xFF9F: + return ("single", c - 0xFEC0) + if c <= 0xFFFF: + if y2000: + if c in _EMU2000_ENC_REJECT: + return None + if c == 0x9B1D: + return ("cell", 2, 0x7D, 0x3B, 1) + if c in _jis._COMB_BASES: + if c2 is None: + if not final: + return "toofew" + cell = _BASE_LONE.get(c) + if cell is None: + return None + return ("cell", 1, cell[0], cell[1], 1) + cell = _PAIR_ENC.get((c, c2)) + if cell is not None: + return ("cell", 1, cell[0], cell[1], 2) + cell = _BASE_LONE.get(c) + if cell is None: + return None + return ("cell", 1, cell[0], cell[1], 1) + if c == 0x5C: + return ("cell", 1, 0x21, 0x40, 1) + if c == 0x7E: + return ("cell", 1, 0x22, 0x32, 1) + if c in (0xFF3C, 0xFF5E): + # euc_jis_2004 maps these to cells 1-1-32 / 1-2-18; the layered + # Shift_JIS-2004 view gives those cells to '\\' and '~'. + return None + cell = _P1_ENC.get(c) + if cell is not None: + return ("cell", 1, cell[0], cell[1], 1) + cell = _P2_ENC.get(c) + if cell is not None: + return ("cell", 2, cell[0], cell[1], 1) + cell = _X0212_ENC.get(c) + if cell is not None: + # JIS X 0212 codes are abandoned by shift_jis_2004 + return None + return None + if (c >> 16) == 0x2: + if y2000 and c == 0x20B9F: + return None + cell = _P1_ENC.get(c) + if cell is not None: + return ("cell", 1, cell[0], cell[1], 1) + cell = _P2_ENC.get(c) + if cell is not None: + return ("cell", 2, cell[0], cell[1], 1) + return None + + +def _sjis2004_encode_core(name, s, errors, final, state, y2000): + out = bytearray() + pending = "" + i = 0 + n = len(s) + while i < n: + c = ord(s[i]) + c2 = ord(s[i + 1]) if i + 1 < n else None + r = _sjis2004_encode_char(c, c2, final, y2000) + if r == "toofew": + pending = s[i:] + break + if r is None: + rep, newpos = _enc_handle(name, errors, s, i, i + 1) + if isinstance(rep, bytes): + out += rep + i = newpos + continue + if rep: + sub, _ = _sjis2004_encode_core(name, rep, "strict", True, state, y2000) + out += sub + i = newpos + continue + if r[0] == "single": + out.append(r[1]) + i += 1 + else: + _tag, plane, c1, cc2, consumed = r + b1, b2 = _sjis2004_cell_to_bytes(plane, c1, cc2) + out.append(b1) + out.append(b2) + i += consumed + return (bytes(out), pending) + + +def _sjis2004_decode_core(name, data, errors, final, state, y2000): + out = [] + i = 0 + n = len(data) + while i < n: + c = data[i] + # JIS X 0201 layer + if c < 0x5C: + out.append(chr(c)) + i += 1 + continue + if c == 0x5C: + out.append("\u00a5") + i += 1 + continue + if c < 0x7E: + out.append(chr(c)) + i += 1 + continue + if c == 0x7E: + out.append("\u203e") + i += 1 + continue + if c == 0x7F: + out.append("\x7f") + i += 1 + continue + if 0xA1 <= c <= 0xDF: + out.append(chr(0xFEC0 + c)) + i += 1 + continue + if (0x81 <= c <= 0x9F) or (0xE0 <= c <= 0xFC): + if i + 1 >= n: + if not final: + break + rep, i = _dec_handle(name, errors, data, i, n, _REASON_INCOMPLETE) + out.append(rep) + continue + b2 = data[i + 1] + if b2 < 0x40 or (0x7E < b2 < 0x80) or b2 > 0xFC: + # cjkcodecs decoders flag one byte per error (`return 1`) + rep, i = _dec_handle(name, errors, data, i, i + 1, _REASON) + out.append(rep) + continue + c1 = c - 0x81 if c < 0xE0 else c - 0xC1 + c2 = b2 - 0x40 if b2 < 0x80 else b2 - 0x41 + c1 = 2 * c1 + (0 if c2 < 0x5E else 1) + c2 = (c2 if c2 < 0x5E else c2 - 0x5E) + 0x21 + if c1 < 0x5E: # plane 1 + if y2000 and (c1 + 0x21, c2) in _EMU2000_DEC_REJECT_P1: + # EMULATE_JISX0213_2000_DECODE_INVALID flags both bytes + rep, i = _dec_handle(name, errors, data, i, i + 2, _REASON) + out.append(rep) + continue + if c1 == 0 and c2 == 0x40: + # shift_jis_2004 exposes the raw jisx0208 value for cell + # 1-1-32 (U+005C); euc/iso2022 decoders override it to + # U+FF3C before consulting the tables. + decoded = "\\" + else: + decoded = _x0213_p1_dec(c1 + 0x21, c2, y2000) + else: # plane 2 + if c1 >= 0x67: + c1 += 0x07 + elif c1 >= 0x63 or c1 == 0x5F: + c1 -= 0x37 + else: + c1 -= 0x3D + decoded = _x0213_p2_dec(c1, c2, y2000) + if decoded is None: + rep, i = _dec_handle(name, errors, data, i, i + 1, _REASON) + out.append(rep) + continue + out.append(decoded) + i += 2 + continue + rep, i = _dec_handle(name, errors, data, i, i + 1, _REASON) + out.append(rep) + return ("".join(out), i) + + +# --------------------------------------------------------------------------- +# codec class factories +# --------------------------------------------------------------------------- + +class _Iso2022IncrementalEncoder(ErrorsProperty, IncrementalEncoder): + name = None + + def __init__(self, errors="strict"): + super().__init__(errors) + self._state = _Iso2022State() + self._pending = "" + + def encode(self, input, final=False): + out, self._pending = _iso2022_encode_core( + self.name, self._pending + input, self.errors, final, self._state + ) + return out + + def reset(self): + # ENCODER_RESET emits the shift-in/ASCII re-designation bytes, but + # they have nowhere to go from reset(); discard state like CPython's + # incremental wrapper does on reset-without-output. + self._state = _Iso2022State() + self._pending = "" + + def getstate(self): + st = self._state + statebytes = bytes(( + _mark_byte(st.g[0]), + _mark_byte(st.g[1]), + _mark_byte(st.g[2]), + _mark_byte(st.g[3]), + 1 if st.shifted else 0, + 0, 0, 0, + )) + return _enc_getstate(self._pending, statebytes) + + def setstate(self, state): + pending, sb = _enc_setstate(state) + st = _Iso2022State() + st.g[0] = _byte_mark(sb[0]) + st.g[1] = _byte_mark(sb[1]) + st.g[2] = _byte_mark(sb[2]) + st.g[3] = _byte_mark(sb[3]) + st.shifted = bool(sb[4] & 1) + self._state = st + self._pending = pending + + +class _Iso2022IncrementalDecoder(ErrorsProperty, IncrementalDecoder): + name = None + + def __init__(self, errors="strict"): + super().__init__(errors) + self._state = _Iso2022State(decoder=True) + self._buffer = b"" + + def decode(self, input, final=False): + data = self._buffer + bytes(input) + result, consumed = _iso2022_decode_core( + self.name, data, self.errors, final, self._state + ) + self._buffer = data[consumed:] + return result + + def reset(self): + self._state = _Iso2022State(decoder=True) + self._buffer = b"" + + def getstate(self): + st = self._state + packed = int.from_bytes( + bytes(( + _mark_byte(st.g[0]), + _mark_byte(st.g[1]), + _mark_byte(st.g[2]), + _mark_byte(st.g[3]), + (1 if st.shifted else 0) | (2 if st.escthrough else 0), + )), + "little", + ) + return (self._buffer, packed) + + def setstate(self, state): + buf, flags = _dec_setstate(state, self.name) + sb = flags.to_bytes(8, "little") + st = _Iso2022State(decoder=True) + st.g[0] = _byte_mark(sb[0]) + st.g[1] = _byte_mark(sb[1]) + st.g[2] = _byte_mark(sb[2]) + st.g[3] = _byte_mark(sb[3]) + st.shifted = bool(sb[4] & 1) + st.escthrough = bool(sb[4] & 2) + self._state = st + self._buffer = buf + + +class _HzIncrementalEncoder(ErrorsProperty, IncrementalEncoder): + def __init__(self, errors="strict"): + super().__init__(errors) + self._state = [0] + + def encode(self, input, final=False): + out, _ = _hz_encode_core(input, self.errors, final, self._state) + return out + + def reset(self): + self._state = [0] + + def getstate(self): + # state.c[0] carries the ~{ shift flag; hz has no pending chars. + return _enc_getstate("", bytes((self._state[0], 0, 0, 0, 0, 0, 0, 0))) + + def setstate(self, state): + _pending, sb = _enc_setstate(state) + self._state = [1 if sb[0] else 0] + + +class _HzIncrementalDecoder(ErrorsProperty, IncrementalDecoder): + def __init__(self, errors="strict"): + super().__init__(errors) + self._state = [0] + self._buffer = b"" + + def decode(self, input, final=False): + data = self._buffer + bytes(input) + result, consumed = _hz_decode_core(data, self.errors, final, self._state) + self._buffer = data[consumed:] + return result + + def reset(self): + self._state = [0] + self._buffer = b"" + + def getstate(self): + return (self._buffer, self._state[0]) + + def setstate(self, state): + buf, flags = _dec_setstate(state, "hz") + self._buffer = buf + self._state = [1 if (flags & 0xFF) else 0] + + +class _StatelessIncrementalEncoder(ErrorsProperty, MbEncStateMixin, + IncrementalEncoder): + _core = None + name = None + _pending = "" + + def encode(self, input, final=False): + out, _ = type(self)._core(self._pending + input, self.errors, final, None) + self._pending = "" + return out + + def reset(self): + self._pending = "" + + +class _BufferedIncrementalDecoder(ErrorsProperty, MbDecStateMixin, + IncrementalDecoder): + _core = None + name = None + + def __init__(self, errors="strict"): + super().__init__(errors) + self._buffer = b"" + self._flags = 0 + + def decode(self, input, final=False): + data = self._buffer + bytes(input) + result, consumed = type(self)._core(data, self.errors, final, None) + self._buffer = data[consumed:] + return result + + def reset(self): + self._buffer = b"" + + +class _Sjis2004IncrementalEncoder(ErrorsProperty, MbEncStateMixin, + IncrementalEncoder): + name = None + y2000 = False + + def __init__(self, errors="strict"): + super().__init__(errors) + self._pending = "" + + def encode(self, input, final=False): + out, self._pending = _sjis2004_encode_core( + self.name, self._pending + input, self.errors, final, None, self.y2000 + ) + return out + + def reset(self): + self._pending = "" + + +class _Sjis2004IncrementalDecoder(ErrorsProperty, MbDecStateMixin, + IncrementalDecoder): + name = None + y2000 = False + + def __init__(self, errors="strict"): + super().__init__(errors) + self._buffer = b"" + self._flags = 0 + + def decode(self, input, final=False): + data = self._buffer + bytes(input) + result, consumed = _sjis2004_decode_core( + self.name, data, self.errors, final, None, self.y2000 + ) + self._buffer = data[consumed:] + return result + + def reset(self): + self._buffer = b"" + + +def _check_decode_input(name, input): + if not isinstance(input, (bytes, bytearray, memoryview)): + raise TypeError( + "decode() argument 'data' must be a bytes-like object, not %s" + % type(input).__name__ + ) + return bytes(input) + + +_REGENTRY_CACHE = {} + + +def getregentry(name): + info = _REGENTRY_CACHE.get(name) + if info is not None: + return info + + if name in _ISO2022_CONFIGS: + enc_cls = type( + "_IncEnc_" + name, (_Iso2022IncrementalEncoder,), {"name": name} + ) + dec_cls = type( + "_IncDec_" + name, (_Iso2022IncrementalDecoder,), {"name": name} + ) + + def encode(input, errors="strict", _name=name): + out, _pending = _iso2022_encode_core( + _name, input, errors, True, _Iso2022State() + ) + return (out, len(input)) + + def decode(input, errors="strict", _name=name): + data = _check_decode_input(_name, input) + text, _consumed = _iso2022_decode_core( + _name, data, errors, True, _Iso2022State(decoder=True) + ) + return (text, len(data)) + + elif name == "hz": + enc_cls = _HzIncrementalEncoder + dec_cls = _HzIncrementalDecoder + + def encode(input, errors="strict"): + out, _ = _hz_encode_core(input, errors, True, [0]) + return (out, len(input)) + + def decode(input, errors="strict"): + data = _check_decode_input("hz", input) + text, _consumed = _hz_decode_core(data, errors, True, [0]) + return (text, len(data)) + + elif name == "johab": + enc_cls = type( + "_IncEnc_johab", + (_StatelessIncrementalEncoder,), + {"name": "johab", "_core": staticmethod(_johab_encode_core)}, + ) + dec_cls = type( + "_IncDec_johab", + (_BufferedIncrementalDecoder,), + {"name": "johab", "_core": staticmethod(_johab_decode_core)}, + ) + + def encode(input, errors="strict"): + out, _ = _johab_encode_core(input, errors, True, None) + return (out, len(input)) + + def decode(input, errors="strict"): + data = _check_decode_input("johab", input) + text, _consumed = _johab_decode_core(data, errors, True, None) + return (text, len(data)) + + elif name in ("shift_jis_2004", "shift_jisx0213"): + y2000 = name == "shift_jisx0213" + enc_cls = type( + "_IncEnc_" + name, + (_Sjis2004IncrementalEncoder,), + {"name": name, "y2000": y2000}, + ) + dec_cls = type( + "_IncDec_" + name, + (_Sjis2004IncrementalDecoder,), + {"name": name, "y2000": y2000}, + ) + + def encode(input, errors="strict", _name=name, _y=y2000): + out, _pending = _sjis2004_encode_core(_name, input, errors, True, None, _y) + return (out, len(input)) + + def decode(input, errors="strict", _name=name, _y=y2000): + data = _check_decode_input(_name, input) + text, _consumed = _sjis2004_decode_core(_name, data, errors, True, None, _y) + return (text, len(data)) + + else: + raise LookupError("unknown encoding: " + name) + + # Stream classes wrap the incremental machinery so designation/shift + # state survives chunked reads/writes (codecs.StreamReader calls decode + # as a plain function otherwise, losing ISO-2022 designations across + # chunk boundaries). + class _Writer(StreamWriter): + def __init__(self, stream, errors="strict"): + super().__init__(stream, errors) + self._encoder = enc_cls(errors) + + def encode(self, input, errors="strict"): + self._encoder.errors = errors + return (self._encoder.encode(input, False), len(input)) + + def reset(self): + super().reset() + enc = getattr(self, "_encoder", None) + if enc is not None: + try: + tail = enc.encode("", True) + except UnicodeEncodeError: + tail = b"" + if tail: + self.stream.write(tail) + enc.reset() + + class _Reader(MbStreamReaderMixin, StreamReader): + def __init__(self, stream, errors="strict"): + super().__init__(stream, errors) + self._decoder = dec_cls(errors) + + def decode(self, input, errors="strict"): + self._decoder.errors = errors + text = self._decoder.decode(bytes(input), False) + # Everything is either consumed or held inside the incremental + # decoder, so report the full input as consumed. + return (text, len(input)) + + def reset(self): + super().reset() + dec = getattr(self, "_decoder", None) + if dec is not None: + dec.reset() + + _Writer.__name__ = "_StreamWriter_" + name + _Reader.__name__ = "_StreamReader_" + name + + info = CodecInfo( + encode=encode, + decode=decode, + incrementalencoder=enc_cls, + incrementaldecoder=dec_cls, + streamreader=_Reader, + streamwriter=_Writer, + name=name, + _is_text_encoding=True, + ) + _REGENTRY_CACHE[name] = info + return info diff --git a/crates/weavepy-vm/src/stdlib/python/_codec_euc_jis_2004.py b/crates/weavepy-vm/src/stdlib/python/_codec_euc_jis_2004.py index 78de96c..687f0f5 100644 --- a/crates/weavepy-vm/src/stdlib/python/_codec_euc_jis_2004.py +++ b/crates/weavepy-vm/src/stdlib/python/_codec_euc_jis_2004.py @@ -19,7 +19,17 @@ CodecInfo, IncrementalEncoder, IncrementalDecoder, - lookup_error as _lookup_error, + StreamReader, + StreamWriter, +) + +from _cjk_common import ( + ErrorsProperty, + MbDecStateMixin, + MbEncStateMixin, + MbStreamReaderMixin, + dec_handle as _common_dec_handle, + enc_handle as _common_enc_handle, ) _NAME = "euc_jis_2004" @@ -920,41 +930,11 @@ def _unpack_u24(b64): _COMB_BASES.add(_c1) -def _backslash(ch): - o = ord(ch) - if o > 0xFFFF: - return "\\U%08x" % o - if o > 0xFF: - return "\\u%04x" % o - return "\\x%02x" % o - - def _enc_handle(errors, s, start, end): - """Resolve an unencodable run ``s[start:end]`` -> (bytes, new_index).""" - if errors == "strict": - raise UnicodeEncodeError(_NAME, s, start, end, _REASON) - if errors == "ignore": - return (b"", end) - if errors == "replace": - return (b"?" * (end - start), end) - if errors == "xmlcharrefreplace": - return ("".join("&#%d;" % ord(c) for c in s[start:end]).encode("ascii"), end) - if errors == "backslashreplace": - return ("".join(_backslash(c) for c in s[start:end]).encode("ascii"), end) - if errors == "namereplace": - import unicodedata - - parts = [] - for c in s[start:end]: - try: - parts.append("\\N{%s}" % unicodedata.name(c)) - except ValueError: - parts.append(_backslash(c)) - return ("".join(parts).encode("ascii"), end) - handler = _lookup_error(errors) - rep, newpos = handler(UnicodeEncodeError(_NAME, s, start, end, _REASON)) - if newpos < 0: - newpos += len(s) + """Resolve an unencodable run ``s[start:end]`` -> (bytes, new_index). + Delegates to the shared multibytecodec.c protocol, then re-encodes a + ``str`` replacement through this codec's own map (strict).""" + rep, newpos = _common_enc_handle(_NAME, errors, s, start, end) if isinstance(rep, str): out = bytearray() for ch in rep: @@ -968,22 +948,23 @@ def _enc_handle(errors, s, start, end): def _dec_handle(errors, data, start, end, reason): """Resolve an undecodable run ``data[start:end]`` -> (str, new_index).""" - if errors == "strict": - raise UnicodeDecodeError(_NAME, bytes(data), start, end, reason) - if errors == "ignore": - return ("", end) - if errors == "replace": - return ("\ufffd", end) - if errors == "backslashreplace": - return ("".join("\\x%02x" % b for b in data[start:end]), end) - handler = _lookup_error(errors) - rep, newpos = handler(UnicodeDecodeError(_NAME, bytes(data), start, end, reason)) - if newpos < 0: - newpos += len(data) - return (rep, newpos) + return _common_dec_handle(_NAME, errors, data, start, end, reason) -def _encode_core(s, errors, final): +# JIS X 0213:2000 emulation (CPython emu_jisx0213_2000.h): `euc_jisx0213` +# shares this engine, but characters added by the 2004 revision must be +# rejected and U+9B1D sits in plane 2 (cell 7D3B) instead. +_EMU2000_ENC_REJECT = frozenset( + (0x9B1C, 0x4FF1, 0x525D, 0x541E, 0x5653, 0x59F8, 0x5C5B, 0x5E77, + 0x7626, 0x7E6B, 0x20B9F) +) +_EMU2000_DEC_REJECT_P1 = frozenset( + ((0x2E, 0x21), (0x2F, 0x7E), (0x4F, 0x54), (0x4F, 0x7E), (0x74, 0x27), + (0x7E, 0x7A), (0x7E, 0x7B), (0x7E, 0x7C), (0x7E, 0x7D), (0x7E, 0x7E)) +) + + +def _encode_core(s, errors, final, y2000=False): """Encode ``s`` -> (bytes, pending). ``pending`` is a combinable base held back at a non-final chunk boundary so it can combine with a following mark.""" out = bytearray() @@ -993,6 +974,16 @@ def _encode_core(s, errors, final): while i < n: ch = s[i] o = ord(ch) + if y2000: + if o in _EMU2000_ENC_REJECT: + rep, newpos = _enc_handle(errors, s, i, i + 1) + out += rep + i = newpos + continue + if o == 0x9B1D: + out += b"\x8f\xfd\xbb" + i += 1 + continue if o in _COMB_BASES: if i + 1 < n: cb = _COMB_ENC.get((o, ord(s[i + 1]))) @@ -1014,7 +1005,7 @@ def _encode_core(s, errors, final): return (bytes(out), pending) -def _decode_core(data, errors, final): +def _decode_core(data, errors, final, y2000=False): out = [] i = 0 n = len(data) @@ -1036,7 +1027,8 @@ def _decode_core(data, errors, final): out.append(chr(0xFF61 + (t - 0xA1))) i += 2 else: - rep, i = _dec_handle(errors, data, i, i + 2, _REASON) + # cjkcodecs decoders flag one byte per error (`return 1`) + rep, i = _dec_handle(errors, data, i, i + 1, _REASON) out.append(rep) continue if b == 0x8F: # SS3 plane 2 @@ -1049,12 +1041,16 @@ def _decode_core(data, errors, final): lead = data[i + 1] trail = data[i + 2] if 0xA1 <= lead <= 0xFE and 0xA1 <= trail <= 0xFE: + if y2000 and lead == 0xFD and trail == 0xBB: + out.append("\u9b1d") + i += 3 + continue v = _DEC2[(lead - 0xA1) * 94 + (trail - 0xA1)] if v < 0x110000: out.append(chr(v)) i += 3 continue - rep, i = _dec_handle(errors, data, i, i + 3, _REASON) + rep, i = _dec_handle(errors, data, i, i + 1, _REASON) out.append(rep) continue if 0xA1 <= b <= 0xFE: # plane 1 @@ -1066,6 +1062,11 @@ def _decode_core(data, errors, final): continue trail = data[i + 1] if 0xA1 <= trail <= 0xFE: + if y2000 and (b - 0x80, trail - 0x80) in _EMU2000_DEC_REJECT_P1: + # EMULATE_JISX0213_2000_DECODE_INVALID flags both bytes + rep, i = _dec_handle(errors, data, i, i + 2, _REASON) + out.append(rep) + continue c = (b - 0xA1) * 94 + (trail - 0xA1) v = _DEC1[c] if v == 0xFFFFFE: @@ -1078,7 +1079,7 @@ def _decode_core(data, errors, final): out.append(chr(v)) i += 2 continue - rep, i = _dec_handle(errors, data, i, i + 2, _REASON) + rep, i = _dec_handle(errors, data, i, i + 1, _REASON) out.append(rep) continue rep, i = _dec_handle(errors, data, i, i + 1, _REASON) @@ -1086,50 +1087,56 @@ def _decode_core(data, errors, final): return ("".join(out), i) -def _encode(input, errors="strict"): - out, _pending = _encode_core(input, errors, True) +def _encode(input, errors="strict", y2000=False): + out, _pending = _encode_core(input, errors, True, y2000) return (out, len(input)) -def _decode(input, errors="strict"): - return _decode_core(bytes(input), errors, True) +def _decode(input, errors="strict", y2000=False): + # Buffer-protocol input only (`bytes(42)` would be 42 zero bytes). + if not isinstance(input, (bytes, bytearray, memoryview)): + raise TypeError( + "decode() argument 'data' must be a bytes-like object, not %s" + % type(input).__name__) + return _decode_core(bytes(input), errors, True, y2000) -class _IncrementalEncoder(IncrementalEncoder): +class _IncrementalEncoder(ErrorsProperty, MbEncStateMixin, IncrementalEncoder): """Stateful encoder: a combinable base at a non-final chunk boundary is buffered so it can combine with a mark arriving in the next ``encode``. ``setstate(0)`` (issued by ``TextIOWrapper.seek``) discards the pending base — matching CPython's ``_codecs_jp`` MBCS encoder.""" + _y2000 = False + def __init__(self, errors="strict"): super().__init__(errors) self._pending = "" def encode(self, input, final=False): - out, self._pending = _encode_core(self._pending + input, self.errors, final) + out, self._pending = _encode_core( + self._pending + input, self.errors, final, self._y2000) return out def reset(self): super().reset() self._pending = "" - def getstate(self): - return ord(self._pending) if self._pending else 0 - - def setstate(self, state): - self._pending = chr(state) if state else "" - -class _IncrementalDecoder(IncrementalDecoder): +class _IncrementalDecoder(ErrorsProperty, MbDecStateMixin, IncrementalDecoder): """Stateful decoder buffering a trailing partial multibyte sequence.""" + _y2000 = False + name = _NAME + def __init__(self, errors="strict"): super().__init__(errors) self._buffer = b"" + self._flags = 0 def decode(self, input, final=False): data = self._buffer + bytes(input) - result, consumed = _decode_core(data, self.errors, final) + result, consumed = _decode_core(data, self.errors, final, self._y2000) self._buffer = data[consumed:] return result @@ -1137,19 +1144,107 @@ def reset(self): super().reset() self._buffer = b"" - def getstate(self): - return (self._buffer, 0) - def setstate(self, state): - self._buffer = state[0] +class _StreamWriter(StreamWriter): + """Stateful writer: chunks flow through a shared incremental encoder so a + combinable base held at a chunk boundary survives to the next write + (CPython's MultibyteStreamWriter).""" + + _y2000 = False + + def __init__(self, stream, errors="strict"): + StreamWriter.__init__(self, stream, errors) + self._encoder = ( + _IncrementalEncoder2000(errors) if self._y2000 + else _IncrementalEncoder(errors) + ) + + def encode(self, input, errors="strict"): + self._encoder.errors = errors + return (self._encoder.encode(input, False), len(input)) + + def reset(self): + StreamWriter.reset(self) + enc = getattr(self, "_encoder", None) + if enc is not None: + try: + tail = enc.encode("", True) + except UnicodeEncodeError: + tail = b"" + if tail: + self.stream.write(tail) + enc.reset() + + +class _StreamReader(MbStreamReaderMixin, StreamReader): + _y2000 = False + + def __init__(self, stream, errors="strict"): + StreamReader.__init__(self, stream, errors) + self._decoder = ( + _IncrementalDecoder2000(errors) if self._y2000 + else _IncrementalDecoder(errors) + ) + + def decode(self, input, errors="strict"): + self._decoder.errors = errors + text = self._decoder.decode(bytes(input), False) + # Unconsumed tail bytes stay buffered inside the incremental + # decoder (and raise from the EOF flush if the stream ends there). + return (text, len(input)) + + def reset(self): + StreamReader.reset(self) + dec = getattr(self, "_decoder", None) + if dec is not None: + dec.reset() + + +class _IncrementalEncoder2000(_IncrementalEncoder): + _y2000 = True + + +class _IncrementalDecoder2000(_IncrementalDecoder): + _y2000 = True + + +class _StreamWriter2000(_StreamWriter): + _y2000 = True + + +class _StreamReader2000(_StreamReader): + _y2000 = True + + +def _encode_2000(input, errors="strict"): + return _encode(input, errors, True) + + +def _decode_2000(input, errors="strict"): + return _decode(input, errors, True) def getregentry(name="euc_jis_2004"): + # CPython's `euc_jisx0213` is this same engine restricted to the JIS X + # 0213:2000 repertoire (emu_jisx0213_2000.h). + if name == "euc_jisx0213": + return CodecInfo( + encode=_encode_2000, + decode=_decode_2000, + incrementalencoder=_IncrementalEncoder2000, + incrementaldecoder=_IncrementalDecoder2000, + streamreader=_StreamReader2000, + streamwriter=_StreamWriter2000, + name=name, + _is_text_encoding=True, + ) return CodecInfo( encode=_encode, decode=_decode, incrementalencoder=_IncrementalEncoder, incrementaldecoder=_IncrementalDecoder, + streamreader=_StreamReader, + streamwriter=_StreamWriter, name=name, _is_text_encoding=True, ) diff --git a/crates/weavepy-vm/src/stdlib/python/_multibytecodec.py b/crates/weavepy-vm/src/stdlib/python/_multibytecodec.py new file mode 100644 index 0000000..11b375a --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/_multibytecodec.py @@ -0,0 +1,54 @@ +"""WeavePy's `_multibytecodec` surface. + +CPython implements the CJK codecs in C (`Modules/cjkcodecs/multibytecodec.c`) +and exposes these base classes; WeavePy implements the same codecs as frozen +Python modules (`_codec_cjk_dbcs`, `_codec_cjk_ext`, `_codec_euc_jis_2004`), +so the classes here exist for the module surface itself: the base types are +not usable directly — like CPython's, they require a ``codec`` attribute that +only properly-constructed subclasses provide (bug #3305: instantiating the +bare base type raises AttributeError, not a crash). +""" + + +class MultibyteCodec: + """Opaque codec handle (CPython's `MultibyteCodec` type).""" + + def encode(self, input, errors=None): + raise self._no_codec() + + def decode(self, input, errors=None): + raise self._no_codec() + + @staticmethod + def _no_codec(): + return TypeError("unbound MultibyteCodec object") + + +class MultibyteIncrementalEncoder: + def __init__(self, errors="strict"): + self.codec # AttributeError on the bare base type, like CPython + self.errors = errors + + +class MultibyteIncrementalDecoder: + def __init__(self, errors="strict"): + self.codec + self.errors = errors + + +class MultibyteStreamReader: + def __init__(self, stream, errors="strict"): + self.codec + self.stream = stream + self.errors = errors + + +class MultibyteStreamWriter: + def __init__(self, stream, errors="strict"): + self.codec + self.stream = stream + self.errors = errors + + +def __create_codec(arg): + raise TypeError("argument type invalid") diff --git a/crates/weavepy-vm/src/stdlib/python/codecs.py b/crates/weavepy-vm/src/stdlib/python/codecs.py index a7eb9c1..cb4f2eb 100644 --- a/crates/weavepy-vm/src/stdlib/python/codecs.py +++ b/crates/weavepy-vm/src/stdlib/python/codecs.py @@ -20,6 +20,37 @@ BOM_LE = BOM_UTF16_LE BOM_BE = BOM_UTF16_BE +# Per-codec `_codecs` entry points, re-exported like CPython's +# `from _codecs import *` (test_codecs calls e.g. `codecs.utf_7_decode` +# / `codecs.utf_16_ex_decode` directly). +utf_7_encode = _codecs.utf_7_encode +utf_7_decode = _codecs.utf_7_decode +utf_8_encode = _codecs.utf_8_encode +utf_8_decode = _codecs.utf_8_decode +utf_16_encode = _codecs.utf_16_encode +utf_16_decode = _codecs.utf_16_decode +utf_16_le_encode = _codecs.utf_16_le_encode +utf_16_le_decode = _codecs.utf_16_le_decode +utf_16_be_encode = _codecs.utf_16_be_encode +utf_16_be_decode = _codecs.utf_16_be_decode +utf_16_ex_decode = _codecs.utf_16_ex_decode +utf_32_encode = _codecs.utf_32_encode +utf_32_decode = _codecs.utf_32_decode +utf_32_le_encode = _codecs.utf_32_le_encode +utf_32_le_decode = _codecs.utf_32_le_decode +utf_32_be_encode = _codecs.utf_32_be_encode +utf_32_be_decode = _codecs.utf_32_be_decode +utf_32_ex_decode = _codecs.utf_32_ex_decode +ascii_encode = _codecs.ascii_encode +ascii_decode = _codecs.ascii_decode +latin_1_encode = _codecs.latin_1_encode +latin_1_decode = _codecs.latin_1_decode +raw_unicode_escape_encode = _codecs.raw_unicode_escape_encode +raw_unicode_escape_decode = _codecs.raw_unicode_escape_decode +unicode_escape_encode = _codecs.unicode_escape_encode +unicode_escape_decode = _codecs.unicode_escape_decode +readbuffer_encode = _codecs.readbuffer_encode + _USER_CODECS = {} _ERROR_HANDLERS = {} @@ -63,32 +94,58 @@ def __iter__(self): def __len__(self): return 4 + # CPython's CodecInfo is a tuple subclass: two lookups of the same codec + # (or a pickle round-trip) compare equal by their 4-tuple. + def __eq__(self, other): + if isinstance(other, CodecInfo): + other = tuple(other) + if isinstance(other, tuple): + return tuple(self) == other + return NotImplemented + + def __hash__(self): + return hash(tuple(self)) + + +def _make_codec(encoding, encode_fn, decode_fn, _is_text_encoding=True, + partial_decode_fn=None): + # Build the CPython-shaped codec surface on top of a stateless + # (encode, decode) pair — real `StreamReader`/`StreamWriter` subclasses + # (CPython's `encodings.*` modules do exactly this) plus incremental + # factories. When `partial_decode_fn` is given it speaks the stateful + # `decode(data, errors, final)` protocol (the UTF `_codecs` natives) and + # drives the incremental decoder / stream reader; otherwise the + # stateless pair is wrapped generically. + class _Reader(StreamReader): + # Binary transform codecs (base64/zlib/…) decode to bytes; their + # stream readers buffer bytes (CPython `charbuffertype = bytes`). + if not _is_text_encoding: + charbuffertype = bytes + + def decode(self, input, errors="strict"): + if partial_decode_fn is not None: + # Explicit final=False: the UTF natives default to it but + # the escape codecs default to final=True. + return partial_decode_fn(input, errors, False) + return decode_fn(input, errors) + + class _Writer(StreamWriter): + def encode(self, input, errors="strict"): + return encode_fn(input, errors) -def _make_codec(encoding, encode_fn, decode_fn, _is_text_encoding=True): - # Build generic incremental factories on top of the stateless - # (encode, decode) pair so `codecs.getincremental*` work for the - # built-in codecs without a bespoke class each. The stream - # reader/writer factories wrap the same stateless pair via the generic - # `_FuncStreamReader`/`_FuncStreamWriter` shims so `codecs.getreader` / - # `codecs.getwriter` (used e.g. by `pandas.read_csv(codecs.getreader( - # "utf-8")(handle))`) return a real callable rather than `None`. def _mk_incremental_encoder(errors="strict"): return _FuncIncrementalEncoder(encode_fn, errors) def _mk_incremental_decoder(errors="strict"): + if partial_decode_fn is not None: + return _StatefulFuncIncrementalDecoder(partial_decode_fn, errors) return _FuncIncrementalDecoder(decode_fn, errors) - def _mk_stream_reader(stream, errors="strict"): - return _FuncStreamReader(decode_fn, stream, errors) - - def _mk_stream_writer(stream, errors="strict"): - return _FuncStreamWriter(encode_fn, stream, errors) - return CodecInfo( encode=encode_fn, decode=decode_fn, - streamreader=_mk_stream_reader, - streamwriter=_mk_stream_writer, + streamreader=_Reader, + streamwriter=_Writer, incrementalencoder=_mk_incremental_encoder, incrementaldecoder=_mk_incremental_decoder, name=encoding, @@ -100,6 +157,11 @@ def _mk_stream_writer(stream, errors="strict"): "utf-8": ("utf_8_encode", "utf_8_decode"), "utf_8": ("utf_8_encode", "utf_8_decode"), "utf8": ("utf_8_encode", "utf_8_decode"), + "utf-7": ("utf_7_encode", "utf_7_decode"), + "utf_7": ("utf_7_encode", "utf_7_decode"), + "utf7": ("utf_7_encode", "utf_7_decode"), + "u7": ("utf_7_encode", "utf_7_decode"), + "unicode-1-1-utf-7": ("utf_7_encode", "utf_7_decode"), "utf-16": ("utf_16_encode", "utf_16_decode"), "utf_16": ("utf_16_encode", "utf_16_decode"), "utf-16-le": ("utf_16_le_encode", "utf_16_le_decode"), @@ -125,6 +187,23 @@ def _mk_stream_writer(stream, errors="strict"): "unicode_escape": ("unicode_escape_encode", "unicode_escape_decode"), } +# `_codecs` decoders that speak the stateful `(input, errors, final)` +# protocol: their stateless `CodecInfo.decode` must pass `final=True` +# (CPython's `encodings/utf_8.py` etc. do exactly this) while the raw +# function drives the incremental decoder / stream reader. +_STATEFUL_DECODE_FNS = { + "utf_8_decode", + "utf_7_decode", + "utf_16_decode", + "utf_16_le_decode", + "utf_16_be_decode", + "utf_32_decode", + "utf_32_le_decode", + "utf_32_be_decode", + "unicode_escape_decode", + "raw_unicode_escape_decode", +} + # CPython's `CodecInfo.name` for each canonical `encodings.` whose # display name differs from the module key (each module's `getregentry()` @@ -184,7 +263,11 @@ def _mk_stream_writer(stream, errors="strict"): def _normalise(name): - return name.replace("-", "_").replace(" ", "_").lower() + # CPython `normalizestring` (codecs.c): the `encodings.normalize_encoding` + # collapse (runs of punctuation → one underscore, non-ASCII dropped, + # `.` kept) plus lower-casing — `'AAA---8'` and `'aaa\xe9-8'` both + # normalize to `'aaa_8'`. + return _cpy_normalize_encoding(name).lower() # CPython `encodings.normalize_encoding` (vendored logic): collapse runs of @@ -261,6 +344,7 @@ def escape_decode(data, errors="strict"): out = bytearray() i = 0 n = len(data) + first_invalid = None # deferred DeprecationWarning message while i < n: c = data[i] if c != 0x5C: @@ -285,31 +369,49 @@ def escape_decode(data, errors="strict"): i += 1 else: break + if v > 0o377 and first_invalid is None: + first_invalid = "invalid octal escape sequence '\\%o'" % v out.append(v & 0xFF) elif c == 0x78: # \xHH hexdig = b"0123456789abcdefABCDEF" if i + 2 <= n and data[i] in hexdig and data[i + 1] in hexdig: out.append(int(data[i:i + 2], 16)) i += 2 - elif errors == "strict": - raise ValueError("invalid \\x escape at position %d" % (i - 2)) - elif errors == "replace": - out.append(0x3F) # '?' - elif errors != "ignore": - raise ValueError( - "decoding error; unknown error handling code: %s" % errors - ) + else: + if errors == "strict": + raise ValueError( + "invalid \\x escape at position %d" % (i - 2)) + elif errors == "replace": + out.append(0x3F) # '?' + elif errors != "ignore": + raise ValueError( + "decoding error; unknown error handling code: %s" + % errors) + # CPython skips the (single) hexdigit of a truncated escape. + if i < n and data[i] in hexdig: + i += 1 else: - # Unknown escape: kept verbatim (backslash included). + # Unknown escape: kept verbatim (backslash included), with a + # DeprecationWarning for the first one (CPython + # `_PyBytes_DecodeEscape2`). + if first_invalid is None: + first_invalid = "invalid escape sequence '\\%s'" % chr(c) out.append(0x5C) out.append(c) + if first_invalid is not None: + import warnings + warnings.warn(first_invalid, DeprecationWarning, stacklevel=2) return bytes(out), n def escape_encode(data, errors="strict"): """Inverse of `escape_decode`: bytes → Python-literal escaped bytes.""" - if not isinstance(data, (bytes, bytearray)): - raise TypeError("escape_encode() argument must be bytes") + # CPython's `escape_encode` takes exactly `bytes` (`O!` converter): + # even `bytearray` is a TypeError. + if type(data) is not bytes: + raise TypeError( + "escape_encode() argument 'data' must be bytes, not %s" + % type(data).__name__) out = bytearray() for c in bytes(data): if c in (0x27, 0x5C): # ' and backslash @@ -354,98 +456,160 @@ def charmap_build(decoding_table): return {ord(c): i for (i, c) in enumerate(decoding_table) if c != "\ufffe"} +def _charmap_decode_lookup(mapping, b): + """CPython ``charmapdecode_lookup``: map byte *b* through *mapping*. + Returns the replacement ``str``, or ``None`` for an undefined position + (missing key / ``None`` / ``'\\ufffe'``). Wrong-typed values raise + TypeError; other lookup exceptions propagate.""" + if isinstance(mapping, str): + if b >= len(mapping): + return None + w = mapping[b] + return None if w == "\ufffe" else w + try: + w = mapping[b] + except LookupError: + return None + if w is None: + return None + if isinstance(w, int): + if not 0 <= w < 0x110000: + raise TypeError("character mapping must be in range(0x110000)") + return chr(w) if w != 0xFFFE else None + if isinstance(w, str): + return None if w == "\ufffe" else w + raise TypeError("character mapping must return integer, None or str") + + def charmap_decode(input, errors="strict", mapping=None): """Decode *input* bytes via *mapping* (a 256-char decode ``str`` or an ``{byte: char-or-ordinal}`` dict); ``None`` decodes as latin-1. Mirrors the C ``_codecs.charmap_decode`` incl. the ``'\\ufffe'`` / missing-key "character maps to " error, routed through the error handler.""" + # CPython's `y*` converter: only buffer-protocol input (an int would + # otherwise become `bytes(42)` — 42 zero bytes). + if not isinstance(input, (bytes, bytearray, memoryview)): + raise TypeError( + "charmap_decode() argument 'data' must be a bytes-like object, " + "not %s" % type(input).__name__) data = bytes(input) if mapping is None: return (data.decode("latin-1", errors), len(data)) out = [] i = 0 n = len(data) + handler = None while i < n: - b = data[i] - ch = None - if isinstance(mapping, str): - if b < len(mapping): - m = mapping[b] - if m != "\ufffe": - ch = m - elif hasattr(mapping, "get"): - m = mapping.get(b) - if isinstance(m, int): - ch = chr(m) - elif isinstance(m, str) and m != "\ufffe": - ch = m - if ch is None: - if errors == "ignore": - i += 1 - continue - if errors == "replace": - out.append("\ufffd") - i += 1 - continue - exc = UnicodeDecodeError( - "charmap", data, i, i + 1, "character maps to " - ) - if errors == "strict": - raise exc - repl, newpos = lookup_error(errors)(exc) - if newpos < 0: - newpos += n - out.append(repl) - i = newpos + ch = _charmap_decode_lookup(mapping, data[i]) + if ch is not None: + out.append(ch) + i += 1 continue - out.append(ch) - i += 1 + exc = UnicodeDecodeError( + "charmap", data, i, i + 1, "character maps to " + ) + if handler is None: + handler = lookup_error(errors) + res = handler(exc) + if ( + not isinstance(res, tuple) + or len(res) != 2 + or not isinstance(res[0], str) + or not isinstance(res[1], int) + ): + raise TypeError("decoding error handler must return (str, int) tuple") + repl, newpos = res + if newpos < 0: + newpos += n + if not 0 <= newpos <= n: + raise IndexError( + "position %d from error handler out of bounds" % newpos + ) + out.append(repl) + i = newpos return ("".join(out), len(data)) +def _charmap_encode_lookup(mapping, cp): + """CPython ``charmapencode_lookup``: map ordinal *cp* through *mapping*. + Returns the output ``bytes``, or ``None`` for an undefined position + (missing key / ``None``). Wrong-typed values raise TypeError; other + lookup exceptions propagate.""" + try: + w = mapping[cp] + except LookupError: + return None + if w is None: + return None + if isinstance(w, int): + if not 0 <= w < 256: + raise TypeError("character mapping must be in range(256)") + return bytes([w]) + if isinstance(w, bytes): + return w + raise TypeError("character mapping must return integer, bytes or None, not %r" % (w,)) + + def charmap_encode(input, errors="strict", mapping=None): - """Encode *input* str via *mapping* (an ``{unicode-ordinal: byte}`` dict as - built by :func:`charmap_build`); ``None`` encodes as latin-1. Mirrors the C - ``_codecs.charmap_encode`` incl. the "character maps to " error - for a missing/``None`` target, routed through the error handler.""" + """Encode *input* str via *mapping* (an ``{unicode-ordinal: byte-or-bytes}`` + dict as built by :func:`charmap_build`); ``None`` encodes as latin-1. + Mirrors the C ``_codecs.charmap_encode``: undefined positions run the + error handler and ``str`` replacements are re-encoded through the same + charmap ("character maps to " if that fails too).""" + if not isinstance(input, str): + raise TypeError( + "charmap_encode() argument 'str' must be str, not %s" + % type(input).__name__) if mapping is None: return (input.encode("latin-1", errors), len(input)) out = bytearray() i = 0 n = len(input) + handler = None while i < n: - b = mapping.get(ord(input[i])) if hasattr(mapping, "get") else None - if b is None: - if errors == "ignore": - i += 1 - continue - if errors == "replace": - out.append(0x3F) # '?' - i += 1 - continue - exc = UnicodeEncodeError( - "charmap", input, i, i + 1, "character maps to " - ) - if errors == "strict": - raise exc - repl, newpos = lookup_error(errors)(exc) - if newpos < 0: - newpos += n - if isinstance(repl, str): - for rc in repl: - rb = mapping.get(ord(rc)) - if rb is None: - raise exc - out.append(rb) - else: - out.extend(bytes(repl)) - i = newpos + b = _charmap_encode_lookup(mapping, ord(input[i])) + if b is not None: + out += b + i += 1 continue - if isinstance(b, int): - out.append(b) + # Collect the full run of unencodable characters (CPython batches + # them into one handler call). + start = i + end = i + 1 + while end < n and _charmap_encode_lookup(mapping, ord(input[end])) is None: + end += 1 + exc = UnicodeEncodeError( + "charmap", input, start, end, "character maps to " + ) + if handler is None: + handler = lookup_error(errors) + res = handler(exc) + if ( + not isinstance(res, tuple) + or len(res) != 2 + or not isinstance(res[0], (str, bytes)) + or not isinstance(res[1], int) + ): + raise TypeError( + "encoding error handler must return (str/bytes, int) tuple" + ) + repl, newpos = res + if newpos < 0: + newpos += n + if not 0 <= newpos <= n: + raise IndexError( + "position %d from error handler out of bounds" % newpos + ) + if isinstance(repl, str): + # Re-encode the replacement through the charmap itself. + for rc in repl: + rb = _charmap_encode_lookup(mapping, ord(rc)) + if rb is None: + raise exc + out += rb else: - out.extend(bytes(b)) - i += 1 + out += repl + i = newpos return (bytes(out), len(input)) @@ -473,8 +637,8 @@ def _hex_encode(s, errors="strict"): def _hex_decode(b, errors="strict"): - if isinstance(b, bytes): - b = b.decode("ascii") + if not isinstance(b, str): + b = bytes(b).decode("ascii") return bytes.fromhex(b), len(b) @@ -540,6 +704,50 @@ def _bz2_decode(input, errors="strict"): return (bz2.decompress(bytes(input)), len(input)) +# CPython's `encodings/uu_codec.py`. +def _uu_encode(input, errors="strict", filename="", mode=0o666): + assert errors == "strict" + import binascii + + data = bytes(input) + filename = filename.replace("\n", "\\n").replace("\r", "\\r") + out = [("begin %o %s\n" % (mode & 0o777, filename)).encode("ascii")] + for i in range(0, len(data), 45): + out.append(binascii.b2a_uu(data[i : i + 45])) + out.append(b" \nend\n") + return (b"".join(out), len(input)) + + +def _uu_decode(input, errors="strict"): + assert errors == "strict" + import binascii + + data = bytes(input) + lines = data.splitlines(keepends=True) + pos = 0 + while True: + if pos >= len(lines): + raise ValueError('Missing "begin" line in input data') + s = lines[pos] + pos += 1 + if s[:5] == b"begin": + break + out = [] + while pos < len(lines): + s = lines[pos] + pos += 1 + if not s or s == b"end\n": + break + try: + chunk = binascii.a2b_uu(s) + except binascii.Error: + # Workaround for broken uuencoders by /Fredrik Lundh. + nbytes = (((s[0] - 32) & 63) * 4 + 5) // 3 + chunk = binascii.a2b_uu(s[:nbytes]) + out.append(chunk) + return (b"".join(out), len(input)) + + _PURE_CODECS = { "rot_13": (_rot13_encode, _rot13_decode), "rot13": (_rot13_encode, _rot13_decode), @@ -557,6 +765,8 @@ def _bz2_decode(input, errors="strict"): "zip": (_zlib_encode, _zlib_decode), "bz2": (_bz2_encode, _bz2_decode), "bz2_codec": (_bz2_encode, _bz2_decode), + "uu": (_uu_encode, _uu_decode), + "uu_codec": (_uu_encode, _uu_decode), } @@ -688,6 +898,368 @@ def setstate(self, state): self.buffer = state[0] +class StreamWriter(Codec): + """CPython ``codecs.StreamWriter`` (vendored verbatim from 3.13).""" + + def __init__(self, stream, errors='strict'): + self.stream = stream + self.errors = errors + + def write(self, object): + """ Writes the object's contents encoded to self.stream. + """ + data, consumed = self.encode(object, self.errors) + self.stream.write(data) + + def writelines(self, list): + """ Writes the concatenated list of strings to the stream + using .write(). + """ + self.write(''.join(list)) + + def reset(self): + pass + + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + if whence == 0 and offset == 0: + self.reset() + + def __getattr__(self, name, getattr=getattr): + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + + +class StreamReader(Codec): + """CPython ``codecs.StreamReader`` (vendored verbatim from 3.13): + real ``bytebuffer``/``charbuffer``/``linebuffer`` bookkeeping so + ``read(size, chars, firstline)`` / ``readline(size, keepends)`` + behave exactly like upstream.""" + + charbuffertype = str + + def __init__(self, stream, errors='strict'): + self.stream = stream + self.errors = errors + self.bytebuffer = b"" + self._empty_charbuffer = self.charbuffertype() + self.charbuffer = self._empty_charbuffer + self.linebuffer = None + + def decode(self, input, errors='strict'): + raise NotImplementedError + + def read(self, size=-1, chars=-1, firstline=False): + # If we have lines cached, first merge them back into characters + if self.linebuffer: + self.charbuffer = self._empty_charbuffer.join(self.linebuffer) + self.linebuffer = None + + if chars < 0: + # For compatibility with other read() methods that take a + # single argument + chars = size + + # read until we get the required number of characters (if available) + while True: + # can the request be satisfied from the character buffer? + if chars >= 0: + if len(self.charbuffer) >= chars: + break + # we need more data + if size < 0: + newdata = self.stream.read() + else: + newdata = self.stream.read(size) + # decode bytes (those remaining from the last call included) + data = self.bytebuffer + newdata + if not data: + break + try: + newchars, decodedbytes = self.decode(data, self.errors) + except UnicodeDecodeError as exc: + if firstline: + newchars, decodedbytes = \ + self.decode(data[:exc.start], self.errors) + lines = newchars.splitlines(keepends=True) + if len(lines)<=1: + raise + else: + raise + # keep undecoded bytes until the next call + self.bytebuffer = data[decodedbytes:] + # put new characters in the character buffer + self.charbuffer += newchars + # there was no data available + if not newdata: + break + if chars < 0: + # Return everything we've got + result = self.charbuffer + self.charbuffer = self._empty_charbuffer + else: + # Return the first chars characters + result = self.charbuffer[:chars] + self.charbuffer = self.charbuffer[chars:] + return result + + def readline(self, size=None, keepends=True): + # If we have lines cached from an earlier read, return + # them unconditionally + if self.linebuffer: + line = self.linebuffer[0] + del self.linebuffer[0] + if len(self.linebuffer) == 1: + # revert to charbuffer mode; we might need more data + # next time + self.charbuffer = self.linebuffer[0] + self.linebuffer = None + if not keepends: + line = line.splitlines(keepends=False)[0] + return line + + readsize = size or 72 + line = self._empty_charbuffer + # If size is given, we call read() only once + while True: + data = self.read(readsize, firstline=True) + if data: + # If we're at a "\r" read one extra character (which might + # be a "\n") to get a proper line ending. If the stream is + # temporarily exhausted we return the wrong line ending. + if (isinstance(data, str) and data.endswith("\r")) or \ + (isinstance(data, bytes) and data.endswith(b"\r")): + data += self.read(size=1, chars=1) + + line += data + lines = line.splitlines(keepends=True) + if lines: + if len(lines) > 1: + # More than one line result; the first line is a full line + # to return + line = lines[0] + del lines[0] + if len(lines) > 1: + # cache the remaining lines + lines[-1] += self.charbuffer + self.linebuffer = lines + self.charbuffer = None + else: + # only one remaining line, put it back into charbuffer + self.charbuffer = lines[0] + self.charbuffer + if not keepends: + line = line.splitlines(keepends=False)[0] + break + line0withend = lines[0] + line0withoutend = lines[0].splitlines(keepends=False)[0] + if line0withend != line0withoutend: # We really have a line end + # Put the rest back together and keep it until the next call + self.charbuffer = self._empty_charbuffer.join(lines[1:]) + \ + self.charbuffer + if keepends: + line = line0withend + else: + line = line0withoutend + break + # we didn't get anything or this was our only try + if not data or size is not None: + if line and not keepends: + line = line.splitlines(keepends=False)[0] + break + if readsize < 8000: + readsize *= 2 + return line + + def readlines(self, sizehint=None, keepends=True): + data = self.read() + return data.splitlines(keepends) + + def reset(self): + self.bytebuffer = b"" + self.charbuffer = self._empty_charbuffer + self.linebuffer = None + + def seek(self, offset, whence=0): + """ Set the input stream's current position. + + Resets the codec buffers used for keeping state. + """ + self.stream.seek(offset, whence) + self.reset() + + def __next__(self): + """ Return the next decoded line from the input stream.""" + line = self.readline() + if line: + return line + raise StopIteration + + def __iter__(self): + return self + + def __getattr__(self, name, getattr=getattr): + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + + +class StreamReaderWriter: + """CPython ``codecs.StreamReaderWriter`` (vendored verbatim).""" + + # Optional attributes set by the file wrappers below + encoding = 'unknown' + + def __init__(self, stream, Reader, Writer, errors='strict'): + self.stream = stream + self.reader = Reader(stream, errors) + self.writer = Writer(stream, errors) + self.errors = errors + + def read(self, size=-1): + return self.reader.read(size) + + def readline(self, size=None, keepends=True): + return self.reader.readline(size, keepends) + + def readlines(self, sizehint=None, keepends=True): + return self.reader.readlines(sizehint, keepends) + + def __next__(self): + """ Return the next decoded line from the input stream.""" + return next(self.reader) + + def __iter__(self): + return self + + def write(self, data): + return self.writer.write(data) + + def writelines(self, list): + return self.writer.writelines(list) + + def reset(self): + self.reader.reset() + self.writer.reset() + + def seek(self, offset, whence=0): + self.stream.seek(offset, whence) + self.reader.reset() + if whence == 0 and offset == 0: + self.writer.reset() + + def __getattr__(self, name, getattr=getattr): + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + # these are needed to make "with StreamReaderWriter(...)" work properly + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + + +class StreamRecoder: + """CPython ``codecs.StreamRecoder`` (vendored verbatim): transcodes + between a frontend data encoding and a backend file encoding.""" + + # Optional attributes set by the file wrappers below + data_encoding = 'unknown' + file_encoding = 'unknown' + + def __init__(self, stream, encode, decode, Reader, Writer, + errors='strict'): + self.stream = stream + self.encode = encode + self.decode = decode + self.reader = Reader(stream, errors) + self.writer = Writer(stream, errors) + self.errors = errors + + def read(self, size=-1): + data = self.reader.read(size) + data, bytesencoded = self.encode(data, self.errors) + return data + + def readline(self, size=None): + if size is None: + data = self.reader.readline() + else: + data = self.reader.readline(size) + data, bytesencoded = self.encode(data, self.errors) + return data + + def readlines(self, sizehint=None): + data = self.reader.read() + data, bytesencoded = self.encode(data, self.errors) + return data.splitlines(keepends=True) + + def __next__(self): + """ Return the next decoded line from the input stream.""" + data = next(self.reader) + data, bytesencoded = self.encode(data, self.errors) + return data + + def __iter__(self): + return self + + def write(self, data): + data, bytesdecoded = self.decode(data, self.errors) + return self.writer.write(data) + + def writelines(self, list): + data = b''.join(list) + data, bytesdecoded = self.decode(data, self.errors) + return self.writer.write(data) + + def reset(self): + self.reader.reset() + self.writer.reset() + + def seek(self, offset, whence=0): + # Seeks must be propagated to both the readers and writers + # as they might need to reset their internal buffers. + self.reader.seek(offset, whence) + self.writer.seek(offset, whence) + + def __getattr__(self, name, getattr=getattr): + """ Inherit all other methods from the underlying stream. + """ + return getattr(self.stream, name) + + def __enter__(self): + return self + + def __exit__(self, type, value, tb): + self.stream.close() + + def __reduce_ex__(self, proto): + raise TypeError("can't serialize %s" % self.__class__.__name__) + class _UTF8SigIncrementalEncoder(IncrementalEncoder): """utf-8-sig incremental encoder: emit the BOM exactly once (CPython ``encodings/utf_8_sig.py``). ``setstate(0)`` is how ``TextIOWrapper`` @@ -731,9 +1303,9 @@ def _buffer_decode(self, input, errors, final): else: self.first = 0 if input[:3] == BOM_UTF8: - (output, consumed) = _codecs.utf_8_decode(input[3:], errors) + (output, consumed) = _codecs.utf_8_decode(input[3:], errors, final) return (output, consumed + 3) - return _codecs.utf_8_decode(input, errors) + return _codecs.utf_8_decode(input, errors, final) def reset(self): super().reset() @@ -748,12 +1320,58 @@ def setstate(self, state): self.first = first +class _UTF8SigStreamWriter(StreamWriter): + """CPython ``encodings/utf_8_sig.py`` StreamWriter.""" + + def reset(self): + StreamWriter.reset(self) + try: + del self.encode + except AttributeError: + pass + + def encode(self, input, errors='strict'): + self.encode = _utf_8_encode_stateless + return _utf_8_sig_encode(input, errors) + + +class _UTF8SigStreamReader(StreamReader): + """CPython ``encodings/utf_8_sig.py`` StreamReader.""" + + def reset(self): + StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + if len(input) < 3: + if BOM_UTF8.startswith(input): + # not enough data to decide if this is a BOM + # => try again on the next call + return ("", 0) + elif input[:3] == BOM_UTF8: + self.decode = _codecs.utf_8_decode + (output, consumed) = _codecs.utf_8_decode(input[3:], errors) + return (output, consumed + 3) + # (else) no BOM present + self.decode = _codecs.utf_8_decode + return _codecs.utf_8_decode(input, errors) + + +def _utf_8_encode_stateless(input, errors='strict'): + return _codecs.utf_8_encode(input, errors) + + def _utf_8_sig_codecinfo(name="utf-8-sig"): return CodecInfo( encode=_utf_8_sig_encode, decode=_utf_8_sig_decode, incrementalencoder=_UTF8SigIncrementalEncoder, incrementaldecoder=_UTF8SigIncrementalDecoder, + streamreader=_UTF8SigStreamReader, + streamwriter=_UTF8SigStreamWriter, name="utf-8-sig", _is_text_encoding=True, ) @@ -832,36 +1450,271 @@ def setstate(self, state): self.encoder = _codecs.utf_32_be_encode +class _Utf16IncrementalDecoder(BufferedIncrementalDecoder): + """CPython ``encodings/utf_16.py`` IncrementalDecoder: BOM-sniffing on + the first chunk, then the resolved LE/BE stateful decoder.""" + + def __init__(self, errors='strict'): + BufferedIncrementalDecoder.__init__(self, errors) + self.decoder = None + + def _buffer_decode(self, input, errors, final): + if self.decoder is None: + (output, consumed, byteorder) = \ + _codecs.utf_16_ex_decode(input, errors, 0, final) + if byteorder == -1: + self.decoder = _codecs.utf_16_le_decode + elif byteorder == 1: + self.decoder = _codecs.utf_16_be_decode + elif consumed >= 2: + raise UnicodeDecodeError("utf-16", input, 0, 2, + "Stream does not start with BOM") + return (output, consumed) + return self.decoder(input, self.errors, final) + + def reset(self): + BufferedIncrementalDecoder.reset(self) + self.decoder = None + + def getstate(self): + # additional state info from the base class must be None here, + # as it isn't passed along to the caller + state = BufferedIncrementalDecoder.getstate(self)[0] + # additional state info we pass to the caller: + # 0: stream is in natural order for this platform + # 1: stream is in unnatural order + # 2: endianness hasn't been determined yet + if self.decoder is None: + return (state, 2) + addstate = int((sys.byteorder == "big") != + (self.decoder is _codecs.utf_16_be_decode)) + return (state, addstate) + + def setstate(self, state): + # state[1] will be ignored by BufferedIncrementalDecoder.setstate() + BufferedIncrementalDecoder.setstate(self, state) + state = state[1] + if state == 0: + self.decoder = (_codecs.utf_16_be_decode + if sys.byteorder == "big" + else _codecs.utf_16_le_decode) + elif state == 1: + self.decoder = (_codecs.utf_16_le_decode + if sys.byteorder == "big" + else _codecs.utf_16_be_decode) + else: + self.decoder = None + + +class _Utf16StreamWriter(StreamWriter): + """CPython ``encodings/utf_16.py`` StreamWriter.""" + + def __init__(self, stream, errors='strict'): + StreamWriter.__init__(self, stream, errors) + self.encoder = None + + def reset(self): + StreamWriter.reset(self) + self.encoder = None + + def encode(self, input, errors='strict'): + if self.encoder is None: + result = _codecs.utf_16_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = _codecs.utf_16_le_encode + else: + self.encoder = _codecs.utf_16_be_encode + return result + else: + return self.encoder(input, errors) + + +class _Utf16StreamReader(StreamReader): + """CPython ``encodings/utf_16.py`` StreamReader.""" + + def reset(self): + StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + (object, consumed, byteorder) = \ + _codecs.utf_16_ex_decode(input, errors, 0, False) + if byteorder == -1: + self.decode = _codecs.utf_16_le_decode + elif byteorder == 1: + self.decode = _codecs.utf_16_be_decode + elif consumed >= 2: + raise UnicodeDecodeError("utf-16", input, 0, 2, + "Stream does not start with BOM") + return (object, consumed) + + +class _Utf32IncrementalDecoder(BufferedIncrementalDecoder): + """CPython ``encodings/utf_32.py`` IncrementalDecoder.""" + + def __init__(self, errors='strict'): + BufferedIncrementalDecoder.__init__(self, errors) + self.decoder = None + + def _buffer_decode(self, input, errors, final): + if self.decoder is None: + (output, consumed, byteorder) = \ + _codecs.utf_32_ex_decode(input, errors, 0, final) + if byteorder == -1: + self.decoder = _codecs.utf_32_le_decode + elif byteorder == 1: + self.decoder = _codecs.utf_32_be_decode + elif consumed >= 4: + raise UnicodeDecodeError("utf-32", input, 0, 4, + "Stream does not start with BOM") + return (output, consumed) + return self.decoder(input, self.errors, final) + + def reset(self): + BufferedIncrementalDecoder.reset(self) + self.decoder = None + + def getstate(self): + state = BufferedIncrementalDecoder.getstate(self)[0] + if self.decoder is None: + return (state, 2) + addstate = int((sys.byteorder == "big") != + (self.decoder is _codecs.utf_32_be_decode)) + return (state, addstate) + + def setstate(self, state): + BufferedIncrementalDecoder.setstate(self, state) + state = state[1] + if state == 0: + self.decoder = (_codecs.utf_32_be_decode + if sys.byteorder == "big" + else _codecs.utf_32_le_decode) + elif state == 1: + self.decoder = (_codecs.utf_32_le_decode + if sys.byteorder == "big" + else _codecs.utf_32_be_decode) + else: + self.decoder = None + + +class _Utf32StreamWriter(StreamWriter): + """CPython ``encodings/utf_32.py`` StreamWriter.""" + + def __init__(self, stream, errors='strict'): + StreamWriter.__init__(self, stream, errors) + self.encoder = None + + def reset(self): + StreamWriter.reset(self) + self.encoder = None + + def encode(self, input, errors='strict'): + if self.encoder is None: + result = _codecs.utf_32_encode(input, errors) + if sys.byteorder == 'little': + self.encoder = _codecs.utf_32_le_encode + else: + self.encoder = _codecs.utf_32_be_encode + return result + else: + return self.encoder(input, errors) + + +class _Utf32StreamReader(StreamReader): + """CPython ``encodings/utf_32.py`` StreamReader.""" + + def reset(self): + StreamReader.reset(self) + try: + del self.decode + except AttributeError: + pass + + def decode(self, input, errors='strict'): + (object, consumed, byteorder) = \ + _codecs.utf_32_ex_decode(input, errors, 0, False) + if byteorder == -1: + self.decode = _codecs.utf_32_le_decode + elif byteorder == 1: + self.decode = _codecs.utf_32_be_decode + elif consumed >= 4: + raise UnicodeDecodeError("utf-32", input, 0, 4, + "Stream does not start with BOM") + return (object, consumed) + + +def _utf_16_decode_stateless(input, errors="strict"): + return _codecs.utf_16_decode(input, errors, True) + + +def _utf_32_decode_stateless(input, errors="strict"): + return _codecs.utf_32_decode(input, errors, True) + + def _utf_16_codecinfo(name="utf-16"): - dec = _codecs.utf_16_decode return CodecInfo( encode=_codecs.utf_16_encode, - decode=dec, + decode=_utf_16_decode_stateless, incrementalencoder=_Utf16IncrementalEncoder, - incrementaldecoder=lambda errors="strict": _FuncIncrementalDecoder(dec, errors), + incrementaldecoder=_Utf16IncrementalDecoder, + streamreader=_Utf16StreamReader, + streamwriter=_Utf16StreamWriter, name=name, _is_text_encoding=True, ) def _utf_32_codecinfo(name="utf-32"): - dec = _codecs.utf_32_decode return CodecInfo( encode=_codecs.utf_32_encode, - decode=dec, + decode=_utf_32_decode_stateless, incrementalencoder=_Utf32IncrementalEncoder, - incrementaldecoder=lambda errors="strict": _FuncIncrementalDecoder(dec, errors), + incrementaldecoder=_Utf32IncrementalDecoder, + streamreader=_Utf32StreamReader, + streamwriter=_Utf32StreamWriter, name=name, _is_text_encoding=True, ) -def _euc_jis_2004_codecinfo(): +def _euc_jis_2004_codecinfo(name="euc_jis_2004"): # The codec's ~70 KB of packed tables are unpacked once at module import; # keep that cold until something actually asks for `euc_jis_2004`. import _codec_euc_jis_2004 as _ejis - return _ejis.getregentry("euc_jis_2004") + return _ejis.getregentry(name) + + +# Canonical names served by the `_codec_cjk_ext` frozen module (spelling +# variants funnel through `encodings.aliases` before this table is consulted). +_CJK_EXT_NAMES = { + "hz": "hz", + "johab": "johab", + "shift_jis_2004": "shift_jis_2004", + "shift_jisx0213": "shift_jisx0213", + "iso2022_jp": "iso2022_jp", + "iso2022_jp_1": "iso2022_jp_1", + "iso2022_jp_2": "iso2022_jp_2", + "iso2022_jp_2004": "iso2022_jp_2004", + "iso2022_jp_3": "iso2022_jp_3", + "iso2022_jp_ext": "iso2022_jp_ext", + "iso2022_kr": "iso2022_kr", +} + +# Canonical names served by the `_codec_cjk_dbcs` frozen module — the +# stateless double/multi-byte CJK codecs with CPython-parity tables +# (RFC 0050 WS3). The engine's `encoding_rs` backend must never claim +# these: WHATWG's indices diverge (its euc-kr IS cp949, its big5 carries +# HKSCS, its shift_jis IS cp932, ...). +_CJK_DBCS_NAMES = frozenset(( + "euc_kr", "cp949", + "euc_jp", "cp932", "shift_jis", + "gb2312", "gbk", "gb18030", + "big5", "cp950", "big5hkscs", +)) # CPython's codec registry caches every successful lookup keyed by the @@ -931,6 +1784,25 @@ def _lookup_uncached(encoding): # dedicated frozen module loaded on first use. if norm in ("euc_jis_2004", "euc_jis2004", "eucjis2004", "jisx0213"): return _euc_jis_2004_codecinfo() + # JIS X 0213:2000 — CPython's `euc_jisx0213` shares the `_codecs_jp` + # engine with `euc_jis_2004` (the 2004 revision only *adds* ten + # characters); serve it from the same frozen port under its own name. + if norm in ("euc_jisx0213", "eucjisx0213"): + return _euc_jis_2004_codecinfo("euc_jisx0213") + # The stateful CJK escape codecs (CPython's Modules/cjkcodecs): HZ-GB-2312, + # the seven ISO-2022 variants, JOHAB and Shift_JIS-2004/X0213 live in a + # dedicated frozen module bridging onto the euc_jp/euc_kr/gb2312 backends + # and the euc_jis_2004 tables. + if norm in _CJK_EXT_NAMES: + import _codec_cjk_ext + + return _codec_cjk_ext.getregentry(_CJK_EXT_NAMES[norm]) + # The stateless CJK DBCS codecs (CPython's Modules/cjkcodecs) with + # generated CPython-parity tables (RFC 0050 WS3). + if norm in _CJK_DBCS_NAMES: + import _codec_cjk_dbcs + + return _codec_cjk_dbcs.getregentry(norm) # `idna` (RFC 3490) and `punycode` (RFC 3492) are pure-Python codecs in # CPython's `encodings` package; WeavePy freezes just those two and resolves # them lazily here (the engine's native `_codecs.lookup` doesn't carry them). @@ -942,6 +1814,14 @@ def _lookup_uncached(encoding): if norm == "punycode": import encodings.punycode as _punycode_mod return _punycode_mod.getregentry() + # CPython's bootstrap search function imports `encodings.` and uses + # its `getregentry()`. WeavePy freezes only the modules that tests and + # stdlib code reach into directly (ascii, utf_8, rot_13, base64_codec, + # the on-demand codepages, …); those take precedence here so their + # CodecInfo members are real module-level (hence picklable) objects. + info = _frozen_encodings_lookup(norm) + if info is not None: + return info display = _DISPLAY_NAMES.get(norm, encoding) if encoding in _PURE_CODECS or _normalise(encoding) in _PURE_CODECS: key = encoding if encoding in _PURE_CODECS else _normalise(encoding) @@ -955,8 +1835,13 @@ def _lookup_uncached(encoding): key = encoding if encoding in _BUILTIN_NAMES else _normalise(encoding) enc_name, dec_name = _BUILTIN_NAMES[key] encode_fn = getattr(_codecs, enc_name) - decode_fn = getattr(_codecs, dec_name) - return _make_codec(display, encode_fn, decode_fn) + raw_decode_fn = getattr(_codecs, dec_name) + if dec_name in _STATEFUL_DECODE_FNS: + def decode_fn(input, errors="strict", _raw=raw_decode_fn): + return _raw(input, errors, True) + return _make_codec(display, encode_fn, decode_fn, + partial_decode_fn=raw_decode_fn) + return _make_codec(display, encode_fn, raw_decode_fn) # Generic fall-through via the engine's own lookup. `_codecs.lookup` # raises `LookupError` for an unknown name (CPython parity; some older # engines raised `ValueError`, so tolerate both). On a miss, defer to @@ -1028,15 +1913,32 @@ def _search_registered(name): return None +def _note_codec_failure(exc, operation, encoding): + """CPython `wrap_codec_error`: note an exception escaping a codec call + with the codec it came from. Failures to attach the note are ignored.""" + try: + exc.add_note("%s with %r codec failed" % (operation, encoding)) + except Exception: + pass + + def encode(obj, encoding="utf-8", errors="strict"): info = lookup(encoding) - out, _ = info.encode(obj, errors) + try: + out, _ = info.encode(obj, errors) + except BaseException as exc: + _note_codec_failure(exc, "encoding", encoding) + raise return out def decode(obj, encoding="utf-8", errors="strict"): info = lookup(encoding) - out, _ = info.decode(obj, errors) + try: + out, _ = info.decode(obj, errors) + except BaseException as exc: + _note_codec_failure(exc, "decoding", encoding) + raise return out @@ -1052,12 +1954,15 @@ def register(search_function): def unregister(search_function): """Unregister a codec search function previously passed to - :func:`register` (no-op if it was never registered). Mirrors - CPython 3.10+ `codecs.unregister`.""" + :func:`register` and clear the registry's lookup cache (CPython + 3.10+ `_PyCodec_Unregister` semantics; no-op if never registered).""" try: _SEARCH_FUNCS.remove(search_function) except ValueError: return + # CPython clears `interp->codec_search_cache` when the function was + # registered, so a stale entry it served can't survive. + _CODEC_CACHE.clear() _SEARCH_FUNCS = [] @@ -1069,36 +1974,135 @@ def register_error(name, handler): _ERROR_HANDLERS[name] = handler +# ---------- built-in error handlers ---------- +# +# Faithful ports of CPython's `Python/codecs.c` handlers. CPython's +# `PyObject_TypeCheck` looks at the *real* type (a `__class__`-faking +# instance is rejected with `TypeError`), and the `PyUnicode*Error_Get*` +# accessors validate the `object` attribute's type and clamp +# `start`/`end` — several tests poke exactly these edges +# (`test_codeccallbacks.test_fake_error_class` / `test_unicode*error`). + + +def _wrong_exception_type(exc): + raise TypeError( + f"don't know how to handle {type(exc).__name__} in error callback" + ) + + +def _real_type_check(exc, cls): + # `PyObject_TypeCheck`: real inheritance, immune to `__class__` fakes. + return cls in type(exc).__mro__ + + +def _exc_fields(exc, kind): + """`(object, start, end)` with CPython's getter validation/clamping. + *kind* is ``'encode'``/``'translate'`` (str payload) or ``'decode'`` + (bytes payload).""" + obj = exc.object + if kind == "decode": + if not isinstance(obj, (bytes, bytearray)): + raise TypeError("object attribute must be bytes") + obj = bytes(obj) + else: + if not isinstance(obj, str): + raise TypeError("object attribute must be unicode") + size = len(obj) + start = exc.start + end = exc.end + if not isinstance(start, int) or not isinstance(end, int): + raise TypeError("an integer is required") + if start < 0: + start = 0 + if start >= size: + start = size - 1 + if end < 1: + end = 1 + if end > size: + end = size + return obj, start, end + + +def _exc_kind(exc): + if _real_type_check(exc, UnicodeEncodeError): + return "encode" + if _real_type_check(exc, UnicodeDecodeError): + return "decode" + if _real_type_check(exc, UnicodeTranslateError): + return "translate" + return None + + def strict_errors(exc): """CPython built-in ``strict`` handler: re-raise.""" - raise exc + if isinstance(exc, BaseException): + raise exc + raise TypeError("codec must pass exception instance") def ignore_errors(exc): """CPython built-in ``ignore`` handler: drop the offending range.""" - if isinstance(exc, (UnicodeEncodeError, UnicodeDecodeError, - UnicodeTranslateError)): - return ("", exc.end) - raise TypeError(f"don't know how to handle {type(exc).__name__} in error callback") + kind = _exc_kind(exc) + if kind is None: + _wrong_exception_type(exc) + _, _, end = _exc_fields(exc, kind) + return ("", end) def replace_errors(exc): - """CPython built-in ``replace`` handler: '?' on encode, U+FFFD on decode.""" - if isinstance(exc, UnicodeEncodeError): - return ("?" * (exc.end - exc.start), exc.end) - if isinstance(exc, (UnicodeDecodeError, UnicodeTranslateError)): - return ("\ufffd" * (exc.end - exc.start), exc.end) - raise TypeError(f"don't know how to handle {type(exc).__name__} in error callback") + """CPython built-in ``replace`` handler: '?' on encode, U+FFFD on + decode/translate.""" + kind = _exc_kind(exc) + if kind is None: + _wrong_exception_type(exc) + _, start, end = _exc_fields(exc, kind) + if kind == "encode": + return ("?" * (end - start), end) + if kind == "decode": + return ("\ufffd", end) + return ("\ufffd" * (end - start), end) def backslashreplace_errors(exc): - """CPython built-in ``backslashreplace`` handler (encode *and* decode).""" - if isinstance(exc, UnicodeDecodeError): - return ("".join(f"\\x{b:02x}" for b in exc.object[exc.start:exc.end]), - exc.end) - if isinstance(exc, (UnicodeEncodeError, UnicodeTranslateError)): - parts = [] - for ch in exc.object[exc.start:exc.end]: + """CPython built-in ``backslashreplace`` handler (encode *and* + decode/translate).""" + kind = _exc_kind(exc) + if kind is None: + _wrong_exception_type(exc) + obj, start, end = _exc_fields(exc, kind) + if kind == "decode": + return ("".join(f"\\x{b:02x}" for b in obj[start:end]), end) + parts = [] + for ch in obj[start:end]: + cp = ord(ch) + if cp < 0x100: + parts.append(f"\\x{cp:02x}") + elif cp < 0x10000: + parts.append(f"\\u{cp:04x}") + else: + parts.append(f"\\U{cp:08x}") + return ("".join(parts), end) + + +def xmlcharrefreplace_errors(exc): + """CPython built-in ``xmlcharrefreplace`` handler (encode only).""" + if _exc_kind(exc) != "encode": + _wrong_exception_type(exc) + obj, start, end = _exc_fields(exc, "encode") + return ("".join(f"&#{ord(ch)};" for ch in obj[start:end]), end) + + +def namereplace_errors(exc): + """CPython built-in ``namereplace`` handler (encode only).""" + if _exc_kind(exc) != "encode": + _wrong_exception_type(exc) + obj, start, end = _exc_fields(exc, "encode") + import unicodedata + parts = [] + for ch in obj[start:end]: + try: + parts.append("\\N{%s}" % unicodedata.name(ch)) + except (KeyError, ValueError): cp = ord(ch) if cp < 0x100: parts.append(f"\\x{cp:02x}") @@ -1106,36 +2110,114 @@ def backslashreplace_errors(exc): parts.append(f"\\u{cp:04x}") else: parts.append(f"\\U{cp:08x}") - return ("".join(parts), exc.end) - raise TypeError(f"don't know how to handle {type(exc).__name__} in error callback") - - -def xmlcharrefreplace_errors(exc): - """CPython built-in ``xmlcharrefreplace`` handler (encode only).""" - if isinstance(exc, UnicodeEncodeError): - return ("".join(f"&#{ord(ch)};" for ch in exc.object[exc.start:exc.end]), - exc.end) - raise TypeError(f"don't know how to handle {type(exc).__name__} in error callback") + return ("".join(parts), end) + + +def _standard_encoding(encoding): + """CPython ``get_standard_encoding``: `(family, bytelength)` where the + family is one of utf-8 / utf-16-le / utf-16-be / utf-32-le / utf-32-be, + or `(None, 0)` when unsupported. Byte-order-less names resolve to the + platform (little-endian) order.""" + norm = encoding.lower().replace("_", "-") + if norm in ("utf-8", "utf8", "cp65001"): + return ("utf-8", 3) + if norm in ("utf-16", "utf16", "u16", "utf-16-le", "utf-16le", "utf16le"): + if norm in ("utf-16", "utf16", "u16") and sys.byteorder == "big": + return ("utf-16-be", 2) + return ("utf-16-le", 2) + if norm in ("utf-16-be", "utf-16be", "utf16be"): + return ("utf-16-be", 2) + if norm in ("utf-32", "utf32", "u32", "utf-32-le", "utf-32le", "utf32le"): + if norm in ("utf-32", "utf32", "u32") and sys.byteorder == "big": + return ("utf-32-be", 4) + return ("utf-32-le", 4) + if norm in ("utf-32-be", "utf-32be", "utf32be"): + return ("utf-32-be", 4) + return (None, 0) + + +def surrogatepass_errors(exc): + """CPython's (static) ``surrogatepass`` handler.""" + kind = _exc_kind(exc) + if kind == "encode": + obj, start, end = _exc_fields(exc, "encode") + family, _ = _standard_encoding(exc.encoding) + if family is None: + raise exc + out = bytearray() + for ch in obj[start:end]: + cp = ord(ch) + if not 0xD800 <= cp <= 0xDFFF: + raise exc + if family == "utf-8": + out += bytes([0xE0 | (cp >> 12), + 0x80 | ((cp >> 6) & 0x3F), + 0x80 | (cp & 0x3F)]) + elif family == "utf-16-le": + out += cp.to_bytes(2, "little") + elif family == "utf-16-be": + out += cp.to_bytes(2, "big") + elif family == "utf-32-le": + out += cp.to_bytes(4, "little") + else: + out += cp.to_bytes(4, "big") + return (bytes(out), end) + if kind == "decode": + obj, start, end = _exc_fields(exc, "decode") + family, bytelength = _standard_encoding(exc.encoding) + if family is None: + raise exc + cp = 0 + p = obj[start:start + bytelength] + if len(p) == bytelength: + if family == "utf-8": + if (p[0] & 0xF0) == 0xE0 and (p[1] & 0xC0) == 0x80 \ + and (p[2] & 0xC0) == 0x80: + cp = ((p[0] & 0x0F) << 12) + ((p[1] & 0x3F) << 6) \ + + (p[2] & 0x3F) + elif family == "utf-16-le": + cp = int.from_bytes(p, "little") + elif family == "utf-16-be": + cp = int.from_bytes(p, "big") + elif family == "utf-32-le": + cp = int.from_bytes(p, "little") + else: + cp = int.from_bytes(p, "big") + if not 0xD800 <= cp <= 0xDFFF: + raise exc + return (chr(cp), start + bytelength) + _wrong_exception_type(exc) -def namereplace_errors(exc): - """CPython built-in ``namereplace`` handler (encode only).""" - if isinstance(exc, UnicodeEncodeError): - import unicodedata - parts = [] - for ch in exc.object[exc.start:exc.end]: - try: - parts.append("\\N{%s}" % unicodedata.name(ch)) - except (KeyError, ValueError): - cp = ord(ch) - if cp < 0x100: - parts.append(f"\\x{cp:02x}") - elif cp < 0x10000: - parts.append(f"\\u{cp:04x}") - else: - parts.append(f"\\U{cp:08x}") - return ("".join(parts), exc.end) - raise TypeError(f"don't know how to handle {type(exc).__name__} in error callback") +def surrogateescape_errors(exc): + """CPython's (static) ``surrogateescape`` handler (PEP 383).""" + kind = _exc_kind(exc) + if kind == "encode": + obj, start, end = _exc_fields(exc, "encode") + out = bytearray() + for ch in obj[start:end]: + cp = ord(ch) + if not 0xDC80 <= cp <= 0xDCFF: + # Not a UTF-8b surrogate — fail with the original error. + raise exc + out.append(cp - 0xDC00) + return (bytes(out), end) + if kind == "decode": + obj, start, end = _exc_fields(exc, "decode") + chars = [] + consumed = 0 + while consumed < 4 and consumed < end - start: + b = obj[start + consumed] + # Refuse to escape ASCII bytes. + if b < 128: + break + chars.append(chr(0xDC00 + b)) + consumed += 1 + if not consumed: + # Codec complained about an ASCII byte. + raise exc + return ("".join(chars), start + consumed) + _wrong_exception_type(exc) _BUILTIN_ERROR_HANDLERS = { @@ -1145,6 +2227,8 @@ def namereplace_errors(exc): "backslashreplace": backslashreplace_errors, "xmlcharrefreplace": xmlcharrefreplace_errors, "namereplace": namereplace_errors, + "surrogateescape": surrogateescape_errors, + "surrogatepass": surrogatepass_errors, } @@ -1153,12 +2237,6 @@ def lookup_error(name): return _ERROR_HANDLERS[name] if name in _BUILTIN_ERROR_HANDLERS: return _BUILTIN_ERROR_HANDLERS[name] - if name in {"surrogateescape", "surrogatepass"}: - # These need codec-internal state; the native codec paths - # implement them, so an explicit lookup gets a passthrough. - def passthrough(exc): # noqa - raise exc - return passthrough raise LookupError(f"unknown error handler name '{name}'") @@ -1249,6 +2327,13 @@ def __init__(self, decode, errors="strict"): super().__init__(errors) self._decode = decode + def decode(self, input, final=False): + # A str→str transform codec (rot_13) driven incrementally + # (`codecs.iterdecode`): no byte buffering applies. + if isinstance(input, str): + return self._decode(input, self.errors)[0] + return super().decode(input, final) + def _buffer_decode(self, input, errors, final): if final or not input: return self._decode(input, errors) @@ -1263,183 +2348,83 @@ def _buffer_decode(self, input, errors, final): return ("", 0) -class StreamReader: - def __init__(self, stream, errors="strict"): - self.stream = stream - self.errors = errors - - def read(self, size=-1, chars=-1, firstline=False): - data = self.stream.read() if size < 0 else self.stream.read(size) - return data.decode(getattr(self, "encoding", "utf-8"), self.errors) if isinstance(data, bytes) else data - - def readline(self, size=-1): - return self.stream.readline(size) - - def readlines(self, sizehint=-1): - return self.stream.readlines(sizehint) - - def __enter__(self): - return self - - def __exit__(self, type, value, tb): - self.stream.close() - - def __iter__(self): - return self - - def __next__(self): - line = self.readline() - if line: - return line - raise StopIteration - - # CPython's `StreamReader.__getattr__` forwards everything it doesn't - # define (`close`, `flush`, `seek`, `tell`, `seekable`, …) to the wrapped - # binary stream, so callers can treat the reader like the file itself. - def __getattr__(self, name): - if name in ("stream", "errors"): - raise AttributeError(name) - return getattr(self.stream, name) - - -class StreamWriter: - def __init__(self, stream, errors="strict"): - self.stream = stream - self.errors = errors - - def write(self, s): - return self.stream.write(s) - - def writelines(self, lines): - for line in lines: - self.write(line) - - def __enter__(self): - return self - - def __exit__(self, type, value, tb): - self.stream.close() +class _StatefulFuncIncrementalDecoder(BufferedIncrementalDecoder): + """Incremental decoder over a *stateful* ``decode(input, errors, final)`` + callable (the `_codecs` UTF natives): the codec itself reports how many + bytes it consumed, so no split-guessing is needed.""" - def __getattr__(self, name): - if name in ("stream", "errors"): - raise AttributeError(name) - return getattr(self.stream, name) - - -class StreamReaderWriter: - def __init__(self, stream, Reader, Writer, errors="strict"): - self.stream = stream - self.reader = Reader(stream, errors) - self.writer = Writer(stream, errors) - - def read(self, size=-1): - return self.reader.read(size) - - def write(self, data): - return self.writer.write(data) - - -class _FuncStreamReader(StreamReader): - """Generic ``StreamReader`` over a stateless ``decode`` callable.""" - - def __init__(self, decode, stream, errors="strict"): - StreamReader.__init__(self, stream, errors) + def __init__(self, decode, errors="strict"): + super().__init__(errors) self._decode = decode - def read(self, size=-1, chars=-1, firstline=False): - data = self.stream.read() if size < 0 else self.stream.read(size) - if isinstance(data, str): - return data - return self._decode(data, self.errors)[0] - - -class _FuncStreamWriter(StreamWriter): - """Generic ``StreamWriter`` over a stateless ``encode`` callable.""" + def _buffer_decode(self, input, errors, final): + return self._decode(input, errors, final) - def __init__(self, encode, stream, errors="strict"): - StreamWriter.__init__(self, stream, errors) - self._encode = encode - def write(self, s): - return self.stream.write(self._encode(s, self.errors)[0]) # ---------- helpers for utf-8/utf-16 file IO ---------- -_builtin_open = open - - -def open(filename, mode="rb", encoding=None, errors="strict", buffering=-1): - """Open a file with codec wrapping. Falls through to the builtin `open`.""" - if "b" not in mode: - mode = mode + "b" - f = _builtin_open(filename, mode) +def open(filename, mode='r', encoding=None, errors='strict', buffering=-1): + """CPython ``codecs.open`` (vendored verbatim): open an encoded file + and wrap it in a :class:`StreamReaderWriter`.""" + if encoding is not None and \ + 'b' not in mode: + # Force opening of the file in binary mode + mode = mode + 'b' + # Late-bound `builtins.open` (CPython does the same), so tests that + # `mock.patch('builtins.open')` intercept this call. + import builtins + file = builtins.open(filename, mode, buffering) if encoding is None: - return f - info = lookup(encoding) - f.encoding = encoding - f.errors = errors - - class _Wrap: - def __init__(self, raw): - self.raw = raw - - def read(self, n=-1): - data = self.raw.read(n) - if isinstance(data, bytes): - text, _ = info.decode(data, errors) - return text - return data - - def write(self, s): - data, _ = info.encode(s, errors) - return self.raw.write(data) + return file - def close(self): - self.raw.close() - - def __enter__(self): - return self - - def __exit__(self, *exc): - self.close() - return False - - return _Wrap(f) - - -# Default error handlers. -def strict_errors(exc): - raise exc - - -def ignore_errors(exc): - return ("", getattr(exc, "end", 0)) + try: + info = lookup(encoding) + srw = StreamReaderWriter(file, info.streamreader, info.streamwriter, errors) + # Add attributes to simplify introspection + srw.encoding = encoding + return srw + except: + file.close() + raise -def replace_errors(exc): - return ("\ufffd", getattr(exc, "end", 0)) - - -_ERROR_HANDLERS["strict"] = strict_errors -_ERROR_HANDLERS["ignore"] = ignore_errors -_ERROR_HANDLERS["replace"] = replace_errors - - -__all__ = [ - "BOM", "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_BE", "BOM_UTF16_LE", - "BOM_UTF32", "BOM_UTF32_BE", "BOM_UTF32_LE", "BOM_BE", "BOM_LE", - "encode", "decode", "lookup", "register", "unregister", - "register_error", "lookup_error", "CodecInfo", - "strict_errors", "ignore_errors", "replace_errors", - "backslashreplace_errors", "xmlcharrefreplace_errors", - "namereplace_errors", - "getencoder", "getdecoder", "getincrementalencoder", - "getincrementaldecoder", "getreader", "getwriter", - "iterencode", "iterdecode", - "IncrementalEncoder", "IncrementalDecoder", - "BufferedIncrementalEncoder", "BufferedIncrementalDecoder", - "StreamReader", "StreamWriter", "StreamReaderWriter", - "open", -] +def EncodedFile(file, data_encoding, file_encoding=None, errors='strict'): + """CPython ``codecs.EncodedFile`` (vendored verbatim): wrap *file* in a + :class:`StreamRecoder` translating between two encodings.""" + if file_encoding is None: + file_encoding = data_encoding + data_info = lookup(data_encoding) + file_info = lookup(file_encoding) + sr = StreamRecoder(file, data_info.encode, data_info.decode, + file_info.streamreader, file_info.streamwriter, errors) + # Add attributes to simplify introspection + sr.data_encoding = data_encoding + sr.file_encoding = file_encoding + return sr + + +# Deprecated (pre-Unicode-3.2) BOM aliases CPython still exports. +BOM32_LE = BOM_UTF16_LE +BOM32_BE = BOM_UTF16_BE +BOM64_LE = BOM_UTF32_LE +BOM64_BE = BOM_UTF32_BE + + +# CPython's exact `codecs.__all__` (3.13). +__all__ = ["register", "lookup", "open", "EncodedFile", "BOM", "BOM_BE", + "BOM_LE", "BOM32_BE", "BOM32_LE", "BOM64_BE", "BOM64_LE", + "BOM_UTF8", "BOM_UTF16", "BOM_UTF16_LE", "BOM_UTF16_BE", + "BOM_UTF32", "BOM_UTF32_LE", "BOM_UTF32_BE", + "CodecInfo", "Codec", "IncrementalEncoder", "IncrementalDecoder", + "StreamReader", "StreamWriter", + "StreamReaderWriter", "StreamRecoder", + "getencoder", "getdecoder", "getincrementalencoder", + "getincrementaldecoder", "getreader", "getwriter", + "encode", "decode", "iterencode", "iterdecode", + "strict_errors", "ignore_errors", "replace_errors", + "xmlcharrefreplace_errors", + "backslashreplace_errors", "namereplace_errors", + "register_error", "lookup_error"] diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/__init__.py b/crates/weavepy-vm/src/stdlib/python/encodings/__init__.py index 3ab7f42..6453d2c 100644 --- a/crates/weavepy-vm/src/stdlib/python/encodings/__init__.py +++ b/crates/weavepy-vm/src/stdlib/python/encodings/__init__.py @@ -10,6 +10,13 @@ from . import aliases +# CPython's search-function cache ({normalised name: CodecInfo}). WeavePy's +# real cache lives in the frozen `codecs` module, but tests (and refleak +# hygiene helpers) pop from `encodings._cache` directly. +_cache = {} +_unknown = '--unknown--' +_MAXCACHE = 500 + def normalize_encoding(encoding): """Normalize an encoding name (CPython semantics). diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/ascii.py b/crates/weavepy-vm/src/stdlib/python/encodings/ascii.py new file mode 100644 index 0000000..2033cde --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/ascii.py @@ -0,0 +1,50 @@ +""" Python 'ascii' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.ascii_encode + decode = codecs.ascii_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.ascii_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.ascii_decode(input, self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +class StreamConverter(StreamWriter,StreamReader): + + encode = codecs.ascii_decode + decode = codecs.ascii_encode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='ascii', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/base64_codec.py b/crates/weavepy-vm/src/stdlib/python/encodings/base64_codec.py new file mode 100644 index 0000000..8e7703b --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/base64_codec.py @@ -0,0 +1,55 @@ +"""Python 'base64_codec' Codec - base64 content transfer encoding. + +This codec de/encodes from bytes to bytes. + +Written by Marc-Andre Lemburg (mal@lemburg.com). +""" + +import codecs +import base64 + +### Codec APIs + +def base64_encode(input, errors='strict'): + assert errors == 'strict' + return (base64.encodebytes(input), len(input)) + +def base64_decode(input, errors='strict'): + assert errors == 'strict' + return (base64.decodebytes(input), len(input)) + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return base64_encode(input, errors) + def decode(self, input, errors='strict'): + return base64_decode(input, errors) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + assert self.errors == 'strict' + return base64.encodebytes(input) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + assert self.errors == 'strict' + return base64.decodebytes(input) + +class StreamWriter(Codec, codecs.StreamWriter): + charbuffertype = bytes + +class StreamReader(Codec, codecs.StreamReader): + charbuffertype = bytes + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='base64', + encode=base64_encode, + decode=base64_decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=False, + ) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/charmap.py b/crates/weavepy-vm/src/stdlib/python/encodings/charmap.py new file mode 100644 index 0000000..81189b1 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/charmap.py @@ -0,0 +1,69 @@ +""" Generic Python Character Mapping Codec. + + Use this codec directly rather than through the automatic + conversion mechanisms supplied by unicode() and .encode(). + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.charmap_encode + decode = codecs.charmap_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def __init__(self, errors='strict', mapping=None): + codecs.IncrementalEncoder.__init__(self, errors) + self.mapping = mapping + + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, self.mapping)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def __init__(self, errors='strict', mapping=None): + codecs.IncrementalDecoder.__init__(self, errors) + self.mapping = mapping + + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, self.mapping)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + + def __init__(self,stream,errors='strict',mapping=None): + codecs.StreamWriter.__init__(self,stream,errors) + self.mapping = mapping + + def encode(self,input,errors='strict'): + return Codec.encode(input,errors,self.mapping) + +class StreamReader(Codec,codecs.StreamReader): + + def __init__(self,stream,errors='strict',mapping=None): + codecs.StreamReader.__init__(self,stream,errors) + self.mapping = mapping + + def decode(self,input,errors='strict'): + return Codec.decode(input,errors,self.mapping) + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='charmap', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1006.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1006.py new file mode 100644 index 0000000..a1221c3 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1006.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1006 generated from 'MAPPINGS/VENDORS/MISC/CP1006.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1006', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u06f0' # 0xA1 -> EXTENDED ARABIC-INDIC DIGIT ZERO + '\u06f1' # 0xA2 -> EXTENDED ARABIC-INDIC DIGIT ONE + '\u06f2' # 0xA3 -> EXTENDED ARABIC-INDIC DIGIT TWO + '\u06f3' # 0xA4 -> EXTENDED ARABIC-INDIC DIGIT THREE + '\u06f4' # 0xA5 -> EXTENDED ARABIC-INDIC DIGIT FOUR + '\u06f5' # 0xA6 -> EXTENDED ARABIC-INDIC DIGIT FIVE + '\u06f6' # 0xA7 -> EXTENDED ARABIC-INDIC DIGIT SIX + '\u06f7' # 0xA8 -> EXTENDED ARABIC-INDIC DIGIT SEVEN + '\u06f8' # 0xA9 -> EXTENDED ARABIC-INDIC DIGIT EIGHT + '\u06f9' # 0xAA -> EXTENDED ARABIC-INDIC DIGIT NINE + '\u060c' # 0xAB -> ARABIC COMMA + '\u061b' # 0xAC -> ARABIC SEMICOLON + '\xad' # 0xAD -> SOFT HYPHEN + '\u061f' # 0xAE -> ARABIC QUESTION MARK + '\ufe81' # 0xAF -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + '\ufe8d' # 0xB0 -> ARABIC LETTER ALEF ISOLATED FORM + '\ufe8e' # 0xB1 -> ARABIC LETTER ALEF FINAL FORM + '\ufe8e' # 0xB2 -> ARABIC LETTER ALEF FINAL FORM + '\ufe8f' # 0xB3 -> ARABIC LETTER BEH ISOLATED FORM + '\ufe91' # 0xB4 -> ARABIC LETTER BEH INITIAL FORM + '\ufb56' # 0xB5 -> ARABIC LETTER PEH ISOLATED FORM + '\ufb58' # 0xB6 -> ARABIC LETTER PEH INITIAL FORM + '\ufe93' # 0xB7 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM + '\ufe95' # 0xB8 -> ARABIC LETTER TEH ISOLATED FORM + '\ufe97' # 0xB9 -> ARABIC LETTER TEH INITIAL FORM + '\ufb66' # 0xBA -> ARABIC LETTER TTEH ISOLATED FORM + '\ufb68' # 0xBB -> ARABIC LETTER TTEH INITIAL FORM + '\ufe99' # 0xBC -> ARABIC LETTER THEH ISOLATED FORM + '\ufe9b' # 0xBD -> ARABIC LETTER THEH INITIAL FORM + '\ufe9d' # 0xBE -> ARABIC LETTER JEEM ISOLATED FORM + '\ufe9f' # 0xBF -> ARABIC LETTER JEEM INITIAL FORM + '\ufb7a' # 0xC0 -> ARABIC LETTER TCHEH ISOLATED FORM + '\ufb7c' # 0xC1 -> ARABIC LETTER TCHEH INITIAL FORM + '\ufea1' # 0xC2 -> ARABIC LETTER HAH ISOLATED FORM + '\ufea3' # 0xC3 -> ARABIC LETTER HAH INITIAL FORM + '\ufea5' # 0xC4 -> ARABIC LETTER KHAH ISOLATED FORM + '\ufea7' # 0xC5 -> ARABIC LETTER KHAH INITIAL FORM + '\ufea9' # 0xC6 -> ARABIC LETTER DAL ISOLATED FORM + '\ufb84' # 0xC7 -> ARABIC LETTER DAHAL ISOLATED FORMN + '\ufeab' # 0xC8 -> ARABIC LETTER THAL ISOLATED FORM + '\ufead' # 0xC9 -> ARABIC LETTER REH ISOLATED FORM + '\ufb8c' # 0xCA -> ARABIC LETTER RREH ISOLATED FORM + '\ufeaf' # 0xCB -> ARABIC LETTER ZAIN ISOLATED FORM + '\ufb8a' # 0xCC -> ARABIC LETTER JEH ISOLATED FORM + '\ufeb1' # 0xCD -> ARABIC LETTER SEEN ISOLATED FORM + '\ufeb3' # 0xCE -> ARABIC LETTER SEEN INITIAL FORM + '\ufeb5' # 0xCF -> ARABIC LETTER SHEEN ISOLATED FORM + '\ufeb7' # 0xD0 -> ARABIC LETTER SHEEN INITIAL FORM + '\ufeb9' # 0xD1 -> ARABIC LETTER SAD ISOLATED FORM + '\ufebb' # 0xD2 -> ARABIC LETTER SAD INITIAL FORM + '\ufebd' # 0xD3 -> ARABIC LETTER DAD ISOLATED FORM + '\ufebf' # 0xD4 -> ARABIC LETTER DAD INITIAL FORM + '\ufec1' # 0xD5 -> ARABIC LETTER TAH ISOLATED FORM + '\ufec5' # 0xD6 -> ARABIC LETTER ZAH ISOLATED FORM + '\ufec9' # 0xD7 -> ARABIC LETTER AIN ISOLATED FORM + '\ufeca' # 0xD8 -> ARABIC LETTER AIN FINAL FORM + '\ufecb' # 0xD9 -> ARABIC LETTER AIN INITIAL FORM + '\ufecc' # 0xDA -> ARABIC LETTER AIN MEDIAL FORM + '\ufecd' # 0xDB -> ARABIC LETTER GHAIN ISOLATED FORM + '\ufece' # 0xDC -> ARABIC LETTER GHAIN FINAL FORM + '\ufecf' # 0xDD -> ARABIC LETTER GHAIN INITIAL FORM + '\ufed0' # 0xDE -> ARABIC LETTER GHAIN MEDIAL FORM + '\ufed1' # 0xDF -> ARABIC LETTER FEH ISOLATED FORM + '\ufed3' # 0xE0 -> ARABIC LETTER FEH INITIAL FORM + '\ufed5' # 0xE1 -> ARABIC LETTER QAF ISOLATED FORM + '\ufed7' # 0xE2 -> ARABIC LETTER QAF INITIAL FORM + '\ufed9' # 0xE3 -> ARABIC LETTER KAF ISOLATED FORM + '\ufedb' # 0xE4 -> ARABIC LETTER KAF INITIAL FORM + '\ufb92' # 0xE5 -> ARABIC LETTER GAF ISOLATED FORM + '\ufb94' # 0xE6 -> ARABIC LETTER GAF INITIAL FORM + '\ufedd' # 0xE7 -> ARABIC LETTER LAM ISOLATED FORM + '\ufedf' # 0xE8 -> ARABIC LETTER LAM INITIAL FORM + '\ufee0' # 0xE9 -> ARABIC LETTER LAM MEDIAL FORM + '\ufee1' # 0xEA -> ARABIC LETTER MEEM ISOLATED FORM + '\ufee3' # 0xEB -> ARABIC LETTER MEEM INITIAL FORM + '\ufb9e' # 0xEC -> ARABIC LETTER NOON GHUNNA ISOLATED FORM + '\ufee5' # 0xED -> ARABIC LETTER NOON ISOLATED FORM + '\ufee7' # 0xEE -> ARABIC LETTER NOON INITIAL FORM + '\ufe85' # 0xEF -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + '\ufeed' # 0xF0 -> ARABIC LETTER WAW ISOLATED FORM + '\ufba6' # 0xF1 -> ARABIC LETTER HEH GOAL ISOLATED FORM + '\ufba8' # 0xF2 -> ARABIC LETTER HEH GOAL INITIAL FORM + '\ufba9' # 0xF3 -> ARABIC LETTER HEH GOAL MEDIAL FORM + '\ufbaa' # 0xF4 -> ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM + '\ufe80' # 0xF5 -> ARABIC LETTER HAMZA ISOLATED FORM + '\ufe89' # 0xF6 -> ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM + '\ufe8a' # 0xF7 -> ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM + '\ufe8b' # 0xF8 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + '\ufef1' # 0xF9 -> ARABIC LETTER YEH ISOLATED FORM + '\ufef2' # 0xFA -> ARABIC LETTER YEH FINAL FORM + '\ufef3' # 0xFB -> ARABIC LETTER YEH INITIAL FORM + '\ufbb0' # 0xFC -> ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM + '\ufbae' # 0xFD -> ARABIC LETTER YEH BARREE ISOLATED FORM + '\ufe7c' # 0xFE -> ARABIC SHADDA ISOLATED FORM + '\ufe7d' # 0xFF -> ARABIC SHADDA MEDIAL FORM +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1026.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1026.py new file mode 100644 index 0000000..46f71f7 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1026.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1026 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP1026.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1026', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '{' # 0x48 -> LEFT CURLY BRACKET + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '\xc7' # 0x4A -> LATIN CAPITAL LETTER C WITH CEDILLA + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + '\u011e' # 0x5A -> LATIN CAPITAL LETTER G WITH BREVE + '\u0130' # 0x5B -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '[' # 0x68 -> LEFT SQUARE BRACKET + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\u015f' # 0x6A -> LATIN SMALL LETTER S WITH CEDILLA + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '\u0131' # 0x79 -> LATIN SMALL LETTER DOTLESS I + ':' # 0x7A -> COLON + '\xd6' # 0x7B -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u015e' # 0x7C -> LATIN CAPITAL LETTER S WITH CEDILLA + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '\xdc' # 0x7F -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '}' # 0x8C -> RIGHT CURLY BRACKET + '`' # 0x8D -> GRAVE ACCENT + '\xa6' # 0x8E -> BROKEN BAR + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '\xf6' # 0xA1 -> LATIN SMALL LETTER O WITH DIAERESIS + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + ']' # 0xAC -> RIGHT SQUARE BRACKET + '$' # 0xAD -> DOLLAR SIGN + '@' # 0xAE -> COMMERCIAL AT + '\xae' # 0xAF -> REGISTERED SIGN + '\xa2' # 0xB0 -> CENT SIGN + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '\xac' # 0xBA -> NOT SIGN + '|' # 0xBB -> VERTICAL LINE + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '\xe7' # 0xC0 -> LATIN SMALL LETTER C WITH CEDILLA + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '~' # 0xCC -> TILDE + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '\u011f' # 0xD0 -> LATIN SMALL LETTER G WITH BREVE + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\\' # 0xDC -> REVERSE SOLIDUS + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xfc' # 0xE0 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '#' # 0xEC -> NUMBER SIGN + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '"' # 0xFC -> QUOTATION MARK + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1125.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1125.py new file mode 100644 index 0000000..b1fd69d --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1125.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec for CP1125 + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1125', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x0082: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x0083: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x0084: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x0085: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x0086: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x0087: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x0088: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x0089: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x008a: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x008b: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x008c: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x008d: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x008e: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x008f: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x0090: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x0091: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x0092: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x0093: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x0094: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x0095: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x0096: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x0097: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x0098: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x0099: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x009a: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x009b: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x009c: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x009d: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x009e: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009f: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a2: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00a3: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00a4: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a5: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a6: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00a7: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00a8: 0x0438, # CYRILLIC SMALL LETTER I + 0x00a9: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00aa: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00ab: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00ac: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00ad: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00ae: 0x043e, # CYRILLIC SMALL LETTER O + 0x00af: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e1: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e2: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e3: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e4: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00e5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00e6: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00e7: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00e8: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00e9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00ea: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x00eb: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00ec: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ed: 0x044d, # CYRILLIC SMALL LETTER E + 0x00ee: 0x044e, # CYRILLIC SMALL LETTER YU + 0x00ef: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00f0: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x00f1: 0x0451, # CYRILLIC SMALL LETTER IO + 0x00f2: 0x0490, # CYRILLIC CAPITAL LETTER GHE WITH UPTURN + 0x00f3: 0x0491, # CYRILLIC SMALL LETTER GHE WITH UPTURN + 0x00f4: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x00f5: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x00f6: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x00f7: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x00f8: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x00f9: 0x0457, # CYRILLIC SMALL LETTER YI + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x2116, # NUMERO SIGN + 0x00fd: 0x00a4, # CURRENCY SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0410' # 0x0080 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0x0081 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0x0082 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0x0083 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0x0084 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0x0085 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0x0086 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0x0087 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0x0088 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0x0089 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0x008a -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0x008b -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0x008c -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0x008d -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0x008e -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0x008f -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0x0090 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0x0091 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0x0092 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0x0093 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0x0094 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0x0095 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0x0096 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0x0097 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0x0098 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0x0099 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0x009b -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0x009d -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0x009e -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0x009f -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0x00a1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0x00a2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0x00a3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0x00a4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0x00a5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0x00a6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0x00a7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0x00a8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0x00a9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0x00aa -> CYRILLIC SMALL LETTER KA + '\u043b' # 0x00ab -> CYRILLIC SMALL LETTER EL + '\u043c' # 0x00ac -> CYRILLIC SMALL LETTER EM + '\u043d' # 0x00ad -> CYRILLIC SMALL LETTER EN + '\u043e' # 0x00ae -> CYRILLIC SMALL LETTER O + '\u043f' # 0x00af -> CYRILLIC SMALL LETTER PE + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u0440' # 0x00e0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0x00e1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0x00e2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0x00e3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0x00e4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0x00e5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0x00e6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0x00e7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0x00e8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0x00e9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0x00ea -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0x00eb -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0x00ed -> CYRILLIC SMALL LETTER E + '\u044e' # 0x00ee -> CYRILLIC SMALL LETTER YU + '\u044f' # 0x00ef -> CYRILLIC SMALL LETTER YA + '\u0401' # 0x00f0 -> CYRILLIC CAPITAL LETTER IO + '\u0451' # 0x00f1 -> CYRILLIC SMALL LETTER IO + '\u0490' # 0x00f2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + '\u0491' # 0x00f3 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + '\u0404' # 0x00f4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0454' # 0x00f5 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0406' # 0x00f6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0x00f7 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0407' # 0x00f8 -> CYRILLIC CAPITAL LETTER YI + '\u0457' # 0x00f9 -> CYRILLIC SMALL LETTER YI + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u2116' # 0x00fc -> NUMERO SIGN + '\xa4' # 0x00fd -> CURRENCY SIGN + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00fd, # CURRENCY SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x0401: 0x00f0, # CYRILLIC CAPITAL LETTER IO + 0x0404: 0x00f4, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0406: 0x00f6, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0407: 0x00f8, # CYRILLIC CAPITAL LETTER YI + 0x0410: 0x0080, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x0081, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x0082, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x0083, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x0084, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x0085, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x0086, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x0087, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x0088, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x0089, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x008a, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x008b, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x008c, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x008d, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x008e, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x008f, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x0090, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x0091, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x0092, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x0093, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x0094, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x0095, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x0096, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x0097, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x0098, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x0099, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x009b, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x009c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x009d, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009e, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x009f, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a1, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00a2, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00a3, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a4, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a5, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00a6, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00a7, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00a8, # CYRILLIC SMALL LETTER I + 0x0439: 0x00a9, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00aa, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00ab, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00ac, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00ad, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00ae, # CYRILLIC SMALL LETTER O + 0x043f: 0x00af, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e0, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e1, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e2, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e3, # CYRILLIC SMALL LETTER U + 0x0444: 0x00e4, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00e5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00e6, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00e7, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00e8, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00e9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x00ea, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00eb, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ec, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00ed, # CYRILLIC SMALL LETTER E + 0x044e: 0x00ee, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00ef, # CYRILLIC SMALL LETTER YA + 0x0451: 0x00f1, # CYRILLIC SMALL LETTER IO + 0x0454: 0x00f5, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0456: 0x00f7, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0457: 0x00f9, # CYRILLIC SMALL LETTER YI + 0x0490: 0x00f2, # CYRILLIC CAPITAL LETTER GHE WITH UPTURN + 0x0491: 0x00f3, # CYRILLIC SMALL LETTER GHE WITH UPTURN + 0x2116: 0x00fc, # NUMERO SIGN + 0x221a: 0x00fb, # SQUARE ROOT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1140.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1140.py new file mode 100644 index 0000000..0a919d8 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1140.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1140 generated from 'python-mappings/CP1140.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1140', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '\xa2' # 0x4A -> CENT SIGN + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '|' # 0x4F -> VERTICAL LINE + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + '!' # 0x5A -> EXCLAMATION MARK + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '\xac' # 0x5F -> NOT SIGN + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\xa6' # 0x6A -> BROKEN BAR + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + '\u20ac' # 0x9F -> EURO SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + '\xae' # 0xAF -> REGISTERED SIGN + '^' # 0xB0 -> CIRCUMFLEX ACCENT + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '[' # 0xBA -> LEFT SQUARE BRACKET + ']' # 0xBB -> RIGHT SQUARE BRACKET + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\\' # 0xE0 -> REVERSE SOLIDUS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1250.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1250.py new file mode 100644 index 0000000..c2c83aa --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1250.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1250 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1250', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\ufffe' # 0x83 -> UNDEFINED + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u015a' # 0x8C -> LATIN CAPITAL LETTER S WITH ACUTE + '\u0164' # 0x8D -> LATIN CAPITAL LETTER T WITH CARON + '\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON + '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u015b' # 0x9C -> LATIN SMALL LETTER S WITH ACUTE + '\u0165' # 0x9D -> LATIN SMALL LETTER T WITH CARON + '\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON + '\u017a' # 0x9F -> LATIN SMALL LETTER Z WITH ACUTE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u02c7' # 0xA1 -> CARON + '\u02d8' # 0xA2 -> BREVE + '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u0104' # 0xA5 -> LATIN CAPITAL LETTER A WITH OGONEK + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u02db' # 0xB2 -> OGONEK + '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\u0105' # 0xB9 -> LATIN SMALL LETTER A WITH OGONEK + '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u013d' # 0xBC -> LATIN CAPITAL LETTER L WITH CARON + '\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT + '\u013e' # 0xBE -> LATIN SMALL LETTER L WITH CARON + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE + '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON + '\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE + '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON + '\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1251.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1251.py new file mode 100644 index 0000000..22bc660 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1251.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1251 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1251', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE + '\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u20ac' # 0x88 -> EURO SIGN + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE + '\u040c' # 0x8D -> CYRILLIC CAPITAL LETTER KJE + '\u040b' # 0x8E -> CYRILLIC CAPITAL LETTER TSHE + '\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE + '\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE + '\u045c' # 0x9D -> CYRILLIC SMALL LETTER KJE + '\u045b' # 0x9E -> CYRILLIC SMALL LETTER TSHE + '\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u040e' # 0xA1 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045e' # 0xA2 -> CYRILLIC SMALL LETTER SHORT U + '\u0408' # 0xA3 -> CYRILLIC CAPITAL LETTER JE + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u0490' # 0xA5 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0404' # 0xAA -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u0407' # 0xAF -> CYRILLIC CAPITAL LETTER YI + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0491' # 0xB4 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + '\u2116' # 0xB9 -> NUMERO SIGN + '\u0454' # 0xBA -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0458' # 0xBC -> CYRILLIC SMALL LETTER JE + '\u0405' # 0xBD -> CYRILLIC CAPITAL LETTER DZE + '\u0455' # 0xBE -> CYRILLIC SMALL LETTER DZE + '\u0457' # 0xBF -> CYRILLIC SMALL LETTER YI + '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1252.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1252.py new file mode 100644 index 0000000..c0e8088 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1252.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1252 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1252', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\ufffe' # 0x8D -> UNDEFINED + '\u017d' # 0x8E -> LATIN CAPITAL LETTER Z WITH CARON + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\ufffe' # 0x9D -> UNDEFINED + '\u017e' # 0x9E -> LATIN SMALL LETTER Z WITH CARON + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1253.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1253.py new file mode 100644 index 0000000..ec9c097 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1253.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1253 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1253.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1253', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0385' # 0xA1 -> GREEK DIALYTIKA TONOS + '\u0386' # 0xA2 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\ufffe' # 0xAA -> UNDEFINED + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u2015' # 0xAF -> HORIZONTAL BAR + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u0384' # 0xB4 -> GREEK TONOS + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA + '\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA + '\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA + '\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0xCC -> GREEK CAPITAL LETTER MU + '\u039d' # 0xCD -> GREEK CAPITAL LETTER NU + '\u039e' # 0xCE -> GREEK CAPITAL LETTER XI + '\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON + '\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO + '\ufffe' # 0xD2 -> UNDEFINED + '\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA + '\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA + '\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + '\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA + '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + '\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA + '\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA + '\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA + '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + '\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0xEC -> GREEK SMALL LETTER MU + '\u03bd' # 0xED -> GREEK SMALL LETTER NU + '\u03be' # 0xEE -> GREEK SMALL LETTER XI + '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + '\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO + '\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA + '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + '\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI + '\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI + '\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI + '\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA + '\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS + '\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1254.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1254.py new file mode 100644 index 0000000..4912327 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1254.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1254 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1254.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1254', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I + '\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1255.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1255.py new file mode 100644 index 0000000..91ce26b --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1255.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1255 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1255.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1255', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\u20aa' # 0xA4 -> NEW SHEQEL SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xd7' # 0xAA -> MULTIPLICATION SIGN + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xf7' # 0xBA -> DIVISION SIGN + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\u05b0' # 0xC0 -> HEBREW POINT SHEVA + '\u05b1' # 0xC1 -> HEBREW POINT HATAF SEGOL + '\u05b2' # 0xC2 -> HEBREW POINT HATAF PATAH + '\u05b3' # 0xC3 -> HEBREW POINT HATAF QAMATS + '\u05b4' # 0xC4 -> HEBREW POINT HIRIQ + '\u05b5' # 0xC5 -> HEBREW POINT TSERE + '\u05b6' # 0xC6 -> HEBREW POINT SEGOL + '\u05b7' # 0xC7 -> HEBREW POINT PATAH + '\u05b8' # 0xC8 -> HEBREW POINT QAMATS + '\u05b9' # 0xC9 -> HEBREW POINT HOLAM + '\ufffe' # 0xCA -> UNDEFINED + '\u05bb' # 0xCB -> HEBREW POINT QUBUTS + '\u05bc' # 0xCC -> HEBREW POINT DAGESH OR MAPIQ + '\u05bd' # 0xCD -> HEBREW POINT METEG + '\u05be' # 0xCE -> HEBREW PUNCTUATION MAQAF + '\u05bf' # 0xCF -> HEBREW POINT RAFE + '\u05c0' # 0xD0 -> HEBREW PUNCTUATION PASEQ + '\u05c1' # 0xD1 -> HEBREW POINT SHIN DOT + '\u05c2' # 0xD2 -> HEBREW POINT SIN DOT + '\u05c3' # 0xD3 -> HEBREW PUNCTUATION SOF PASUQ + '\u05f0' # 0xD4 -> HEBREW LIGATURE YIDDISH DOUBLE VAV + '\u05f1' # 0xD5 -> HEBREW LIGATURE YIDDISH VAV YOD + '\u05f2' # 0xD6 -> HEBREW LIGATURE YIDDISH DOUBLE YOD + '\u05f3' # 0xD7 -> HEBREW PUNCTUATION GERESH + '\u05f4' # 0xD8 -> HEBREW PUNCTUATION GERSHAYIM + '\ufffe' # 0xD9 -> UNDEFINED + '\ufffe' # 0xDA -> UNDEFINED + '\ufffe' # 0xDB -> UNDEFINED + '\ufffe' # 0xDC -> UNDEFINED + '\ufffe' # 0xDD -> UNDEFINED + '\ufffe' # 0xDE -> UNDEFINED + '\ufffe' # 0xDF -> UNDEFINED + '\u05d0' # 0xE0 -> HEBREW LETTER ALEF + '\u05d1' # 0xE1 -> HEBREW LETTER BET + '\u05d2' # 0xE2 -> HEBREW LETTER GIMEL + '\u05d3' # 0xE3 -> HEBREW LETTER DALET + '\u05d4' # 0xE4 -> HEBREW LETTER HE + '\u05d5' # 0xE5 -> HEBREW LETTER VAV + '\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN + '\u05d7' # 0xE7 -> HEBREW LETTER HET + '\u05d8' # 0xE8 -> HEBREW LETTER TET + '\u05d9' # 0xE9 -> HEBREW LETTER YOD + '\u05da' # 0xEA -> HEBREW LETTER FINAL KAF + '\u05db' # 0xEB -> HEBREW LETTER KAF + '\u05dc' # 0xEC -> HEBREW LETTER LAMED + '\u05dd' # 0xED -> HEBREW LETTER FINAL MEM + '\u05de' # 0xEE -> HEBREW LETTER MEM + '\u05df' # 0xEF -> HEBREW LETTER FINAL NUN + '\u05e0' # 0xF0 -> HEBREW LETTER NUN + '\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH + '\u05e2' # 0xF2 -> HEBREW LETTER AYIN + '\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE + '\u05e4' # 0xF4 -> HEBREW LETTER PE + '\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0xF6 -> HEBREW LETTER TSADI + '\u05e7' # 0xF7 -> HEBREW LETTER QOF + '\u05e8' # 0xF8 -> HEBREW LETTER RESH + '\u05e9' # 0xF9 -> HEBREW LETTER SHIN + '\u05ea' # 0xFA -> HEBREW LETTER TAV + '\ufffe' # 0xFB -> UNDEFINED + '\ufffe' # 0xFC -> UNDEFINED + '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + '\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1256.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1256.py new file mode 100644 index 0000000..fd6afab --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1256.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1256 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1256.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1256', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\u067e' # 0x81 -> ARABIC LETTER PEH + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0679' # 0x8A -> ARABIC LETTER TTEH + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\u0686' # 0x8D -> ARABIC LETTER TCHEH + '\u0698' # 0x8E -> ARABIC LETTER JEH + '\u0688' # 0x8F -> ARABIC LETTER DDAL + '\u06af' # 0x90 -> ARABIC LETTER GAF + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u06a9' # 0x98 -> ARABIC LETTER KEHEH + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0691' # 0x9A -> ARABIC LETTER RREH + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\u200c' # 0x9D -> ZERO WIDTH NON-JOINER + '\u200d' # 0x9E -> ZERO WIDTH JOINER + '\u06ba' # 0x9F -> ARABIC LETTER NOON GHUNNA + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u060c' # 0xA1 -> ARABIC COMMA + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u06be' # 0xAA -> ARABIC LETTER HEH DOACHASHMEE + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\u061b' # 0xBA -> ARABIC SEMICOLON + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\u061f' # 0xBF -> ARABIC QUESTION MARK + '\u06c1' # 0xC0 -> ARABIC LETTER HEH GOAL + '\u0621' # 0xC1 -> ARABIC LETTER HAMZA + '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0xC7 -> ARABIC LETTER ALEF + '\u0628' # 0xC8 -> ARABIC LETTER BEH + '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xCA -> ARABIC LETTER TEH + '\u062b' # 0xCB -> ARABIC LETTER THEH + '\u062c' # 0xCC -> ARABIC LETTER JEEM + '\u062d' # 0xCD -> ARABIC LETTER HAH + '\u062e' # 0xCE -> ARABIC LETTER KHAH + '\u062f' # 0xCF -> ARABIC LETTER DAL + '\u0630' # 0xD0 -> ARABIC LETTER THAL + '\u0631' # 0xD1 -> ARABIC LETTER REH + '\u0632' # 0xD2 -> ARABIC LETTER ZAIN + '\u0633' # 0xD3 -> ARABIC LETTER SEEN + '\u0634' # 0xD4 -> ARABIC LETTER SHEEN + '\u0635' # 0xD5 -> ARABIC LETTER SAD + '\u0636' # 0xD6 -> ARABIC LETTER DAD + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0637' # 0xD8 -> ARABIC LETTER TAH + '\u0638' # 0xD9 -> ARABIC LETTER ZAH + '\u0639' # 0xDA -> ARABIC LETTER AIN + '\u063a' # 0xDB -> ARABIC LETTER GHAIN + '\u0640' # 0xDC -> ARABIC TATWEEL + '\u0641' # 0xDD -> ARABIC LETTER FEH + '\u0642' # 0xDE -> ARABIC LETTER QAF + '\u0643' # 0xDF -> ARABIC LETTER KAF + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\u0644' # 0xE1 -> ARABIC LETTER LAM + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0645' # 0xE3 -> ARABIC LETTER MEEM + '\u0646' # 0xE4 -> ARABIC LETTER NOON + '\u0647' # 0xE5 -> ARABIC LETTER HEH + '\u0648' # 0xE6 -> ARABIC LETTER WAW + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0649' # 0xEC -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xED -> ARABIC LETTER YEH + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u064b' # 0xF0 -> ARABIC FATHATAN + '\u064c' # 0xF1 -> ARABIC DAMMATAN + '\u064d' # 0xF2 -> ARABIC KASRATAN + '\u064e' # 0xF3 -> ARABIC FATHA + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u064f' # 0xF5 -> ARABIC DAMMA + '\u0650' # 0xF6 -> ARABIC KASRA + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0651' # 0xF8 -> ARABIC SHADDA + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\u0652' # 0xFA -> ARABIC SUKUN + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + '\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1257.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1257.py new file mode 100644 index 0000000..9ebc90d --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1257.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1257 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1257.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1257', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\ufffe' # 0x83 -> UNDEFINED + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\xa8' # 0x8D -> DIAERESIS + '\u02c7' # 0x8E -> CARON + '\xb8' # 0x8F -> CEDILLA + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\xaf' # 0x9D -> MACRON + '\u02db' # 0x9E -> OGONEK + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\ufffe' # 0xA1 -> UNDEFINED + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\ufffe' # 0xA5 -> UNDEFINED + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xc6' # 0xAF -> LATIN CAPITAL LETTER AE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xe6' # 0xBF -> LATIN SMALL LETTER AE + '\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON + '\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE + '\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON + '\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE + '\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE + '\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK + '\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK + '\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON + '\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK + '\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE + '\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE + '\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA + '\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA + '\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON + '\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA + '\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK + '\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE + '\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE + '\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp1258.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp1258.py new file mode 100644 index 0000000..784378a --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp1258.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp1258 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1258.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp1258', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\ufffe' # 0x8A -> UNDEFINED + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u0300' # 0xCC -> COMBINING GRAVE ACCENT + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\u0309' # 0xD2 -> COMBINING HOOK ABOVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u01a0' # 0xD5 -> LATIN CAPITAL LETTER O WITH HORN + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u01af' # 0xDD -> LATIN CAPITAL LETTER U WITH HORN + '\u0303' # 0xDE -> COMBINING TILDE + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0301' # 0xEC -> COMBINING ACUTE ACCENT + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\u0323' # 0xF2 -> COMBINING DOT BELOW + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u01a1' # 0xF5 -> LATIN SMALL LETTER O WITH HORN + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u01b0' # 0xFD -> LATIN SMALL LETTER U WITH HORN + '\u20ab' # 0xFE -> DONG SIGN + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp273.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp273.py new file mode 100644 index 0000000..69c6d77 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp273.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp273 generated from 'python-mappings/CP273.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp273', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL (NUL) + '\x01' # 0x01 -> START OF HEADING (SOH) + '\x02' # 0x02 -> START OF TEXT (STX) + '\x03' # 0x03 -> END OF TEXT (ETX) + '\x9c' # 0x04 -> STRING TERMINATOR (ST) + '\t' # 0x05 -> CHARACTER TABULATION (HT) + '\x86' # 0x06 -> START OF SELECTED AREA (SSA) + '\x7f' # 0x07 -> DELETE (DEL) + '\x97' # 0x08 -> END OF GUARDED AREA (EPA) + '\x8d' # 0x09 -> REVERSE LINE FEED (RI) + '\x8e' # 0x0A -> SINGLE-SHIFT TWO (SS2) + '\x0b' # 0x0B -> LINE TABULATION (VT) + '\x0c' # 0x0C -> FORM FEED (FF) + '\r' # 0x0D -> CARRIAGE RETURN (CR) + '\x0e' # 0x0E -> SHIFT OUT (SO) + '\x0f' # 0x0F -> SHIFT IN (SI) + '\x10' # 0x10 -> DATALINK ESCAPE (DLE) + '\x11' # 0x11 -> DEVICE CONTROL ONE (DC1) + '\x12' # 0x12 -> DEVICE CONTROL TWO (DC2) + '\x13' # 0x13 -> DEVICE CONTROL THREE (DC3) + '\x9d' # 0x14 -> OPERATING SYSTEM COMMAND (OSC) + '\x85' # 0x15 -> NEXT LINE (NEL) + '\x08' # 0x16 -> BACKSPACE (BS) + '\x87' # 0x17 -> END OF SELECTED AREA (ESA) + '\x18' # 0x18 -> CANCEL (CAN) + '\x19' # 0x19 -> END OF MEDIUM (EM) + '\x92' # 0x1A -> PRIVATE USE TWO (PU2) + '\x8f' # 0x1B -> SINGLE-SHIFT THREE (SS3) + '\x1c' # 0x1C -> FILE SEPARATOR (IS4) + '\x1d' # 0x1D -> GROUP SEPARATOR (IS3) + '\x1e' # 0x1E -> RECORD SEPARATOR (IS2) + '\x1f' # 0x1F -> UNIT SEPARATOR (IS1) + '\x80' # 0x20 -> PADDING CHARACTER (PAD) + '\x81' # 0x21 -> HIGH OCTET PRESET (HOP) + '\x82' # 0x22 -> BREAK PERMITTED HERE (BPH) + '\x83' # 0x23 -> NO BREAK HERE (NBH) + '\x84' # 0x24 -> INDEX (IND) + '\n' # 0x25 -> LINE FEED (LF) + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK (ETB) + '\x1b' # 0x27 -> ESCAPE (ESC) + '\x88' # 0x28 -> CHARACTER TABULATION SET (HTS) + '\x89' # 0x29 -> CHARACTER TABULATION WITH JUSTIFICATION (HTJ) + '\x8a' # 0x2A -> LINE TABULATION SET (VTS) + '\x8b' # 0x2B -> PARTIAL LINE FORWARD (PLD) + '\x8c' # 0x2C -> PARTIAL LINE BACKWARD (PLU) + '\x05' # 0x2D -> ENQUIRY (ENQ) + '\x06' # 0x2E -> ACKNOWLEDGE (ACK) + '\x07' # 0x2F -> BELL (BEL) + '\x90' # 0x30 -> DEVICE CONTROL STRING (DCS) + '\x91' # 0x31 -> PRIVATE USE ONE (PU1) + '\x16' # 0x32 -> SYNCHRONOUS IDLE (SYN) + '\x93' # 0x33 -> SET TRANSMIT STATE (STS) + '\x94' # 0x34 -> CANCEL CHARACTER (CCH) + '\x95' # 0x35 -> MESSAGE WAITING (MW) + '\x96' # 0x36 -> START OF GUARDED AREA (SPA) + '\x04' # 0x37 -> END OF TRANSMISSION (EOT) + '\x98' # 0x38 -> START OF STRING (SOS) + '\x99' # 0x39 -> SINGLE GRAPHIC CHARACTER INTRODUCER (SGCI) + '\x9a' # 0x3A -> SINGLE CHARACTER INTRODUCER (SCI) + '\x9b' # 0x3B -> CONTROL SEQUENCE INTRODUCER (CSI) + '\x14' # 0x3C -> DEVICE CONTROL FOUR (DC4) + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE (NAK) + '\x9e' # 0x3E -> PRIVACY MESSAGE (PM) + '\x1a' # 0x3F -> SUBSTITUTE (SUB) + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '{' # 0x43 -> LEFT CURLY BRACKET + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '\xc4' # 0x4A -> LATIN CAPITAL LETTER A WITH DIAERESIS + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '~' # 0x59 -> TILDE + '\xdc' # 0x5A -> LATIN CAPITAL LETTER U WITH DIAERESIS + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '[' # 0x63 -> LEFT SQUARE BRACKET + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\xf6' # 0x6A -> LATIN SMALL LETTER O WITH DIAERESIS + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '\xa7' # 0x7C -> SECTION SIGN + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (Icelandic) + '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (Icelandic) + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LETTER AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LETTER AE + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '\xdf' # 0xA1 -> LATIN SMALL LETTER SHARP S (German) + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (Icelandic) + '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xae' # 0xAF -> REGISTERED SIGN + '\xa2' # 0xB0 -> CENT SIGN + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '@' # 0xB5 -> COMMERCIAL AT + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '\xac' # 0xBA -> NOT SIGN + '|' # 0xBB -> VERTICAL LINE + '\u203e' # 0xBC -> OVERLINE + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '\xe4' # 0xC0 -> LATIN SMALL LETTER A WITH DIAERESIS + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xa6' # 0xCC -> BROKEN BAR + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '\xfc' # 0xD0 -> LATIN SMALL LETTER U WITH DIAERESIS + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '}' # 0xDC -> RIGHT CURLY BRACKET + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0xE0 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\\' # 0xEC -> REVERSE SOLIDUS + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + ']' # 0xFC -> RIGHT SQUARE BRACKET + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> APPLICATION PROGRAM COMMAND (APC) +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp424.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp424.py new file mode 100644 index 0000000..6753daf --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp424.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp424 generated from 'MAPPINGS/VENDORS/MISC/CP424.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp424', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> SELECT + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> REQUIRED NEW LINE + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> GRAPHIC ESCAPE + '\x8d' # 0x09 -> SUPERSCRIPT + '\x8e' # 0x0A -> REPEAT + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> RESTORE/ENABLE PRESENTATION + '\x85' # 0x15 -> NEW LINE + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> PROGRAM OPERATOR COMMUNICATION + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> UNIT BACK SPACE + '\x8f' # 0x1B -> CUSTOMER USE ONE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> DIGIT SELECT + '\x81' # 0x21 -> START OF SIGNIFICANCE + '\x82' # 0x22 -> FIELD SEPARATOR + '\x83' # 0x23 -> WORD UNDERSCORE + '\x84' # 0x24 -> BYPASS OR INHIBIT PRESENTATION + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> SET ATTRIBUTE + '\x89' # 0x29 -> START FIELD EXTENDED + '\x8a' # 0x2A -> SET MODE OR SWITCH + '\x8b' # 0x2B -> CONTROL SEQUENCE PREFIX + '\x8c' # 0x2C -> MODIFY FIELD ATTRIBUTE + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> + '\x91' # 0x31 -> + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> INDEX RETURN + '\x94' # 0x34 -> PRESENTATION POSITION + '\x95' # 0x35 -> TRANSPARENT + '\x96' # 0x36 -> NUMERIC BACKSPACE + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> SUBSCRIPT + '\x99' # 0x39 -> INDENT TABULATION + '\x9a' # 0x3A -> REVERSE FORM FEED + '\x9b' # 0x3B -> CUSTOMER USE THREE + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\u05d0' # 0x41 -> HEBREW LETTER ALEF + '\u05d1' # 0x42 -> HEBREW LETTER BET + '\u05d2' # 0x43 -> HEBREW LETTER GIMEL + '\u05d3' # 0x44 -> HEBREW LETTER DALET + '\u05d4' # 0x45 -> HEBREW LETTER HE + '\u05d5' # 0x46 -> HEBREW LETTER VAV + '\u05d6' # 0x47 -> HEBREW LETTER ZAYIN + '\u05d7' # 0x48 -> HEBREW LETTER HET + '\u05d8' # 0x49 -> HEBREW LETTER TET + '\xa2' # 0x4A -> CENT SIGN + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '|' # 0x4F -> VERTICAL LINE + '&' # 0x50 -> AMPERSAND + '\u05d9' # 0x51 -> HEBREW LETTER YOD + '\u05da' # 0x52 -> HEBREW LETTER FINAL KAF + '\u05db' # 0x53 -> HEBREW LETTER KAF + '\u05dc' # 0x54 -> HEBREW LETTER LAMED + '\u05dd' # 0x55 -> HEBREW LETTER FINAL MEM + '\u05de' # 0x56 -> HEBREW LETTER MEM + '\u05df' # 0x57 -> HEBREW LETTER FINAL NUN + '\u05e0' # 0x58 -> HEBREW LETTER NUN + '\u05e1' # 0x59 -> HEBREW LETTER SAMEKH + '!' # 0x5A -> EXCLAMATION MARK + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '\xac' # 0x5F -> NOT SIGN + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\u05e2' # 0x62 -> HEBREW LETTER AYIN + '\u05e3' # 0x63 -> HEBREW LETTER FINAL PE + '\u05e4' # 0x64 -> HEBREW LETTER PE + '\u05e5' # 0x65 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0x66 -> HEBREW LETTER TSADI + '\u05e7' # 0x67 -> HEBREW LETTER QOF + '\u05e8' # 0x68 -> HEBREW LETTER RESH + '\u05e9' # 0x69 -> HEBREW LETTER SHIN + '\xa6' # 0x6A -> BROKEN BAR + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\ufffe' # 0x70 -> UNDEFINED + '\u05ea' # 0x71 -> HEBREW LETTER TAV + '\ufffe' # 0x72 -> UNDEFINED + '\ufffe' # 0x73 -> UNDEFINED + '\xa0' # 0x74 -> NO-BREAK SPACE + '\ufffe' # 0x75 -> UNDEFINED + '\ufffe' # 0x76 -> UNDEFINED + '\ufffe' # 0x77 -> UNDEFINED + '\u2017' # 0x78 -> DOUBLE LOW LINE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\ufffe' # 0x80 -> UNDEFINED + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\ufffe' # 0x9A -> UNDEFINED + '\ufffe' # 0x9B -> UNDEFINED + '\ufffe' # 0x9C -> UNDEFINED + '\xb8' # 0x9D -> CEDILLA + '\ufffe' # 0x9E -> UNDEFINED + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\ufffe' # 0xAA -> UNDEFINED + '\ufffe' # 0xAB -> UNDEFINED + '\ufffe' # 0xAC -> UNDEFINED + '\ufffe' # 0xAD -> UNDEFINED + '\ufffe' # 0xAE -> UNDEFINED + '\xae' # 0xAF -> REGISTERED SIGN + '^' # 0xB0 -> CIRCUMFLEX ACCENT + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '[' # 0xBA -> LEFT SQUARE BRACKET + ']' # 0xBB -> RIGHT SQUARE BRACKET + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\ufffe' # 0xCB -> UNDEFINED + '\ufffe' # 0xCC -> UNDEFINED + '\ufffe' # 0xCD -> UNDEFINED + '\ufffe' # 0xCE -> UNDEFINED + '\ufffe' # 0xCF -> UNDEFINED + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\ufffe' # 0xDB -> UNDEFINED + '\ufffe' # 0xDC -> UNDEFINED + '\ufffe' # 0xDD -> UNDEFINED + '\ufffe' # 0xDE -> UNDEFINED + '\ufffe' # 0xDF -> UNDEFINED + '\\' # 0xE0 -> REVERSE SOLIDUS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\ufffe' # 0xEB -> UNDEFINED + '\ufffe' # 0xEC -> UNDEFINED + '\ufffe' # 0xED -> UNDEFINED + '\ufffe' # 0xEE -> UNDEFINED + '\ufffe' # 0xEF -> UNDEFINED + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\ufffe' # 0xFB -> UNDEFINED + '\ufffe' # 0xFC -> UNDEFINED + '\ufffe' # 0xFD -> UNDEFINED + '\ufffe' # 0xFE -> UNDEFINED + '\x9f' # 0xFF -> EIGHT ONES +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp437.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp437.py new file mode 100644 index 0000000..b6c75e2 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp437.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec cp437 generated from 'VENDORS/MICSFT/PC/CP437.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp437', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00a5, # YEN SIGN + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xa5' # 0x009d -> YEN SIGN + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a5: 0x009d, # YEN SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp500.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp500.py new file mode 100644 index 0000000..5f61535 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp500.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp500 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP500.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp500', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\xa0' # 0x41 -> NO-BREAK SPACE + '\xe2' # 0x42 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x43 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x44 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0x45 -> LATIN SMALL LETTER A WITH ACUTE + '\xe3' # 0x46 -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x47 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x48 -> LATIN SMALL LETTER C WITH CEDILLA + '\xf1' # 0x49 -> LATIN SMALL LETTER N WITH TILDE + '[' # 0x4A -> LEFT SQUARE BRACKET + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\xe9' # 0x51 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0x52 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x53 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x54 -> LATIN SMALL LETTER E WITH GRAVE + '\xed' # 0x55 -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0x56 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x57 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xec' # 0x58 -> LATIN SMALL LETTER I WITH GRAVE + '\xdf' # 0x59 -> LATIN SMALL LETTER SHARP S (GERMAN) + ']' # 0x5A -> RIGHT SQUARE BRACKET + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\xc2' # 0x62 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc4' # 0x63 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc0' # 0x64 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0x65 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0x66 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc5' # 0x67 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x68 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xd1' # 0x69 -> LATIN CAPITAL LETTER N WITH TILDE + '\xa6' # 0x6A -> BROKEN BAR + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xf8' # 0x70 -> LATIN SMALL LETTER O WITH STROKE + '\xc9' # 0x71 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0x72 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x73 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x74 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0x75 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x76 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x77 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0x78 -> LATIN CAPITAL LETTER I WITH GRAVE + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\xd8' # 0x80 -> LATIN CAPITAL LETTER O WITH STROKE + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\xab' # 0x8A -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x8B -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xf0' # 0x8C -> LATIN SMALL LETTER ETH (ICELANDIC) + '\xfd' # 0x8D -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0x8E -> LATIN SMALL LETTER THORN (ICELANDIC) + '\xb1' # 0x8F -> PLUS-MINUS SIGN + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\xaa' # 0x9A -> FEMININE ORDINAL INDICATOR + '\xba' # 0x9B -> MASCULINE ORDINAL INDICATOR + '\xe6' # 0x9C -> LATIN SMALL LIGATURE AE + '\xb8' # 0x9D -> CEDILLA + '\xc6' # 0x9E -> LATIN CAPITAL LIGATURE AE + '\xa4' # 0x9F -> CURRENCY SIGN + '\xb5' # 0xA0 -> MICRO SIGN + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\xa1' # 0xAA -> INVERTED EXCLAMATION MARK + '\xbf' # 0xAB -> INVERTED QUESTION MARK + '\xd0' # 0xAC -> LATIN CAPITAL LETTER ETH (ICELANDIC) + '\xdd' # 0xAD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xAE -> LATIN CAPITAL LETTER THORN (ICELANDIC) + '\xae' # 0xAF -> REGISTERED SIGN + '\xa2' # 0xB0 -> CENT SIGN + '\xa3' # 0xB1 -> POUND SIGN + '\xa5' # 0xB2 -> YEN SIGN + '\xb7' # 0xB3 -> MIDDLE DOT + '\xa9' # 0xB4 -> COPYRIGHT SIGN + '\xa7' # 0xB5 -> SECTION SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xbc' # 0xB7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xB8 -> VULGAR FRACTION ONE HALF + '\xbe' # 0xB9 -> VULGAR FRACTION THREE QUARTERS + '\xac' # 0xBA -> NOT SIGN + '|' # 0xBB -> VERTICAL LINE + '\xaf' # 0xBC -> MACRON + '\xa8' # 0xBD -> DIAERESIS + '\xb4' # 0xBE -> ACUTE ACCENT + '\xd7' # 0xBF -> MULTIPLICATION SIGN + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\xf4' # 0xCB -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0xCC -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0xCD -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xCE -> LATIN SMALL LETTER O WITH ACUTE + '\xf5' # 0xCF -> LATIN SMALL LETTER O WITH TILDE + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb9' # 0xDA -> SUPERSCRIPT ONE + '\xfb' # 0xDB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xDC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xf9' # 0xDD -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xDE -> LATIN SMALL LETTER U WITH ACUTE + '\xff' # 0xDF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\\' # 0xE0 -> REVERSE SOLIDUS + '\xf7' # 0xE1 -> DIVISION SIGN + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xd4' # 0xEB -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd6' # 0xEC -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd2' # 0xED -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd5' # 0xEF -> LATIN CAPITAL LETTER O WITH TILDE + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xdb' # 0xFB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xFC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xd9' # 0xFD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xFE -> LATIN CAPITAL LETTER U WITH ACUTE + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp720.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp720.py new file mode 100644 index 0000000..96d6096 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp720.py @@ -0,0 +1,309 @@ +"""Python Character Mapping Codec cp720 generated on Windows: +Vista 6.0.6002 SP2 Multiprocessor Free with the command: + python Tools/unicode/genwincodec.py 720 +"""#" + + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp720', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\x80' + '\x81' + '\xe9' # 0x82 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x83 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\x84' + '\xe0' # 0x85 -> LATIN SMALL LETTER A WITH GRAVE + '\x86' + '\xe7' # 0x87 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x88 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x89 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x8A -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x8B -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x8C -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\x8d' + '\x8e' + '\x8f' + '\x90' + '\u0651' # 0x91 -> ARABIC SHADDA + '\u0652' # 0x92 -> ARABIC SUKUN + '\xf4' # 0x93 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xa4' # 0x94 -> CURRENCY SIGN + '\u0640' # 0x95 -> ARABIC TATWEEL + '\xfb' # 0x96 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x97 -> LATIN SMALL LETTER U WITH GRAVE + '\u0621' # 0x98 -> ARABIC LETTER HAMZA + '\u0622' # 0x99 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0x9A -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0x9B -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\xa3' # 0x9C -> POUND SIGN + '\u0625' # 0x9D -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0x9E -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0x9F -> ARABIC LETTER ALEF + '\u0628' # 0xA0 -> ARABIC LETTER BEH + '\u0629' # 0xA1 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xA2 -> ARABIC LETTER TEH + '\u062b' # 0xA3 -> ARABIC LETTER THEH + '\u062c' # 0xA4 -> ARABIC LETTER JEEM + '\u062d' # 0xA5 -> ARABIC LETTER HAH + '\u062e' # 0xA6 -> ARABIC LETTER KHAH + '\u062f' # 0xA7 -> ARABIC LETTER DAL + '\u0630' # 0xA8 -> ARABIC LETTER THAL + '\u0631' # 0xA9 -> ARABIC LETTER REH + '\u0632' # 0xAA -> ARABIC LETTER ZAIN + '\u0633' # 0xAB -> ARABIC LETTER SEEN + '\u0634' # 0xAC -> ARABIC LETTER SHEEN + '\u0635' # 0xAD -> ARABIC LETTER SAD + '\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0xB0 -> LIGHT SHADE + '\u2592' # 0xB1 -> MEDIUM SHADE + '\u2593' # 0xB2 -> DARK SHADE + '\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0xB5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0xB6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0xB8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0xBD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0xBE -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0xC6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0xC7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0xCF -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0xD0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0xD1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0xD2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0xD3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0xD4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0xD5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0xD6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0xD7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0xD8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0xDB -> FULL BLOCK + '\u2584' # 0xDC -> LOWER HALF BLOCK + '\u258c' # 0xDD -> LEFT HALF BLOCK + '\u2590' # 0xDE -> RIGHT HALF BLOCK + '\u2580' # 0xDF -> UPPER HALF BLOCK + '\u0636' # 0xE0 -> ARABIC LETTER DAD + '\u0637' # 0xE1 -> ARABIC LETTER TAH + '\u0638' # 0xE2 -> ARABIC LETTER ZAH + '\u0639' # 0xE3 -> ARABIC LETTER AIN + '\u063a' # 0xE4 -> ARABIC LETTER GHAIN + '\u0641' # 0xE5 -> ARABIC LETTER FEH + '\xb5' # 0xE6 -> MICRO SIGN + '\u0642' # 0xE7 -> ARABIC LETTER QAF + '\u0643' # 0xE8 -> ARABIC LETTER KAF + '\u0644' # 0xE9 -> ARABIC LETTER LAM + '\u0645' # 0xEA -> ARABIC LETTER MEEM + '\u0646' # 0xEB -> ARABIC LETTER NOON + '\u0647' # 0xEC -> ARABIC LETTER HEH + '\u0648' # 0xED -> ARABIC LETTER WAW + '\u0649' # 0xEE -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xEF -> ARABIC LETTER YEH + '\u2261' # 0xF0 -> IDENTICAL TO + '\u064b' # 0xF1 -> ARABIC FATHATAN + '\u064c' # 0xF2 -> ARABIC DAMMATAN + '\u064d' # 0xF3 -> ARABIC KASRATAN + '\u064e' # 0xF4 -> ARABIC FATHA + '\u064f' # 0xF5 -> ARABIC DAMMA + '\u0650' # 0xF6 -> ARABIC KASRA + '\u2248' # 0xF7 -> ALMOST EQUAL TO + '\xb0' # 0xF8 -> DEGREE SIGN + '\u2219' # 0xF9 -> BULLET OPERATOR + '\xb7' # 0xFA -> MIDDLE DOT + '\u221a' # 0xFB -> SQUARE ROOT + '\u207f' # 0xFC -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0xFD -> SUPERSCRIPT TWO + '\u25a0' # 0xFE -> BLACK SQUARE + '\xa0' # 0xFF -> NO-BREAK SPACE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp775.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp775.py new file mode 100644 index 0000000..fe06e7b --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp775.py @@ -0,0 +1,697 @@ +""" Python Character Mapping Codec cp775 generated from 'VENDORS/MICSFT/PC/CP775.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp775', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x0101, # LATIN SMALL LETTER A WITH MACRON + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x0123, # LATIN SMALL LETTER G WITH CEDILLA + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x0107, # LATIN SMALL LETTER C WITH ACUTE + 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE + 0x0089: 0x0113, # LATIN SMALL LETTER E WITH MACRON + 0x008a: 0x0156, # LATIN CAPITAL LETTER R WITH CEDILLA + 0x008b: 0x0157, # LATIN SMALL LETTER R WITH CEDILLA + 0x008c: 0x012b, # LATIN SMALL LETTER I WITH MACRON + 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x014d, # LATIN SMALL LETTER O WITH MACRON + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA + 0x0096: 0x00a2, # CENT SIGN + 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE + 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x00a4, # CURRENCY SIGN + 0x00a0: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON + 0x00a1: 0x012a, # LATIN CAPITAL LETTER I WITH MACRON + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x00a4: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00a5: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE + 0x00a6: 0x201d, # RIGHT DOUBLE QUOTATION MARK + 0x00a7: 0x00a6, # BROKEN BAR + 0x00a8: 0x00a9, # COPYRIGHT SIGN + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK + 0x00b6: 0x010c, # LATIN CAPITAL LETTER C WITH CARON + 0x00b7: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK + 0x00b8: 0x0116, # LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x012e, # LATIN CAPITAL LETTER I WITH OGONEK + 0x00be: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x0172, # LATIN CAPITAL LETTER U WITH OGONEK + 0x00c7: 0x016a, # LATIN CAPITAL LETTER U WITH MACRON + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON + 0x00d0: 0x0105, # LATIN SMALL LETTER A WITH OGONEK + 0x00d1: 0x010d, # LATIN SMALL LETTER C WITH CARON + 0x00d2: 0x0119, # LATIN SMALL LETTER E WITH OGONEK + 0x00d3: 0x0117, # LATIN SMALL LETTER E WITH DOT ABOVE + 0x00d4: 0x012f, # LATIN SMALL LETTER I WITH OGONEK + 0x00d5: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00d6: 0x0173, # LATIN SMALL LETTER U WITH OGONEK + 0x00d7: 0x016b, # LATIN SMALL LETTER U WITH MACRON + 0x00d8: 0x017e, # LATIN SMALL LETTER Z WITH CARON + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e2: 0x014c, # LATIN CAPITAL LETTER O WITH MACRON + 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x0144, # LATIN SMALL LETTER N WITH ACUTE + 0x00e8: 0x0136, # LATIN CAPITAL LETTER K WITH CEDILLA + 0x00e9: 0x0137, # LATIN SMALL LETTER K WITH CEDILLA + 0x00ea: 0x013b, # LATIN CAPITAL LETTER L WITH CEDILLA + 0x00eb: 0x013c, # LATIN SMALL LETTER L WITH CEDILLA + 0x00ec: 0x0146, # LATIN SMALL LETTER N WITH CEDILLA + 0x00ed: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON + 0x00ee: 0x0145, # LATIN CAPITAL LETTER N WITH CEDILLA + 0x00ef: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x201c, # LEFT DOUBLE QUOTATION MARK + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x201e, # DOUBLE LOW-9 QUOTATION MARK + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0106' # 0x0080 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\u0101' # 0x0083 -> LATIN SMALL LETTER A WITH MACRON + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u0123' # 0x0085 -> LATIN SMALL LETTER G WITH CEDILLA + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\u0107' # 0x0087 -> LATIN SMALL LETTER C WITH ACUTE + '\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE + '\u0113' # 0x0089 -> LATIN SMALL LETTER E WITH MACRON + '\u0156' # 0x008a -> LATIN CAPITAL LETTER R WITH CEDILLA + '\u0157' # 0x008b -> LATIN SMALL LETTER R WITH CEDILLA + '\u012b' # 0x008c -> LATIN SMALL LETTER I WITH MACRON + '\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\u014d' # 0x0093 -> LATIN SMALL LETTER O WITH MACRON + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u0122' # 0x0095 -> LATIN CAPITAL LETTER G WITH CEDILLA + '\xa2' # 0x0096 -> CENT SIGN + '\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\xa4' # 0x009f -> CURRENCY SIGN + '\u0100' # 0x00a0 -> LATIN CAPITAL LETTER A WITH MACRON + '\u012a' # 0x00a1 -> LATIN CAPITAL LETTER I WITH MACRON + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\u017b' # 0x00a3 -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017c' # 0x00a4 -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u017a' # 0x00a5 -> LATIN SMALL LETTER Z WITH ACUTE + '\u201d' # 0x00a6 -> RIGHT DOUBLE QUOTATION MARK + '\xa6' # 0x00a7 -> BROKEN BAR + '\xa9' # 0x00a8 -> COPYRIGHT SIGN + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\u0141' # 0x00ad -> LATIN CAPITAL LETTER L WITH STROKE + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u0104' # 0x00b5 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u010c' # 0x00b6 -> LATIN CAPITAL LETTER C WITH CARON + '\u0118' # 0x00b7 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0116' # 0x00b8 -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u012e' # 0x00bd -> LATIN CAPITAL LETTER I WITH OGONEK + '\u0160' # 0x00be -> LATIN CAPITAL LETTER S WITH CARON + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u0172' # 0x00c6 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u016a' # 0x00c7 -> LATIN CAPITAL LETTER U WITH MACRON + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u017d' # 0x00cf -> LATIN CAPITAL LETTER Z WITH CARON + '\u0105' # 0x00d0 -> LATIN SMALL LETTER A WITH OGONEK + '\u010d' # 0x00d1 -> LATIN SMALL LETTER C WITH CARON + '\u0119' # 0x00d2 -> LATIN SMALL LETTER E WITH OGONEK + '\u0117' # 0x00d3 -> LATIN SMALL LETTER E WITH DOT ABOVE + '\u012f' # 0x00d4 -> LATIN SMALL LETTER I WITH OGONEK + '\u0161' # 0x00d5 -> LATIN SMALL LETTER S WITH CARON + '\u0173' # 0x00d6 -> LATIN SMALL LETTER U WITH OGONEK + '\u016b' # 0x00d7 -> LATIN SMALL LETTER U WITH MACRON + '\u017e' # 0x00d8 -> LATIN SMALL LETTER Z WITH CARON + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) + '\u014c' # 0x00e2 -> LATIN CAPITAL LETTER O WITH MACRON + '\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\u0144' # 0x00e7 -> LATIN SMALL LETTER N WITH ACUTE + '\u0136' # 0x00e8 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u0137' # 0x00e9 -> LATIN SMALL LETTER K WITH CEDILLA + '\u013b' # 0x00ea -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u013c' # 0x00eb -> LATIN SMALL LETTER L WITH CEDILLA + '\u0146' # 0x00ec -> LATIN SMALL LETTER N WITH CEDILLA + '\u0112' # 0x00ed -> LATIN CAPITAL LETTER E WITH MACRON + '\u0145' # 0x00ee -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u2019' # 0x00ef -> RIGHT SINGLE QUOTATION MARK + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u201c' # 0x00f2 -> LEFT DOUBLE QUOTATION MARK + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u201e' # 0x00f7 -> DOUBLE LOW-9 QUOTATION MARK + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a2: 0x0096, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x009f, # CURRENCY SIGN + 0x00a6: 0x00a7, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a9: 0x00a8, # COPYRIGHT SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0100: 0x00a0, # LATIN CAPITAL LETTER A WITH MACRON + 0x0101: 0x0083, # LATIN SMALL LETTER A WITH MACRON + 0x0104: 0x00b5, # LATIN CAPITAL LETTER A WITH OGONEK + 0x0105: 0x00d0, # LATIN SMALL LETTER A WITH OGONEK + 0x0106: 0x0080, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0107: 0x0087, # LATIN SMALL LETTER C WITH ACUTE + 0x010c: 0x00b6, # LATIN CAPITAL LETTER C WITH CARON + 0x010d: 0x00d1, # LATIN SMALL LETTER C WITH CARON + 0x0112: 0x00ed, # LATIN CAPITAL LETTER E WITH MACRON + 0x0113: 0x0089, # LATIN SMALL LETTER E WITH MACRON + 0x0116: 0x00b8, # LATIN CAPITAL LETTER E WITH DOT ABOVE + 0x0117: 0x00d3, # LATIN SMALL LETTER E WITH DOT ABOVE + 0x0118: 0x00b7, # LATIN CAPITAL LETTER E WITH OGONEK + 0x0119: 0x00d2, # LATIN SMALL LETTER E WITH OGONEK + 0x0122: 0x0095, # LATIN CAPITAL LETTER G WITH CEDILLA + 0x0123: 0x0085, # LATIN SMALL LETTER G WITH CEDILLA + 0x012a: 0x00a1, # LATIN CAPITAL LETTER I WITH MACRON + 0x012b: 0x008c, # LATIN SMALL LETTER I WITH MACRON + 0x012e: 0x00bd, # LATIN CAPITAL LETTER I WITH OGONEK + 0x012f: 0x00d4, # LATIN SMALL LETTER I WITH OGONEK + 0x0136: 0x00e8, # LATIN CAPITAL LETTER K WITH CEDILLA + 0x0137: 0x00e9, # LATIN SMALL LETTER K WITH CEDILLA + 0x013b: 0x00ea, # LATIN CAPITAL LETTER L WITH CEDILLA + 0x013c: 0x00eb, # LATIN SMALL LETTER L WITH CEDILLA + 0x0141: 0x00ad, # LATIN CAPITAL LETTER L WITH STROKE + 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE + 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE + 0x0144: 0x00e7, # LATIN SMALL LETTER N WITH ACUTE + 0x0145: 0x00ee, # LATIN CAPITAL LETTER N WITH CEDILLA + 0x0146: 0x00ec, # LATIN SMALL LETTER N WITH CEDILLA + 0x014c: 0x00e2, # LATIN CAPITAL LETTER O WITH MACRON + 0x014d: 0x0093, # LATIN SMALL LETTER O WITH MACRON + 0x0156: 0x008a, # LATIN CAPITAL LETTER R WITH CEDILLA + 0x0157: 0x008b, # LATIN SMALL LETTER R WITH CEDILLA + 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE + 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE + 0x0160: 0x00be, # LATIN CAPITAL LETTER S WITH CARON + 0x0161: 0x00d5, # LATIN SMALL LETTER S WITH CARON + 0x016a: 0x00c7, # LATIN CAPITAL LETTER U WITH MACRON + 0x016b: 0x00d7, # LATIN SMALL LETTER U WITH MACRON + 0x0172: 0x00c6, # LATIN CAPITAL LETTER U WITH OGONEK + 0x0173: 0x00d6, # LATIN SMALL LETTER U WITH OGONEK + 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x017a: 0x00a5, # LATIN SMALL LETTER Z WITH ACUTE + 0x017b: 0x00a3, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x017c: 0x00a4, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x017d: 0x00cf, # LATIN CAPITAL LETTER Z WITH CARON + 0x017e: 0x00d8, # LATIN SMALL LETTER Z WITH CARON + 0x2019: 0x00ef, # RIGHT SINGLE QUOTATION MARK + 0x201c: 0x00f2, # LEFT DOUBLE QUOTATION MARK + 0x201d: 0x00a6, # RIGHT DOUBLE QUOTATION MARK + 0x201e: 0x00f7, # DOUBLE LOW-9 QUOTATION MARK + 0x2219: 0x00f9, # BULLET OPERATOR + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp850.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp850.py new file mode 100644 index 0000000..f98aef9 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp850.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP850.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp850', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH + 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: 0x0131, # LATIN SMALL LETTER DOTLESS I + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN + 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2017, # DOUBLE LOW LINE + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa9' # 0x00b8 -> COPYRIGHT SIGN + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0x00bd -> CENT SIGN + '\xa5' # 0x00be -> YEN SIGN + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH + '\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH + '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + '\u0131' # 0x00d5 -> LATIN SMALL LETTER DOTLESS I + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\xa6' # 0x00dd -> BROKEN BAR + '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN + '\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xaf' # 0x00ee -> MACRON + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2017' # 0x00f2 -> DOUBLE LOW LINE + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0131: 0x00d5, # LATIN SMALL LETTER DOTLESS I + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x2017: 0x00f2, # DOUBLE LOW LINE + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp852.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp852.py new file mode 100644 index 0000000..34d8a0e --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp852.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP852.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp852', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x016f, # LATIN SMALL LETTER U WITH RING ABOVE + 0x0086: 0x0107, # LATIN SMALL LETTER C WITH ACUTE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x0142, # LATIN SMALL LETTER L WITH STROKE + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x0150, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + 0x008b: 0x0151, # LATIN SMALL LETTER O WITH DOUBLE ACUTE + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x0179, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x0139, # LATIN CAPITAL LETTER L WITH ACUTE + 0x0092: 0x013a, # LATIN SMALL LETTER L WITH ACUTE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x013d, # LATIN CAPITAL LETTER L WITH CARON + 0x0096: 0x013e, # LATIN SMALL LETTER L WITH CARON + 0x0097: 0x015a, # LATIN CAPITAL LETTER S WITH ACUTE + 0x0098: 0x015b, # LATIN SMALL LETTER S WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x0164, # LATIN CAPITAL LETTER T WITH CARON + 0x009c: 0x0165, # LATIN SMALL LETTER T WITH CARON + 0x009d: 0x0141, # LATIN CAPITAL LETTER L WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x010d, # LATIN SMALL LETTER C WITH CARON + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK + 0x00a5: 0x0105, # LATIN SMALL LETTER A WITH OGONEK + 0x00a6: 0x017d, # LATIN CAPITAL LETTER Z WITH CARON + 0x00a7: 0x017e, # LATIN SMALL LETTER Z WITH CARON + 0x00a8: 0x0118, # LATIN CAPITAL LETTER E WITH OGONEK + 0x00a9: 0x0119, # LATIN SMALL LETTER E WITH OGONEK + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x017a, # LATIN SMALL LETTER Z WITH ACUTE + 0x00ac: 0x010c, # LATIN CAPITAL LETTER C WITH CARON + 0x00ad: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x011a, # LATIN CAPITAL LETTER E WITH CARON + 0x00b8: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x00be: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x0102, # LATIN CAPITAL LETTER A WITH BREVE + 0x00c7: 0x0103, # LATIN SMALL LETTER A WITH BREVE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x0111, # LATIN SMALL LETTER D WITH STROKE + 0x00d1: 0x0110, # LATIN CAPITAL LETTER D WITH STROKE + 0x00d2: 0x010e, # LATIN CAPITAL LETTER D WITH CARON + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x010f, # LATIN SMALL LETTER D WITH CARON + 0x00d5: 0x0147, # LATIN CAPITAL LETTER N WITH CARON + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x011b, # LATIN SMALL LETTER E WITH CARON + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x0162, # LATIN CAPITAL LETTER T WITH CEDILLA + 0x00de: 0x016e, # LATIN CAPITAL LETTER U WITH RING ABOVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x0143, # LATIN CAPITAL LETTER N WITH ACUTE + 0x00e4: 0x0144, # LATIN SMALL LETTER N WITH ACUTE + 0x00e5: 0x0148, # LATIN SMALL LETTER N WITH CARON + 0x00e6: 0x0160, # LATIN CAPITAL LETTER S WITH CARON + 0x00e7: 0x0161, # LATIN SMALL LETTER S WITH CARON + 0x00e8: 0x0154, # LATIN CAPITAL LETTER R WITH ACUTE + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x0155, # LATIN SMALL LETTER R WITH ACUTE + 0x00eb: 0x0170, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x02dd, # DOUBLE ACUTE ACCENT + 0x00f2: 0x02db, # OGONEK + 0x00f3: 0x02c7, # CARON + 0x00f4: 0x02d8, # BREVE + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x02d9, # DOT ABOVE + 0x00fb: 0x0171, # LATIN SMALL LETTER U WITH DOUBLE ACUTE + 0x00fc: 0x0158, # LATIN CAPITAL LETTER R WITH CARON + 0x00fd: 0x0159, # LATIN SMALL LETTER R WITH CARON + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u016f' # 0x0085 -> LATIN SMALL LETTER U WITH RING ABOVE + '\u0107' # 0x0086 -> LATIN SMALL LETTER C WITH ACUTE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\u0142' # 0x0088 -> LATIN SMALL LETTER L WITH STROKE + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0150' # 0x008a -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\u0151' # 0x008b -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u0179' # 0x008d -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0106' # 0x008f -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0139' # 0x0091 -> LATIN CAPITAL LETTER L WITH ACUTE + '\u013a' # 0x0092 -> LATIN SMALL LETTER L WITH ACUTE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u013d' # 0x0095 -> LATIN CAPITAL LETTER L WITH CARON + '\u013e' # 0x0096 -> LATIN SMALL LETTER L WITH CARON + '\u015a' # 0x0097 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u015b' # 0x0098 -> LATIN SMALL LETTER S WITH ACUTE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0164' # 0x009b -> LATIN CAPITAL LETTER T WITH CARON + '\u0165' # 0x009c -> LATIN SMALL LETTER T WITH CARON + '\u0141' # 0x009d -> LATIN CAPITAL LETTER L WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\u010d' # 0x009f -> LATIN SMALL LETTER C WITH CARON + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\u0104' # 0x00a4 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0105' # 0x00a5 -> LATIN SMALL LETTER A WITH OGONEK + '\u017d' # 0x00a6 -> LATIN CAPITAL LETTER Z WITH CARON + '\u017e' # 0x00a7 -> LATIN SMALL LETTER Z WITH CARON + '\u0118' # 0x00a8 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0119' # 0x00a9 -> LATIN SMALL LETTER E WITH OGONEK + '\xac' # 0x00aa -> NOT SIGN + '\u017a' # 0x00ab -> LATIN SMALL LETTER Z WITH ACUTE + '\u010c' # 0x00ac -> LATIN CAPITAL LETTER C WITH CARON + '\u015f' # 0x00ad -> LATIN SMALL LETTER S WITH CEDILLA + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u011a' # 0x00b7 -> LATIN CAPITAL LETTER E WITH CARON + '\u015e' # 0x00b8 -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u017b' # 0x00bd -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017c' # 0x00be -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u0102' # 0x00c6 -> LATIN CAPITAL LETTER A WITH BREVE + '\u0103' # 0x00c7 -> LATIN SMALL LETTER A WITH BREVE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\u0111' # 0x00d0 -> LATIN SMALL LETTER D WITH STROKE + '\u0110' # 0x00d1 -> LATIN CAPITAL LETTER D WITH STROKE + '\u010e' # 0x00d2 -> LATIN CAPITAL LETTER D WITH CARON + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u010f' # 0x00d4 -> LATIN SMALL LETTER D WITH CARON + '\u0147' # 0x00d5 -> LATIN CAPITAL LETTER N WITH CARON + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u011b' # 0x00d8 -> LATIN SMALL LETTER E WITH CARON + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u0162' # 0x00dd -> LATIN CAPITAL LETTER T WITH CEDILLA + '\u016e' # 0x00de -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0143' # 0x00e3 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0144' # 0x00e4 -> LATIN SMALL LETTER N WITH ACUTE + '\u0148' # 0x00e5 -> LATIN SMALL LETTER N WITH CARON + '\u0160' # 0x00e6 -> LATIN CAPITAL LETTER S WITH CARON + '\u0161' # 0x00e7 -> LATIN SMALL LETTER S WITH CARON + '\u0154' # 0x00e8 -> LATIN CAPITAL LETTER R WITH ACUTE + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0155' # 0x00ea -> LATIN SMALL LETTER R WITH ACUTE + '\u0170' # 0x00eb -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0163' # 0x00ee -> LATIN SMALL LETTER T WITH CEDILLA + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\u02dd' # 0x00f1 -> DOUBLE ACUTE ACCENT + '\u02db' # 0x00f2 -> OGONEK + '\u02c7' # 0x00f3 -> CARON + '\u02d8' # 0x00f4 -> BREVE + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\u02d9' # 0x00fa -> DOT ABOVE + '\u0171' # 0x00fb -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\u0158' # 0x00fc -> LATIN CAPITAL LETTER R WITH CARON + '\u0159' # 0x00fd -> LATIN SMALL LETTER R WITH CARON + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b8: 0x00f7, # CEDILLA + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x0102: 0x00c6, # LATIN CAPITAL LETTER A WITH BREVE + 0x0103: 0x00c7, # LATIN SMALL LETTER A WITH BREVE + 0x0104: 0x00a4, # LATIN CAPITAL LETTER A WITH OGONEK + 0x0105: 0x00a5, # LATIN SMALL LETTER A WITH OGONEK + 0x0106: 0x008f, # LATIN CAPITAL LETTER C WITH ACUTE + 0x0107: 0x0086, # LATIN SMALL LETTER C WITH ACUTE + 0x010c: 0x00ac, # LATIN CAPITAL LETTER C WITH CARON + 0x010d: 0x009f, # LATIN SMALL LETTER C WITH CARON + 0x010e: 0x00d2, # LATIN CAPITAL LETTER D WITH CARON + 0x010f: 0x00d4, # LATIN SMALL LETTER D WITH CARON + 0x0110: 0x00d1, # LATIN CAPITAL LETTER D WITH STROKE + 0x0111: 0x00d0, # LATIN SMALL LETTER D WITH STROKE + 0x0118: 0x00a8, # LATIN CAPITAL LETTER E WITH OGONEK + 0x0119: 0x00a9, # LATIN SMALL LETTER E WITH OGONEK + 0x011a: 0x00b7, # LATIN CAPITAL LETTER E WITH CARON + 0x011b: 0x00d8, # LATIN SMALL LETTER E WITH CARON + 0x0139: 0x0091, # LATIN CAPITAL LETTER L WITH ACUTE + 0x013a: 0x0092, # LATIN SMALL LETTER L WITH ACUTE + 0x013d: 0x0095, # LATIN CAPITAL LETTER L WITH CARON + 0x013e: 0x0096, # LATIN SMALL LETTER L WITH CARON + 0x0141: 0x009d, # LATIN CAPITAL LETTER L WITH STROKE + 0x0142: 0x0088, # LATIN SMALL LETTER L WITH STROKE + 0x0143: 0x00e3, # LATIN CAPITAL LETTER N WITH ACUTE + 0x0144: 0x00e4, # LATIN SMALL LETTER N WITH ACUTE + 0x0147: 0x00d5, # LATIN CAPITAL LETTER N WITH CARON + 0x0148: 0x00e5, # LATIN SMALL LETTER N WITH CARON + 0x0150: 0x008a, # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + 0x0151: 0x008b, # LATIN SMALL LETTER O WITH DOUBLE ACUTE + 0x0154: 0x00e8, # LATIN CAPITAL LETTER R WITH ACUTE + 0x0155: 0x00ea, # LATIN SMALL LETTER R WITH ACUTE + 0x0158: 0x00fc, # LATIN CAPITAL LETTER R WITH CARON + 0x0159: 0x00fd, # LATIN SMALL LETTER R WITH CARON + 0x015a: 0x0097, # LATIN CAPITAL LETTER S WITH ACUTE + 0x015b: 0x0098, # LATIN SMALL LETTER S WITH ACUTE + 0x015e: 0x00b8, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x015f: 0x00ad, # LATIN SMALL LETTER S WITH CEDILLA + 0x0160: 0x00e6, # LATIN CAPITAL LETTER S WITH CARON + 0x0161: 0x00e7, # LATIN SMALL LETTER S WITH CARON + 0x0162: 0x00dd, # LATIN CAPITAL LETTER T WITH CEDILLA + 0x0163: 0x00ee, # LATIN SMALL LETTER T WITH CEDILLA + 0x0164: 0x009b, # LATIN CAPITAL LETTER T WITH CARON + 0x0165: 0x009c, # LATIN SMALL LETTER T WITH CARON + 0x016e: 0x00de, # LATIN CAPITAL LETTER U WITH RING ABOVE + 0x016f: 0x0085, # LATIN SMALL LETTER U WITH RING ABOVE + 0x0170: 0x00eb, # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + 0x0171: 0x00fb, # LATIN SMALL LETTER U WITH DOUBLE ACUTE + 0x0179: 0x008d, # LATIN CAPITAL LETTER Z WITH ACUTE + 0x017a: 0x00ab, # LATIN SMALL LETTER Z WITH ACUTE + 0x017b: 0x00bd, # LATIN CAPITAL LETTER Z WITH DOT ABOVE + 0x017c: 0x00be, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x017d: 0x00a6, # LATIN CAPITAL LETTER Z WITH CARON + 0x017e: 0x00a7, # LATIN SMALL LETTER Z WITH CARON + 0x02c7: 0x00f3, # CARON + 0x02d8: 0x00f4, # BREVE + 0x02d9: 0x00fa, # DOT ABOVE + 0x02db: 0x00f2, # OGONEK + 0x02dd: 0x00f1, # DOUBLE ACUTE ACCENT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp855.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp855.py new file mode 100644 index 0000000..4fe9210 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp855.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP855.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp855', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0452, # CYRILLIC SMALL LETTER DJE + 0x0081: 0x0402, # CYRILLIC CAPITAL LETTER DJE + 0x0082: 0x0453, # CYRILLIC SMALL LETTER GJE + 0x0083: 0x0403, # CYRILLIC CAPITAL LETTER GJE + 0x0084: 0x0451, # CYRILLIC SMALL LETTER IO + 0x0085: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x0086: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0087: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0088: 0x0455, # CYRILLIC SMALL LETTER DZE + 0x0089: 0x0405, # CYRILLIC CAPITAL LETTER DZE + 0x008a: 0x0456, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x008b: 0x0406, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x008c: 0x0457, # CYRILLIC SMALL LETTER YI + 0x008d: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x008e: 0x0458, # CYRILLIC SMALL LETTER JE + 0x008f: 0x0408, # CYRILLIC CAPITAL LETTER JE + 0x0090: 0x0459, # CYRILLIC SMALL LETTER LJE + 0x0091: 0x0409, # CYRILLIC CAPITAL LETTER LJE + 0x0092: 0x045a, # CYRILLIC SMALL LETTER NJE + 0x0093: 0x040a, # CYRILLIC CAPITAL LETTER NJE + 0x0094: 0x045b, # CYRILLIC SMALL LETTER TSHE + 0x0095: 0x040b, # CYRILLIC CAPITAL LETTER TSHE + 0x0096: 0x045c, # CYRILLIC SMALL LETTER KJE + 0x0097: 0x040c, # CYRILLIC CAPITAL LETTER KJE + 0x0098: 0x045e, # CYRILLIC SMALL LETTER SHORT U + 0x0099: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U + 0x009a: 0x045f, # CYRILLIC SMALL LETTER DZHE + 0x009b: 0x040f, # CYRILLIC CAPITAL LETTER DZHE + 0x009c: 0x044e, # CYRILLIC SMALL LETTER YU + 0x009d: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009e: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x009f: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x00a2: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a3: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x00a4: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00a5: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x00a6: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a7: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x00a8: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a9: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x00aa: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00ab: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x00ac: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00ad: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00b6: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x00b7: 0x0438, # CYRILLIC SMALL LETTER I + 0x00b8: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00be: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00c7: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00d1: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x00d2: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00d3: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x00d4: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00d5: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x00d6: 0x043e, # CYRILLIC SMALL LETTER O + 0x00d7: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x00d8: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x00de: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00e1: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e2: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x00e3: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e4: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x00e5: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e6: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x00e7: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e8: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x00e9: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00ea: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x00eb: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00ec: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x00ed: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ee: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x00ef: 0x2116, # NUMERO SIGN + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00f2: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x00f3: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00f4: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x00f5: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00f6: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x00f7: 0x044d, # CYRILLIC SMALL LETTER E + 0x00f8: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x00f9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00fa: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x00fb: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00fc: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x00fd: 0x00a7, # SECTION SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0452' # 0x0080 -> CYRILLIC SMALL LETTER DJE + '\u0402' # 0x0081 -> CYRILLIC CAPITAL LETTER DJE + '\u0453' # 0x0082 -> CYRILLIC SMALL LETTER GJE + '\u0403' # 0x0083 -> CYRILLIC CAPITAL LETTER GJE + '\u0451' # 0x0084 -> CYRILLIC SMALL LETTER IO + '\u0401' # 0x0085 -> CYRILLIC CAPITAL LETTER IO + '\u0454' # 0x0086 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0404' # 0x0087 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0455' # 0x0088 -> CYRILLIC SMALL LETTER DZE + '\u0405' # 0x0089 -> CYRILLIC CAPITAL LETTER DZE + '\u0456' # 0x008a -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0406' # 0x008b -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0457' # 0x008c -> CYRILLIC SMALL LETTER YI + '\u0407' # 0x008d -> CYRILLIC CAPITAL LETTER YI + '\u0458' # 0x008e -> CYRILLIC SMALL LETTER JE + '\u0408' # 0x008f -> CYRILLIC CAPITAL LETTER JE + '\u0459' # 0x0090 -> CYRILLIC SMALL LETTER LJE + '\u0409' # 0x0091 -> CYRILLIC CAPITAL LETTER LJE + '\u045a' # 0x0092 -> CYRILLIC SMALL LETTER NJE + '\u040a' # 0x0093 -> CYRILLIC CAPITAL LETTER NJE + '\u045b' # 0x0094 -> CYRILLIC SMALL LETTER TSHE + '\u040b' # 0x0095 -> CYRILLIC CAPITAL LETTER TSHE + '\u045c' # 0x0096 -> CYRILLIC SMALL LETTER KJE + '\u040c' # 0x0097 -> CYRILLIC CAPITAL LETTER KJE + '\u045e' # 0x0098 -> CYRILLIC SMALL LETTER SHORT U + '\u040e' # 0x0099 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045f' # 0x009a -> CYRILLIC SMALL LETTER DZHE + '\u040f' # 0x009b -> CYRILLIC CAPITAL LETTER DZHE + '\u044e' # 0x009c -> CYRILLIC SMALL LETTER YU + '\u042e' # 0x009d -> CYRILLIC CAPITAL LETTER YU + '\u044a' # 0x009e -> CYRILLIC SMALL LETTER HARD SIGN + '\u042a' # 0x009f -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + '\u0410' # 0x00a1 -> CYRILLIC CAPITAL LETTER A + '\u0431' # 0x00a2 -> CYRILLIC SMALL LETTER BE + '\u0411' # 0x00a3 -> CYRILLIC CAPITAL LETTER BE + '\u0446' # 0x00a4 -> CYRILLIC SMALL LETTER TSE + '\u0426' # 0x00a5 -> CYRILLIC CAPITAL LETTER TSE + '\u0434' # 0x00a6 -> CYRILLIC SMALL LETTER DE + '\u0414' # 0x00a7 -> CYRILLIC CAPITAL LETTER DE + '\u0435' # 0x00a8 -> CYRILLIC SMALL LETTER IE + '\u0415' # 0x00a9 -> CYRILLIC CAPITAL LETTER IE + '\u0444' # 0x00aa -> CYRILLIC SMALL LETTER EF + '\u0424' # 0x00ab -> CYRILLIC CAPITAL LETTER EF + '\u0433' # 0x00ac -> CYRILLIC SMALL LETTER GHE + '\u0413' # 0x00ad -> CYRILLIC CAPITAL LETTER GHE + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u0445' # 0x00b5 -> CYRILLIC SMALL LETTER HA + '\u0425' # 0x00b6 -> CYRILLIC CAPITAL LETTER HA + '\u0438' # 0x00b7 -> CYRILLIC SMALL LETTER I + '\u0418' # 0x00b8 -> CYRILLIC CAPITAL LETTER I + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u0439' # 0x00bd -> CYRILLIC SMALL LETTER SHORT I + '\u0419' # 0x00be -> CYRILLIC CAPITAL LETTER SHORT I + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u043a' # 0x00c6 -> CYRILLIC SMALL LETTER KA + '\u041a' # 0x00c7 -> CYRILLIC CAPITAL LETTER KA + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\u043b' # 0x00d0 -> CYRILLIC SMALL LETTER EL + '\u041b' # 0x00d1 -> CYRILLIC CAPITAL LETTER EL + '\u043c' # 0x00d2 -> CYRILLIC SMALL LETTER EM + '\u041c' # 0x00d3 -> CYRILLIC CAPITAL LETTER EM + '\u043d' # 0x00d4 -> CYRILLIC SMALL LETTER EN + '\u041d' # 0x00d5 -> CYRILLIC CAPITAL LETTER EN + '\u043e' # 0x00d6 -> CYRILLIC SMALL LETTER O + '\u041e' # 0x00d7 -> CYRILLIC CAPITAL LETTER O + '\u043f' # 0x00d8 -> CYRILLIC SMALL LETTER PE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u041f' # 0x00dd -> CYRILLIC CAPITAL LETTER PE + '\u044f' # 0x00de -> CYRILLIC SMALL LETTER YA + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u042f' # 0x00e0 -> CYRILLIC CAPITAL LETTER YA + '\u0440' # 0x00e1 -> CYRILLIC SMALL LETTER ER + '\u0420' # 0x00e2 -> CYRILLIC CAPITAL LETTER ER + '\u0441' # 0x00e3 -> CYRILLIC SMALL LETTER ES + '\u0421' # 0x00e4 -> CYRILLIC CAPITAL LETTER ES + '\u0442' # 0x00e5 -> CYRILLIC SMALL LETTER TE + '\u0422' # 0x00e6 -> CYRILLIC CAPITAL LETTER TE + '\u0443' # 0x00e7 -> CYRILLIC SMALL LETTER U + '\u0423' # 0x00e8 -> CYRILLIC CAPITAL LETTER U + '\u0436' # 0x00e9 -> CYRILLIC SMALL LETTER ZHE + '\u0416' # 0x00ea -> CYRILLIC CAPITAL LETTER ZHE + '\u0432' # 0x00eb -> CYRILLIC SMALL LETTER VE + '\u0412' # 0x00ec -> CYRILLIC CAPITAL LETTER VE + '\u044c' # 0x00ed -> CYRILLIC SMALL LETTER SOFT SIGN + '\u042c' # 0x00ee -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u2116' # 0x00ef -> NUMERO SIGN + '\xad' # 0x00f0 -> SOFT HYPHEN + '\u044b' # 0x00f1 -> CYRILLIC SMALL LETTER YERU + '\u042b' # 0x00f2 -> CYRILLIC CAPITAL LETTER YERU + '\u0437' # 0x00f3 -> CYRILLIC SMALL LETTER ZE + '\u0417' # 0x00f4 -> CYRILLIC CAPITAL LETTER ZE + '\u0448' # 0x00f5 -> CYRILLIC SMALL LETTER SHA + '\u0428' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHA + '\u044d' # 0x00f7 -> CYRILLIC SMALL LETTER E + '\u042d' # 0x00f8 -> CYRILLIC CAPITAL LETTER E + '\u0449' # 0x00f9 -> CYRILLIC SMALL LETTER SHCHA + '\u0429' # 0x00fa -> CYRILLIC CAPITAL LETTER SHCHA + '\u0447' # 0x00fb -> CYRILLIC SMALL LETTER CHE + '\u0427' # 0x00fc -> CYRILLIC CAPITAL LETTER CHE + '\xa7' # 0x00fd -> SECTION SIGN + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a7: 0x00fd, # SECTION SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x0401: 0x0085, # CYRILLIC CAPITAL LETTER IO + 0x0402: 0x0081, # CYRILLIC CAPITAL LETTER DJE + 0x0403: 0x0083, # CYRILLIC CAPITAL LETTER GJE + 0x0404: 0x0087, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0405: 0x0089, # CYRILLIC CAPITAL LETTER DZE + 0x0406: 0x008b, # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0407: 0x008d, # CYRILLIC CAPITAL LETTER YI + 0x0408: 0x008f, # CYRILLIC CAPITAL LETTER JE + 0x0409: 0x0091, # CYRILLIC CAPITAL LETTER LJE + 0x040a: 0x0093, # CYRILLIC CAPITAL LETTER NJE + 0x040b: 0x0095, # CYRILLIC CAPITAL LETTER TSHE + 0x040c: 0x0097, # CYRILLIC CAPITAL LETTER KJE + 0x040e: 0x0099, # CYRILLIC CAPITAL LETTER SHORT U + 0x040f: 0x009b, # CYRILLIC CAPITAL LETTER DZHE + 0x0410: 0x00a1, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x00a3, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x00ec, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x00ad, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x00a7, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x00a9, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x00ea, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x00f4, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x00b8, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x00be, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x00c7, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x00d1, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x00d3, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x00d5, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x00d7, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x00dd, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x00e2, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x00e4, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x00e6, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x00e8, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x00ab, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x00b6, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x00a5, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x00fc, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x00f6, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x00fa, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009f, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x00f2, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x00ee, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x00f8, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009d, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x00e0, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a2, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00eb, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00ac, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a6, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a8, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00e9, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00f3, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00b7, # CYRILLIC SMALL LETTER I + 0x0439: 0x00bd, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00c6, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00d0, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00d2, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00d4, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00d6, # CYRILLIC SMALL LETTER O + 0x043f: 0x00d8, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e1, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e3, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e5, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e7, # CYRILLIC SMALL LETTER U + 0x0444: 0x00aa, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00b5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00a4, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00fb, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00f5, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00f9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x009e, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00f1, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ed, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00f7, # CYRILLIC SMALL LETTER E + 0x044e: 0x009c, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00de, # CYRILLIC SMALL LETTER YA + 0x0451: 0x0084, # CYRILLIC SMALL LETTER IO + 0x0452: 0x0080, # CYRILLIC SMALL LETTER DJE + 0x0453: 0x0082, # CYRILLIC SMALL LETTER GJE + 0x0454: 0x0086, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0455: 0x0088, # CYRILLIC SMALL LETTER DZE + 0x0456: 0x008a, # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + 0x0457: 0x008c, # CYRILLIC SMALL LETTER YI + 0x0458: 0x008e, # CYRILLIC SMALL LETTER JE + 0x0459: 0x0090, # CYRILLIC SMALL LETTER LJE + 0x045a: 0x0092, # CYRILLIC SMALL LETTER NJE + 0x045b: 0x0094, # CYRILLIC SMALL LETTER TSHE + 0x045c: 0x0096, # CYRILLIC SMALL LETTER KJE + 0x045e: 0x0098, # CYRILLIC SMALL LETTER SHORT U + 0x045f: 0x009a, # CYRILLIC SMALL LETTER DZHE + 0x2116: 0x00ef, # NUMERO SIGN + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp856.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp856.py new file mode 100644 index 0000000..cacbfb2 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp856.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp856 generated from 'MAPPINGS/VENDORS/MISC/CP856.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp856', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u05d0' # 0x80 -> HEBREW LETTER ALEF + '\u05d1' # 0x81 -> HEBREW LETTER BET + '\u05d2' # 0x82 -> HEBREW LETTER GIMEL + '\u05d3' # 0x83 -> HEBREW LETTER DALET + '\u05d4' # 0x84 -> HEBREW LETTER HE + '\u05d5' # 0x85 -> HEBREW LETTER VAV + '\u05d6' # 0x86 -> HEBREW LETTER ZAYIN + '\u05d7' # 0x87 -> HEBREW LETTER HET + '\u05d8' # 0x88 -> HEBREW LETTER TET + '\u05d9' # 0x89 -> HEBREW LETTER YOD + '\u05da' # 0x8A -> HEBREW LETTER FINAL KAF + '\u05db' # 0x8B -> HEBREW LETTER KAF + '\u05dc' # 0x8C -> HEBREW LETTER LAMED + '\u05dd' # 0x8D -> HEBREW LETTER FINAL MEM + '\u05de' # 0x8E -> HEBREW LETTER MEM + '\u05df' # 0x8F -> HEBREW LETTER FINAL NUN + '\u05e0' # 0x90 -> HEBREW LETTER NUN + '\u05e1' # 0x91 -> HEBREW LETTER SAMEKH + '\u05e2' # 0x92 -> HEBREW LETTER AYIN + '\u05e3' # 0x93 -> HEBREW LETTER FINAL PE + '\u05e4' # 0x94 -> HEBREW LETTER PE + '\u05e5' # 0x95 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0x96 -> HEBREW LETTER TSADI + '\u05e7' # 0x97 -> HEBREW LETTER QOF + '\u05e8' # 0x98 -> HEBREW LETTER RESH + '\u05e9' # 0x99 -> HEBREW LETTER SHIN + '\u05ea' # 0x9A -> HEBREW LETTER TAV + '\ufffe' # 0x9B -> UNDEFINED + '\xa3' # 0x9C -> POUND SIGN + '\ufffe' # 0x9D -> UNDEFINED + '\xd7' # 0x9E -> MULTIPLICATION SIGN + '\ufffe' # 0x9F -> UNDEFINED + '\ufffe' # 0xA0 -> UNDEFINED + '\ufffe' # 0xA1 -> UNDEFINED + '\ufffe' # 0xA2 -> UNDEFINED + '\ufffe' # 0xA3 -> UNDEFINED + '\ufffe' # 0xA4 -> UNDEFINED + '\ufffe' # 0xA5 -> UNDEFINED + '\ufffe' # 0xA6 -> UNDEFINED + '\ufffe' # 0xA7 -> UNDEFINED + '\ufffe' # 0xA8 -> UNDEFINED + '\xae' # 0xA9 -> REGISTERED SIGN + '\xac' # 0xAA -> NOT SIGN + '\xbd' # 0xAB -> VULGAR FRACTION ONE HALF + '\xbc' # 0xAC -> VULGAR FRACTION ONE QUARTER + '\ufffe' # 0xAD -> UNDEFINED + '\xab' # 0xAE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xAF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0xB0 -> LIGHT SHADE + '\u2592' # 0xB1 -> MEDIUM SHADE + '\u2593' # 0xB2 -> DARK SHADE + '\u2502' # 0xB3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0xB4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\ufffe' # 0xB5 -> UNDEFINED + '\ufffe' # 0xB6 -> UNDEFINED + '\ufffe' # 0xB7 -> UNDEFINED + '\xa9' # 0xB8 -> COPYRIGHT SIGN + '\u2563' # 0xB9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0xBA -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0xBB -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0xBC -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0xBD -> CENT SIGN + '\xa5' # 0xBE -> YEN SIGN + '\u2510' # 0xBF -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0xC0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0xC1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0xC2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0xC3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0xC4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0xC5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\ufffe' # 0xC6 -> UNDEFINED + '\ufffe' # 0xC7 -> UNDEFINED + '\u255a' # 0xC8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0xC9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0xCA -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0xCB -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0xCC -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0xCD -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0xCE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0xCF -> CURRENCY SIGN + '\ufffe' # 0xD0 -> UNDEFINED + '\ufffe' # 0xD1 -> UNDEFINED + '\ufffe' # 0xD2 -> UNDEFINED + '\ufffe' # 0xD3 -> UNDEFINEDS + '\ufffe' # 0xD4 -> UNDEFINED + '\ufffe' # 0xD5 -> UNDEFINED + '\ufffe' # 0xD6 -> UNDEFINEDE + '\ufffe' # 0xD7 -> UNDEFINED + '\ufffe' # 0xD8 -> UNDEFINED + '\u2518' # 0xD9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0xDA -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0xDB -> FULL BLOCK + '\u2584' # 0xDC -> LOWER HALF BLOCK + '\xa6' # 0xDD -> BROKEN BAR + '\ufffe' # 0xDE -> UNDEFINED + '\u2580' # 0xDF -> UPPER HALF BLOCK + '\ufffe' # 0xE0 -> UNDEFINED + '\ufffe' # 0xE1 -> UNDEFINED + '\ufffe' # 0xE2 -> UNDEFINED + '\ufffe' # 0xE3 -> UNDEFINED + '\ufffe' # 0xE4 -> UNDEFINED + '\ufffe' # 0xE5 -> UNDEFINED + '\xb5' # 0xE6 -> MICRO SIGN + '\ufffe' # 0xE7 -> UNDEFINED + '\ufffe' # 0xE8 -> UNDEFINED + '\ufffe' # 0xE9 -> UNDEFINED + '\ufffe' # 0xEA -> UNDEFINED + '\ufffe' # 0xEB -> UNDEFINED + '\ufffe' # 0xEC -> UNDEFINED + '\ufffe' # 0xED -> UNDEFINED + '\xaf' # 0xEE -> MACRON + '\xb4' # 0xEF -> ACUTE ACCENT + '\xad' # 0xF0 -> SOFT HYPHEN + '\xb1' # 0xF1 -> PLUS-MINUS SIGN + '\u2017' # 0xF2 -> DOUBLE LOW LINE + '\xbe' # 0xF3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0xF4 -> PILCROW SIGN + '\xa7' # 0xF5 -> SECTION SIGN + '\xf7' # 0xF6 -> DIVISION SIGN + '\xb8' # 0xF7 -> CEDILLA + '\xb0' # 0xF8 -> DEGREE SIGN + '\xa8' # 0xF9 -> DIAERESIS + '\xb7' # 0xFA -> MIDDLE DOT + '\xb9' # 0xFB -> SUPERSCRIPT ONE + '\xb3' # 0xFC -> SUPERSCRIPT THREE + '\xb2' # 0xFD -> SUPERSCRIPT TWO + '\u25a0' # 0xFE -> BLACK SQUARE + '\xa0' # 0xFF -> NO-BREAK SPACE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp857.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp857.py new file mode 100644 index 0000000..741b059 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp857.py @@ -0,0 +1,694 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP857.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp857', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x0131, # LATIN SMALL LETTER DOTLESS I + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x015e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x009f: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x011e, # LATIN CAPITAL LETTER G WITH BREVE + 0x00a7: 0x011f, # LATIN SMALL LETTER G WITH BREVE + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00d1: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: None, # UNDEFINED + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: None, # UNDEFINED + 0x00e8: 0x00d7, # MULTIPLICATION SIGN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ed: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: None, # UNDEFINED + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u0131' # 0x008d -> LATIN SMALL LETTER DOTLESS I + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\u0130' # 0x0098 -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\u015e' # 0x009e -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u015f' # 0x009f -> LATIN SMALL LETTER S WITH CEDILLA + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\u011e' # 0x00a6 -> LATIN CAPITAL LETTER G WITH BREVE + '\u011f' # 0x00a7 -> LATIN SMALL LETTER G WITH BREVE + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa9' # 0x00b8 -> COPYRIGHT SIGN + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0x00bd -> CENT SIGN + '\xa5' # 0x00be -> YEN SIGN + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\xba' # 0x00d0 -> MASCULINE ORDINAL INDICATOR + '\xaa' # 0x00d1 -> FEMININE ORDINAL INDICATOR + '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + '\ufffe' # 0x00d5 -> UNDEFINED + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\xa6' # 0x00dd -> BROKEN BAR + '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\ufffe' # 0x00e7 -> UNDEFINED + '\xd7' # 0x00e8 -> MULTIPLICATION SIGN + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + '\xec' # 0x00ec -> LATIN SMALL LETTER I WITH GRAVE + '\xff' # 0x00ed -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xaf' # 0x00ee -> MACRON + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\ufffe' # 0x00f2 -> UNDEFINED + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00d1, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00d0, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x00e8, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x00ed, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x011e: 0x00a6, # LATIN CAPITAL LETTER G WITH BREVE + 0x011f: 0x00a7, # LATIN SMALL LETTER G WITH BREVE + 0x0130: 0x0098, # LATIN CAPITAL LETTER I WITH DOT ABOVE + 0x0131: 0x008d, # LATIN SMALL LETTER DOTLESS I + 0x015e: 0x009e, # LATIN CAPITAL LETTER S WITH CEDILLA + 0x015f: 0x009f, # LATIN SMALL LETTER S WITH CEDILLA + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp858.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp858.py new file mode 100644 index 0000000..7579f52 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp858.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec for CP858, modified from cp850. + +""" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp858', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x00d7, # MULTIPLICATION SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00ae, # REGISTERED SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00b6: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00b7: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00b8: 0x00a9, # COPYRIGHT SIGN + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x00a2, # CENT SIGN + 0x00be: 0x00a5, # YEN SIGN + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x00c7: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x00a4, # CURRENCY SIGN + 0x00d0: 0x00f0, # LATIN SMALL LETTER ETH + 0x00d1: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x00d2: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00d3: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00d4: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00d5: 0x20ac, # EURO SIGN + 0x00d6: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d7: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00d8: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x00a6, # BROKEN BAR + 0x00de: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00e3: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00e4: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x00e5: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x00fe, # LATIN SMALL LETTER THORN + 0x00e8: 0x00de, # LATIN CAPITAL LETTER THORN + 0x00e9: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00ea: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00eb: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00ec: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x00ed: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00ee: 0x00af, # MACRON + 0x00ef: 0x00b4, # ACUTE ACCENT + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2017, # DOUBLE LOW LINE + 0x00f3: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00f4: 0x00b6, # PILCROW SIGN + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x00b8, # CEDILLA + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x00b9, # SUPERSCRIPT ONE + 0x00fc: 0x00b3, # SUPERSCRIPT THREE + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\xd7' # 0x009e -> MULTIPLICATION SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xae' # 0x00a9 -> REGISTERED SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\xc1' # 0x00b5 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0x00b6 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc0' # 0x00b7 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa9' # 0x00b8 -> COPYRIGHT SIGN + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\xa2' # 0x00bd -> CENT SIGN + '\xa5' # 0x00be -> YEN SIGN + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\xe3' # 0x00c6 -> LATIN SMALL LETTER A WITH TILDE + '\xc3' # 0x00c7 -> LATIN CAPITAL LETTER A WITH TILDE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa4' # 0x00cf -> CURRENCY SIGN + '\xf0' # 0x00d0 -> LATIN SMALL LETTER ETH + '\xd0' # 0x00d1 -> LATIN CAPITAL LETTER ETH + '\xca' # 0x00d2 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0x00d3 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0x00d4 -> LATIN CAPITAL LETTER E WITH GRAVE + '\u20ac' # 0x00d5 -> EURO SIGN + '\xcd' # 0x00d6 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0x00d7 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0x00d8 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\xa6' # 0x00dd -> BROKEN BAR + '\xcc' # 0x00de -> LATIN CAPITAL LETTER I WITH GRAVE + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\xd3' # 0x00e0 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\xd4' # 0x00e2 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd2' # 0x00e3 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xf5' # 0x00e4 -> LATIN SMALL LETTER O WITH TILDE + '\xd5' # 0x00e5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xb5' # 0x00e6 -> MICRO SIGN + '\xfe' # 0x00e7 -> LATIN SMALL LETTER THORN + '\xde' # 0x00e8 -> LATIN CAPITAL LETTER THORN + '\xda' # 0x00e9 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0x00ea -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0x00eb -> LATIN CAPITAL LETTER U WITH GRAVE + '\xfd' # 0x00ec -> LATIN SMALL LETTER Y WITH ACUTE + '\xdd' # 0x00ed -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xaf' # 0x00ee -> MACRON + '\xb4' # 0x00ef -> ACUTE ACCENT + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2017' # 0x00f2 -> DOUBLE LOW LINE + '\xbe' # 0x00f3 -> VULGAR FRACTION THREE QUARTERS + '\xb6' # 0x00f4 -> PILCROW SIGN + '\xa7' # 0x00f5 -> SECTION SIGN + '\xf7' # 0x00f6 -> DIVISION SIGN + '\xb8' # 0x00f7 -> CEDILLA + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\xb7' # 0x00fa -> MIDDLE DOT + '\xb9' # 0x00fb -> SUPERSCRIPT ONE + '\xb3' # 0x00fc -> SUPERSCRIPT THREE + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x00bd, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00cf, # CURRENCY SIGN + 0x00a5: 0x00be, # YEN SIGN + 0x00a6: 0x00dd, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x00b8, # COPYRIGHT SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00ae: 0x00a9, # REGISTERED SIGN + 0x00af: 0x00ee, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00fc, # SUPERSCRIPT THREE + 0x00b4: 0x00ef, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x00f4, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00f7, # CEDILLA + 0x00b9: 0x00fb, # SUPERSCRIPT ONE + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00f3, # VULGAR FRACTION THREE QUARTERS + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x00b7, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x00b5, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x00b6, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x00c7, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x00d4, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x00d2, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x00d3, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00cc: 0x00de, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x00d6, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00ce: 0x00d7, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x00d8, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d0: 0x00d1, # LATIN CAPITAL LETTER ETH + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00e3, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x00e0, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x00e2, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x00e5, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d7: 0x009e, # MULTIPLICATION SIGN + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00d9: 0x00eb, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x00e9, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00db: 0x00ea, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x00ed, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x00e8, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x00c6, # LATIN SMALL LETTER A WITH TILDE + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f0: 0x00d0, # LATIN SMALL LETTER ETH + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x00e4, # LATIN SMALL LETTER O WITH TILDE + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x00ec, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x00e7, # LATIN SMALL LETTER THORN + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x20ac: 0x00d5, # EURO SIGN + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x2017: 0x00f2, # DOUBLE LOW LINE + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp860.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp860.py new file mode 100644 index 0000000..65903e7 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp860.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP860.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp860', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e3, # LATIN SMALL LETTER A WITH TILDE + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x008c: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c3, # LATIN CAPITAL LETTER A WITH TILDE + 0x008f: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x0092: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f5, # LATIN SMALL LETTER O WITH TILDE + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00cc, # LATIN CAPITAL LETTER I WITH GRAVE + 0x0099: 0x00d5, # LATIN CAPITAL LETTER O WITH TILDE + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x00d2, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0x0084 -> LATIN SMALL LETTER A WITH TILDE + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xc1' # 0x0086 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xca' # 0x0089 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xcd' # 0x008b -> LATIN CAPITAL LETTER I WITH ACUTE + '\xd4' # 0x008c -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc3' # 0x008e -> LATIN CAPITAL LETTER A WITH TILDE + '\xc2' # 0x008f -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xc0' # 0x0091 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc8' # 0x0092 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0x0094 -> LATIN SMALL LETTER O WITH TILDE + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xda' # 0x0096 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xcc' # 0x0098 -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd5' # 0x0099 -> LATIN CAPITAL LETTER O WITH TILDE + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE + '\u20a7' # 0x009e -> PESETA SIGN + '\xd3' # 0x009f -> LATIN CAPITAL LETTER O WITH ACUTE + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\xd2' # 0x00a9 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c0: 0x0091, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c1: 0x0086, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c2: 0x008f, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c3: 0x008e, # LATIN CAPITAL LETTER A WITH TILDE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x0092, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x0089, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cc: 0x0098, # LATIN CAPITAL LETTER I WITH GRAVE + 0x00cd: 0x008b, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d2: 0x00a9, # LATIN CAPITAL LETTER O WITH GRAVE + 0x00d3: 0x009f, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d4: 0x008c, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d5: 0x0099, # LATIN CAPITAL LETTER O WITH TILDE + 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00da: 0x0096, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e3: 0x0084, # LATIN SMALL LETTER A WITH TILDE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f5: 0x0094, # LATIN SMALL LETTER O WITH TILDE + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp861.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp861.py new file mode 100644 index 0000000..860a05f --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp861.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP861.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp861', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00d0, # LATIN CAPITAL LETTER ETH + 0x008c: 0x00f0, # LATIN SMALL LETTER ETH + 0x008d: 0x00de, # LATIN CAPITAL LETTER THORN + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00fe, # LATIN SMALL LETTER THORN + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00dd, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x0098: 0x00fd, # LATIN SMALL LETTER Y WITH ACUTE + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00c1, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00a5: 0x00cd, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00a6: 0x00d3, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00a7: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xd0' # 0x008b -> LATIN CAPITAL LETTER ETH + '\xf0' # 0x008c -> LATIN SMALL LETTER ETH + '\xde' # 0x008d -> LATIN CAPITAL LETTER THORN + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xfe' # 0x0095 -> LATIN SMALL LETTER THORN + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xdd' # 0x0097 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xfd' # 0x0098 -> LATIN SMALL LETTER Y WITH ACUTE + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xc1' # 0x00a4 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcd' # 0x00a5 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xd3' # 0x00a6 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xda' # 0x00a7 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a3: 0x009c, # POUND SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c1: 0x00a4, # LATIN CAPITAL LETTER A WITH ACUTE + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00cd: 0x00a5, # LATIN CAPITAL LETTER I WITH ACUTE + 0x00d0: 0x008b, # LATIN CAPITAL LETTER ETH + 0x00d3: 0x00a6, # LATIN CAPITAL LETTER O WITH ACUTE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00da: 0x00a7, # LATIN CAPITAL LETTER U WITH ACUTE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00dd: 0x0097, # LATIN CAPITAL LETTER Y WITH ACUTE + 0x00de: 0x008d, # LATIN CAPITAL LETTER THORN + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f0: 0x008c, # LATIN SMALL LETTER ETH + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00fd: 0x0098, # LATIN SMALL LETTER Y WITH ACUTE + 0x00fe: 0x0095, # LATIN SMALL LETTER THORN + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp862.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp862.py new file mode 100644 index 0000000..3df22f9 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp862.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP862.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp862', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x05d0, # HEBREW LETTER ALEF + 0x0081: 0x05d1, # HEBREW LETTER BET + 0x0082: 0x05d2, # HEBREW LETTER GIMEL + 0x0083: 0x05d3, # HEBREW LETTER DALET + 0x0084: 0x05d4, # HEBREW LETTER HE + 0x0085: 0x05d5, # HEBREW LETTER VAV + 0x0086: 0x05d6, # HEBREW LETTER ZAYIN + 0x0087: 0x05d7, # HEBREW LETTER HET + 0x0088: 0x05d8, # HEBREW LETTER TET + 0x0089: 0x05d9, # HEBREW LETTER YOD + 0x008a: 0x05da, # HEBREW LETTER FINAL KAF + 0x008b: 0x05db, # HEBREW LETTER KAF + 0x008c: 0x05dc, # HEBREW LETTER LAMED + 0x008d: 0x05dd, # HEBREW LETTER FINAL MEM + 0x008e: 0x05de, # HEBREW LETTER MEM + 0x008f: 0x05df, # HEBREW LETTER FINAL NUN + 0x0090: 0x05e0, # HEBREW LETTER NUN + 0x0091: 0x05e1, # HEBREW LETTER SAMEKH + 0x0092: 0x05e2, # HEBREW LETTER AYIN + 0x0093: 0x05e3, # HEBREW LETTER FINAL PE + 0x0094: 0x05e4, # HEBREW LETTER PE + 0x0095: 0x05e5, # HEBREW LETTER FINAL TSADI + 0x0096: 0x05e6, # HEBREW LETTER TSADI + 0x0097: 0x05e7, # HEBREW LETTER QOF + 0x0098: 0x05e8, # HEBREW LETTER RESH + 0x0099: 0x05e9, # HEBREW LETTER SHIN + 0x009a: 0x05ea, # HEBREW LETTER TAV + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00a5, # YEN SIGN + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u05d0' # 0x0080 -> HEBREW LETTER ALEF + '\u05d1' # 0x0081 -> HEBREW LETTER BET + '\u05d2' # 0x0082 -> HEBREW LETTER GIMEL + '\u05d3' # 0x0083 -> HEBREW LETTER DALET + '\u05d4' # 0x0084 -> HEBREW LETTER HE + '\u05d5' # 0x0085 -> HEBREW LETTER VAV + '\u05d6' # 0x0086 -> HEBREW LETTER ZAYIN + '\u05d7' # 0x0087 -> HEBREW LETTER HET + '\u05d8' # 0x0088 -> HEBREW LETTER TET + '\u05d9' # 0x0089 -> HEBREW LETTER YOD + '\u05da' # 0x008a -> HEBREW LETTER FINAL KAF + '\u05db' # 0x008b -> HEBREW LETTER KAF + '\u05dc' # 0x008c -> HEBREW LETTER LAMED + '\u05dd' # 0x008d -> HEBREW LETTER FINAL MEM + '\u05de' # 0x008e -> HEBREW LETTER MEM + '\u05df' # 0x008f -> HEBREW LETTER FINAL NUN + '\u05e0' # 0x0090 -> HEBREW LETTER NUN + '\u05e1' # 0x0091 -> HEBREW LETTER SAMEKH + '\u05e2' # 0x0092 -> HEBREW LETTER AYIN + '\u05e3' # 0x0093 -> HEBREW LETTER FINAL PE + '\u05e4' # 0x0094 -> HEBREW LETTER PE + '\u05e5' # 0x0095 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0x0096 -> HEBREW LETTER TSADI + '\u05e7' # 0x0097 -> HEBREW LETTER QOF + '\u05e8' # 0x0098 -> HEBREW LETTER RESH + '\u05e9' # 0x0099 -> HEBREW LETTER SHIN + '\u05ea' # 0x009a -> HEBREW LETTER TAV + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xa5' # 0x009d -> YEN SIGN + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S (GERMAN) + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a5: 0x009d, # YEN SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S (GERMAN) + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x05d0: 0x0080, # HEBREW LETTER ALEF + 0x05d1: 0x0081, # HEBREW LETTER BET + 0x05d2: 0x0082, # HEBREW LETTER GIMEL + 0x05d3: 0x0083, # HEBREW LETTER DALET + 0x05d4: 0x0084, # HEBREW LETTER HE + 0x05d5: 0x0085, # HEBREW LETTER VAV + 0x05d6: 0x0086, # HEBREW LETTER ZAYIN + 0x05d7: 0x0087, # HEBREW LETTER HET + 0x05d8: 0x0088, # HEBREW LETTER TET + 0x05d9: 0x0089, # HEBREW LETTER YOD + 0x05da: 0x008a, # HEBREW LETTER FINAL KAF + 0x05db: 0x008b, # HEBREW LETTER KAF + 0x05dc: 0x008c, # HEBREW LETTER LAMED + 0x05dd: 0x008d, # HEBREW LETTER FINAL MEM + 0x05de: 0x008e, # HEBREW LETTER MEM + 0x05df: 0x008f, # HEBREW LETTER FINAL NUN + 0x05e0: 0x0090, # HEBREW LETTER NUN + 0x05e1: 0x0091, # HEBREW LETTER SAMEKH + 0x05e2: 0x0092, # HEBREW LETTER AYIN + 0x05e3: 0x0093, # HEBREW LETTER FINAL PE + 0x05e4: 0x0094, # HEBREW LETTER PE + 0x05e5: 0x0095, # HEBREW LETTER FINAL TSADI + 0x05e6: 0x0096, # HEBREW LETTER TSADI + 0x05e7: 0x0097, # HEBREW LETTER QOF + 0x05e8: 0x0098, # HEBREW LETTER RESH + 0x05e9: 0x0099, # HEBREW LETTER SHIN + 0x05ea: 0x009a, # HEBREW LETTER TAV + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp863.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp863.py new file mode 100644 index 0000000..764180b --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp863.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP863.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp863', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00c2, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00b6, # PILCROW SIGN + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x2017, # DOUBLE LOW LINE + 0x008e: 0x00c0, # LATIN CAPITAL LETTER A WITH GRAVE + 0x008f: 0x00a7, # SECTION SIGN + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00c8, # LATIN CAPITAL LETTER E WITH GRAVE + 0x0092: 0x00ca, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00cb, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x0095: 0x00cf, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00a4, # CURRENCY SIGN + 0x0099: 0x00d4, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00a2, # CENT SIGN + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d9, # LATIN CAPITAL LETTER U WITH GRAVE + 0x009e: 0x00db, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00a6, # BROKEN BAR + 0x00a1: 0x00b4, # ACUTE ACCENT + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00a8, # DIAERESIS + 0x00a5: 0x00b8, # CEDILLA + 0x00a6: 0x00b3, # SUPERSCRIPT THREE + 0x00a7: 0x00af, # MACRON + 0x00a8: 0x00ce, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00be, # VULGAR FRACTION THREE QUARTERS + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xc2' # 0x0084 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xb6' # 0x0086 -> PILCROW SIGN + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u2017' # 0x008d -> DOUBLE LOW LINE + '\xc0' # 0x008e -> LATIN CAPITAL LETTER A WITH GRAVE + '\xa7' # 0x008f -> SECTION SIGN + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xc8' # 0x0091 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xca' # 0x0092 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xcb' # 0x0094 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcf' # 0x0095 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xa4' # 0x0098 -> CURRENCY SIGN + '\xd4' # 0x0099 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xa2' # 0x009b -> CENT SIGN + '\xa3' # 0x009c -> POUND SIGN + '\xd9' # 0x009d -> LATIN CAPITAL LETTER U WITH GRAVE + '\xdb' # 0x009e -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xa6' # 0x00a0 -> BROKEN BAR + '\xb4' # 0x00a1 -> ACUTE ACCENT + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xa8' # 0x00a4 -> DIAERESIS + '\xb8' # 0x00a5 -> CEDILLA + '\xb3' # 0x00a6 -> SUPERSCRIPT THREE + '\xaf' # 0x00a7 -> MACRON + '\xce' # 0x00a8 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xbe' # 0x00ad -> VULGAR FRACTION THREE QUARTERS + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a2: 0x009b, # CENT SIGN + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x0098, # CURRENCY SIGN + 0x00a6: 0x00a0, # BROKEN BAR + 0x00a7: 0x008f, # SECTION SIGN + 0x00a8: 0x00a4, # DIAERESIS + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00af: 0x00a7, # MACRON + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b3: 0x00a6, # SUPERSCRIPT THREE + 0x00b4: 0x00a1, # ACUTE ACCENT + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b6: 0x0086, # PILCROW SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00b8: 0x00a5, # CEDILLA + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00be: 0x00ad, # VULGAR FRACTION THREE QUARTERS + 0x00c0: 0x008e, # LATIN CAPITAL LETTER A WITH GRAVE + 0x00c2: 0x0084, # LATIN CAPITAL LETTER A WITH CIRCUMFLEX + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c8: 0x0091, # LATIN CAPITAL LETTER E WITH GRAVE + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00ca: 0x0092, # LATIN CAPITAL LETTER E WITH CIRCUMFLEX + 0x00cb: 0x0094, # LATIN CAPITAL LETTER E WITH DIAERESIS + 0x00ce: 0x00a8, # LATIN CAPITAL LETTER I WITH CIRCUMFLEX + 0x00cf: 0x0095, # LATIN CAPITAL LETTER I WITH DIAERESIS + 0x00d4: 0x0099, # LATIN CAPITAL LETTER O WITH CIRCUMFLEX + 0x00d9: 0x009d, # LATIN CAPITAL LETTER U WITH GRAVE + 0x00db: 0x009e, # LATIN CAPITAL LETTER U WITH CIRCUMFLEX + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x2017: 0x008d, # DOUBLE LOW LINE + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp864.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp864.py new file mode 100644 index 0000000..53df482 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp864.py @@ -0,0 +1,690 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP864.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp864', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0025: 0x066a, # ARABIC PERCENT SIGN + 0x0080: 0x00b0, # DEGREE SIGN + 0x0081: 0x00b7, # MIDDLE DOT + 0x0082: 0x2219, # BULLET OPERATOR + 0x0083: 0x221a, # SQUARE ROOT + 0x0084: 0x2592, # MEDIUM SHADE + 0x0085: 0x2500, # FORMS LIGHT HORIZONTAL + 0x0086: 0x2502, # FORMS LIGHT VERTICAL + 0x0087: 0x253c, # FORMS LIGHT VERTICAL AND HORIZONTAL + 0x0088: 0x2524, # FORMS LIGHT VERTICAL AND LEFT + 0x0089: 0x252c, # FORMS LIGHT DOWN AND HORIZONTAL + 0x008a: 0x251c, # FORMS LIGHT VERTICAL AND RIGHT + 0x008b: 0x2534, # FORMS LIGHT UP AND HORIZONTAL + 0x008c: 0x2510, # FORMS LIGHT DOWN AND LEFT + 0x008d: 0x250c, # FORMS LIGHT DOWN AND RIGHT + 0x008e: 0x2514, # FORMS LIGHT UP AND RIGHT + 0x008f: 0x2518, # FORMS LIGHT UP AND LEFT + 0x0090: 0x03b2, # GREEK SMALL BETA + 0x0091: 0x221e, # INFINITY + 0x0092: 0x03c6, # GREEK SMALL PHI + 0x0093: 0x00b1, # PLUS-OR-MINUS SIGN + 0x0094: 0x00bd, # FRACTION 1/2 + 0x0095: 0x00bc, # FRACTION 1/4 + 0x0096: 0x2248, # ALMOST EQUAL TO + 0x0097: 0x00ab, # LEFT POINTING GUILLEMET + 0x0098: 0x00bb, # RIGHT POINTING GUILLEMET + 0x0099: 0xfef7, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + 0x009a: 0xfef8, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + 0x009b: None, # UNDEFINED + 0x009c: None, # UNDEFINED + 0x009d: 0xfefb, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + 0x009e: 0xfefc, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM + 0x009f: None, # UNDEFINED + 0x00a1: 0x00ad, # SOFT HYPHEN + 0x00a2: 0xfe82, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + 0x00a5: 0xfe84, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + 0x00a6: None, # UNDEFINED + 0x00a7: None, # UNDEFINED + 0x00a8: 0xfe8e, # ARABIC LETTER ALEF FINAL FORM + 0x00a9: 0xfe8f, # ARABIC LETTER BEH ISOLATED FORM + 0x00aa: 0xfe95, # ARABIC LETTER TEH ISOLATED FORM + 0x00ab: 0xfe99, # ARABIC LETTER THEH ISOLATED FORM + 0x00ac: 0x060c, # ARABIC COMMA + 0x00ad: 0xfe9d, # ARABIC LETTER JEEM ISOLATED FORM + 0x00ae: 0xfea1, # ARABIC LETTER HAH ISOLATED FORM + 0x00af: 0xfea5, # ARABIC LETTER KHAH ISOLATED FORM + 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO + 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE + 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO + 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE + 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR + 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE + 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX + 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN + 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT + 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE + 0x00ba: 0xfed1, # ARABIC LETTER FEH ISOLATED FORM + 0x00bb: 0x061b, # ARABIC SEMICOLON + 0x00bc: 0xfeb1, # ARABIC LETTER SEEN ISOLATED FORM + 0x00bd: 0xfeb5, # ARABIC LETTER SHEEN ISOLATED FORM + 0x00be: 0xfeb9, # ARABIC LETTER SAD ISOLATED FORM + 0x00bf: 0x061f, # ARABIC QUESTION MARK + 0x00c0: 0x00a2, # CENT SIGN + 0x00c1: 0xfe80, # ARABIC LETTER HAMZA ISOLATED FORM + 0x00c2: 0xfe81, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + 0x00c3: 0xfe83, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + 0x00c4: 0xfe85, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + 0x00c5: 0xfeca, # ARABIC LETTER AIN FINAL FORM + 0x00c6: 0xfe8b, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + 0x00c7: 0xfe8d, # ARABIC LETTER ALEF ISOLATED FORM + 0x00c8: 0xfe91, # ARABIC LETTER BEH INITIAL FORM + 0x00c9: 0xfe93, # ARABIC LETTER TEH MARBUTA ISOLATED FORM + 0x00ca: 0xfe97, # ARABIC LETTER TEH INITIAL FORM + 0x00cb: 0xfe9b, # ARABIC LETTER THEH INITIAL FORM + 0x00cc: 0xfe9f, # ARABIC LETTER JEEM INITIAL FORM + 0x00cd: 0xfea3, # ARABIC LETTER HAH INITIAL FORM + 0x00ce: 0xfea7, # ARABIC LETTER KHAH INITIAL FORM + 0x00cf: 0xfea9, # ARABIC LETTER DAL ISOLATED FORM + 0x00d0: 0xfeab, # ARABIC LETTER THAL ISOLATED FORM + 0x00d1: 0xfead, # ARABIC LETTER REH ISOLATED FORM + 0x00d2: 0xfeaf, # ARABIC LETTER ZAIN ISOLATED FORM + 0x00d3: 0xfeb3, # ARABIC LETTER SEEN INITIAL FORM + 0x00d4: 0xfeb7, # ARABIC LETTER SHEEN INITIAL FORM + 0x00d5: 0xfebb, # ARABIC LETTER SAD INITIAL FORM + 0x00d6: 0xfebf, # ARABIC LETTER DAD INITIAL FORM + 0x00d7: 0xfec1, # ARABIC LETTER TAH ISOLATED FORM + 0x00d8: 0xfec5, # ARABIC LETTER ZAH ISOLATED FORM + 0x00d9: 0xfecb, # ARABIC LETTER AIN INITIAL FORM + 0x00da: 0xfecf, # ARABIC LETTER GHAIN INITIAL FORM + 0x00db: 0x00a6, # BROKEN VERTICAL BAR + 0x00dc: 0x00ac, # NOT SIGN + 0x00dd: 0x00f7, # DIVISION SIGN + 0x00de: 0x00d7, # MULTIPLICATION SIGN + 0x00df: 0xfec9, # ARABIC LETTER AIN ISOLATED FORM + 0x00e0: 0x0640, # ARABIC TATWEEL + 0x00e1: 0xfed3, # ARABIC LETTER FEH INITIAL FORM + 0x00e2: 0xfed7, # ARABIC LETTER QAF INITIAL FORM + 0x00e3: 0xfedb, # ARABIC LETTER KAF INITIAL FORM + 0x00e4: 0xfedf, # ARABIC LETTER LAM INITIAL FORM + 0x00e5: 0xfee3, # ARABIC LETTER MEEM INITIAL FORM + 0x00e6: 0xfee7, # ARABIC LETTER NOON INITIAL FORM + 0x00e7: 0xfeeb, # ARABIC LETTER HEH INITIAL FORM + 0x00e8: 0xfeed, # ARABIC LETTER WAW ISOLATED FORM + 0x00e9: 0xfeef, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM + 0x00ea: 0xfef3, # ARABIC LETTER YEH INITIAL FORM + 0x00eb: 0xfebd, # ARABIC LETTER DAD ISOLATED FORM + 0x00ec: 0xfecc, # ARABIC LETTER AIN MEDIAL FORM + 0x00ed: 0xfece, # ARABIC LETTER GHAIN FINAL FORM + 0x00ee: 0xfecd, # ARABIC LETTER GHAIN ISOLATED FORM + 0x00ef: 0xfee1, # ARABIC LETTER MEEM ISOLATED FORM + 0x00f0: 0xfe7d, # ARABIC SHADDA MEDIAL FORM + 0x00f1: 0x0651, # ARABIC SHADDAH + 0x00f2: 0xfee5, # ARABIC LETTER NOON ISOLATED FORM + 0x00f3: 0xfee9, # ARABIC LETTER HEH ISOLATED FORM + 0x00f4: 0xfeec, # ARABIC LETTER HEH MEDIAL FORM + 0x00f5: 0xfef0, # ARABIC LETTER ALEF MAKSURA FINAL FORM + 0x00f6: 0xfef2, # ARABIC LETTER YEH FINAL FORM + 0x00f7: 0xfed0, # ARABIC LETTER GHAIN MEDIAL FORM + 0x00f8: 0xfed5, # ARABIC LETTER QAF ISOLATED FORM + 0x00f9: 0xfef5, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + 0x00fa: 0xfef6, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + 0x00fb: 0xfedd, # ARABIC LETTER LAM ISOLATED FORM + 0x00fc: 0xfed9, # ARABIC LETTER KAF ISOLATED FORM + 0x00fd: 0xfef1, # ARABIC LETTER YEH ISOLATED FORM + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: None, # UNDEFINED +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '\u066a' # 0x0025 -> ARABIC PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xb0' # 0x0080 -> DEGREE SIGN + '\xb7' # 0x0081 -> MIDDLE DOT + '\u2219' # 0x0082 -> BULLET OPERATOR + '\u221a' # 0x0083 -> SQUARE ROOT + '\u2592' # 0x0084 -> MEDIUM SHADE + '\u2500' # 0x0085 -> FORMS LIGHT HORIZONTAL + '\u2502' # 0x0086 -> FORMS LIGHT VERTICAL + '\u253c' # 0x0087 -> FORMS LIGHT VERTICAL AND HORIZONTAL + '\u2524' # 0x0088 -> FORMS LIGHT VERTICAL AND LEFT + '\u252c' # 0x0089 -> FORMS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x008a -> FORMS LIGHT VERTICAL AND RIGHT + '\u2534' # 0x008b -> FORMS LIGHT UP AND HORIZONTAL + '\u2510' # 0x008c -> FORMS LIGHT DOWN AND LEFT + '\u250c' # 0x008d -> FORMS LIGHT DOWN AND RIGHT + '\u2514' # 0x008e -> FORMS LIGHT UP AND RIGHT + '\u2518' # 0x008f -> FORMS LIGHT UP AND LEFT + '\u03b2' # 0x0090 -> GREEK SMALL BETA + '\u221e' # 0x0091 -> INFINITY + '\u03c6' # 0x0092 -> GREEK SMALL PHI + '\xb1' # 0x0093 -> PLUS-OR-MINUS SIGN + '\xbd' # 0x0094 -> FRACTION 1/2 + '\xbc' # 0x0095 -> FRACTION 1/4 + '\u2248' # 0x0096 -> ALMOST EQUAL TO + '\xab' # 0x0097 -> LEFT POINTING GUILLEMET + '\xbb' # 0x0098 -> RIGHT POINTING GUILLEMET + '\ufef7' # 0x0099 -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + '\ufef8' # 0x009a -> ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + '\ufffe' # 0x009b -> UNDEFINED + '\ufffe' # 0x009c -> UNDEFINED + '\ufefb' # 0x009d -> ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + '\ufefc' # 0x009e -> ARABIC LIGATURE LAM WITH ALEF FINAL FORM + '\ufffe' # 0x009f -> UNDEFINED + '\xa0' # 0x00a0 -> NON-BREAKING SPACE + '\xad' # 0x00a1 -> SOFT HYPHEN + '\ufe82' # 0x00a2 -> ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + '\xa3' # 0x00a3 -> POUND SIGN + '\xa4' # 0x00a4 -> CURRENCY SIGN + '\ufe84' # 0x00a5 -> ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + '\ufffe' # 0x00a6 -> UNDEFINED + '\ufffe' # 0x00a7 -> UNDEFINED + '\ufe8e' # 0x00a8 -> ARABIC LETTER ALEF FINAL FORM + '\ufe8f' # 0x00a9 -> ARABIC LETTER BEH ISOLATED FORM + '\ufe95' # 0x00aa -> ARABIC LETTER TEH ISOLATED FORM + '\ufe99' # 0x00ab -> ARABIC LETTER THEH ISOLATED FORM + '\u060c' # 0x00ac -> ARABIC COMMA + '\ufe9d' # 0x00ad -> ARABIC LETTER JEEM ISOLATED FORM + '\ufea1' # 0x00ae -> ARABIC LETTER HAH ISOLATED FORM + '\ufea5' # 0x00af -> ARABIC LETTER KHAH ISOLATED FORM + '\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO + '\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE + '\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO + '\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE + '\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR + '\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE + '\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX + '\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN + '\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT + '\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE + '\ufed1' # 0x00ba -> ARABIC LETTER FEH ISOLATED FORM + '\u061b' # 0x00bb -> ARABIC SEMICOLON + '\ufeb1' # 0x00bc -> ARABIC LETTER SEEN ISOLATED FORM + '\ufeb5' # 0x00bd -> ARABIC LETTER SHEEN ISOLATED FORM + '\ufeb9' # 0x00be -> ARABIC LETTER SAD ISOLATED FORM + '\u061f' # 0x00bf -> ARABIC QUESTION MARK + '\xa2' # 0x00c0 -> CENT SIGN + '\ufe80' # 0x00c1 -> ARABIC LETTER HAMZA ISOLATED FORM + '\ufe81' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + '\ufe83' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + '\ufe85' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + '\ufeca' # 0x00c5 -> ARABIC LETTER AIN FINAL FORM + '\ufe8b' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + '\ufe8d' # 0x00c7 -> ARABIC LETTER ALEF ISOLATED FORM + '\ufe91' # 0x00c8 -> ARABIC LETTER BEH INITIAL FORM + '\ufe93' # 0x00c9 -> ARABIC LETTER TEH MARBUTA ISOLATED FORM + '\ufe97' # 0x00ca -> ARABIC LETTER TEH INITIAL FORM + '\ufe9b' # 0x00cb -> ARABIC LETTER THEH INITIAL FORM + '\ufe9f' # 0x00cc -> ARABIC LETTER JEEM INITIAL FORM + '\ufea3' # 0x00cd -> ARABIC LETTER HAH INITIAL FORM + '\ufea7' # 0x00ce -> ARABIC LETTER KHAH INITIAL FORM + '\ufea9' # 0x00cf -> ARABIC LETTER DAL ISOLATED FORM + '\ufeab' # 0x00d0 -> ARABIC LETTER THAL ISOLATED FORM + '\ufead' # 0x00d1 -> ARABIC LETTER REH ISOLATED FORM + '\ufeaf' # 0x00d2 -> ARABIC LETTER ZAIN ISOLATED FORM + '\ufeb3' # 0x00d3 -> ARABIC LETTER SEEN INITIAL FORM + '\ufeb7' # 0x00d4 -> ARABIC LETTER SHEEN INITIAL FORM + '\ufebb' # 0x00d5 -> ARABIC LETTER SAD INITIAL FORM + '\ufebf' # 0x00d6 -> ARABIC LETTER DAD INITIAL FORM + '\ufec1' # 0x00d7 -> ARABIC LETTER TAH ISOLATED FORM + '\ufec5' # 0x00d8 -> ARABIC LETTER ZAH ISOLATED FORM + '\ufecb' # 0x00d9 -> ARABIC LETTER AIN INITIAL FORM + '\ufecf' # 0x00da -> ARABIC LETTER GHAIN INITIAL FORM + '\xa6' # 0x00db -> BROKEN VERTICAL BAR + '\xac' # 0x00dc -> NOT SIGN + '\xf7' # 0x00dd -> DIVISION SIGN + '\xd7' # 0x00de -> MULTIPLICATION SIGN + '\ufec9' # 0x00df -> ARABIC LETTER AIN ISOLATED FORM + '\u0640' # 0x00e0 -> ARABIC TATWEEL + '\ufed3' # 0x00e1 -> ARABIC LETTER FEH INITIAL FORM + '\ufed7' # 0x00e2 -> ARABIC LETTER QAF INITIAL FORM + '\ufedb' # 0x00e3 -> ARABIC LETTER KAF INITIAL FORM + '\ufedf' # 0x00e4 -> ARABIC LETTER LAM INITIAL FORM + '\ufee3' # 0x00e5 -> ARABIC LETTER MEEM INITIAL FORM + '\ufee7' # 0x00e6 -> ARABIC LETTER NOON INITIAL FORM + '\ufeeb' # 0x00e7 -> ARABIC LETTER HEH INITIAL FORM + '\ufeed' # 0x00e8 -> ARABIC LETTER WAW ISOLATED FORM + '\ufeef' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA ISOLATED FORM + '\ufef3' # 0x00ea -> ARABIC LETTER YEH INITIAL FORM + '\ufebd' # 0x00eb -> ARABIC LETTER DAD ISOLATED FORM + '\ufecc' # 0x00ec -> ARABIC LETTER AIN MEDIAL FORM + '\ufece' # 0x00ed -> ARABIC LETTER GHAIN FINAL FORM + '\ufecd' # 0x00ee -> ARABIC LETTER GHAIN ISOLATED FORM + '\ufee1' # 0x00ef -> ARABIC LETTER MEEM ISOLATED FORM + '\ufe7d' # 0x00f0 -> ARABIC SHADDA MEDIAL FORM + '\u0651' # 0x00f1 -> ARABIC SHADDAH + '\ufee5' # 0x00f2 -> ARABIC LETTER NOON ISOLATED FORM + '\ufee9' # 0x00f3 -> ARABIC LETTER HEH ISOLATED FORM + '\ufeec' # 0x00f4 -> ARABIC LETTER HEH MEDIAL FORM + '\ufef0' # 0x00f5 -> ARABIC LETTER ALEF MAKSURA FINAL FORM + '\ufef2' # 0x00f6 -> ARABIC LETTER YEH FINAL FORM + '\ufed0' # 0x00f7 -> ARABIC LETTER GHAIN MEDIAL FORM + '\ufed5' # 0x00f8 -> ARABIC LETTER QAF ISOLATED FORM + '\ufef5' # 0x00f9 -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + '\ufef6' # 0x00fa -> ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + '\ufedd' # 0x00fb -> ARABIC LETTER LAM ISOLATED FORM + '\ufed9' # 0x00fc -> ARABIC LETTER KAF ISOLATED FORM + '\ufef1' # 0x00fd -> ARABIC LETTER YEH ISOLATED FORM + '\u25a0' # 0x00fe -> BLACK SQUARE + '\ufffe' # 0x00ff -> UNDEFINED +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00a0, # NON-BREAKING SPACE + 0x00a2: 0x00c0, # CENT SIGN + 0x00a3: 0x00a3, # POUND SIGN + 0x00a4: 0x00a4, # CURRENCY SIGN + 0x00a6: 0x00db, # BROKEN VERTICAL BAR + 0x00ab: 0x0097, # LEFT POINTING GUILLEMET + 0x00ac: 0x00dc, # NOT SIGN + 0x00ad: 0x00a1, # SOFT HYPHEN + 0x00b0: 0x0080, # DEGREE SIGN + 0x00b1: 0x0093, # PLUS-OR-MINUS SIGN + 0x00b7: 0x0081, # MIDDLE DOT + 0x00bb: 0x0098, # RIGHT POINTING GUILLEMET + 0x00bc: 0x0095, # FRACTION 1/4 + 0x00bd: 0x0094, # FRACTION 1/2 + 0x00d7: 0x00de, # MULTIPLICATION SIGN + 0x00f7: 0x00dd, # DIVISION SIGN + 0x03b2: 0x0090, # GREEK SMALL BETA + 0x03c6: 0x0092, # GREEK SMALL PHI + 0x060c: 0x00ac, # ARABIC COMMA + 0x061b: 0x00bb, # ARABIC SEMICOLON + 0x061f: 0x00bf, # ARABIC QUESTION MARK + 0x0640: 0x00e0, # ARABIC TATWEEL + 0x0651: 0x00f1, # ARABIC SHADDAH + 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO + 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE + 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO + 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE + 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR + 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE + 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX + 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN + 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT + 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE + 0x066a: 0x0025, # ARABIC PERCENT SIGN + 0x2219: 0x0082, # BULLET OPERATOR + 0x221a: 0x0083, # SQUARE ROOT + 0x221e: 0x0091, # INFINITY + 0x2248: 0x0096, # ALMOST EQUAL TO + 0x2500: 0x0085, # FORMS LIGHT HORIZONTAL + 0x2502: 0x0086, # FORMS LIGHT VERTICAL + 0x250c: 0x008d, # FORMS LIGHT DOWN AND RIGHT + 0x2510: 0x008c, # FORMS LIGHT DOWN AND LEFT + 0x2514: 0x008e, # FORMS LIGHT UP AND RIGHT + 0x2518: 0x008f, # FORMS LIGHT UP AND LEFT + 0x251c: 0x008a, # FORMS LIGHT VERTICAL AND RIGHT + 0x2524: 0x0088, # FORMS LIGHT VERTICAL AND LEFT + 0x252c: 0x0089, # FORMS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x008b, # FORMS LIGHT UP AND HORIZONTAL + 0x253c: 0x0087, # FORMS LIGHT VERTICAL AND HORIZONTAL + 0x2592: 0x0084, # MEDIUM SHADE + 0x25a0: 0x00fe, # BLACK SQUARE + 0xfe7d: 0x00f0, # ARABIC SHADDA MEDIAL FORM + 0xfe80: 0x00c1, # ARABIC LETTER HAMZA ISOLATED FORM + 0xfe81: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + 0xfe82: 0x00a2, # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + 0xfe83: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + 0xfe84: 0x00a5, # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + 0xfe85: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + 0xfe8b: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + 0xfe8d: 0x00c7, # ARABIC LETTER ALEF ISOLATED FORM + 0xfe8e: 0x00a8, # ARABIC LETTER ALEF FINAL FORM + 0xfe8f: 0x00a9, # ARABIC LETTER BEH ISOLATED FORM + 0xfe91: 0x00c8, # ARABIC LETTER BEH INITIAL FORM + 0xfe93: 0x00c9, # ARABIC LETTER TEH MARBUTA ISOLATED FORM + 0xfe95: 0x00aa, # ARABIC LETTER TEH ISOLATED FORM + 0xfe97: 0x00ca, # ARABIC LETTER TEH INITIAL FORM + 0xfe99: 0x00ab, # ARABIC LETTER THEH ISOLATED FORM + 0xfe9b: 0x00cb, # ARABIC LETTER THEH INITIAL FORM + 0xfe9d: 0x00ad, # ARABIC LETTER JEEM ISOLATED FORM + 0xfe9f: 0x00cc, # ARABIC LETTER JEEM INITIAL FORM + 0xfea1: 0x00ae, # ARABIC LETTER HAH ISOLATED FORM + 0xfea3: 0x00cd, # ARABIC LETTER HAH INITIAL FORM + 0xfea5: 0x00af, # ARABIC LETTER KHAH ISOLATED FORM + 0xfea7: 0x00ce, # ARABIC LETTER KHAH INITIAL FORM + 0xfea9: 0x00cf, # ARABIC LETTER DAL ISOLATED FORM + 0xfeab: 0x00d0, # ARABIC LETTER THAL ISOLATED FORM + 0xfead: 0x00d1, # ARABIC LETTER REH ISOLATED FORM + 0xfeaf: 0x00d2, # ARABIC LETTER ZAIN ISOLATED FORM + 0xfeb1: 0x00bc, # ARABIC LETTER SEEN ISOLATED FORM + 0xfeb3: 0x00d3, # ARABIC LETTER SEEN INITIAL FORM + 0xfeb5: 0x00bd, # ARABIC LETTER SHEEN ISOLATED FORM + 0xfeb7: 0x00d4, # ARABIC LETTER SHEEN INITIAL FORM + 0xfeb9: 0x00be, # ARABIC LETTER SAD ISOLATED FORM + 0xfebb: 0x00d5, # ARABIC LETTER SAD INITIAL FORM + 0xfebd: 0x00eb, # ARABIC LETTER DAD ISOLATED FORM + 0xfebf: 0x00d6, # ARABIC LETTER DAD INITIAL FORM + 0xfec1: 0x00d7, # ARABIC LETTER TAH ISOLATED FORM + 0xfec5: 0x00d8, # ARABIC LETTER ZAH ISOLATED FORM + 0xfec9: 0x00df, # ARABIC LETTER AIN ISOLATED FORM + 0xfeca: 0x00c5, # ARABIC LETTER AIN FINAL FORM + 0xfecb: 0x00d9, # ARABIC LETTER AIN INITIAL FORM + 0xfecc: 0x00ec, # ARABIC LETTER AIN MEDIAL FORM + 0xfecd: 0x00ee, # ARABIC LETTER GHAIN ISOLATED FORM + 0xfece: 0x00ed, # ARABIC LETTER GHAIN FINAL FORM + 0xfecf: 0x00da, # ARABIC LETTER GHAIN INITIAL FORM + 0xfed0: 0x00f7, # ARABIC LETTER GHAIN MEDIAL FORM + 0xfed1: 0x00ba, # ARABIC LETTER FEH ISOLATED FORM + 0xfed3: 0x00e1, # ARABIC LETTER FEH INITIAL FORM + 0xfed5: 0x00f8, # ARABIC LETTER QAF ISOLATED FORM + 0xfed7: 0x00e2, # ARABIC LETTER QAF INITIAL FORM + 0xfed9: 0x00fc, # ARABIC LETTER KAF ISOLATED FORM + 0xfedb: 0x00e3, # ARABIC LETTER KAF INITIAL FORM + 0xfedd: 0x00fb, # ARABIC LETTER LAM ISOLATED FORM + 0xfedf: 0x00e4, # ARABIC LETTER LAM INITIAL FORM + 0xfee1: 0x00ef, # ARABIC LETTER MEEM ISOLATED FORM + 0xfee3: 0x00e5, # ARABIC LETTER MEEM INITIAL FORM + 0xfee5: 0x00f2, # ARABIC LETTER NOON ISOLATED FORM + 0xfee7: 0x00e6, # ARABIC LETTER NOON INITIAL FORM + 0xfee9: 0x00f3, # ARABIC LETTER HEH ISOLATED FORM + 0xfeeb: 0x00e7, # ARABIC LETTER HEH INITIAL FORM + 0xfeec: 0x00f4, # ARABIC LETTER HEH MEDIAL FORM + 0xfeed: 0x00e8, # ARABIC LETTER WAW ISOLATED FORM + 0xfeef: 0x00e9, # ARABIC LETTER ALEF MAKSURA ISOLATED FORM + 0xfef0: 0x00f5, # ARABIC LETTER ALEF MAKSURA FINAL FORM + 0xfef1: 0x00fd, # ARABIC LETTER YEH ISOLATED FORM + 0xfef2: 0x00f6, # ARABIC LETTER YEH FINAL FORM + 0xfef3: 0x00ea, # ARABIC LETTER YEH INITIAL FORM + 0xfef5: 0x00f9, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + 0xfef6: 0x00fa, # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + 0xfef7: 0x0099, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + 0xfef8: 0x009a, # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + 0xfefb: 0x009d, # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + 0xfefc: 0x009e, # ARABIC LIGATURE LAM WITH ALEF FINAL FORM +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp865.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp865.py new file mode 100644 index 0000000..6726cf3 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp865.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP865.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp865', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x0082: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x0083: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x0084: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x0085: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0086: 0x00e5, # LATIN SMALL LETTER A WITH RING ABOVE + 0x0087: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x0088: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0089: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x008a: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x008b: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x008c: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x008d: 0x00ec, # LATIN SMALL LETTER I WITH GRAVE + 0x008e: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x008f: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x0090: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0091: 0x00e6, # LATIN SMALL LIGATURE AE + 0x0092: 0x00c6, # LATIN CAPITAL LIGATURE AE + 0x0093: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x0094: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x0095: 0x00f2, # LATIN SMALL LETTER O WITH GRAVE + 0x0096: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x0097: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x0098: 0x00ff, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0099: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x009a: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x009b: 0x00f8, # LATIN SMALL LETTER O WITH STROKE + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x00d8, # LATIN CAPITAL LETTER O WITH STROKE + 0x009e: 0x20a7, # PESETA SIGN + 0x009f: 0x0192, # LATIN SMALL LETTER F WITH HOOK + 0x00a0: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x00a1: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x00a2: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x00a3: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x00a4: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x00a5: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x00a6: 0x00aa, # FEMININE ORDINAL INDICATOR + 0x00a7: 0x00ba, # MASCULINE ORDINAL INDICATOR + 0x00a8: 0x00bf, # INVERTED QUESTION MARK + 0x00a9: 0x2310, # REVERSED NOT SIGN + 0x00aa: 0x00ac, # NOT SIGN + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x00bc, # VULGAR FRACTION ONE QUARTER + 0x00ad: 0x00a1, # INVERTED EXCLAMATION MARK + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00a4, # CURRENCY SIGN + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00e1: 0x00df, # LATIN SMALL LETTER SHARP S + 0x00e2: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00e3: 0x03c0, # GREEK SMALL LETTER PI + 0x00e4: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00e5: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00e6: 0x00b5, # MICRO SIGN + 0x00e7: 0x03c4, # GREEK SMALL LETTER TAU + 0x00e8: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00e9: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ea: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00eb: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00ec: 0x221e, # INFINITY + 0x00ed: 0x03c6, # GREEK SMALL LETTER PHI + 0x00ee: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00ef: 0x2229, # INTERSECTION + 0x00f0: 0x2261, # IDENTICAL TO + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x2265, # GREATER-THAN OR EQUAL TO + 0x00f3: 0x2264, # LESS-THAN OR EQUAL TO + 0x00f4: 0x2320, # TOP HALF INTEGRAL + 0x00f5: 0x2321, # BOTTOM HALF INTEGRAL + 0x00f6: 0x00f7, # DIVISION SIGN + 0x00f7: 0x2248, # ALMOST EQUAL TO + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x207f, # SUPERSCRIPT LATIN SMALL LETTER N + 0x00fd: 0x00b2, # SUPERSCRIPT TWO + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\xc7' # 0x0080 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xfc' # 0x0081 -> LATIN SMALL LETTER U WITH DIAERESIS + '\xe9' # 0x0082 -> LATIN SMALL LETTER E WITH ACUTE + '\xe2' # 0x0083 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x0084 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe0' # 0x0085 -> LATIN SMALL LETTER A WITH GRAVE + '\xe5' # 0x0086 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x0087 -> LATIN SMALL LETTER C WITH CEDILLA + '\xea' # 0x0088 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0089 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xe8' # 0x008a -> LATIN SMALL LETTER E WITH GRAVE + '\xef' # 0x008b -> LATIN SMALL LETTER I WITH DIAERESIS + '\xee' # 0x008c -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xec' # 0x008d -> LATIN SMALL LETTER I WITH GRAVE + '\xc4' # 0x008e -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x008f -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc9' # 0x0090 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xe6' # 0x0091 -> LATIN SMALL LIGATURE AE + '\xc6' # 0x0092 -> LATIN CAPITAL LIGATURE AE + '\xf4' # 0x0093 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x0094 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf2' # 0x0095 -> LATIN SMALL LETTER O WITH GRAVE + '\xfb' # 0x0096 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xf9' # 0x0097 -> LATIN SMALL LETTER U WITH GRAVE + '\xff' # 0x0098 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xd6' # 0x0099 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x009a -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xf8' # 0x009b -> LATIN SMALL LETTER O WITH STROKE + '\xa3' # 0x009c -> POUND SIGN + '\xd8' # 0x009d -> LATIN CAPITAL LETTER O WITH STROKE + '\u20a7' # 0x009e -> PESETA SIGN + '\u0192' # 0x009f -> LATIN SMALL LETTER F WITH HOOK + '\xe1' # 0x00a0 -> LATIN SMALL LETTER A WITH ACUTE + '\xed' # 0x00a1 -> LATIN SMALL LETTER I WITH ACUTE + '\xf3' # 0x00a2 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0x00a3 -> LATIN SMALL LETTER U WITH ACUTE + '\xf1' # 0x00a4 -> LATIN SMALL LETTER N WITH TILDE + '\xd1' # 0x00a5 -> LATIN CAPITAL LETTER N WITH TILDE + '\xaa' # 0x00a6 -> FEMININE ORDINAL INDICATOR + '\xba' # 0x00a7 -> MASCULINE ORDINAL INDICATOR + '\xbf' # 0x00a8 -> INVERTED QUESTION MARK + '\u2310' # 0x00a9 -> REVERSED NOT SIGN + '\xac' # 0x00aa -> NOT SIGN + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\xbc' # 0x00ac -> VULGAR FRACTION ONE QUARTER + '\xa1' # 0x00ad -> INVERTED EXCLAMATION MARK + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xa4' # 0x00af -> CURRENCY SIGN + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b1' # 0x00e0 -> GREEK SMALL LETTER ALPHA + '\xdf' # 0x00e1 -> LATIN SMALL LETTER SHARP S + '\u0393' # 0x00e2 -> GREEK CAPITAL LETTER GAMMA + '\u03c0' # 0x00e3 -> GREEK SMALL LETTER PI + '\u03a3' # 0x00e4 -> GREEK CAPITAL LETTER SIGMA + '\u03c3' # 0x00e5 -> GREEK SMALL LETTER SIGMA + '\xb5' # 0x00e6 -> MICRO SIGN + '\u03c4' # 0x00e7 -> GREEK SMALL LETTER TAU + '\u03a6' # 0x00e8 -> GREEK CAPITAL LETTER PHI + '\u0398' # 0x00e9 -> GREEK CAPITAL LETTER THETA + '\u03a9' # 0x00ea -> GREEK CAPITAL LETTER OMEGA + '\u03b4' # 0x00eb -> GREEK SMALL LETTER DELTA + '\u221e' # 0x00ec -> INFINITY + '\u03c6' # 0x00ed -> GREEK SMALL LETTER PHI + '\u03b5' # 0x00ee -> GREEK SMALL LETTER EPSILON + '\u2229' # 0x00ef -> INTERSECTION + '\u2261' # 0x00f0 -> IDENTICAL TO + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u2265' # 0x00f2 -> GREATER-THAN OR EQUAL TO + '\u2264' # 0x00f3 -> LESS-THAN OR EQUAL TO + '\u2320' # 0x00f4 -> TOP HALF INTEGRAL + '\u2321' # 0x00f5 -> BOTTOM HALF INTEGRAL + '\xf7' # 0x00f6 -> DIVISION SIGN + '\u2248' # 0x00f7 -> ALMOST EQUAL TO + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u207f' # 0x00fc -> SUPERSCRIPT LATIN SMALL LETTER N + '\xb2' # 0x00fd -> SUPERSCRIPT TWO + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a1: 0x00ad, # INVERTED EXCLAMATION MARK + 0x00a3: 0x009c, # POUND SIGN + 0x00a4: 0x00af, # CURRENCY SIGN + 0x00aa: 0x00a6, # FEMININE ORDINAL INDICATOR + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x00aa, # NOT SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x00fd, # SUPERSCRIPT TWO + 0x00b5: 0x00e6, # MICRO SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x00ba: 0x00a7, # MASCULINE ORDINAL INDICATOR + 0x00bc: 0x00ac, # VULGAR FRACTION ONE QUARTER + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x00bf: 0x00a8, # INVERTED QUESTION MARK + 0x00c4: 0x008e, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c5: 0x008f, # LATIN CAPITAL LETTER A WITH RING ABOVE + 0x00c6: 0x0092, # LATIN CAPITAL LIGATURE AE + 0x00c7: 0x0080, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0090, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x00a5, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0099, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00d8: 0x009d, # LATIN CAPITAL LETTER O WITH STROKE + 0x00dc: 0x009a, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00df: 0x00e1, # LATIN SMALL LETTER SHARP S + 0x00e0: 0x0085, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x00a0, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0083, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x0084, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e5: 0x0086, # LATIN SMALL LETTER A WITH RING ABOVE + 0x00e6: 0x0091, # LATIN SMALL LIGATURE AE + 0x00e7: 0x0087, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008a, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x0082, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0088, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0089, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ec: 0x008d, # LATIN SMALL LETTER I WITH GRAVE + 0x00ed: 0x00a1, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x008c, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x008b, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x00a4, # LATIN SMALL LETTER N WITH TILDE + 0x00f2: 0x0095, # LATIN SMALL LETTER O WITH GRAVE + 0x00f3: 0x00a2, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0093, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x0094, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x00f6, # DIVISION SIGN + 0x00f8: 0x009b, # LATIN SMALL LETTER O WITH STROKE + 0x00f9: 0x0097, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x00a3, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x0096, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x0081, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00ff: 0x0098, # LATIN SMALL LETTER Y WITH DIAERESIS + 0x0192: 0x009f, # LATIN SMALL LETTER F WITH HOOK + 0x0393: 0x00e2, # GREEK CAPITAL LETTER GAMMA + 0x0398: 0x00e9, # GREEK CAPITAL LETTER THETA + 0x03a3: 0x00e4, # GREEK CAPITAL LETTER SIGMA + 0x03a6: 0x00e8, # GREEK CAPITAL LETTER PHI + 0x03a9: 0x00ea, # GREEK CAPITAL LETTER OMEGA + 0x03b1: 0x00e0, # GREEK SMALL LETTER ALPHA + 0x03b4: 0x00eb, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00ee, # GREEK SMALL LETTER EPSILON + 0x03c0: 0x00e3, # GREEK SMALL LETTER PI + 0x03c3: 0x00e5, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00e7, # GREEK SMALL LETTER TAU + 0x03c6: 0x00ed, # GREEK SMALL LETTER PHI + 0x207f: 0x00fc, # SUPERSCRIPT LATIN SMALL LETTER N + 0x20a7: 0x009e, # PESETA SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x221e: 0x00ec, # INFINITY + 0x2229: 0x00ef, # INTERSECTION + 0x2248: 0x00f7, # ALMOST EQUAL TO + 0x2261: 0x00f0, # IDENTICAL TO + 0x2264: 0x00f3, # LESS-THAN OR EQUAL TO + 0x2265: 0x00f2, # GREATER-THAN OR EQUAL TO + 0x2310: 0x00a9, # REVERSED NOT SIGN + 0x2320: 0x00f4, # TOP HALF INTEGRAL + 0x2321: 0x00f5, # BOTTOM HALF INTEGRAL + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp866.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp866.py new file mode 100644 index 0000000..bec7ae3 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp866.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP866.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp866', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A + 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE + 0x0082: 0x0412, # CYRILLIC CAPITAL LETTER VE + 0x0083: 0x0413, # CYRILLIC CAPITAL LETTER GHE + 0x0084: 0x0414, # CYRILLIC CAPITAL LETTER DE + 0x0085: 0x0415, # CYRILLIC CAPITAL LETTER IE + 0x0086: 0x0416, # CYRILLIC CAPITAL LETTER ZHE + 0x0087: 0x0417, # CYRILLIC CAPITAL LETTER ZE + 0x0088: 0x0418, # CYRILLIC CAPITAL LETTER I + 0x0089: 0x0419, # CYRILLIC CAPITAL LETTER SHORT I + 0x008a: 0x041a, # CYRILLIC CAPITAL LETTER KA + 0x008b: 0x041b, # CYRILLIC CAPITAL LETTER EL + 0x008c: 0x041c, # CYRILLIC CAPITAL LETTER EM + 0x008d: 0x041d, # CYRILLIC CAPITAL LETTER EN + 0x008e: 0x041e, # CYRILLIC CAPITAL LETTER O + 0x008f: 0x041f, # CYRILLIC CAPITAL LETTER PE + 0x0090: 0x0420, # CYRILLIC CAPITAL LETTER ER + 0x0091: 0x0421, # CYRILLIC CAPITAL LETTER ES + 0x0092: 0x0422, # CYRILLIC CAPITAL LETTER TE + 0x0093: 0x0423, # CYRILLIC CAPITAL LETTER U + 0x0094: 0x0424, # CYRILLIC CAPITAL LETTER EF + 0x0095: 0x0425, # CYRILLIC CAPITAL LETTER HA + 0x0096: 0x0426, # CYRILLIC CAPITAL LETTER TSE + 0x0097: 0x0427, # CYRILLIC CAPITAL LETTER CHE + 0x0098: 0x0428, # CYRILLIC CAPITAL LETTER SHA + 0x0099: 0x0429, # CYRILLIC CAPITAL LETTER SHCHA + 0x009a: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x009b: 0x042b, # CYRILLIC CAPITAL LETTER YERU + 0x009c: 0x042c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x009d: 0x042d, # CYRILLIC CAPITAL LETTER E + 0x009e: 0x042e, # CYRILLIC CAPITAL LETTER YU + 0x009f: 0x042f, # CYRILLIC CAPITAL LETTER YA + 0x00a0: 0x0430, # CYRILLIC SMALL LETTER A + 0x00a1: 0x0431, # CYRILLIC SMALL LETTER BE + 0x00a2: 0x0432, # CYRILLIC SMALL LETTER VE + 0x00a3: 0x0433, # CYRILLIC SMALL LETTER GHE + 0x00a4: 0x0434, # CYRILLIC SMALL LETTER DE + 0x00a5: 0x0435, # CYRILLIC SMALL LETTER IE + 0x00a6: 0x0436, # CYRILLIC SMALL LETTER ZHE + 0x00a7: 0x0437, # CYRILLIC SMALL LETTER ZE + 0x00a8: 0x0438, # CYRILLIC SMALL LETTER I + 0x00a9: 0x0439, # CYRILLIC SMALL LETTER SHORT I + 0x00aa: 0x043a, # CYRILLIC SMALL LETTER KA + 0x00ab: 0x043b, # CYRILLIC SMALL LETTER EL + 0x00ac: 0x043c, # CYRILLIC SMALL LETTER EM + 0x00ad: 0x043d, # CYRILLIC SMALL LETTER EN + 0x00ae: 0x043e, # CYRILLIC SMALL LETTER O + 0x00af: 0x043f, # CYRILLIC SMALL LETTER PE + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x2561, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x00b6: 0x2562, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x00b7: 0x2556, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x00b8: 0x2555, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x255c, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x00be: 0x255b, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x255e, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x00c7: 0x255f, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x2567, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x00d0: 0x2568, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x00d1: 0x2564, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x00d2: 0x2565, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x00d3: 0x2559, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x00d4: 0x2558, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x00d5: 0x2552, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x00d6: 0x2553, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x00d7: 0x256b, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x00d8: 0x256a, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x258c, # LEFT HALF BLOCK + 0x00de: 0x2590, # RIGHT HALF BLOCK + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x0440, # CYRILLIC SMALL LETTER ER + 0x00e1: 0x0441, # CYRILLIC SMALL LETTER ES + 0x00e2: 0x0442, # CYRILLIC SMALL LETTER TE + 0x00e3: 0x0443, # CYRILLIC SMALL LETTER U + 0x00e4: 0x0444, # CYRILLIC SMALL LETTER EF + 0x00e5: 0x0445, # CYRILLIC SMALL LETTER HA + 0x00e6: 0x0446, # CYRILLIC SMALL LETTER TSE + 0x00e7: 0x0447, # CYRILLIC SMALL LETTER CHE + 0x00e8: 0x0448, # CYRILLIC SMALL LETTER SHA + 0x00e9: 0x0449, # CYRILLIC SMALL LETTER SHCHA + 0x00ea: 0x044a, # CYRILLIC SMALL LETTER HARD SIGN + 0x00eb: 0x044b, # CYRILLIC SMALL LETTER YERU + 0x00ec: 0x044c, # CYRILLIC SMALL LETTER SOFT SIGN + 0x00ed: 0x044d, # CYRILLIC SMALL LETTER E + 0x00ee: 0x044e, # CYRILLIC SMALL LETTER YU + 0x00ef: 0x044f, # CYRILLIC SMALL LETTER YA + 0x00f0: 0x0401, # CYRILLIC CAPITAL LETTER IO + 0x00f1: 0x0451, # CYRILLIC SMALL LETTER IO + 0x00f2: 0x0404, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x00f3: 0x0454, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x00f4: 0x0407, # CYRILLIC CAPITAL LETTER YI + 0x00f5: 0x0457, # CYRILLIC SMALL LETTER YI + 0x00f6: 0x040e, # CYRILLIC CAPITAL LETTER SHORT U + 0x00f7: 0x045e, # CYRILLIC SMALL LETTER SHORT U + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x2219, # BULLET OPERATOR + 0x00fa: 0x00b7, # MIDDLE DOT + 0x00fb: 0x221a, # SQUARE ROOT + 0x00fc: 0x2116, # NUMERO SIGN + 0x00fd: 0x00a4, # CURRENCY SIGN + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\u0410' # 0x0080 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0x0081 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0x0082 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0x0083 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0x0084 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0x0085 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0x0086 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0x0087 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0x0088 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0x0089 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0x008a -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0x008b -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0x008c -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0x008d -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0x008e -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0x008f -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0x0090 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0x0091 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0x0092 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0x0093 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0x0094 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0x0095 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0x0096 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0x0097 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0x0098 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0x0099 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0x009a -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0x009b -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0x009c -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0x009d -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0x009e -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0x009f -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0x00a0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0x00a1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0x00a2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0x00a3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0x00a4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0x00a5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0x00a6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0x00a7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0x00a8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0x00a9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0x00aa -> CYRILLIC SMALL LETTER KA + '\u043b' # 0x00ab -> CYRILLIC SMALL LETTER EL + '\u043c' # 0x00ac -> CYRILLIC SMALL LETTER EM + '\u043d' # 0x00ad -> CYRILLIC SMALL LETTER EN + '\u043e' # 0x00ae -> CYRILLIC SMALL LETTER O + '\u043f' # 0x00af -> CYRILLIC SMALL LETTER PE + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u2561' # 0x00b5 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u2562' # 0x00b6 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2556' # 0x00b7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2555' # 0x00b8 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255c' # 0x00bd -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255b' # 0x00be -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u255e' # 0x00c6 -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0x00c7 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u2567' # 0x00cf -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0x00d0 -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2564' # 0x00d1 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0x00d2 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2559' # 0x00d3 -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u2558' # 0x00d4 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2552' # 0x00d5 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u2553' # 0x00d6 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u256b' # 0x00d7 -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256a' # 0x00d8 -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u258c' # 0x00dd -> LEFT HALF BLOCK + '\u2590' # 0x00de -> RIGHT HALF BLOCK + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u0440' # 0x00e0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0x00e1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0x00e2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0x00e3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0x00e4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0x00e5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0x00e6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0x00e7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0x00e8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0x00e9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0x00ea -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0x00eb -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0x00ec -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0x00ed -> CYRILLIC SMALL LETTER E + '\u044e' # 0x00ee -> CYRILLIC SMALL LETTER YU + '\u044f' # 0x00ef -> CYRILLIC SMALL LETTER YA + '\u0401' # 0x00f0 -> CYRILLIC CAPITAL LETTER IO + '\u0451' # 0x00f1 -> CYRILLIC SMALL LETTER IO + '\u0404' # 0x00f2 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0454' # 0x00f3 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0407' # 0x00f4 -> CYRILLIC CAPITAL LETTER YI + '\u0457' # 0x00f5 -> CYRILLIC SMALL LETTER YI + '\u040e' # 0x00f6 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045e' # 0x00f7 -> CYRILLIC SMALL LETTER SHORT U + '\xb0' # 0x00f8 -> DEGREE SIGN + '\u2219' # 0x00f9 -> BULLET OPERATOR + '\xb7' # 0x00fa -> MIDDLE DOT + '\u221a' # 0x00fb -> SQUARE ROOT + '\u2116' # 0x00fc -> NUMERO SIGN + '\xa4' # 0x00fd -> CURRENCY SIGN + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a4: 0x00fd, # CURRENCY SIGN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b7: 0x00fa, # MIDDLE DOT + 0x0401: 0x00f0, # CYRILLIC CAPITAL LETTER IO + 0x0404: 0x00f2, # CYRILLIC CAPITAL LETTER UKRAINIAN IE + 0x0407: 0x00f4, # CYRILLIC CAPITAL LETTER YI + 0x040e: 0x00f6, # CYRILLIC CAPITAL LETTER SHORT U + 0x0410: 0x0080, # CYRILLIC CAPITAL LETTER A + 0x0411: 0x0081, # CYRILLIC CAPITAL LETTER BE + 0x0412: 0x0082, # CYRILLIC CAPITAL LETTER VE + 0x0413: 0x0083, # CYRILLIC CAPITAL LETTER GHE + 0x0414: 0x0084, # CYRILLIC CAPITAL LETTER DE + 0x0415: 0x0085, # CYRILLIC CAPITAL LETTER IE + 0x0416: 0x0086, # CYRILLIC CAPITAL LETTER ZHE + 0x0417: 0x0087, # CYRILLIC CAPITAL LETTER ZE + 0x0418: 0x0088, # CYRILLIC CAPITAL LETTER I + 0x0419: 0x0089, # CYRILLIC CAPITAL LETTER SHORT I + 0x041a: 0x008a, # CYRILLIC CAPITAL LETTER KA + 0x041b: 0x008b, # CYRILLIC CAPITAL LETTER EL + 0x041c: 0x008c, # CYRILLIC CAPITAL LETTER EM + 0x041d: 0x008d, # CYRILLIC CAPITAL LETTER EN + 0x041e: 0x008e, # CYRILLIC CAPITAL LETTER O + 0x041f: 0x008f, # CYRILLIC CAPITAL LETTER PE + 0x0420: 0x0090, # CYRILLIC CAPITAL LETTER ER + 0x0421: 0x0091, # CYRILLIC CAPITAL LETTER ES + 0x0422: 0x0092, # CYRILLIC CAPITAL LETTER TE + 0x0423: 0x0093, # CYRILLIC CAPITAL LETTER U + 0x0424: 0x0094, # CYRILLIC CAPITAL LETTER EF + 0x0425: 0x0095, # CYRILLIC CAPITAL LETTER HA + 0x0426: 0x0096, # CYRILLIC CAPITAL LETTER TSE + 0x0427: 0x0097, # CYRILLIC CAPITAL LETTER CHE + 0x0428: 0x0098, # CYRILLIC CAPITAL LETTER SHA + 0x0429: 0x0099, # CYRILLIC CAPITAL LETTER SHCHA + 0x042a: 0x009a, # CYRILLIC CAPITAL LETTER HARD SIGN + 0x042b: 0x009b, # CYRILLIC CAPITAL LETTER YERU + 0x042c: 0x009c, # CYRILLIC CAPITAL LETTER SOFT SIGN + 0x042d: 0x009d, # CYRILLIC CAPITAL LETTER E + 0x042e: 0x009e, # CYRILLIC CAPITAL LETTER YU + 0x042f: 0x009f, # CYRILLIC CAPITAL LETTER YA + 0x0430: 0x00a0, # CYRILLIC SMALL LETTER A + 0x0431: 0x00a1, # CYRILLIC SMALL LETTER BE + 0x0432: 0x00a2, # CYRILLIC SMALL LETTER VE + 0x0433: 0x00a3, # CYRILLIC SMALL LETTER GHE + 0x0434: 0x00a4, # CYRILLIC SMALL LETTER DE + 0x0435: 0x00a5, # CYRILLIC SMALL LETTER IE + 0x0436: 0x00a6, # CYRILLIC SMALL LETTER ZHE + 0x0437: 0x00a7, # CYRILLIC SMALL LETTER ZE + 0x0438: 0x00a8, # CYRILLIC SMALL LETTER I + 0x0439: 0x00a9, # CYRILLIC SMALL LETTER SHORT I + 0x043a: 0x00aa, # CYRILLIC SMALL LETTER KA + 0x043b: 0x00ab, # CYRILLIC SMALL LETTER EL + 0x043c: 0x00ac, # CYRILLIC SMALL LETTER EM + 0x043d: 0x00ad, # CYRILLIC SMALL LETTER EN + 0x043e: 0x00ae, # CYRILLIC SMALL LETTER O + 0x043f: 0x00af, # CYRILLIC SMALL LETTER PE + 0x0440: 0x00e0, # CYRILLIC SMALL LETTER ER + 0x0441: 0x00e1, # CYRILLIC SMALL LETTER ES + 0x0442: 0x00e2, # CYRILLIC SMALL LETTER TE + 0x0443: 0x00e3, # CYRILLIC SMALL LETTER U + 0x0444: 0x00e4, # CYRILLIC SMALL LETTER EF + 0x0445: 0x00e5, # CYRILLIC SMALL LETTER HA + 0x0446: 0x00e6, # CYRILLIC SMALL LETTER TSE + 0x0447: 0x00e7, # CYRILLIC SMALL LETTER CHE + 0x0448: 0x00e8, # CYRILLIC SMALL LETTER SHA + 0x0449: 0x00e9, # CYRILLIC SMALL LETTER SHCHA + 0x044a: 0x00ea, # CYRILLIC SMALL LETTER HARD SIGN + 0x044b: 0x00eb, # CYRILLIC SMALL LETTER YERU + 0x044c: 0x00ec, # CYRILLIC SMALL LETTER SOFT SIGN + 0x044d: 0x00ed, # CYRILLIC SMALL LETTER E + 0x044e: 0x00ee, # CYRILLIC SMALL LETTER YU + 0x044f: 0x00ef, # CYRILLIC SMALL LETTER YA + 0x0451: 0x00f1, # CYRILLIC SMALL LETTER IO + 0x0454: 0x00f3, # CYRILLIC SMALL LETTER UKRAINIAN IE + 0x0457: 0x00f5, # CYRILLIC SMALL LETTER YI + 0x045e: 0x00f7, # CYRILLIC SMALL LETTER SHORT U + 0x2116: 0x00fc, # NUMERO SIGN + 0x2219: 0x00f9, # BULLET OPERATOR + 0x221a: 0x00fb, # SQUARE ROOT + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2552: 0x00d5, # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + 0x2553: 0x00d6, # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2555: 0x00b8, # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + 0x2556: 0x00b7, # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x2558: 0x00d4, # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + 0x2559: 0x00d3, # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255b: 0x00be, # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + 0x255c: 0x00bd, # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x255e: 0x00c6, # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + 0x255f: 0x00c7, # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2561: 0x00b5, # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + 0x2562: 0x00b6, # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2564: 0x00d1, # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + 0x2565: 0x00d2, # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2567: 0x00cf, # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + 0x2568: 0x00d0, # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256a: 0x00d8, # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + 0x256b: 0x00d7, # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x258c: 0x00dd, # LEFT HALF BLOCK + 0x2590: 0x00de, # RIGHT HALF BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp869.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp869.py new file mode 100644 index 0000000..8d8a29b --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp869.py @@ -0,0 +1,689 @@ +""" Python Character Mapping Codec generated from 'VENDORS/MICSFT/PC/CP869.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp869', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: None, # UNDEFINED + 0x0081: None, # UNDEFINED + 0x0082: None, # UNDEFINED + 0x0083: None, # UNDEFINED + 0x0084: None, # UNDEFINED + 0x0085: None, # UNDEFINED + 0x0086: 0x0386, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0087: None, # UNDEFINED + 0x0088: 0x00b7, # MIDDLE DOT + 0x0089: 0x00ac, # NOT SIGN + 0x008a: 0x00a6, # BROKEN BAR + 0x008b: 0x2018, # LEFT SINGLE QUOTATION MARK + 0x008c: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x008d: 0x0388, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x008e: 0x2015, # HORIZONTAL BAR + 0x008f: 0x0389, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x0090: 0x038a, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x0091: 0x03aa, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x0092: 0x038c, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x0093: None, # UNDEFINED + 0x0094: None, # UNDEFINED + 0x0095: 0x038e, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x0096: 0x03ab, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x0097: 0x00a9, # COPYRIGHT SIGN + 0x0098: 0x038f, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0099: 0x00b2, # SUPERSCRIPT TWO + 0x009a: 0x00b3, # SUPERSCRIPT THREE + 0x009b: 0x03ac, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x009c: 0x00a3, # POUND SIGN + 0x009d: 0x03ad, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x009e: 0x03ae, # GREEK SMALL LETTER ETA WITH TONOS + 0x009f: 0x03af, # GREEK SMALL LETTER IOTA WITH TONOS + 0x00a0: 0x03ca, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x00a1: 0x0390, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x00a2: 0x03cc, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x00a3: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x00a4: 0x0391, # GREEK CAPITAL LETTER ALPHA + 0x00a5: 0x0392, # GREEK CAPITAL LETTER BETA + 0x00a6: 0x0393, # GREEK CAPITAL LETTER GAMMA + 0x00a7: 0x0394, # GREEK CAPITAL LETTER DELTA + 0x00a8: 0x0395, # GREEK CAPITAL LETTER EPSILON + 0x00a9: 0x0396, # GREEK CAPITAL LETTER ZETA + 0x00aa: 0x0397, # GREEK CAPITAL LETTER ETA + 0x00ab: 0x00bd, # VULGAR FRACTION ONE HALF + 0x00ac: 0x0398, # GREEK CAPITAL LETTER THETA + 0x00ad: 0x0399, # GREEK CAPITAL LETTER IOTA + 0x00ae: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00af: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00b0: 0x2591, # LIGHT SHADE + 0x00b1: 0x2592, # MEDIUM SHADE + 0x00b2: 0x2593, # DARK SHADE + 0x00b3: 0x2502, # BOX DRAWINGS LIGHT VERTICAL + 0x00b4: 0x2524, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x00b5: 0x039a, # GREEK CAPITAL LETTER KAPPA + 0x00b6: 0x039b, # GREEK CAPITAL LETTER LAMDA + 0x00b7: 0x039c, # GREEK CAPITAL LETTER MU + 0x00b8: 0x039d, # GREEK CAPITAL LETTER NU + 0x00b9: 0x2563, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x00ba: 0x2551, # BOX DRAWINGS DOUBLE VERTICAL + 0x00bb: 0x2557, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x00bc: 0x255d, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x00bd: 0x039e, # GREEK CAPITAL LETTER XI + 0x00be: 0x039f, # GREEK CAPITAL LETTER OMICRON + 0x00bf: 0x2510, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x00c0: 0x2514, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x00c1: 0x2534, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x00c2: 0x252c, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x00c3: 0x251c, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x00c4: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL + 0x00c5: 0x253c, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x00c6: 0x03a0, # GREEK CAPITAL LETTER PI + 0x00c7: 0x03a1, # GREEK CAPITAL LETTER RHO + 0x00c8: 0x255a, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x00c9: 0x2554, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x00ca: 0x2569, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x00cb: 0x2566, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x00cc: 0x2560, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x00cd: 0x2550, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x00ce: 0x256c, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x00cf: 0x03a3, # GREEK CAPITAL LETTER SIGMA + 0x00d0: 0x03a4, # GREEK CAPITAL LETTER TAU + 0x00d1: 0x03a5, # GREEK CAPITAL LETTER UPSILON + 0x00d2: 0x03a6, # GREEK CAPITAL LETTER PHI + 0x00d3: 0x03a7, # GREEK CAPITAL LETTER CHI + 0x00d4: 0x03a8, # GREEK CAPITAL LETTER PSI + 0x00d5: 0x03a9, # GREEK CAPITAL LETTER OMEGA + 0x00d6: 0x03b1, # GREEK SMALL LETTER ALPHA + 0x00d7: 0x03b2, # GREEK SMALL LETTER BETA + 0x00d8: 0x03b3, # GREEK SMALL LETTER GAMMA + 0x00d9: 0x2518, # BOX DRAWINGS LIGHT UP AND LEFT + 0x00da: 0x250c, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x00db: 0x2588, # FULL BLOCK + 0x00dc: 0x2584, # LOWER HALF BLOCK + 0x00dd: 0x03b4, # GREEK SMALL LETTER DELTA + 0x00de: 0x03b5, # GREEK SMALL LETTER EPSILON + 0x00df: 0x2580, # UPPER HALF BLOCK + 0x00e0: 0x03b6, # GREEK SMALL LETTER ZETA + 0x00e1: 0x03b7, # GREEK SMALL LETTER ETA + 0x00e2: 0x03b8, # GREEK SMALL LETTER THETA + 0x00e3: 0x03b9, # GREEK SMALL LETTER IOTA + 0x00e4: 0x03ba, # GREEK SMALL LETTER KAPPA + 0x00e5: 0x03bb, # GREEK SMALL LETTER LAMDA + 0x00e6: 0x03bc, # GREEK SMALL LETTER MU + 0x00e7: 0x03bd, # GREEK SMALL LETTER NU + 0x00e8: 0x03be, # GREEK SMALL LETTER XI + 0x00e9: 0x03bf, # GREEK SMALL LETTER OMICRON + 0x00ea: 0x03c0, # GREEK SMALL LETTER PI + 0x00eb: 0x03c1, # GREEK SMALL LETTER RHO + 0x00ec: 0x03c3, # GREEK SMALL LETTER SIGMA + 0x00ed: 0x03c2, # GREEK SMALL LETTER FINAL SIGMA + 0x00ee: 0x03c4, # GREEK SMALL LETTER TAU + 0x00ef: 0x0384, # GREEK TONOS + 0x00f0: 0x00ad, # SOFT HYPHEN + 0x00f1: 0x00b1, # PLUS-MINUS SIGN + 0x00f2: 0x03c5, # GREEK SMALL LETTER UPSILON + 0x00f3: 0x03c6, # GREEK SMALL LETTER PHI + 0x00f4: 0x03c7, # GREEK SMALL LETTER CHI + 0x00f5: 0x00a7, # SECTION SIGN + 0x00f6: 0x03c8, # GREEK SMALL LETTER PSI + 0x00f7: 0x0385, # GREEK DIALYTIKA TONOS + 0x00f8: 0x00b0, # DEGREE SIGN + 0x00f9: 0x00a8, # DIAERESIS + 0x00fa: 0x03c9, # GREEK SMALL LETTER OMEGA + 0x00fb: 0x03cb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x00fc: 0x03b0, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x00fd: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x00fe: 0x25a0, # BLACK SQUARE + 0x00ff: 0x00a0, # NO-BREAK SPACE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> NULL + '\x01' # 0x0001 -> START OF HEADING + '\x02' # 0x0002 -> START OF TEXT + '\x03' # 0x0003 -> END OF TEXT + '\x04' # 0x0004 -> END OF TRANSMISSION + '\x05' # 0x0005 -> ENQUIRY + '\x06' # 0x0006 -> ACKNOWLEDGE + '\x07' # 0x0007 -> BELL + '\x08' # 0x0008 -> BACKSPACE + '\t' # 0x0009 -> HORIZONTAL TABULATION + '\n' # 0x000a -> LINE FEED + '\x0b' # 0x000b -> VERTICAL TABULATION + '\x0c' # 0x000c -> FORM FEED + '\r' # 0x000d -> CARRIAGE RETURN + '\x0e' # 0x000e -> SHIFT OUT + '\x0f' # 0x000f -> SHIFT IN + '\x10' # 0x0010 -> DATA LINK ESCAPE + '\x11' # 0x0011 -> DEVICE CONTROL ONE + '\x12' # 0x0012 -> DEVICE CONTROL TWO + '\x13' # 0x0013 -> DEVICE CONTROL THREE + '\x14' # 0x0014 -> DEVICE CONTROL FOUR + '\x15' # 0x0015 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x0016 -> SYNCHRONOUS IDLE + '\x17' # 0x0017 -> END OF TRANSMISSION BLOCK + '\x18' # 0x0018 -> CANCEL + '\x19' # 0x0019 -> END OF MEDIUM + '\x1a' # 0x001a -> SUBSTITUTE + '\x1b' # 0x001b -> ESCAPE + '\x1c' # 0x001c -> FILE SEPARATOR + '\x1d' # 0x001d -> GROUP SEPARATOR + '\x1e' # 0x001e -> RECORD SEPARATOR + '\x1f' # 0x001f -> UNIT SEPARATOR + ' ' # 0x0020 -> SPACE + '!' # 0x0021 -> EXCLAMATION MARK + '"' # 0x0022 -> QUOTATION MARK + '#' # 0x0023 -> NUMBER SIGN + '$' # 0x0024 -> DOLLAR SIGN + '%' # 0x0025 -> PERCENT SIGN + '&' # 0x0026 -> AMPERSAND + "'" # 0x0027 -> APOSTROPHE + '(' # 0x0028 -> LEFT PARENTHESIS + ')' # 0x0029 -> RIGHT PARENTHESIS + '*' # 0x002a -> ASTERISK + '+' # 0x002b -> PLUS SIGN + ',' # 0x002c -> COMMA + '-' # 0x002d -> HYPHEN-MINUS + '.' # 0x002e -> FULL STOP + '/' # 0x002f -> SOLIDUS + '0' # 0x0030 -> DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE + '2' # 0x0032 -> DIGIT TWO + '3' # 0x0033 -> DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE + ':' # 0x003a -> COLON + ';' # 0x003b -> SEMICOLON + '<' # 0x003c -> LESS-THAN SIGN + '=' # 0x003d -> EQUALS SIGN + '>' # 0x003e -> GREATER-THAN SIGN + '?' # 0x003f -> QUESTION MARK + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET + '\\' # 0x005c -> REVERSE SOLIDUS + ']' # 0x005d -> RIGHT SQUARE BRACKET + '^' # 0x005e -> CIRCUMFLEX ACCENT + '_' # 0x005f -> LOW LINE + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET + '|' # 0x007c -> VERTICAL LINE + '}' # 0x007d -> RIGHT CURLY BRACKET + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> DELETE + '\ufffe' # 0x0080 -> UNDEFINED + '\ufffe' # 0x0081 -> UNDEFINED + '\ufffe' # 0x0082 -> UNDEFINED + '\ufffe' # 0x0083 -> UNDEFINED + '\ufffe' # 0x0084 -> UNDEFINED + '\ufffe' # 0x0085 -> UNDEFINED + '\u0386' # 0x0086 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\ufffe' # 0x0087 -> UNDEFINED + '\xb7' # 0x0088 -> MIDDLE DOT + '\xac' # 0x0089 -> NOT SIGN + '\xa6' # 0x008a -> BROKEN BAR + '\u2018' # 0x008b -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x008c -> RIGHT SINGLE QUOTATION MARK + '\u0388' # 0x008d -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u2015' # 0x008e -> HORIZONTAL BAR + '\u0389' # 0x008f -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0x0090 -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\u03aa' # 0x0091 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u038c' # 0x0092 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\ufffe' # 0x0093 -> UNDEFINED + '\ufffe' # 0x0094 -> UNDEFINED + '\u038e' # 0x0095 -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u03ab' # 0x0096 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\xa9' # 0x0097 -> COPYRIGHT SIGN + '\u038f' # 0x0098 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\xb2' # 0x0099 -> SUPERSCRIPT TWO + '\xb3' # 0x009a -> SUPERSCRIPT THREE + '\u03ac' # 0x009b -> GREEK SMALL LETTER ALPHA WITH TONOS + '\xa3' # 0x009c -> POUND SIGN + '\u03ad' # 0x009d -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0x009e -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0x009f -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03ca' # 0x00a0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u0390' # 0x00a1 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u03cc' # 0x00a2 -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0x00a3 -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u0391' # 0x00a4 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0x00a5 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0x00a6 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0x00a7 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0x00a8 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0x00a9 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0x00aa -> GREEK CAPITAL LETTER ETA + '\xbd' # 0x00ab -> VULGAR FRACTION ONE HALF + '\u0398' # 0x00ac -> GREEK CAPITAL LETTER THETA + '\u0399' # 0x00ad -> GREEK CAPITAL LETTER IOTA + '\xab' # 0x00ae -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0x00af -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2591' # 0x00b0 -> LIGHT SHADE + '\u2592' # 0x00b1 -> MEDIUM SHADE + '\u2593' # 0x00b2 -> DARK SHADE + '\u2502' # 0x00b3 -> BOX DRAWINGS LIGHT VERTICAL + '\u2524' # 0x00b4 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u039a' # 0x00b5 -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0x00b6 -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0x00b7 -> GREEK CAPITAL LETTER MU + '\u039d' # 0x00b8 -> GREEK CAPITAL LETTER NU + '\u2563' # 0x00b9 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2551' # 0x00ba -> BOX DRAWINGS DOUBLE VERTICAL + '\u2557' # 0x00bb -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u255d' # 0x00bc -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u039e' # 0x00bd -> GREEK CAPITAL LETTER XI + '\u039f' # 0x00be -> GREEK CAPITAL LETTER OMICRON + '\u2510' # 0x00bf -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x00c0 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2534' # 0x00c1 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u252c' # 0x00c2 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u251c' # 0x00c3 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2500' # 0x00c4 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u253c' # 0x00c5 -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u03a0' # 0x00c6 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0x00c7 -> GREEK CAPITAL LETTER RHO + '\u255a' # 0x00c8 -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u2554' # 0x00c9 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2569' # 0x00ca -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u2566' # 0x00cb -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2560' # 0x00cc -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2550' # 0x00cd -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u256c' # 0x00ce -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\u03a3' # 0x00cf -> GREEK CAPITAL LETTER SIGMA + '\u03a4' # 0x00d0 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0x00d1 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0x00d2 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0x00d3 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0x00d4 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0x00d5 -> GREEK CAPITAL LETTER OMEGA + '\u03b1' # 0x00d6 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0x00d7 -> GREEK SMALL LETTER BETA + '\u03b3' # 0x00d8 -> GREEK SMALL LETTER GAMMA + '\u2518' # 0x00d9 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u250c' # 0x00da -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2588' # 0x00db -> FULL BLOCK + '\u2584' # 0x00dc -> LOWER HALF BLOCK + '\u03b4' # 0x00dd -> GREEK SMALL LETTER DELTA + '\u03b5' # 0x00de -> GREEK SMALL LETTER EPSILON + '\u2580' # 0x00df -> UPPER HALF BLOCK + '\u03b6' # 0x00e0 -> GREEK SMALL LETTER ZETA + '\u03b7' # 0x00e1 -> GREEK SMALL LETTER ETA + '\u03b8' # 0x00e2 -> GREEK SMALL LETTER THETA + '\u03b9' # 0x00e3 -> GREEK SMALL LETTER IOTA + '\u03ba' # 0x00e4 -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0x00e5 -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0x00e6 -> GREEK SMALL LETTER MU + '\u03bd' # 0x00e7 -> GREEK SMALL LETTER NU + '\u03be' # 0x00e8 -> GREEK SMALL LETTER XI + '\u03bf' # 0x00e9 -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0x00ea -> GREEK SMALL LETTER PI + '\u03c1' # 0x00eb -> GREEK SMALL LETTER RHO + '\u03c3' # 0x00ec -> GREEK SMALL LETTER SIGMA + '\u03c2' # 0x00ed -> GREEK SMALL LETTER FINAL SIGMA + '\u03c4' # 0x00ee -> GREEK SMALL LETTER TAU + '\u0384' # 0x00ef -> GREEK TONOS + '\xad' # 0x00f0 -> SOFT HYPHEN + '\xb1' # 0x00f1 -> PLUS-MINUS SIGN + '\u03c5' # 0x00f2 -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0x00f3 -> GREEK SMALL LETTER PHI + '\u03c7' # 0x00f4 -> GREEK SMALL LETTER CHI + '\xa7' # 0x00f5 -> SECTION SIGN + '\u03c8' # 0x00f6 -> GREEK SMALL LETTER PSI + '\u0385' # 0x00f7 -> GREEK DIALYTIKA TONOS + '\xb0' # 0x00f8 -> DEGREE SIGN + '\xa8' # 0x00f9 -> DIAERESIS + '\u03c9' # 0x00fa -> GREEK SMALL LETTER OMEGA + '\u03cb' # 0x00fb -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03b0' # 0x00fc -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u03ce' # 0x00fd -> GREEK SMALL LETTER OMEGA WITH TONOS + '\u25a0' # 0x00fe -> BLACK SQUARE + '\xa0' # 0x00ff -> NO-BREAK SPACE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # NULL + 0x0001: 0x0001, # START OF HEADING + 0x0002: 0x0002, # START OF TEXT + 0x0003: 0x0003, # END OF TEXT + 0x0004: 0x0004, # END OF TRANSMISSION + 0x0005: 0x0005, # ENQUIRY + 0x0006: 0x0006, # ACKNOWLEDGE + 0x0007: 0x0007, # BELL + 0x0008: 0x0008, # BACKSPACE + 0x0009: 0x0009, # HORIZONTAL TABULATION + 0x000a: 0x000a, # LINE FEED + 0x000b: 0x000b, # VERTICAL TABULATION + 0x000c: 0x000c, # FORM FEED + 0x000d: 0x000d, # CARRIAGE RETURN + 0x000e: 0x000e, # SHIFT OUT + 0x000f: 0x000f, # SHIFT IN + 0x0010: 0x0010, # DATA LINK ESCAPE + 0x0011: 0x0011, # DEVICE CONTROL ONE + 0x0012: 0x0012, # DEVICE CONTROL TWO + 0x0013: 0x0013, # DEVICE CONTROL THREE + 0x0014: 0x0014, # DEVICE CONTROL FOUR + 0x0015: 0x0015, # NEGATIVE ACKNOWLEDGE + 0x0016: 0x0016, # SYNCHRONOUS IDLE + 0x0017: 0x0017, # END OF TRANSMISSION BLOCK + 0x0018: 0x0018, # CANCEL + 0x0019: 0x0019, # END OF MEDIUM + 0x001a: 0x001a, # SUBSTITUTE + 0x001b: 0x001b, # ESCAPE + 0x001c: 0x001c, # FILE SEPARATOR + 0x001d: 0x001d, # GROUP SEPARATOR + 0x001e: 0x001e, # RECORD SEPARATOR + 0x001f: 0x001f, # UNIT SEPARATOR + 0x0020: 0x0020, # SPACE + 0x0021: 0x0021, # EXCLAMATION MARK + 0x0022: 0x0022, # QUOTATION MARK + 0x0023: 0x0023, # NUMBER SIGN + 0x0024: 0x0024, # DOLLAR SIGN + 0x0025: 0x0025, # PERCENT SIGN + 0x0026: 0x0026, # AMPERSAND + 0x0027: 0x0027, # APOSTROPHE + 0x0028: 0x0028, # LEFT PARENTHESIS + 0x0029: 0x0029, # RIGHT PARENTHESIS + 0x002a: 0x002a, # ASTERISK + 0x002b: 0x002b, # PLUS SIGN + 0x002c: 0x002c, # COMMA + 0x002d: 0x002d, # HYPHEN-MINUS + 0x002e: 0x002e, # FULL STOP + 0x002f: 0x002f, # SOLIDUS + 0x0030: 0x0030, # DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE + 0x003a: 0x003a, # COLON + 0x003b: 0x003b, # SEMICOLON + 0x003c: 0x003c, # LESS-THAN SIGN + 0x003d: 0x003d, # EQUALS SIGN + 0x003e: 0x003e, # GREATER-THAN SIGN + 0x003f: 0x003f, # QUESTION MARK + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET + 0x005c: 0x005c, # REVERSE SOLIDUS + 0x005d: 0x005d, # RIGHT SQUARE BRACKET + 0x005e: 0x005e, # CIRCUMFLEX ACCENT + 0x005f: 0x005f, # LOW LINE + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET + 0x007c: 0x007c, # VERTICAL LINE + 0x007d: 0x007d, # RIGHT CURLY BRACKET + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # DELETE + 0x00a0: 0x00ff, # NO-BREAK SPACE + 0x00a3: 0x009c, # POUND SIGN + 0x00a6: 0x008a, # BROKEN BAR + 0x00a7: 0x00f5, # SECTION SIGN + 0x00a8: 0x00f9, # DIAERESIS + 0x00a9: 0x0097, # COPYRIGHT SIGN + 0x00ab: 0x00ae, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00ac: 0x0089, # NOT SIGN + 0x00ad: 0x00f0, # SOFT HYPHEN + 0x00b0: 0x00f8, # DEGREE SIGN + 0x00b1: 0x00f1, # PLUS-MINUS SIGN + 0x00b2: 0x0099, # SUPERSCRIPT TWO + 0x00b3: 0x009a, # SUPERSCRIPT THREE + 0x00b7: 0x0088, # MIDDLE DOT + 0x00bb: 0x00af, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + 0x00bd: 0x00ab, # VULGAR FRACTION ONE HALF + 0x0384: 0x00ef, # GREEK TONOS + 0x0385: 0x00f7, # GREEK DIALYTIKA TONOS + 0x0386: 0x0086, # GREEK CAPITAL LETTER ALPHA WITH TONOS + 0x0388: 0x008d, # GREEK CAPITAL LETTER EPSILON WITH TONOS + 0x0389: 0x008f, # GREEK CAPITAL LETTER ETA WITH TONOS + 0x038a: 0x0090, # GREEK CAPITAL LETTER IOTA WITH TONOS + 0x038c: 0x0092, # GREEK CAPITAL LETTER OMICRON WITH TONOS + 0x038e: 0x0095, # GREEK CAPITAL LETTER UPSILON WITH TONOS + 0x038f: 0x0098, # GREEK CAPITAL LETTER OMEGA WITH TONOS + 0x0390: 0x00a1, # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + 0x0391: 0x00a4, # GREEK CAPITAL LETTER ALPHA + 0x0392: 0x00a5, # GREEK CAPITAL LETTER BETA + 0x0393: 0x00a6, # GREEK CAPITAL LETTER GAMMA + 0x0394: 0x00a7, # GREEK CAPITAL LETTER DELTA + 0x0395: 0x00a8, # GREEK CAPITAL LETTER EPSILON + 0x0396: 0x00a9, # GREEK CAPITAL LETTER ZETA + 0x0397: 0x00aa, # GREEK CAPITAL LETTER ETA + 0x0398: 0x00ac, # GREEK CAPITAL LETTER THETA + 0x0399: 0x00ad, # GREEK CAPITAL LETTER IOTA + 0x039a: 0x00b5, # GREEK CAPITAL LETTER KAPPA + 0x039b: 0x00b6, # GREEK CAPITAL LETTER LAMDA + 0x039c: 0x00b7, # GREEK CAPITAL LETTER MU + 0x039d: 0x00b8, # GREEK CAPITAL LETTER NU + 0x039e: 0x00bd, # GREEK CAPITAL LETTER XI + 0x039f: 0x00be, # GREEK CAPITAL LETTER OMICRON + 0x03a0: 0x00c6, # GREEK CAPITAL LETTER PI + 0x03a1: 0x00c7, # GREEK CAPITAL LETTER RHO + 0x03a3: 0x00cf, # GREEK CAPITAL LETTER SIGMA + 0x03a4: 0x00d0, # GREEK CAPITAL LETTER TAU + 0x03a5: 0x00d1, # GREEK CAPITAL LETTER UPSILON + 0x03a6: 0x00d2, # GREEK CAPITAL LETTER PHI + 0x03a7: 0x00d3, # GREEK CAPITAL LETTER CHI + 0x03a8: 0x00d4, # GREEK CAPITAL LETTER PSI + 0x03a9: 0x00d5, # GREEK CAPITAL LETTER OMEGA + 0x03aa: 0x0091, # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + 0x03ab: 0x0096, # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + 0x03ac: 0x009b, # GREEK SMALL LETTER ALPHA WITH TONOS + 0x03ad: 0x009d, # GREEK SMALL LETTER EPSILON WITH TONOS + 0x03ae: 0x009e, # GREEK SMALL LETTER ETA WITH TONOS + 0x03af: 0x009f, # GREEK SMALL LETTER IOTA WITH TONOS + 0x03b0: 0x00fc, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + 0x03b1: 0x00d6, # GREEK SMALL LETTER ALPHA + 0x03b2: 0x00d7, # GREEK SMALL LETTER BETA + 0x03b3: 0x00d8, # GREEK SMALL LETTER GAMMA + 0x03b4: 0x00dd, # GREEK SMALL LETTER DELTA + 0x03b5: 0x00de, # GREEK SMALL LETTER EPSILON + 0x03b6: 0x00e0, # GREEK SMALL LETTER ZETA + 0x03b7: 0x00e1, # GREEK SMALL LETTER ETA + 0x03b8: 0x00e2, # GREEK SMALL LETTER THETA + 0x03b9: 0x00e3, # GREEK SMALL LETTER IOTA + 0x03ba: 0x00e4, # GREEK SMALL LETTER KAPPA + 0x03bb: 0x00e5, # GREEK SMALL LETTER LAMDA + 0x03bc: 0x00e6, # GREEK SMALL LETTER MU + 0x03bd: 0x00e7, # GREEK SMALL LETTER NU + 0x03be: 0x00e8, # GREEK SMALL LETTER XI + 0x03bf: 0x00e9, # GREEK SMALL LETTER OMICRON + 0x03c0: 0x00ea, # GREEK SMALL LETTER PI + 0x03c1: 0x00eb, # GREEK SMALL LETTER RHO + 0x03c2: 0x00ed, # GREEK SMALL LETTER FINAL SIGMA + 0x03c3: 0x00ec, # GREEK SMALL LETTER SIGMA + 0x03c4: 0x00ee, # GREEK SMALL LETTER TAU + 0x03c5: 0x00f2, # GREEK SMALL LETTER UPSILON + 0x03c6: 0x00f3, # GREEK SMALL LETTER PHI + 0x03c7: 0x00f4, # GREEK SMALL LETTER CHI + 0x03c8: 0x00f6, # GREEK SMALL LETTER PSI + 0x03c9: 0x00fa, # GREEK SMALL LETTER OMEGA + 0x03ca: 0x00a0, # GREEK SMALL LETTER IOTA WITH DIALYTIKA + 0x03cb: 0x00fb, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA + 0x03cc: 0x00a2, # GREEK SMALL LETTER OMICRON WITH TONOS + 0x03cd: 0x00a3, # GREEK SMALL LETTER UPSILON WITH TONOS + 0x03ce: 0x00fd, # GREEK SMALL LETTER OMEGA WITH TONOS + 0x2015: 0x008e, # HORIZONTAL BAR + 0x2018: 0x008b, # LEFT SINGLE QUOTATION MARK + 0x2019: 0x008c, # RIGHT SINGLE QUOTATION MARK + 0x2500: 0x00c4, # BOX DRAWINGS LIGHT HORIZONTAL + 0x2502: 0x00b3, # BOX DRAWINGS LIGHT VERTICAL + 0x250c: 0x00da, # BOX DRAWINGS LIGHT DOWN AND RIGHT + 0x2510: 0x00bf, # BOX DRAWINGS LIGHT DOWN AND LEFT + 0x2514: 0x00c0, # BOX DRAWINGS LIGHT UP AND RIGHT + 0x2518: 0x00d9, # BOX DRAWINGS LIGHT UP AND LEFT + 0x251c: 0x00c3, # BOX DRAWINGS LIGHT VERTICAL AND RIGHT + 0x2524: 0x00b4, # BOX DRAWINGS LIGHT VERTICAL AND LEFT + 0x252c: 0x00c2, # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + 0x2534: 0x00c1, # BOX DRAWINGS LIGHT UP AND HORIZONTAL + 0x253c: 0x00c5, # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + 0x2550: 0x00cd, # BOX DRAWINGS DOUBLE HORIZONTAL + 0x2551: 0x00ba, # BOX DRAWINGS DOUBLE VERTICAL + 0x2554: 0x00c9, # BOX DRAWINGS DOUBLE DOWN AND RIGHT + 0x2557: 0x00bb, # BOX DRAWINGS DOUBLE DOWN AND LEFT + 0x255a: 0x00c8, # BOX DRAWINGS DOUBLE UP AND RIGHT + 0x255d: 0x00bc, # BOX DRAWINGS DOUBLE UP AND LEFT + 0x2560: 0x00cc, # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + 0x2563: 0x00b9, # BOX DRAWINGS DOUBLE VERTICAL AND LEFT + 0x2566: 0x00cb, # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + 0x2569: 0x00ca, # BOX DRAWINGS DOUBLE UP AND HORIZONTAL + 0x256c: 0x00ce, # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + 0x2580: 0x00df, # UPPER HALF BLOCK + 0x2584: 0x00dc, # LOWER HALF BLOCK + 0x2588: 0x00db, # FULL BLOCK + 0x2591: 0x00b0, # LIGHT SHADE + 0x2592: 0x00b1, # MEDIUM SHADE + 0x2593: 0x00b2, # DARK SHADE + 0x25a0: 0x00fe, # BLACK SQUARE +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp874.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp874.py new file mode 100644 index 0000000..59bfcbc --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp874.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp874 generated from 'MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp874', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\ufffe' # 0x81 -> UNDEFINED + '\ufffe' # 0x82 -> UNDEFINED + '\ufffe' # 0x83 -> UNDEFINED + '\ufffe' # 0x84 -> UNDEFINED + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\ufffe' # 0x86 -> UNDEFINED + '\ufffe' # 0x87 -> UNDEFINED + '\ufffe' # 0x88 -> UNDEFINED + '\ufffe' # 0x89 -> UNDEFINED + '\ufffe' # 0x8A -> UNDEFINED + '\ufffe' # 0x8B -> UNDEFINED + '\ufffe' # 0x8C -> UNDEFINED + '\ufffe' # 0x8D -> UNDEFINED + '\ufffe' # 0x8E -> UNDEFINED + '\ufffe' # 0x8F -> UNDEFINED + '\ufffe' # 0x90 -> UNDEFINED + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\ufffe' # 0x99 -> UNDEFINED + '\ufffe' # 0x9A -> UNDEFINED + '\ufffe' # 0x9B -> UNDEFINED + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + '\u0e0b' # 0xAB -> THAI CHARACTER SO SO + '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + '\u0e0d' # 0xAD -> THAI CHARACTER YO YING + '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + '\u0e19' # 0xB9 -> THAI CHARACTER NO NU + '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + '\u0e1d' # 0xBD -> THAI CHARACTER FO FA + '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + '\u0e21' # 0xC1 -> THAI CHARACTER MO MA + '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + '\u0e24' # 0xC4 -> THAI CHARACTER RU + '\u0e25' # 0xC5 -> THAI CHARACTER LO LING + '\u0e26' # 0xC6 -> THAI CHARACTER LU + '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + '\u0e2d' # 0xCD -> THAI CHARACTER O ANG + '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + '\u0e30' # 0xD0 -> THAI CHARACTER SARA A + '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + '\u0e34' # 0xD4 -> THAI CHARACTER SARA I + '\u0e35' # 0xD5 -> THAI CHARACTER SARA II + '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + '\u0e38' # 0xD8 -> THAI CHARACTER SARA U + '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + '\ufffe' # 0xDB -> UNDEFINED + '\ufffe' # 0xDC -> UNDEFINED + '\ufffe' # 0xDD -> UNDEFINED + '\ufffe' # 0xDE -> UNDEFINED + '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + '\u0e40' # 0xE0 -> THAI CHARACTER SARA E + '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + '\u0e42' # 0xE2 -> THAI CHARACTER SARA O + '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + '\u0e50' # 0xF0 -> THAI DIGIT ZERO + '\u0e51' # 0xF1 -> THAI DIGIT ONE + '\u0e52' # 0xF2 -> THAI DIGIT TWO + '\u0e53' # 0xF3 -> THAI DIGIT THREE + '\u0e54' # 0xF4 -> THAI DIGIT FOUR + '\u0e55' # 0xF5 -> THAI DIGIT FIVE + '\u0e56' # 0xF6 -> THAI DIGIT SIX + '\u0e57' # 0xF7 -> THAI DIGIT SEVEN + '\u0e58' # 0xF8 -> THAI DIGIT EIGHT + '\u0e59' # 0xF9 -> THAI DIGIT NINE + '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + '\ufffe' # 0xFC -> UNDEFINED + '\ufffe' # 0xFD -> UNDEFINED + '\ufffe' # 0xFE -> UNDEFINED + '\ufffe' # 0xFF -> UNDEFINED +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/cp875.py b/crates/weavepy-vm/src/stdlib/python/encodings/cp875.py new file mode 100644 index 0000000..c25a5a4 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/cp875.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec cp875 generated from 'MAPPINGS/VENDORS/MICSFT/EBCDIC/CP875.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='cp875', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x9c' # 0x04 -> CONTROL + '\t' # 0x05 -> HORIZONTAL TABULATION + '\x86' # 0x06 -> CONTROL + '\x7f' # 0x07 -> DELETE + '\x97' # 0x08 -> CONTROL + '\x8d' # 0x09 -> CONTROL + '\x8e' # 0x0A -> CONTROL + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x9d' # 0x14 -> CONTROL + '\x85' # 0x15 -> CONTROL + '\x08' # 0x16 -> BACKSPACE + '\x87' # 0x17 -> CONTROL + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x92' # 0x1A -> CONTROL + '\x8f' # 0x1B -> CONTROL + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + '\x80' # 0x20 -> CONTROL + '\x81' # 0x21 -> CONTROL + '\x82' # 0x22 -> CONTROL + '\x83' # 0x23 -> CONTROL + '\x84' # 0x24 -> CONTROL + '\n' # 0x25 -> LINE FEED + '\x17' # 0x26 -> END OF TRANSMISSION BLOCK + '\x1b' # 0x27 -> ESCAPE + '\x88' # 0x28 -> CONTROL + '\x89' # 0x29 -> CONTROL + '\x8a' # 0x2A -> CONTROL + '\x8b' # 0x2B -> CONTROL + '\x8c' # 0x2C -> CONTROL + '\x05' # 0x2D -> ENQUIRY + '\x06' # 0x2E -> ACKNOWLEDGE + '\x07' # 0x2F -> BELL + '\x90' # 0x30 -> CONTROL + '\x91' # 0x31 -> CONTROL + '\x16' # 0x32 -> SYNCHRONOUS IDLE + '\x93' # 0x33 -> CONTROL + '\x94' # 0x34 -> CONTROL + '\x95' # 0x35 -> CONTROL + '\x96' # 0x36 -> CONTROL + '\x04' # 0x37 -> END OF TRANSMISSION + '\x98' # 0x38 -> CONTROL + '\x99' # 0x39 -> CONTROL + '\x9a' # 0x3A -> CONTROL + '\x9b' # 0x3B -> CONTROL + '\x14' # 0x3C -> DEVICE CONTROL FOUR + '\x15' # 0x3D -> NEGATIVE ACKNOWLEDGE + '\x9e' # 0x3E -> CONTROL + '\x1a' # 0x3F -> SUBSTITUTE + ' ' # 0x40 -> SPACE + '\u0391' # 0x41 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0x42 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0x43 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0x44 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0x45 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0x46 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0x47 -> GREEK CAPITAL LETTER ETA + '\u0398' # 0x48 -> GREEK CAPITAL LETTER THETA + '\u0399' # 0x49 -> GREEK CAPITAL LETTER IOTA + '[' # 0x4A -> LEFT SQUARE BRACKET + '.' # 0x4B -> FULL STOP + '<' # 0x4C -> LESS-THAN SIGN + '(' # 0x4D -> LEFT PARENTHESIS + '+' # 0x4E -> PLUS SIGN + '!' # 0x4F -> EXCLAMATION MARK + '&' # 0x50 -> AMPERSAND + '\u039a' # 0x51 -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0x52 -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0x53 -> GREEK CAPITAL LETTER MU + '\u039d' # 0x54 -> GREEK CAPITAL LETTER NU + '\u039e' # 0x55 -> GREEK CAPITAL LETTER XI + '\u039f' # 0x56 -> GREEK CAPITAL LETTER OMICRON + '\u03a0' # 0x57 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0x58 -> GREEK CAPITAL LETTER RHO + '\u03a3' # 0x59 -> GREEK CAPITAL LETTER SIGMA + ']' # 0x5A -> RIGHT SQUARE BRACKET + '$' # 0x5B -> DOLLAR SIGN + '*' # 0x5C -> ASTERISK + ')' # 0x5D -> RIGHT PARENTHESIS + ';' # 0x5E -> SEMICOLON + '^' # 0x5F -> CIRCUMFLEX ACCENT + '-' # 0x60 -> HYPHEN-MINUS + '/' # 0x61 -> SOLIDUS + '\u03a4' # 0x62 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0x63 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0x64 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0x65 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0x66 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0x67 -> GREEK CAPITAL LETTER OMEGA + '\u03aa' # 0x68 -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u03ab' # 0x69 -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '|' # 0x6A -> VERTICAL LINE + ',' # 0x6B -> COMMA + '%' # 0x6C -> PERCENT SIGN + '_' # 0x6D -> LOW LINE + '>' # 0x6E -> GREATER-THAN SIGN + '?' # 0x6F -> QUESTION MARK + '\xa8' # 0x70 -> DIAERESIS + '\u0386' # 0x71 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\u0388' # 0x72 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0389' # 0x73 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\xa0' # 0x74 -> NO-BREAK SPACE + '\u038a' # 0x75 -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\u038c' # 0x76 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\u038e' # 0x77 -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u038f' # 0x78 -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '`' # 0x79 -> GRAVE ACCENT + ':' # 0x7A -> COLON + '#' # 0x7B -> NUMBER SIGN + '@' # 0x7C -> COMMERCIAL AT + "'" # 0x7D -> APOSTROPHE + '=' # 0x7E -> EQUALS SIGN + '"' # 0x7F -> QUOTATION MARK + '\u0385' # 0x80 -> GREEK DIALYTIKA TONOS + 'a' # 0x81 -> LATIN SMALL LETTER A + 'b' # 0x82 -> LATIN SMALL LETTER B + 'c' # 0x83 -> LATIN SMALL LETTER C + 'd' # 0x84 -> LATIN SMALL LETTER D + 'e' # 0x85 -> LATIN SMALL LETTER E + 'f' # 0x86 -> LATIN SMALL LETTER F + 'g' # 0x87 -> LATIN SMALL LETTER G + 'h' # 0x88 -> LATIN SMALL LETTER H + 'i' # 0x89 -> LATIN SMALL LETTER I + '\u03b1' # 0x8A -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0x8B -> GREEK SMALL LETTER BETA + '\u03b3' # 0x8C -> GREEK SMALL LETTER GAMMA + '\u03b4' # 0x8D -> GREEK SMALL LETTER DELTA + '\u03b5' # 0x8E -> GREEK SMALL LETTER EPSILON + '\u03b6' # 0x8F -> GREEK SMALL LETTER ZETA + '\xb0' # 0x90 -> DEGREE SIGN + 'j' # 0x91 -> LATIN SMALL LETTER J + 'k' # 0x92 -> LATIN SMALL LETTER K + 'l' # 0x93 -> LATIN SMALL LETTER L + 'm' # 0x94 -> LATIN SMALL LETTER M + 'n' # 0x95 -> LATIN SMALL LETTER N + 'o' # 0x96 -> LATIN SMALL LETTER O + 'p' # 0x97 -> LATIN SMALL LETTER P + 'q' # 0x98 -> LATIN SMALL LETTER Q + 'r' # 0x99 -> LATIN SMALL LETTER R + '\u03b7' # 0x9A -> GREEK SMALL LETTER ETA + '\u03b8' # 0x9B -> GREEK SMALL LETTER THETA + '\u03b9' # 0x9C -> GREEK SMALL LETTER IOTA + '\u03ba' # 0x9D -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0x9E -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0x9F -> GREEK SMALL LETTER MU + '\xb4' # 0xA0 -> ACUTE ACCENT + '~' # 0xA1 -> TILDE + 's' # 0xA2 -> LATIN SMALL LETTER S + 't' # 0xA3 -> LATIN SMALL LETTER T + 'u' # 0xA4 -> LATIN SMALL LETTER U + 'v' # 0xA5 -> LATIN SMALL LETTER V + 'w' # 0xA6 -> LATIN SMALL LETTER W + 'x' # 0xA7 -> LATIN SMALL LETTER X + 'y' # 0xA8 -> LATIN SMALL LETTER Y + 'z' # 0xA9 -> LATIN SMALL LETTER Z + '\u03bd' # 0xAA -> GREEK SMALL LETTER NU + '\u03be' # 0xAB -> GREEK SMALL LETTER XI + '\u03bf' # 0xAC -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xAD -> GREEK SMALL LETTER PI + '\u03c1' # 0xAE -> GREEK SMALL LETTER RHO + '\u03c3' # 0xAF -> GREEK SMALL LETTER SIGMA + '\xa3' # 0xB0 -> POUND SIGN + '\u03ac' # 0xB1 -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u03ad' # 0xB2 -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xB3 -> GREEK SMALL LETTER ETA WITH TONOS + '\u03ca' # 0xB4 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03af' # 0xB5 -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03cc' # 0xB6 -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0xB7 -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03cb' # 0xB8 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03ce' # 0xB9 -> GREEK SMALL LETTER OMEGA WITH TONOS + '\u03c2' # 0xBA -> GREEK SMALL LETTER FINAL SIGMA + '\u03c4' # 0xBB -> GREEK SMALL LETTER TAU + '\u03c5' # 0xBC -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0xBD -> GREEK SMALL LETTER PHI + '\u03c7' # 0xBE -> GREEK SMALL LETTER CHI + '\u03c8' # 0xBF -> GREEK SMALL LETTER PSI + '{' # 0xC0 -> LEFT CURLY BRACKET + 'A' # 0xC1 -> LATIN CAPITAL LETTER A + 'B' # 0xC2 -> LATIN CAPITAL LETTER B + 'C' # 0xC3 -> LATIN CAPITAL LETTER C + 'D' # 0xC4 -> LATIN CAPITAL LETTER D + 'E' # 0xC5 -> LATIN CAPITAL LETTER E + 'F' # 0xC6 -> LATIN CAPITAL LETTER F + 'G' # 0xC7 -> LATIN CAPITAL LETTER G + 'H' # 0xC8 -> LATIN CAPITAL LETTER H + 'I' # 0xC9 -> LATIN CAPITAL LETTER I + '\xad' # 0xCA -> SOFT HYPHEN + '\u03c9' # 0xCB -> GREEK SMALL LETTER OMEGA + '\u0390' # 0xCC -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u03b0' # 0xCD -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u2018' # 0xCE -> LEFT SINGLE QUOTATION MARK + '\u2015' # 0xCF -> HORIZONTAL BAR + '}' # 0xD0 -> RIGHT CURLY BRACKET + 'J' # 0xD1 -> LATIN CAPITAL LETTER J + 'K' # 0xD2 -> LATIN CAPITAL LETTER K + 'L' # 0xD3 -> LATIN CAPITAL LETTER L + 'M' # 0xD4 -> LATIN CAPITAL LETTER M + 'N' # 0xD5 -> LATIN CAPITAL LETTER N + 'O' # 0xD6 -> LATIN CAPITAL LETTER O + 'P' # 0xD7 -> LATIN CAPITAL LETTER P + 'Q' # 0xD8 -> LATIN CAPITAL LETTER Q + 'R' # 0xD9 -> LATIN CAPITAL LETTER R + '\xb1' # 0xDA -> PLUS-MINUS SIGN + '\xbd' # 0xDB -> VULGAR FRACTION ONE HALF + '\x1a' # 0xDC -> SUBSTITUTE + '\u0387' # 0xDD -> GREEK ANO TELEIA + '\u2019' # 0xDE -> RIGHT SINGLE QUOTATION MARK + '\xa6' # 0xDF -> BROKEN BAR + '\\' # 0xE0 -> REVERSE SOLIDUS + '\x1a' # 0xE1 -> SUBSTITUTE + 'S' # 0xE2 -> LATIN CAPITAL LETTER S + 'T' # 0xE3 -> LATIN CAPITAL LETTER T + 'U' # 0xE4 -> LATIN CAPITAL LETTER U + 'V' # 0xE5 -> LATIN CAPITAL LETTER V + 'W' # 0xE6 -> LATIN CAPITAL LETTER W + 'X' # 0xE7 -> LATIN CAPITAL LETTER X + 'Y' # 0xE8 -> LATIN CAPITAL LETTER Y + 'Z' # 0xE9 -> LATIN CAPITAL LETTER Z + '\xb2' # 0xEA -> SUPERSCRIPT TWO + '\xa7' # 0xEB -> SECTION SIGN + '\x1a' # 0xEC -> SUBSTITUTE + '\x1a' # 0xED -> SUBSTITUTE + '\xab' # 0xEE -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xEF -> NOT SIGN + '0' # 0xF0 -> DIGIT ZERO + '1' # 0xF1 -> DIGIT ONE + '2' # 0xF2 -> DIGIT TWO + '3' # 0xF3 -> DIGIT THREE + '4' # 0xF4 -> DIGIT FOUR + '5' # 0xF5 -> DIGIT FIVE + '6' # 0xF6 -> DIGIT SIX + '7' # 0xF7 -> DIGIT SEVEN + '8' # 0xF8 -> DIGIT EIGHT + '9' # 0xF9 -> DIGIT NINE + '\xb3' # 0xFA -> SUPERSCRIPT THREE + '\xa9' # 0xFB -> COPYRIGHT SIGN + '\x1a' # 0xFC -> SUBSTITUTE + '\x1a' # 0xFD -> SUBSTITUTE + '\xbb' # 0xFE -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\x9f' # 0xFF -> CONTROL +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/hp_roman8.py b/crates/weavepy-vm/src/stdlib/python/encodings/hp_roman8.py new file mode 100644 index 0000000..58de103 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/hp_roman8.py @@ -0,0 +1,314 @@ +""" Python Character Mapping Codec generated from 'hp_roman8.txt' with gencodec.py. + + Based on data from ftp://dkuug.dk/i18n/charmaps/HP-ROMAN8 (Keld Simonsen) + + Original source: LaserJet IIP Printer User's Manual HP part no + 33471-90901, Hewlet-Packard, June 1989. + + (Used with permission) + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='hp-roman8', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xc0' # 0xA1 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc2' # 0xA2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc8' # 0xA3 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xca' # 0xA4 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xA5 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xce' # 0xA6 -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xA7 -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xb4' # 0xA8 -> ACUTE ACCENT + '\u02cb' # 0xA9 -> MODIFIER LETTER GRAVE ACCENT (MANDARIN CHINESE FOURTH TONE) + '\u02c6' # 0xAA -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\xa8' # 0xAB -> DIAERESIS + '\u02dc' # 0xAC -> SMALL TILDE + '\xd9' # 0xAD -> LATIN CAPITAL LETTER U WITH GRAVE + '\xdb' # 0xAE -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\u20a4' # 0xAF -> LIRA SIGN + '\xaf' # 0xB0 -> MACRON + '\xdd' # 0xB1 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xfd' # 0xB2 -> LATIN SMALL LETTER Y WITH ACUTE + '\xb0' # 0xB3 -> DEGREE SIGN + '\xc7' # 0xB4 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xe7' # 0xB5 -> LATIN SMALL LETTER C WITH CEDILLA + '\xd1' # 0xB6 -> LATIN CAPITAL LETTER N WITH TILDE + '\xf1' # 0xB7 -> LATIN SMALL LETTER N WITH TILDE + '\xa1' # 0xB8 -> INVERTED EXCLAMATION MARK + '\xbf' # 0xB9 -> INVERTED QUESTION MARK + '\xa4' # 0xBA -> CURRENCY SIGN + '\xa3' # 0xBB -> POUND SIGN + '\xa5' # 0xBC -> YEN SIGN + '\xa7' # 0xBD -> SECTION SIGN + '\u0192' # 0xBE -> LATIN SMALL LETTER F WITH HOOK + '\xa2' # 0xBF -> CENT SIGN + '\xe2' # 0xC0 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xea' # 0xC1 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xf4' # 0xC2 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xfb' # 0xC3 -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xe1' # 0xC4 -> LATIN SMALL LETTER A WITH ACUTE + '\xe9' # 0xC5 -> LATIN SMALL LETTER E WITH ACUTE + '\xf3' # 0xC6 -> LATIN SMALL LETTER O WITH ACUTE + '\xfa' # 0xC7 -> LATIN SMALL LETTER U WITH ACUTE + '\xe0' # 0xC8 -> LATIN SMALL LETTER A WITH GRAVE + '\xe8' # 0xC9 -> LATIN SMALL LETTER E WITH GRAVE + '\xf2' # 0xCA -> LATIN SMALL LETTER O WITH GRAVE + '\xf9' # 0xCB -> LATIN SMALL LETTER U WITH GRAVE + '\xe4' # 0xCC -> LATIN SMALL LETTER A WITH DIAERESIS + '\xeb' # 0xCD -> LATIN SMALL LETTER E WITH DIAERESIS + '\xf6' # 0xCE -> LATIN SMALL LETTER O WITH DIAERESIS + '\xfc' # 0xCF -> LATIN SMALL LETTER U WITH DIAERESIS + '\xc5' # 0xD0 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xee' # 0xD1 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xd8' # 0xD2 -> LATIN CAPITAL LETTER O WITH STROKE + '\xc6' # 0xD3 -> LATIN CAPITAL LETTER AE + '\xe5' # 0xD4 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xed' # 0xD5 -> LATIN SMALL LETTER I WITH ACUTE + '\xf8' # 0xD6 -> LATIN SMALL LETTER O WITH STROKE + '\xe6' # 0xD7 -> LATIN SMALL LETTER AE + '\xc4' # 0xD8 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xec' # 0xD9 -> LATIN SMALL LETTER I WITH GRAVE + '\xd6' # 0xDA -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0xDB -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xc9' # 0xDC -> LATIN CAPITAL LETTER E WITH ACUTE + '\xef' # 0xDD -> LATIN SMALL LETTER I WITH DIAERESIS + '\xdf' # 0xDE -> LATIN SMALL LETTER SHARP S (GERMAN) + '\xd4' # 0xDF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xc1' # 0xE0 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc3' # 0xE1 -> LATIN CAPITAL LETTER A WITH TILDE + '\xe3' # 0xE2 -> LATIN SMALL LETTER A WITH TILDE + '\xd0' # 0xE3 -> LATIN CAPITAL LETTER ETH (ICELANDIC) + '\xf0' # 0xE4 -> LATIN SMALL LETTER ETH (ICELANDIC) + '\xcd' # 0xE5 -> LATIN CAPITAL LETTER I WITH ACUTE + '\xcc' # 0xE6 -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xE7 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd2' # 0xE8 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd5' # 0xE9 -> LATIN CAPITAL LETTER O WITH TILDE + '\xf5' # 0xEA -> LATIN SMALL LETTER O WITH TILDE + '\u0160' # 0xEB -> LATIN CAPITAL LETTER S WITH CARON + '\u0161' # 0xEC -> LATIN SMALL LETTER S WITH CARON + '\xda' # 0xED -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0178' # 0xEE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xff' # 0xEF -> LATIN SMALL LETTER Y WITH DIAERESIS + '\xde' # 0xF0 -> LATIN CAPITAL LETTER THORN (ICELANDIC) + '\xfe' # 0xF1 -> LATIN SMALL LETTER THORN (ICELANDIC) + '\xb7' # 0xF2 -> MIDDLE DOT + '\xb5' # 0xF3 -> MICRO SIGN + '\xb6' # 0xF4 -> PILCROW SIGN + '\xbe' # 0xF5 -> VULGAR FRACTION THREE QUARTERS + '\u2014' # 0xF6 -> EM DASH + '\xbc' # 0xF7 -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xF8 -> VULGAR FRACTION ONE HALF + '\xaa' # 0xF9 -> FEMININE ORDINAL INDICATOR + '\xba' # 0xFA -> MASCULINE ORDINAL INDICATOR + '\xab' # 0xFB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u25a0' # 0xFC -> BLACK SQUARE + '\xbb' # 0xFD -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xb1' # 0xFE -> PLUS-MINUS SIGN + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_1.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_1.py new file mode 100644 index 0000000..8cfc01f --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_1.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_1 generated from 'MAPPINGS/ISO8859/8859-1.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-1', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_10.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_10.py new file mode 100644 index 0000000..b4fb041 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_10.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_10 generated from 'MAPPINGS/ISO8859/8859-10.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-10', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0112' # 0xA2 -> LATIN CAPITAL LETTER E WITH MACRON + '\u0122' # 0xA3 -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u012a' # 0xA4 -> LATIN CAPITAL LETTER I WITH MACRON + '\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE + '\u0136' # 0xA6 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\xa7' # 0xA7 -> SECTION SIGN + '\u013b' # 0xA8 -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u0110' # 0xA9 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0160' # 0xAA -> LATIN CAPITAL LETTER S WITH CARON + '\u0166' # 0xAB -> LATIN CAPITAL LETTER T WITH STROKE + '\u017d' # 0xAC -> LATIN CAPITAL LETTER Z WITH CARON + '\xad' # 0xAD -> SOFT HYPHEN + '\u016a' # 0xAE -> LATIN CAPITAL LETTER U WITH MACRON + '\u014a' # 0xAF -> LATIN CAPITAL LETTER ENG + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + '\u0113' # 0xB2 -> LATIN SMALL LETTER E WITH MACRON + '\u0123' # 0xB3 -> LATIN SMALL LETTER G WITH CEDILLA + '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON + '\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE + '\u0137' # 0xB6 -> LATIN SMALL LETTER K WITH CEDILLA + '\xb7' # 0xB7 -> MIDDLE DOT + '\u013c' # 0xB8 -> LATIN SMALL LETTER L WITH CEDILLA + '\u0111' # 0xB9 -> LATIN SMALL LETTER D WITH STROKE + '\u0161' # 0xBA -> LATIN SMALL LETTER S WITH CARON + '\u0167' # 0xBB -> LATIN SMALL LETTER T WITH STROKE + '\u017e' # 0xBC -> LATIN SMALL LETTER Z WITH CARON + '\u2015' # 0xBD -> HORIZONTAL BAR + '\u016b' # 0xBE -> LATIN SMALL LETTER U WITH MACRON + '\u014b' # 0xBF -> LATIN SMALL LETTER ENG + '\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + '\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u0168' # 0xD7 -> LATIN CAPITAL LETTER U WITH TILDE + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + '\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA + '\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u0169' # 0xF7 -> LATIN SMALL LETTER U WITH TILDE + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + '\u0138' # 0xFF -> LATIN SMALL LETTER KRA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_11.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_11.py new file mode 100644 index 0000000..c7258ec --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_11.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_11 generated from 'MAPPINGS/ISO8859/8859-11.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-11', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + '\u0e0b' # 0xAB -> THAI CHARACTER SO SO + '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + '\u0e0d' # 0xAD -> THAI CHARACTER YO YING + '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + '\u0e19' # 0xB9 -> THAI CHARACTER NO NU + '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + '\u0e1d' # 0xBD -> THAI CHARACTER FO FA + '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + '\u0e21' # 0xC1 -> THAI CHARACTER MO MA + '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + '\u0e24' # 0xC4 -> THAI CHARACTER RU + '\u0e25' # 0xC5 -> THAI CHARACTER LO LING + '\u0e26' # 0xC6 -> THAI CHARACTER LU + '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + '\u0e2d' # 0xCD -> THAI CHARACTER O ANG + '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + '\u0e30' # 0xD0 -> THAI CHARACTER SARA A + '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + '\u0e34' # 0xD4 -> THAI CHARACTER SARA I + '\u0e35' # 0xD5 -> THAI CHARACTER SARA II + '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + '\u0e38' # 0xD8 -> THAI CHARACTER SARA U + '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + '\u0e40' # 0xE0 -> THAI CHARACTER SARA E + '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + '\u0e42' # 0xE2 -> THAI CHARACTER SARA O + '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + '\u0e50' # 0xF0 -> THAI DIGIT ZERO + '\u0e51' # 0xF1 -> THAI DIGIT ONE + '\u0e52' # 0xF2 -> THAI DIGIT TWO + '\u0e53' # 0xF3 -> THAI DIGIT THREE + '\u0e54' # 0xF4 -> THAI DIGIT FOUR + '\u0e55' # 0xF5 -> THAI DIGIT FIVE + '\u0e56' # 0xF6 -> THAI DIGIT SIX + '\u0e57' # 0xF7 -> THAI DIGIT SEVEN + '\u0e58' # 0xF8 -> THAI DIGIT EIGHT + '\u0e59' # 0xF9 -> THAI DIGIT NINE + '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_13.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_13.py new file mode 100644 index 0000000..6f8eab2 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_13.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_13 generated from 'MAPPINGS/ISO8859/8859-13.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-13', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u201d' # 0xA1 -> RIGHT DOUBLE QUOTATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xd8' # 0xA8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0156' # 0xAA -> LATIN CAPITAL LETTER R WITH CEDILLA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xc6' # 0xAF -> LATIN CAPITAL LETTER AE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u201c' # 0xB4 -> LEFT DOUBLE QUOTATION MARK + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xf8' # 0xB8 -> LATIN SMALL LETTER O WITH STROKE + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\u0157' # 0xBA -> LATIN SMALL LETTER R WITH CEDILLA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xe6' # 0xBF -> LATIN SMALL LETTER AE + '\u0104' # 0xC0 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u012e' # 0xC1 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u0100' # 0xC2 -> LATIN CAPITAL LETTER A WITH MACRON + '\u0106' # 0xC3 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\u0118' # 0xC6 -> LATIN CAPITAL LETTER E WITH OGONEK + '\u0112' # 0xC7 -> LATIN CAPITAL LETTER E WITH MACRON + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0179' # 0xCA -> LATIN CAPITAL LETTER Z WITH ACUTE + '\u0116' # 0xCB -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\u0122' # 0xCC -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u0136' # 0xCD -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u012a' # 0xCE -> LATIN CAPITAL LETTER I WITH MACRON + '\u013b' # 0xCF -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u0160' # 0xD0 -> LATIN CAPITAL LETTER S WITH CARON + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0145' # 0xD2 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\u014c' # 0xD4 -> LATIN CAPITAL LETTER O WITH MACRON + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0172' # 0xD8 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u0141' # 0xD9 -> LATIN CAPITAL LETTER L WITH STROKE + '\u015a' # 0xDA -> LATIN CAPITAL LETTER S WITH ACUTE + '\u016a' # 0xDB -> LATIN CAPITAL LETTER U WITH MACRON + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u017b' # 0xDD -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u017d' # 0xDE -> LATIN CAPITAL LETTER Z WITH CARON + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\u0105' # 0xE0 -> LATIN SMALL LETTER A WITH OGONEK + '\u012f' # 0xE1 -> LATIN SMALL LETTER I WITH OGONEK + '\u0101' # 0xE2 -> LATIN SMALL LETTER A WITH MACRON + '\u0107' # 0xE3 -> LATIN SMALL LETTER C WITH ACUTE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\u0119' # 0xE6 -> LATIN SMALL LETTER E WITH OGONEK + '\u0113' # 0xE7 -> LATIN SMALL LETTER E WITH MACRON + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u017a' # 0xEA -> LATIN SMALL LETTER Z WITH ACUTE + '\u0117' # 0xEB -> LATIN SMALL LETTER E WITH DOT ABOVE + '\u0123' # 0xEC -> LATIN SMALL LETTER G WITH CEDILLA + '\u0137' # 0xED -> LATIN SMALL LETTER K WITH CEDILLA + '\u012b' # 0xEE -> LATIN SMALL LETTER I WITH MACRON + '\u013c' # 0xEF -> LATIN SMALL LETTER L WITH CEDILLA + '\u0161' # 0xF0 -> LATIN SMALL LETTER S WITH CARON + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0146' # 0xF2 -> LATIN SMALL LETTER N WITH CEDILLA + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\u014d' # 0xF4 -> LATIN SMALL LETTER O WITH MACRON + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0173' # 0xF8 -> LATIN SMALL LETTER U WITH OGONEK + '\u0142' # 0xF9 -> LATIN SMALL LETTER L WITH STROKE + '\u015b' # 0xFA -> LATIN SMALL LETTER S WITH ACUTE + '\u016b' # 0xFB -> LATIN SMALL LETTER U WITH MACRON + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u017e' # 0xFE -> LATIN SMALL LETTER Z WITH CARON + '\u2019' # 0xFF -> RIGHT SINGLE QUOTATION MARK +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_14.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_14.py new file mode 100644 index 0000000..7568d4e --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_14.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_14 generated from 'MAPPINGS/ISO8859/8859-14.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-14', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u1e02' # 0xA1 -> LATIN CAPITAL LETTER B WITH DOT ABOVE + '\u1e03' # 0xA2 -> LATIN SMALL LETTER B WITH DOT ABOVE + '\xa3' # 0xA3 -> POUND SIGN + '\u010a' # 0xA4 -> LATIN CAPITAL LETTER C WITH DOT ABOVE + '\u010b' # 0xA5 -> LATIN SMALL LETTER C WITH DOT ABOVE + '\u1e0a' # 0xA6 -> LATIN CAPITAL LETTER D WITH DOT ABOVE + '\xa7' # 0xA7 -> SECTION SIGN + '\u1e80' # 0xA8 -> LATIN CAPITAL LETTER W WITH GRAVE + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u1e82' # 0xAA -> LATIN CAPITAL LETTER W WITH ACUTE + '\u1e0b' # 0xAB -> LATIN SMALL LETTER D WITH DOT ABOVE + '\u1ef2' # 0xAC -> LATIN CAPITAL LETTER Y WITH GRAVE + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u0178' # 0xAF -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u1e1e' # 0xB0 -> LATIN CAPITAL LETTER F WITH DOT ABOVE + '\u1e1f' # 0xB1 -> LATIN SMALL LETTER F WITH DOT ABOVE + '\u0120' # 0xB2 -> LATIN CAPITAL LETTER G WITH DOT ABOVE + '\u0121' # 0xB3 -> LATIN SMALL LETTER G WITH DOT ABOVE + '\u1e40' # 0xB4 -> LATIN CAPITAL LETTER M WITH DOT ABOVE + '\u1e41' # 0xB5 -> LATIN SMALL LETTER M WITH DOT ABOVE + '\xb6' # 0xB6 -> PILCROW SIGN + '\u1e56' # 0xB7 -> LATIN CAPITAL LETTER P WITH DOT ABOVE + '\u1e81' # 0xB8 -> LATIN SMALL LETTER W WITH GRAVE + '\u1e57' # 0xB9 -> LATIN SMALL LETTER P WITH DOT ABOVE + '\u1e83' # 0xBA -> LATIN SMALL LETTER W WITH ACUTE + '\u1e60' # 0xBB -> LATIN CAPITAL LETTER S WITH DOT ABOVE + '\u1ef3' # 0xBC -> LATIN SMALL LETTER Y WITH GRAVE + '\u1e84' # 0xBD -> LATIN CAPITAL LETTER W WITH DIAERESIS + '\u1e85' # 0xBE -> LATIN SMALL LETTER W WITH DIAERESIS + '\u1e61' # 0xBF -> LATIN SMALL LETTER S WITH DOT ABOVE + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u0174' # 0xD0 -> LATIN CAPITAL LETTER W WITH CIRCUMFLEX + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u1e6a' # 0xD7 -> LATIN CAPITAL LETTER T WITH DOT ABOVE + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0176' # 0xDE -> LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u0175' # 0xF0 -> LATIN SMALL LETTER W WITH CIRCUMFLEX + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u1e6b' # 0xF7 -> LATIN SMALL LETTER T WITH DOT ABOVE + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\u0177' # 0xFE -> LATIN SMALL LETTER Y WITH CIRCUMFLEX + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_15.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_15.py new file mode 100644 index 0000000..43bdecd --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_15.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_15 generated from 'MAPPINGS/ISO8859/8859-15.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-15', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\u20ac' # 0xA4 -> EURO SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON + '\xa7' # 0xA7 -> SECTION SIGN + '\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xBD -> LATIN SMALL LIGATURE OE + '\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_16.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_16.py new file mode 100644 index 0000000..e70c96e --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_16.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_16 generated from 'MAPPINGS/ISO8859/8859-16.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-16', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0105' # 0xA2 -> LATIN SMALL LETTER A WITH OGONEK + '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + '\u20ac' # 0xA4 -> EURO SIGN + '\u201e' # 0xA5 -> DOUBLE LOW-9 QUOTATION MARK + '\u0160' # 0xA6 -> LATIN CAPITAL LETTER S WITH CARON + '\xa7' # 0xA7 -> SECTION SIGN + '\u0161' # 0xA8 -> LATIN SMALL LETTER S WITH CARON + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0218' # 0xAA -> LATIN CAPITAL LETTER S WITH COMMA BELOW + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xad' # 0xAD -> SOFT HYPHEN + '\u017a' # 0xAE -> LATIN SMALL LETTER Z WITH ACUTE + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u010c' # 0xB2 -> LATIN CAPITAL LETTER C WITH CARON + '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + '\u017d' # 0xB4 -> LATIN CAPITAL LETTER Z WITH CARON + '\u201d' # 0xB5 -> RIGHT DOUBLE QUOTATION MARK + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u017e' # 0xB8 -> LATIN SMALL LETTER Z WITH CARON + '\u010d' # 0xB9 -> LATIN SMALL LETTER C WITH CARON + '\u0219' # 0xBA -> LATIN SMALL LETTER S WITH COMMA BELOW + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0152' # 0xBC -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xBD -> LATIN SMALL LIGATURE OE + '\u0178' # 0xBE -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0106' # 0xC5 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\u015a' # 0xD7 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u0170' # 0xD8 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0118' # 0xDD -> LATIN CAPITAL LETTER E WITH OGONEK + '\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u0107' # 0xE5 -> LATIN SMALL LETTER C WITH ACUTE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\u015b' # 0xF7 -> LATIN SMALL LETTER S WITH ACUTE + '\u0171' # 0xF8 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0119' # 0xFD -> LATIN SMALL LETTER E WITH OGONEK + '\u021b' # 0xFE -> LATIN SMALL LETTER T WITH COMMA BELOW + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_2.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_2.py new file mode 100644 index 0000000..3698747 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_2.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_2 generated from 'MAPPINGS/ISO8859/8859-2.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u02d8' # 0xA2 -> BREVE + '\u0141' # 0xA3 -> LATIN CAPITAL LETTER L WITH STROKE + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u013d' # 0xA5 -> LATIN CAPITAL LETTER L WITH CARON + '\u015a' # 0xA6 -> LATIN CAPITAL LETTER S WITH ACUTE + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u0164' # 0xAB -> LATIN CAPITAL LETTER T WITH CARON + '\u0179' # 0xAC -> LATIN CAPITAL LETTER Z WITH ACUTE + '\xad' # 0xAD -> SOFT HYPHEN + '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + '\u02db' # 0xB2 -> OGONEK + '\u0142' # 0xB3 -> LATIN SMALL LETTER L WITH STROKE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\u013e' # 0xB5 -> LATIN SMALL LETTER L WITH CARON + '\u015b' # 0xB6 -> LATIN SMALL LETTER S WITH ACUTE + '\u02c7' # 0xB7 -> CARON + '\xb8' # 0xB8 -> CEDILLA + '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + '\u0165' # 0xBB -> LATIN SMALL LETTER T WITH CARON + '\u017a' # 0xBC -> LATIN SMALL LETTER Z WITH ACUTE + '\u02dd' # 0xBD -> DOUBLE ACUTE ACCENT + '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u0154' # 0xC0 -> LATIN CAPITAL LETTER R WITH ACUTE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0102' # 0xC3 -> LATIN CAPITAL LETTER A WITH BREVE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0139' # 0xC5 -> LATIN CAPITAL LETTER L WITH ACUTE + '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u011a' # 0xCC -> LATIN CAPITAL LETTER E WITH CARON + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u010e' # 0xCF -> LATIN CAPITAL LETTER D WITH CARON + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0143' # 0xD1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\u0147' # 0xD2 -> LATIN CAPITAL LETTER N WITH CARON + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0150' # 0xD5 -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u0158' # 0xD8 -> LATIN CAPITAL LETTER R WITH CARON + '\u016e' # 0xD9 -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\u0170' # 0xDB -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\u0162' # 0xDE -> LATIN CAPITAL LETTER T WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0155' # 0xE0 -> LATIN SMALL LETTER R WITH ACUTE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\u0103' # 0xE3 -> LATIN SMALL LETTER A WITH BREVE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u013a' # 0xE5 -> LATIN SMALL LETTER L WITH ACUTE + '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u011b' # 0xEC -> LATIN SMALL LETTER E WITH CARON + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u010f' # 0xEF -> LATIN SMALL LETTER D WITH CARON + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0144' # 0xF1 -> LATIN SMALL LETTER N WITH ACUTE + '\u0148' # 0xF2 -> LATIN SMALL LETTER N WITH CARON + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0151' # 0xF5 -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u0159' # 0xF8 -> LATIN SMALL LETTER R WITH CARON + '\u016f' # 0xF9 -> LATIN SMALL LETTER U WITH RING ABOVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\u0171' # 0xFB -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\u0163' # 0xFE -> LATIN SMALL LETTER T WITH CEDILLA + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_3.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_3.py new file mode 100644 index 0000000..96d3063 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_3.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_3 generated from 'MAPPINGS/ISO8859/8859-3.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-3', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0126' # 0xA1 -> LATIN CAPITAL LETTER H WITH STROKE + '\u02d8' # 0xA2 -> BREVE + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\ufffe' + '\u0124' # 0xA6 -> LATIN CAPITAL LETTER H WITH CIRCUMFLEX + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\u0130' # 0xA9 -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u015e' # 0xAA -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u011e' # 0xAB -> LATIN CAPITAL LETTER G WITH BREVE + '\u0134' # 0xAC -> LATIN CAPITAL LETTER J WITH CIRCUMFLEX + '\xad' # 0xAD -> SOFT HYPHEN + '\ufffe' + '\u017b' # 0xAF -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0127' # 0xB1 -> LATIN SMALL LETTER H WITH STROKE + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\u0125' # 0xB6 -> LATIN SMALL LETTER H WITH CIRCUMFLEX + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\u0131' # 0xB9 -> LATIN SMALL LETTER DOTLESS I + '\u015f' # 0xBA -> LATIN SMALL LETTER S WITH CEDILLA + '\u011f' # 0xBB -> LATIN SMALL LETTER G WITH BREVE + '\u0135' # 0xBC -> LATIN SMALL LETTER J WITH CIRCUMFLEX + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\ufffe' + '\u017c' # 0xBF -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\ufffe' + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u010a' # 0xC5 -> LATIN CAPITAL LETTER C WITH DOT ABOVE + '\u0108' # 0xC6 -> LATIN CAPITAL LETTER C WITH CIRCUMFLEX + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\ufffe' + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0120' # 0xD5 -> LATIN CAPITAL LETTER G WITH DOT ABOVE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\u011c' # 0xD8 -> LATIN CAPITAL LETTER G WITH CIRCUMFLEX + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u016c' # 0xDD -> LATIN CAPITAL LETTER U WITH BREVE + '\u015c' # 0xDE -> LATIN CAPITAL LETTER S WITH CIRCUMFLEX + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\ufffe' + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\u010b' # 0xE5 -> LATIN SMALL LETTER C WITH DOT ABOVE + '\u0109' # 0xE6 -> LATIN SMALL LETTER C WITH CIRCUMFLEX + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\ufffe' + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\u0121' # 0xF5 -> LATIN SMALL LETTER G WITH DOT ABOVE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\u011d' # 0xF8 -> LATIN SMALL LETTER G WITH CIRCUMFLEX + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u016d' # 0xFD -> LATIN SMALL LETTER U WITH BREVE + '\u015d' # 0xFE -> LATIN SMALL LETTER S WITH CIRCUMFLEX + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_4.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_4.py new file mode 100644 index 0000000..65c1e00 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_4.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_4 generated from 'MAPPINGS/ISO8859/8859-4.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-4', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0104' # 0xA1 -> LATIN CAPITAL LETTER A WITH OGONEK + '\u0138' # 0xA2 -> LATIN SMALL LETTER KRA + '\u0156' # 0xA3 -> LATIN CAPITAL LETTER R WITH CEDILLA + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u0128' # 0xA5 -> LATIN CAPITAL LETTER I WITH TILDE + '\u013b' # 0xA6 -> LATIN CAPITAL LETTER L WITH CEDILLA + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + '\u0112' # 0xAA -> LATIN CAPITAL LETTER E WITH MACRON + '\u0122' # 0xAB -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u0166' # 0xAC -> LATIN CAPITAL LETTER T WITH STROKE + '\xad' # 0xAD -> SOFT HYPHEN + '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\u0105' # 0xB1 -> LATIN SMALL LETTER A WITH OGONEK + '\u02db' # 0xB2 -> OGONEK + '\u0157' # 0xB3 -> LATIN SMALL LETTER R WITH CEDILLA + '\xb4' # 0xB4 -> ACUTE ACCENT + '\u0129' # 0xB5 -> LATIN SMALL LETTER I WITH TILDE + '\u013c' # 0xB6 -> LATIN SMALL LETTER L WITH CEDILLA + '\u02c7' # 0xB7 -> CARON + '\xb8' # 0xB8 -> CEDILLA + '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + '\u0113' # 0xBA -> LATIN SMALL LETTER E WITH MACRON + '\u0123' # 0xBB -> LATIN SMALL LETTER G WITH CEDILLA + '\u0167' # 0xBC -> LATIN SMALL LETTER T WITH STROKE + '\u014a' # 0xBD -> LATIN CAPITAL LETTER ENG + '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + '\u014b' # 0xBF -> LATIN SMALL LETTER ENG + '\u0100' # 0xC0 -> LATIN CAPITAL LETTER A WITH MACRON + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\u012e' # 0xC7 -> LATIN CAPITAL LETTER I WITH OGONEK + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0118' # 0xCA -> LATIN CAPITAL LETTER E WITH OGONEK + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u0116' # 0xCC -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\u012a' # 0xCF -> LATIN CAPITAL LETTER I WITH MACRON + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u0145' # 0xD1 -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u014c' # 0xD2 -> LATIN CAPITAL LETTER O WITH MACRON + '\u0136' # 0xD3 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\u0172' # 0xD9 -> LATIN CAPITAL LETTER U WITH OGONEK + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0168' # 0xDD -> LATIN CAPITAL LETTER U WITH TILDE + '\u016a' # 0xDE -> LATIN CAPITAL LETTER U WITH MACRON + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\u0101' # 0xE0 -> LATIN SMALL LETTER A WITH MACRON + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\u012f' # 0xE7 -> LATIN SMALL LETTER I WITH OGONEK + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\u0119' # 0xEA -> LATIN SMALL LETTER E WITH OGONEK + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\u0117' # 0xEC -> LATIN SMALL LETTER E WITH DOT ABOVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\u012b' # 0xEF -> LATIN SMALL LETTER I WITH MACRON + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\u0146' # 0xF1 -> LATIN SMALL LETTER N WITH CEDILLA + '\u014d' # 0xF2 -> LATIN SMALL LETTER O WITH MACRON + '\u0137' # 0xF3 -> LATIN SMALL LETTER K WITH CEDILLA + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\u0173' # 0xF9 -> LATIN SMALL LETTER U WITH OGONEK + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0169' # 0xFD -> LATIN SMALL LETTER U WITH TILDE + '\u016b' # 0xFE -> LATIN SMALL LETTER U WITH MACRON + '\u02d9' # 0xFF -> DOT ABOVE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_5.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_5.py new file mode 100644 index 0000000..a3c868a --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_5.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_5 generated from 'MAPPINGS/ISO8859/8859-5.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-5', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u0401' # 0xA1 -> CYRILLIC CAPITAL LETTER IO + '\u0402' # 0xA2 -> CYRILLIC CAPITAL LETTER DJE + '\u0403' # 0xA3 -> CYRILLIC CAPITAL LETTER GJE + '\u0404' # 0xA4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0405' # 0xA5 -> CYRILLIC CAPITAL LETTER DZE + '\u0406' # 0xA6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0407' # 0xA7 -> CYRILLIC CAPITAL LETTER YI + '\u0408' # 0xA8 -> CYRILLIC CAPITAL LETTER JE + '\u0409' # 0xA9 -> CYRILLIC CAPITAL LETTER LJE + '\u040a' # 0xAA -> CYRILLIC CAPITAL LETTER NJE + '\u040b' # 0xAB -> CYRILLIC CAPITAL LETTER TSHE + '\u040c' # 0xAC -> CYRILLIC CAPITAL LETTER KJE + '\xad' # 0xAD -> SOFT HYPHEN + '\u040e' # 0xAE -> CYRILLIC CAPITAL LETTER SHORT U + '\u040f' # 0xAF -> CYRILLIC CAPITAL LETTER DZHE + '\u0410' # 0xB0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xB1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xB2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xB3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xB4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xB5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xB6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xB7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xB8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xB9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xBA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xBB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xBC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xBD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xBE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xBF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xC0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xC1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xC2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xC3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xC4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xC5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xC6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xC7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xC8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xC9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xCA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xCB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xCC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xCD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xCE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xCF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xD0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xD1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xD2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xD3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xD4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xD5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xD7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xD8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xD9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xDA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xDB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xDC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xDD -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xDE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xDF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xE0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xE1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xE2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xE3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xE4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xE5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xE6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xE7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xE8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xE9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xEA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xEB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xEC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xED -> CYRILLIC SMALL LETTER E + '\u044e' # 0xEE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xEF -> CYRILLIC SMALL LETTER YA + '\u2116' # 0xF0 -> NUMERO SIGN + '\u0451' # 0xF1 -> CYRILLIC SMALL LETTER IO + '\u0452' # 0xF2 -> CYRILLIC SMALL LETTER DJE + '\u0453' # 0xF3 -> CYRILLIC SMALL LETTER GJE + '\u0454' # 0xF4 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0455' # 0xF5 -> CYRILLIC SMALL LETTER DZE + '\u0456' # 0xF6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0457' # 0xF7 -> CYRILLIC SMALL LETTER YI + '\u0458' # 0xF8 -> CYRILLIC SMALL LETTER JE + '\u0459' # 0xF9 -> CYRILLIC SMALL LETTER LJE + '\u045a' # 0xFA -> CYRILLIC SMALL LETTER NJE + '\u045b' # 0xFB -> CYRILLIC SMALL LETTER TSHE + '\u045c' # 0xFC -> CYRILLIC SMALL LETTER KJE + '\xa7' # 0xFD -> SECTION SIGN + '\u045e' # 0xFE -> CYRILLIC SMALL LETTER SHORT U + '\u045f' # 0xFF -> CYRILLIC SMALL LETTER DZHE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_6.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_6.py new file mode 100644 index 0000000..b02ade6 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_6.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_6 generated from 'MAPPINGS/ISO8859/8859-6.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-6', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\ufffe' + '\ufffe' + '\ufffe' + '\xa4' # 0xA4 -> CURRENCY SIGN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u060c' # 0xAC -> ARABIC COMMA + '\xad' # 0xAD -> SOFT HYPHEN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u061b' # 0xBB -> ARABIC SEMICOLON + '\ufffe' + '\ufffe' + '\ufffe' + '\u061f' # 0xBF -> ARABIC QUESTION MARK + '\ufffe' + '\u0621' # 0xC1 -> ARABIC LETTER HAMZA + '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0xC7 -> ARABIC LETTER ALEF + '\u0628' # 0xC8 -> ARABIC LETTER BEH + '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xCA -> ARABIC LETTER TEH + '\u062b' # 0xCB -> ARABIC LETTER THEH + '\u062c' # 0xCC -> ARABIC LETTER JEEM + '\u062d' # 0xCD -> ARABIC LETTER HAH + '\u062e' # 0xCE -> ARABIC LETTER KHAH + '\u062f' # 0xCF -> ARABIC LETTER DAL + '\u0630' # 0xD0 -> ARABIC LETTER THAL + '\u0631' # 0xD1 -> ARABIC LETTER REH + '\u0632' # 0xD2 -> ARABIC LETTER ZAIN + '\u0633' # 0xD3 -> ARABIC LETTER SEEN + '\u0634' # 0xD4 -> ARABIC LETTER SHEEN + '\u0635' # 0xD5 -> ARABIC LETTER SAD + '\u0636' # 0xD6 -> ARABIC LETTER DAD + '\u0637' # 0xD7 -> ARABIC LETTER TAH + '\u0638' # 0xD8 -> ARABIC LETTER ZAH + '\u0639' # 0xD9 -> ARABIC LETTER AIN + '\u063a' # 0xDA -> ARABIC LETTER GHAIN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u0640' # 0xE0 -> ARABIC TATWEEL + '\u0641' # 0xE1 -> ARABIC LETTER FEH + '\u0642' # 0xE2 -> ARABIC LETTER QAF + '\u0643' # 0xE3 -> ARABIC LETTER KAF + '\u0644' # 0xE4 -> ARABIC LETTER LAM + '\u0645' # 0xE5 -> ARABIC LETTER MEEM + '\u0646' # 0xE6 -> ARABIC LETTER NOON + '\u0647' # 0xE7 -> ARABIC LETTER HEH + '\u0648' # 0xE8 -> ARABIC LETTER WAW + '\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xEA -> ARABIC LETTER YEH + '\u064b' # 0xEB -> ARABIC FATHATAN + '\u064c' # 0xEC -> ARABIC DAMMATAN + '\u064d' # 0xED -> ARABIC KASRATAN + '\u064e' # 0xEE -> ARABIC FATHA + '\u064f' # 0xEF -> ARABIC DAMMA + '\u0650' # 0xF0 -> ARABIC KASRA + '\u0651' # 0xF1 -> ARABIC SHADDA + '\u0652' # 0xF2 -> ARABIC SUKUN + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_7.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_7.py new file mode 100644 index 0000000..d7b39cb --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_7.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_7 generated from 'MAPPINGS/ISO8859/8859-7.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-7', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u2018' # 0xA1 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xA2 -> RIGHT SINGLE QUOTATION MARK + '\xa3' # 0xA3 -> POUND SIGN + '\u20ac' # 0xA4 -> EURO SIGN + '\u20af' # 0xA5 -> DRACHMA SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u037a' # 0xAA -> GREEK YPOGEGRAMMENI + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\ufffe' + '\u2015' # 0xAF -> HORIZONTAL BAR + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\u0384' # 0xB4 -> GREEK TONOS + '\u0385' # 0xB5 -> GREEK DIALYTIKA TONOS + '\u0386' # 0xB6 -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0388' # 0xB8 -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0389' # 0xB9 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0xBA -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u038c' # 0xBC -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\u038e' # 0xBE -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u038f' # 0xBF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\u0390' # 0xC0 -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u0391' # 0xC1 -> GREEK CAPITAL LETTER ALPHA + '\u0392' # 0xC2 -> GREEK CAPITAL LETTER BETA + '\u0393' # 0xC3 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0xC4 -> GREEK CAPITAL LETTER DELTA + '\u0395' # 0xC5 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0xC6 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0xC7 -> GREEK CAPITAL LETTER ETA + '\u0398' # 0xC8 -> GREEK CAPITAL LETTER THETA + '\u0399' # 0xC9 -> GREEK CAPITAL LETTER IOTA + '\u039a' # 0xCA -> GREEK CAPITAL LETTER KAPPA + '\u039b' # 0xCB -> GREEK CAPITAL LETTER LAMDA + '\u039c' # 0xCC -> GREEK CAPITAL LETTER MU + '\u039d' # 0xCD -> GREEK CAPITAL LETTER NU + '\u039e' # 0xCE -> GREEK CAPITAL LETTER XI + '\u039f' # 0xCF -> GREEK CAPITAL LETTER OMICRON + '\u03a0' # 0xD0 -> GREEK CAPITAL LETTER PI + '\u03a1' # 0xD1 -> GREEK CAPITAL LETTER RHO + '\ufffe' + '\u03a3' # 0xD3 -> GREEK CAPITAL LETTER SIGMA + '\u03a4' # 0xD4 -> GREEK CAPITAL LETTER TAU + '\u03a5' # 0xD5 -> GREEK CAPITAL LETTER UPSILON + '\u03a6' # 0xD6 -> GREEK CAPITAL LETTER PHI + '\u03a7' # 0xD7 -> GREEK CAPITAL LETTER CHI + '\u03a8' # 0xD8 -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0xD9 -> GREEK CAPITAL LETTER OMEGA + '\u03aa' # 0xDA -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\u03ab' # 0xDB -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\u03ac' # 0xDC -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u03ad' # 0xDD -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xDE -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0xDF -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03b0' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + '\u03b3' # 0xE3 -> GREEK SMALL LETTER GAMMA + '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + '\u03b6' # 0xE6 -> GREEK SMALL LETTER ZETA + '\u03b7' # 0xE7 -> GREEK SMALL LETTER ETA + '\u03b8' # 0xE8 -> GREEK SMALL LETTER THETA + '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + '\u03ba' # 0xEA -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0xEB -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0xEC -> GREEK SMALL LETTER MU + '\u03bd' # 0xED -> GREEK SMALL LETTER NU + '\u03be' # 0xEE -> GREEK SMALL LETTER XI + '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + '\u03c1' # 0xF1 -> GREEK SMALL LETTER RHO + '\u03c2' # 0xF2 -> GREEK SMALL LETTER FINAL SIGMA + '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + '\u03c5' # 0xF5 -> GREEK SMALL LETTER UPSILON + '\u03c6' # 0xF6 -> GREEK SMALL LETTER PHI + '\u03c7' # 0xF7 -> GREEK SMALL LETTER CHI + '\u03c8' # 0xF8 -> GREEK SMALL LETTER PSI + '\u03c9' # 0xF9 -> GREEK SMALL LETTER OMEGA + '\u03ca' # 0xFA -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03cb' # 0xFB -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u03cc' # 0xFC -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u03cd' # 0xFD -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03ce' # 0xFE -> GREEK SMALL LETTER OMEGA WITH TONOS + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_8.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_8.py new file mode 100644 index 0000000..8184902 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_8.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_8 generated from 'MAPPINGS/ISO8859/8859-8.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-8', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\ufffe' + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xd7' # 0xAA -> MULTIPLICATION SIGN + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xf7' # 0xBA -> DIVISION SIGN + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u2017' # 0xDF -> DOUBLE LOW LINE + '\u05d0' # 0xE0 -> HEBREW LETTER ALEF + '\u05d1' # 0xE1 -> HEBREW LETTER BET + '\u05d2' # 0xE2 -> HEBREW LETTER GIMEL + '\u05d3' # 0xE3 -> HEBREW LETTER DALET + '\u05d4' # 0xE4 -> HEBREW LETTER HE + '\u05d5' # 0xE5 -> HEBREW LETTER VAV + '\u05d6' # 0xE6 -> HEBREW LETTER ZAYIN + '\u05d7' # 0xE7 -> HEBREW LETTER HET + '\u05d8' # 0xE8 -> HEBREW LETTER TET + '\u05d9' # 0xE9 -> HEBREW LETTER YOD + '\u05da' # 0xEA -> HEBREW LETTER FINAL KAF + '\u05db' # 0xEB -> HEBREW LETTER KAF + '\u05dc' # 0xEC -> HEBREW LETTER LAMED + '\u05dd' # 0xED -> HEBREW LETTER FINAL MEM + '\u05de' # 0xEE -> HEBREW LETTER MEM + '\u05df' # 0xEF -> HEBREW LETTER FINAL NUN + '\u05e0' # 0xF0 -> HEBREW LETTER NUN + '\u05e1' # 0xF1 -> HEBREW LETTER SAMEKH + '\u05e2' # 0xF2 -> HEBREW LETTER AYIN + '\u05e3' # 0xF3 -> HEBREW LETTER FINAL PE + '\u05e4' # 0xF4 -> HEBREW LETTER PE + '\u05e5' # 0xF5 -> HEBREW LETTER FINAL TSADI + '\u05e6' # 0xF6 -> HEBREW LETTER TSADI + '\u05e7' # 0xF7 -> HEBREW LETTER QOF + '\u05e8' # 0xF8 -> HEBREW LETTER RESH + '\u05e9' # 0xF9 -> HEBREW LETTER SHIN + '\u05ea' # 0xFA -> HEBREW LETTER TAV + '\ufffe' + '\ufffe' + '\u200e' # 0xFD -> LEFT-TO-RIGHT MARK + '\u200f' # 0xFE -> RIGHT-TO-LEFT MARK + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_9.py b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_9.py new file mode 100644 index 0000000..e539fdd --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/iso8859_9.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec iso8859_9 generated from 'MAPPINGS/ISO8859/8859-9.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-9', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\u011e' # 0xD0 -> LATIN CAPITAL LETTER G WITH BREVE + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0130' # 0xDD -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\u011f' # 0xF0 -> LATIN SMALL LETTER G WITH BREVE + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\u0131' # 0xFD -> LATIN SMALL LETTER DOTLESS I + '\u015f' # 0xFE -> LATIN SMALL LETTER S WITH CEDILLA + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/koi8_r.py b/crates/weavepy-vm/src/stdlib/python/encodings/koi8_r.py new file mode 100644 index 0000000..41ddde8 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/koi8_r.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec koi8_r generated from 'MAPPINGS/VENDORS/MISC/KOI8-R.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-r', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL + '\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u2580' # 0x8B -> UPPER HALF BLOCK + '\u2584' # 0x8C -> LOWER HALF BLOCK + '\u2588' # 0x8D -> FULL BLOCK + '\u258c' # 0x8E -> LEFT HALF BLOCK + '\u2590' # 0x8F -> RIGHT HALF BLOCK + '\u2591' # 0x90 -> LIGHT SHADE + '\u2592' # 0x91 -> MEDIUM SHADE + '\u2593' # 0x92 -> DARK SHADE + '\u2320' # 0x93 -> TOP HALF INTEGRAL + '\u25a0' # 0x94 -> BLACK SQUARE + '\u2219' # 0x95 -> BULLET OPERATOR + '\u221a' # 0x96 -> SQUARE ROOT + '\u2248' # 0x97 -> ALMOST EQUAL TO + '\u2264' # 0x98 -> LESS-THAN OR EQUAL TO + '\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO + '\xa0' # 0x9A -> NO-BREAK SPACE + '\u2321' # 0x9B -> BOTTOM HALF INTEGRAL + '\xb0' # 0x9C -> DEGREE SIGN + '\xb2' # 0x9D -> SUPERSCRIPT TWO + '\xb7' # 0x9E -> MIDDLE DOT + '\xf7' # 0x9F -> DIVISION SIGN + '\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL + '\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + '\u2553' # 0xA4 -> BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + '\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u2555' # 0xA6 -> BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + '\u2556' # 0xA7 -> BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + '\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u255c' # 0xAD -> BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + '\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + '\u2562' # 0xB4 -> BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + '\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u2564' # 0xB6 -> BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + '\u2565' # 0xB7 -> BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + '\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u256b' # 0xBD -> BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + '\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa9' # 0xBF -> COPYRIGHT SIGN + '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/koi8_t.py b/crates/weavepy-vm/src/stdlib/python/encodings/koi8_t.py new file mode 100644 index 0000000..b5415ba --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/koi8_t.py @@ -0,0 +1,308 @@ +""" Python Character Mapping Codec koi8_t +""" +# http://ru.wikipedia.org/wiki/КОИ-8 +# http://www.opensource.apple.com/source/libiconv/libiconv-4/libiconv/tests/KOI8-T.TXT + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-t', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u049b' # 0x80 -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u0493' # 0x81 -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0492' # 0x83 -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\ufffe' # 0x88 -> UNDEFINED + '\u2030' # 0x89 -> PER MILLE SIGN + '\u04b3' # 0x8A -> CYRILLIC SMALL LETTER HA WITH DESCENDER + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u04b2' # 0x8C -> CYRILLIC CAPITAL LETTER HA WITH DESCENDER + '\u04b7' # 0x8D -> CYRILLIC SMALL LETTER CHE WITH DESCENDER + '\u04b6' # 0x8E -> CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + '\ufffe' # 0x8F -> UNDEFINED + '\u049a' # 0x90 -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\ufffe' # 0x9A -> UNDEFINED + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufffe' # 0x9C -> UNDEFINED + '\ufffe' # 0x9D -> UNDEFINED + '\ufffe' # 0x9E -> UNDEFINED + '\ufffe' # 0x9F -> UNDEFINED + '\ufffe' # 0xA0 -> UNDEFINED + '\u04ef' # 0xA1 -> CYRILLIC SMALL LETTER U WITH MACRON + '\u04ee' # 0xA2 -> CYRILLIC CAPITAL LETTER U WITH MACRON + '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u04e3' # 0xA5 -> CYRILLIC SMALL LETTER I WITH MACRON + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\ufffe' # 0xA8 -> UNDEFINED + '\ufffe' # 0xA9 -> UNDEFINED + '\ufffe' # 0xAA -> UNDEFINED + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\ufffe' # 0xAF -> UNDEFINED + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + '\ufffe' # 0xB4 -> UNDEFINED + '\u04e2' # 0xB5 -> CYRILLIC CAPITAL LETTER I WITH MACRON + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\ufffe' # 0xB8 -> UNDEFINED + '\u2116' # 0xB9 -> NUMERO SIGN + '\ufffe' # 0xBA -> UNDEFINED + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\ufffe' # 0xBC -> UNDEFINED + '\ufffe' # 0xBD -> UNDEFINED + '\ufffe' # 0xBE -> UNDEFINED + '\xa9' # 0xBF -> COPYRIGHT SIGN + '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/koi8_u.py b/crates/weavepy-vm/src/stdlib/python/encodings/koi8_u.py new file mode 100644 index 0000000..f9e3fae --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/koi8_u.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec koi8_u generated from 'python-mappings/KOI8-U.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='koi8-u', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u2500' # 0x80 -> BOX DRAWINGS LIGHT HORIZONTAL + '\u2502' # 0x81 -> BOX DRAWINGS LIGHT VERTICAL + '\u250c' # 0x82 -> BOX DRAWINGS LIGHT DOWN AND RIGHT + '\u2510' # 0x83 -> BOX DRAWINGS LIGHT DOWN AND LEFT + '\u2514' # 0x84 -> BOX DRAWINGS LIGHT UP AND RIGHT + '\u2518' # 0x85 -> BOX DRAWINGS LIGHT UP AND LEFT + '\u251c' # 0x86 -> BOX DRAWINGS LIGHT VERTICAL AND RIGHT + '\u2524' # 0x87 -> BOX DRAWINGS LIGHT VERTICAL AND LEFT + '\u252c' # 0x88 -> BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + '\u2534' # 0x89 -> BOX DRAWINGS LIGHT UP AND HORIZONTAL + '\u253c' # 0x8A -> BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + '\u2580' # 0x8B -> UPPER HALF BLOCK + '\u2584' # 0x8C -> LOWER HALF BLOCK + '\u2588' # 0x8D -> FULL BLOCK + '\u258c' # 0x8E -> LEFT HALF BLOCK + '\u2590' # 0x8F -> RIGHT HALF BLOCK + '\u2591' # 0x90 -> LIGHT SHADE + '\u2592' # 0x91 -> MEDIUM SHADE + '\u2593' # 0x92 -> DARK SHADE + '\u2320' # 0x93 -> TOP HALF INTEGRAL + '\u25a0' # 0x94 -> BLACK SQUARE + '\u2219' # 0x95 -> BULLET OPERATOR + '\u221a' # 0x96 -> SQUARE ROOT + '\u2248' # 0x97 -> ALMOST EQUAL TO + '\u2264' # 0x98 -> LESS-THAN OR EQUAL TO + '\u2265' # 0x99 -> GREATER-THAN OR EQUAL TO + '\xa0' # 0x9A -> NO-BREAK SPACE + '\u2321' # 0x9B -> BOTTOM HALF INTEGRAL + '\xb0' # 0x9C -> DEGREE SIGN + '\xb2' # 0x9D -> SUPERSCRIPT TWO + '\xb7' # 0x9E -> MIDDLE DOT + '\xf7' # 0x9F -> DIVISION SIGN + '\u2550' # 0xA0 -> BOX DRAWINGS DOUBLE HORIZONTAL + '\u2551' # 0xA1 -> BOX DRAWINGS DOUBLE VERTICAL + '\u2552' # 0xA2 -> BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + '\u0451' # 0xA3 -> CYRILLIC SMALL LETTER IO + '\u0454' # 0xA4 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u2554' # 0xA5 -> BOX DRAWINGS DOUBLE DOWN AND RIGHT + '\u0456' # 0xA6 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0457' # 0xA7 -> CYRILLIC SMALL LETTER YI (UKRAINIAN) + '\u2557' # 0xA8 -> BOX DRAWINGS DOUBLE DOWN AND LEFT + '\u2558' # 0xA9 -> BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + '\u2559' # 0xAA -> BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + '\u255a' # 0xAB -> BOX DRAWINGS DOUBLE UP AND RIGHT + '\u255b' # 0xAC -> BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + '\u0491' # 0xAD -> CYRILLIC SMALL LETTER UKRAINIAN GHE WITH UPTURN + '\u255d' # 0xAE -> BOX DRAWINGS DOUBLE UP AND LEFT + '\u255e' # 0xAF -> BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + '\u255f' # 0xB0 -> BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + '\u2560' # 0xB1 -> BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + '\u2561' # 0xB2 -> BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + '\u0401' # 0xB3 -> CYRILLIC CAPITAL LETTER IO + '\u0404' # 0xB4 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u2563' # 0xB5 -> BOX DRAWINGS DOUBLE VERTICAL AND LEFT + '\u0406' # 0xB6 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0407' # 0xB7 -> CYRILLIC CAPITAL LETTER YI (UKRAINIAN) + '\u2566' # 0xB8 -> BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + '\u2567' # 0xB9 -> BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + '\u2568' # 0xBA -> BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + '\u2569' # 0xBB -> BOX DRAWINGS DOUBLE UP AND HORIZONTAL + '\u256a' # 0xBC -> BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + '\u0490' # 0xBD -> CYRILLIC CAPITAL LETTER UKRAINIAN GHE WITH UPTURN + '\u256c' # 0xBE -> BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + '\xa9' # 0xBF -> COPYRIGHT SIGN + '\u044e' # 0xC0 -> CYRILLIC SMALL LETTER YU + '\u0430' # 0xC1 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xC2 -> CYRILLIC SMALL LETTER BE + '\u0446' # 0xC3 -> CYRILLIC SMALL LETTER TSE + '\u0434' # 0xC4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xC5 -> CYRILLIC SMALL LETTER IE + '\u0444' # 0xC6 -> CYRILLIC SMALL LETTER EF + '\u0433' # 0xC7 -> CYRILLIC SMALL LETTER GHE + '\u0445' # 0xC8 -> CYRILLIC SMALL LETTER HA + '\u0438' # 0xC9 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xCA -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xCB -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xCC -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xCD -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xCE -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xCF -> CYRILLIC SMALL LETTER O + '\u043f' # 0xD0 -> CYRILLIC SMALL LETTER PE + '\u044f' # 0xD1 -> CYRILLIC SMALL LETTER YA + '\u0440' # 0xD2 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xD3 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xD4 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xD5 -> CYRILLIC SMALL LETTER U + '\u0436' # 0xD6 -> CYRILLIC SMALL LETTER ZHE + '\u0432' # 0xD7 -> CYRILLIC SMALL LETTER VE + '\u044c' # 0xD8 -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044b' # 0xD9 -> CYRILLIC SMALL LETTER YERU + '\u0437' # 0xDA -> CYRILLIC SMALL LETTER ZE + '\u0448' # 0xDB -> CYRILLIC SMALL LETTER SHA + '\u044d' # 0xDC -> CYRILLIC SMALL LETTER E + '\u0449' # 0xDD -> CYRILLIC SMALL LETTER SHCHA + '\u0447' # 0xDE -> CYRILLIC SMALL LETTER CHE + '\u044a' # 0xDF -> CYRILLIC SMALL LETTER HARD SIGN + '\u042e' # 0xE0 -> CYRILLIC CAPITAL LETTER YU + '\u0410' # 0xE1 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xE2 -> CYRILLIC CAPITAL LETTER BE + '\u0426' # 0xE3 -> CYRILLIC CAPITAL LETTER TSE + '\u0414' # 0xE4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xE5 -> CYRILLIC CAPITAL LETTER IE + '\u0424' # 0xE6 -> CYRILLIC CAPITAL LETTER EF + '\u0413' # 0xE7 -> CYRILLIC CAPITAL LETTER GHE + '\u0425' # 0xE8 -> CYRILLIC CAPITAL LETTER HA + '\u0418' # 0xE9 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xEA -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xEB -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xEC -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xED -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xEE -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xEF -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xF0 -> CYRILLIC CAPITAL LETTER PE + '\u042f' # 0xF1 -> CYRILLIC CAPITAL LETTER YA + '\u0420' # 0xF2 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xF3 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xF4 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xF5 -> CYRILLIC CAPITAL LETTER U + '\u0416' # 0xF6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0412' # 0xF7 -> CYRILLIC CAPITAL LETTER VE + '\u042c' # 0xF8 -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042b' # 0xF9 -> CYRILLIC CAPITAL LETTER YERU + '\u0417' # 0xFA -> CYRILLIC CAPITAL LETTER ZE + '\u0428' # 0xFB -> CYRILLIC CAPITAL LETTER SHA + '\u042d' # 0xFC -> CYRILLIC CAPITAL LETTER E + '\u0429' # 0xFD -> CYRILLIC CAPITAL LETTER SHCHA + '\u0427' # 0xFE -> CYRILLIC CAPITAL LETTER CHE + '\u042a' # 0xFF -> CYRILLIC CAPITAL LETTER HARD SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/kz1048.py b/crates/weavepy-vm/src/stdlib/python/encodings/kz1048.py new file mode 100644 index 0000000..712aee6 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/kz1048.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec kz1048 generated from 'MAPPINGS/VENDORS/MISC/KZ1048.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self, input, errors='strict'): + return codecs.charmap_encode(input, errors, encoding_table) + + def decode(self, input, errors='strict'): + return codecs.charmap_decode(input, errors, decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input, self.errors, encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input, self.errors, decoding_table)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='kz1048', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u0402' # 0x80 -> CYRILLIC CAPITAL LETTER DJE + '\u0403' # 0x81 -> CYRILLIC CAPITAL LETTER GJE + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0453' # 0x83 -> CYRILLIC SMALL LETTER GJE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u20ac' # 0x88 -> EURO SIGN + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0409' # 0x8A -> CYRILLIC CAPITAL LETTER LJE + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u040a' # 0x8C -> CYRILLIC CAPITAL LETTER NJE + '\u049a' # 0x8D -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u04ba' # 0x8E -> CYRILLIC CAPITAL LETTER SHHA + '\u040f' # 0x8F -> CYRILLIC CAPITAL LETTER DZHE + '\u0452' # 0x90 -> CYRILLIC SMALL LETTER DJE + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\ufffe' # 0x98 -> UNDEFINED + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0459' # 0x9A -> CYRILLIC SMALL LETTER LJE + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u045a' # 0x9C -> CYRILLIC SMALL LETTER NJE + '\u049b' # 0x9D -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u04bb' # 0x9E -> CYRILLIC SMALL LETTER SHHA + '\u045f' # 0x9F -> CYRILLIC SMALL LETTER DZHE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u04b0' # 0xA1 -> CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + '\u04b1' # 0xA2 -> CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + '\u04d8' # 0xA3 -> CYRILLIC CAPITAL LETTER SCHWA + '\xa4' # 0xA4 -> CURRENCY SIGN + '\u04e8' # 0xA5 -> CYRILLIC CAPITAL LETTER BARRED O + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u0492' # 0xAA -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\u04ae' # 0xAF -> CYRILLIC CAPITAL LETTER STRAIGHT U + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u04e9' # 0xB4 -> CYRILLIC SMALL LETTER BARRED O + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + '\u2116' # 0xB9 -> NUMERO SIGN + '\u0493' # 0xBA -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u04d9' # 0xBC -> CYRILLIC SMALL LETTER SCHWA + '\u04a2' # 0xBD -> CYRILLIC CAPITAL LETTER EN WITH DESCENDER + '\u04a3' # 0xBE -> CYRILLIC SMALL LETTER EN WITH DESCENDER + '\u04af' # 0xBF -> CYRILLIC SMALL LETTER STRAIGHT U + '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table = codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/latin_1.py b/crates/weavepy-vm/src/stdlib/python/encodings/latin_1.py new file mode 100644 index 0000000..370160c --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/latin_1.py @@ -0,0 +1,50 @@ +""" Python 'latin-1' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + # Note: Binding these as C functions will result in the class not + # converting them to methods. This is intended. + encode = codecs.latin_1_encode + decode = codecs.latin_1_decode + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.latin_1_encode(input,self.errors)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.latin_1_decode(input,self.errors)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +class StreamConverter(StreamWriter,StreamReader): + + encode = codecs.latin_1_decode + decode = codecs.latin_1_encode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='iso8859-1', + encode=Codec.encode, + decode=Codec.decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_arabic.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_arabic.py new file mode 100644 index 0000000..72847e8 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_arabic.py @@ -0,0 +1,698 @@ +""" Python Character Mapping Codec generated from 'VENDORS/APPLE/ARABIC.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_map) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_map)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-arabic', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + +### Decoding Map + +decoding_map = codecs.make_identity_dict(range(256)) +decoding_map.update({ + 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x0081: 0x00a0, # NO-BREAK SPACE, right-left + 0x0082: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x0083: 0x00c9, # LATIN CAPITAL LETTER E WITH ACUTE + 0x0084: 0x00d1, # LATIN CAPITAL LETTER N WITH TILDE + 0x0085: 0x00d6, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x0086: 0x00dc, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x0087: 0x00e1, # LATIN SMALL LETTER A WITH ACUTE + 0x0088: 0x00e0, # LATIN SMALL LETTER A WITH GRAVE + 0x0089: 0x00e2, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x008a: 0x00e4, # LATIN SMALL LETTER A WITH DIAERESIS + 0x008b: 0x06ba, # ARABIC LETTER NOON GHUNNA + 0x008c: 0x00ab, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x008d: 0x00e7, # LATIN SMALL LETTER C WITH CEDILLA + 0x008e: 0x00e9, # LATIN SMALL LETTER E WITH ACUTE + 0x008f: 0x00e8, # LATIN SMALL LETTER E WITH GRAVE + 0x0090: 0x00ea, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x0091: 0x00eb, # LATIN SMALL LETTER E WITH DIAERESIS + 0x0092: 0x00ed, # LATIN SMALL LETTER I WITH ACUTE + 0x0093: 0x2026, # HORIZONTAL ELLIPSIS, right-left + 0x0094: 0x00ee, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x0095: 0x00ef, # LATIN SMALL LETTER I WITH DIAERESIS + 0x0096: 0x00f1, # LATIN SMALL LETTER N WITH TILDE + 0x0097: 0x00f3, # LATIN SMALL LETTER O WITH ACUTE + 0x0098: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x0099: 0x00f4, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x009a: 0x00f6, # LATIN SMALL LETTER O WITH DIAERESIS + 0x009b: 0x00f7, # DIVISION SIGN, right-left + 0x009c: 0x00fa, # LATIN SMALL LETTER U WITH ACUTE + 0x009d: 0x00f9, # LATIN SMALL LETTER U WITH GRAVE + 0x009e: 0x00fb, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x009f: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS + 0x00a0: 0x0020, # SPACE, right-left + 0x00a1: 0x0021, # EXCLAMATION MARK, right-left + 0x00a2: 0x0022, # QUOTATION MARK, right-left + 0x00a3: 0x0023, # NUMBER SIGN, right-left + 0x00a4: 0x0024, # DOLLAR SIGN, right-left + 0x00a5: 0x066a, # ARABIC PERCENT SIGN + 0x00a6: 0x0026, # AMPERSAND, right-left + 0x00a7: 0x0027, # APOSTROPHE, right-left + 0x00a8: 0x0028, # LEFT PARENTHESIS, right-left + 0x00a9: 0x0029, # RIGHT PARENTHESIS, right-left + 0x00aa: 0x002a, # ASTERISK, right-left + 0x00ab: 0x002b, # PLUS SIGN, right-left + 0x00ac: 0x060c, # ARABIC COMMA + 0x00ad: 0x002d, # HYPHEN-MINUS, right-left + 0x00ae: 0x002e, # FULL STOP, right-left + 0x00af: 0x002f, # SOLIDUS, right-left + 0x00b0: 0x0660, # ARABIC-INDIC DIGIT ZERO, right-left (need override) + 0x00b1: 0x0661, # ARABIC-INDIC DIGIT ONE, right-left (need override) + 0x00b2: 0x0662, # ARABIC-INDIC DIGIT TWO, right-left (need override) + 0x00b3: 0x0663, # ARABIC-INDIC DIGIT THREE, right-left (need override) + 0x00b4: 0x0664, # ARABIC-INDIC DIGIT FOUR, right-left (need override) + 0x00b5: 0x0665, # ARABIC-INDIC DIGIT FIVE, right-left (need override) + 0x00b6: 0x0666, # ARABIC-INDIC DIGIT SIX, right-left (need override) + 0x00b7: 0x0667, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) + 0x00b8: 0x0668, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) + 0x00b9: 0x0669, # ARABIC-INDIC DIGIT NINE, right-left (need override) + 0x00ba: 0x003a, # COLON, right-left + 0x00bb: 0x061b, # ARABIC SEMICOLON + 0x00bc: 0x003c, # LESS-THAN SIGN, right-left + 0x00bd: 0x003d, # EQUALS SIGN, right-left + 0x00be: 0x003e, # GREATER-THAN SIGN, right-left + 0x00bf: 0x061f, # ARABIC QUESTION MARK + 0x00c0: 0x274a, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + 0x00c1: 0x0621, # ARABIC LETTER HAMZA + 0x00c2: 0x0622, # ARABIC LETTER ALEF WITH MADDA ABOVE + 0x00c3: 0x0623, # ARABIC LETTER ALEF WITH HAMZA ABOVE + 0x00c4: 0x0624, # ARABIC LETTER WAW WITH HAMZA ABOVE + 0x00c5: 0x0625, # ARABIC LETTER ALEF WITH HAMZA BELOW + 0x00c6: 0x0626, # ARABIC LETTER YEH WITH HAMZA ABOVE + 0x00c7: 0x0627, # ARABIC LETTER ALEF + 0x00c8: 0x0628, # ARABIC LETTER BEH + 0x00c9: 0x0629, # ARABIC LETTER TEH MARBUTA + 0x00ca: 0x062a, # ARABIC LETTER TEH + 0x00cb: 0x062b, # ARABIC LETTER THEH + 0x00cc: 0x062c, # ARABIC LETTER JEEM + 0x00cd: 0x062d, # ARABIC LETTER HAH + 0x00ce: 0x062e, # ARABIC LETTER KHAH + 0x00cf: 0x062f, # ARABIC LETTER DAL + 0x00d0: 0x0630, # ARABIC LETTER THAL + 0x00d1: 0x0631, # ARABIC LETTER REH + 0x00d2: 0x0632, # ARABIC LETTER ZAIN + 0x00d3: 0x0633, # ARABIC LETTER SEEN + 0x00d4: 0x0634, # ARABIC LETTER SHEEN + 0x00d5: 0x0635, # ARABIC LETTER SAD + 0x00d6: 0x0636, # ARABIC LETTER DAD + 0x00d7: 0x0637, # ARABIC LETTER TAH + 0x00d8: 0x0638, # ARABIC LETTER ZAH + 0x00d9: 0x0639, # ARABIC LETTER AIN + 0x00da: 0x063a, # ARABIC LETTER GHAIN + 0x00db: 0x005b, # LEFT SQUARE BRACKET, right-left + 0x00dc: 0x005c, # REVERSE SOLIDUS, right-left + 0x00dd: 0x005d, # RIGHT SQUARE BRACKET, right-left + 0x00de: 0x005e, # CIRCUMFLEX ACCENT, right-left + 0x00df: 0x005f, # LOW LINE, right-left + 0x00e0: 0x0640, # ARABIC TATWEEL + 0x00e1: 0x0641, # ARABIC LETTER FEH + 0x00e2: 0x0642, # ARABIC LETTER QAF + 0x00e3: 0x0643, # ARABIC LETTER KAF + 0x00e4: 0x0644, # ARABIC LETTER LAM + 0x00e5: 0x0645, # ARABIC LETTER MEEM + 0x00e6: 0x0646, # ARABIC LETTER NOON + 0x00e7: 0x0647, # ARABIC LETTER HEH + 0x00e8: 0x0648, # ARABIC LETTER WAW + 0x00e9: 0x0649, # ARABIC LETTER ALEF MAKSURA + 0x00ea: 0x064a, # ARABIC LETTER YEH + 0x00eb: 0x064b, # ARABIC FATHATAN + 0x00ec: 0x064c, # ARABIC DAMMATAN + 0x00ed: 0x064d, # ARABIC KASRATAN + 0x00ee: 0x064e, # ARABIC FATHA + 0x00ef: 0x064f, # ARABIC DAMMA + 0x00f0: 0x0650, # ARABIC KASRA + 0x00f1: 0x0651, # ARABIC SHADDA + 0x00f2: 0x0652, # ARABIC SUKUN + 0x00f3: 0x067e, # ARABIC LETTER PEH + 0x00f4: 0x0679, # ARABIC LETTER TTEH + 0x00f5: 0x0686, # ARABIC LETTER TCHEH + 0x00f6: 0x06d5, # ARABIC LETTER AE + 0x00f7: 0x06a4, # ARABIC LETTER VEH + 0x00f8: 0x06af, # ARABIC LETTER GAF + 0x00f9: 0x0688, # ARABIC LETTER DDAL + 0x00fa: 0x0691, # ARABIC LETTER RREH + 0x00fb: 0x007b, # LEFT CURLY BRACKET, right-left + 0x00fc: 0x007c, # VERTICAL LINE, right-left + 0x00fd: 0x007d, # RIGHT CURLY BRACKET, right-left + 0x00fe: 0x0698, # ARABIC LETTER JEH + 0x00ff: 0x06d2, # ARABIC LETTER YEH BARREE +}) + +### Decoding Table + +decoding_table = ( + '\x00' # 0x0000 -> CONTROL CHARACTER + '\x01' # 0x0001 -> CONTROL CHARACTER + '\x02' # 0x0002 -> CONTROL CHARACTER + '\x03' # 0x0003 -> CONTROL CHARACTER + '\x04' # 0x0004 -> CONTROL CHARACTER + '\x05' # 0x0005 -> CONTROL CHARACTER + '\x06' # 0x0006 -> CONTROL CHARACTER + '\x07' # 0x0007 -> CONTROL CHARACTER + '\x08' # 0x0008 -> CONTROL CHARACTER + '\t' # 0x0009 -> CONTROL CHARACTER + '\n' # 0x000a -> CONTROL CHARACTER + '\x0b' # 0x000b -> CONTROL CHARACTER + '\x0c' # 0x000c -> CONTROL CHARACTER + '\r' # 0x000d -> CONTROL CHARACTER + '\x0e' # 0x000e -> CONTROL CHARACTER + '\x0f' # 0x000f -> CONTROL CHARACTER + '\x10' # 0x0010 -> CONTROL CHARACTER + '\x11' # 0x0011 -> CONTROL CHARACTER + '\x12' # 0x0012 -> CONTROL CHARACTER + '\x13' # 0x0013 -> CONTROL CHARACTER + '\x14' # 0x0014 -> CONTROL CHARACTER + '\x15' # 0x0015 -> CONTROL CHARACTER + '\x16' # 0x0016 -> CONTROL CHARACTER + '\x17' # 0x0017 -> CONTROL CHARACTER + '\x18' # 0x0018 -> CONTROL CHARACTER + '\x19' # 0x0019 -> CONTROL CHARACTER + '\x1a' # 0x001a -> CONTROL CHARACTER + '\x1b' # 0x001b -> CONTROL CHARACTER + '\x1c' # 0x001c -> CONTROL CHARACTER + '\x1d' # 0x001d -> CONTROL CHARACTER + '\x1e' # 0x001e -> CONTROL CHARACTER + '\x1f' # 0x001f -> CONTROL CHARACTER + ' ' # 0x0020 -> SPACE, left-right + '!' # 0x0021 -> EXCLAMATION MARK, left-right + '"' # 0x0022 -> QUOTATION MARK, left-right + '#' # 0x0023 -> NUMBER SIGN, left-right + '$' # 0x0024 -> DOLLAR SIGN, left-right + '%' # 0x0025 -> PERCENT SIGN, left-right + '&' # 0x0026 -> AMPERSAND, left-right + "'" # 0x0027 -> APOSTROPHE, left-right + '(' # 0x0028 -> LEFT PARENTHESIS, left-right + ')' # 0x0029 -> RIGHT PARENTHESIS, left-right + '*' # 0x002a -> ASTERISK, left-right + '+' # 0x002b -> PLUS SIGN, left-right + ',' # 0x002c -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + '-' # 0x002d -> HYPHEN-MINUS, left-right + '.' # 0x002e -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + '/' # 0x002f -> SOLIDUS, left-right + '0' # 0x0030 -> DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO + '1' # 0x0031 -> DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE + '2' # 0x0032 -> DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO + '3' # 0x0033 -> DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE + '4' # 0x0034 -> DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR + '5' # 0x0035 -> DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE + '6' # 0x0036 -> DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX + '7' # 0x0037 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN + '8' # 0x0038 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT + '9' # 0x0039 -> DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE + ':' # 0x003a -> COLON, left-right + ';' # 0x003b -> SEMICOLON, left-right + '<' # 0x003c -> LESS-THAN SIGN, left-right + '=' # 0x003d -> EQUALS SIGN, left-right + '>' # 0x003e -> GREATER-THAN SIGN, left-right + '?' # 0x003f -> QUESTION MARK, left-right + '@' # 0x0040 -> COMMERCIAL AT + 'A' # 0x0041 -> LATIN CAPITAL LETTER A + 'B' # 0x0042 -> LATIN CAPITAL LETTER B + 'C' # 0x0043 -> LATIN CAPITAL LETTER C + 'D' # 0x0044 -> LATIN CAPITAL LETTER D + 'E' # 0x0045 -> LATIN CAPITAL LETTER E + 'F' # 0x0046 -> LATIN CAPITAL LETTER F + 'G' # 0x0047 -> LATIN CAPITAL LETTER G + 'H' # 0x0048 -> LATIN CAPITAL LETTER H + 'I' # 0x0049 -> LATIN CAPITAL LETTER I + 'J' # 0x004a -> LATIN CAPITAL LETTER J + 'K' # 0x004b -> LATIN CAPITAL LETTER K + 'L' # 0x004c -> LATIN CAPITAL LETTER L + 'M' # 0x004d -> LATIN CAPITAL LETTER M + 'N' # 0x004e -> LATIN CAPITAL LETTER N + 'O' # 0x004f -> LATIN CAPITAL LETTER O + 'P' # 0x0050 -> LATIN CAPITAL LETTER P + 'Q' # 0x0051 -> LATIN CAPITAL LETTER Q + 'R' # 0x0052 -> LATIN CAPITAL LETTER R + 'S' # 0x0053 -> LATIN CAPITAL LETTER S + 'T' # 0x0054 -> LATIN CAPITAL LETTER T + 'U' # 0x0055 -> LATIN CAPITAL LETTER U + 'V' # 0x0056 -> LATIN CAPITAL LETTER V + 'W' # 0x0057 -> LATIN CAPITAL LETTER W + 'X' # 0x0058 -> LATIN CAPITAL LETTER X + 'Y' # 0x0059 -> LATIN CAPITAL LETTER Y + 'Z' # 0x005a -> LATIN CAPITAL LETTER Z + '[' # 0x005b -> LEFT SQUARE BRACKET, left-right + '\\' # 0x005c -> REVERSE SOLIDUS, left-right + ']' # 0x005d -> RIGHT SQUARE BRACKET, left-right + '^' # 0x005e -> CIRCUMFLEX ACCENT, left-right + '_' # 0x005f -> LOW LINE, left-right + '`' # 0x0060 -> GRAVE ACCENT + 'a' # 0x0061 -> LATIN SMALL LETTER A + 'b' # 0x0062 -> LATIN SMALL LETTER B + 'c' # 0x0063 -> LATIN SMALL LETTER C + 'd' # 0x0064 -> LATIN SMALL LETTER D + 'e' # 0x0065 -> LATIN SMALL LETTER E + 'f' # 0x0066 -> LATIN SMALL LETTER F + 'g' # 0x0067 -> LATIN SMALL LETTER G + 'h' # 0x0068 -> LATIN SMALL LETTER H + 'i' # 0x0069 -> LATIN SMALL LETTER I + 'j' # 0x006a -> LATIN SMALL LETTER J + 'k' # 0x006b -> LATIN SMALL LETTER K + 'l' # 0x006c -> LATIN SMALL LETTER L + 'm' # 0x006d -> LATIN SMALL LETTER M + 'n' # 0x006e -> LATIN SMALL LETTER N + 'o' # 0x006f -> LATIN SMALL LETTER O + 'p' # 0x0070 -> LATIN SMALL LETTER P + 'q' # 0x0071 -> LATIN SMALL LETTER Q + 'r' # 0x0072 -> LATIN SMALL LETTER R + 's' # 0x0073 -> LATIN SMALL LETTER S + 't' # 0x0074 -> LATIN SMALL LETTER T + 'u' # 0x0075 -> LATIN SMALL LETTER U + 'v' # 0x0076 -> LATIN SMALL LETTER V + 'w' # 0x0077 -> LATIN SMALL LETTER W + 'x' # 0x0078 -> LATIN SMALL LETTER X + 'y' # 0x0079 -> LATIN SMALL LETTER Y + 'z' # 0x007a -> LATIN SMALL LETTER Z + '{' # 0x007b -> LEFT CURLY BRACKET, left-right + '|' # 0x007c -> VERTICAL LINE, left-right + '}' # 0x007d -> RIGHT CURLY BRACKET, left-right + '~' # 0x007e -> TILDE + '\x7f' # 0x007f -> CONTROL CHARACTER + '\xc4' # 0x0080 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xa0' # 0x0081 -> NO-BREAK SPACE, right-left + '\xc7' # 0x0082 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x0083 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x0084 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x0085 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x0086 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x0087 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x0088 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x0089 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x008a -> LATIN SMALL LETTER A WITH DIAERESIS + '\u06ba' # 0x008b -> ARABIC LETTER NOON GHUNNA + '\xab' # 0x008c -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xe7' # 0x008d -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x008e -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x008f -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x0090 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x0091 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x0092 -> LATIN SMALL LETTER I WITH ACUTE + '\u2026' # 0x0093 -> HORIZONTAL ELLIPSIS, right-left + '\xee' # 0x0094 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x0095 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x0096 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x0097 -> LATIN SMALL LETTER O WITH ACUTE + '\xbb' # 0x0098 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xf4' # 0x0099 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x009a -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0x009b -> DIVISION SIGN, right-left + '\xfa' # 0x009c -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x009d -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x009e -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x009f -> LATIN SMALL LETTER U WITH DIAERESIS + ' ' # 0x00a0 -> SPACE, right-left + '!' # 0x00a1 -> EXCLAMATION MARK, right-left + '"' # 0x00a2 -> QUOTATION MARK, right-left + '#' # 0x00a3 -> NUMBER SIGN, right-left + '$' # 0x00a4 -> DOLLAR SIGN, right-left + '\u066a' # 0x00a5 -> ARABIC PERCENT SIGN + '&' # 0x00a6 -> AMPERSAND, right-left + "'" # 0x00a7 -> APOSTROPHE, right-left + '(' # 0x00a8 -> LEFT PARENTHESIS, right-left + ')' # 0x00a9 -> RIGHT PARENTHESIS, right-left + '*' # 0x00aa -> ASTERISK, right-left + '+' # 0x00ab -> PLUS SIGN, right-left + '\u060c' # 0x00ac -> ARABIC COMMA + '-' # 0x00ad -> HYPHEN-MINUS, right-left + '.' # 0x00ae -> FULL STOP, right-left + '/' # 0x00af -> SOLIDUS, right-left + '\u0660' # 0x00b0 -> ARABIC-INDIC DIGIT ZERO, right-left (need override) + '\u0661' # 0x00b1 -> ARABIC-INDIC DIGIT ONE, right-left (need override) + '\u0662' # 0x00b2 -> ARABIC-INDIC DIGIT TWO, right-left (need override) + '\u0663' # 0x00b3 -> ARABIC-INDIC DIGIT THREE, right-left (need override) + '\u0664' # 0x00b4 -> ARABIC-INDIC DIGIT FOUR, right-left (need override) + '\u0665' # 0x00b5 -> ARABIC-INDIC DIGIT FIVE, right-left (need override) + '\u0666' # 0x00b6 -> ARABIC-INDIC DIGIT SIX, right-left (need override) + '\u0667' # 0x00b7 -> ARABIC-INDIC DIGIT SEVEN, right-left (need override) + '\u0668' # 0x00b8 -> ARABIC-INDIC DIGIT EIGHT, right-left (need override) + '\u0669' # 0x00b9 -> ARABIC-INDIC DIGIT NINE, right-left (need override) + ':' # 0x00ba -> COLON, right-left + '\u061b' # 0x00bb -> ARABIC SEMICOLON + '<' # 0x00bc -> LESS-THAN SIGN, right-left + '=' # 0x00bd -> EQUALS SIGN, right-left + '>' # 0x00be -> GREATER-THAN SIGN, right-left + '\u061f' # 0x00bf -> ARABIC QUESTION MARK + '\u274a' # 0x00c0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + '\u0621' # 0x00c1 -> ARABIC LETTER HAMZA + '\u0622' # 0x00c2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0x00c3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0x00c4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0x00c5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0x00c6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0x00c7 -> ARABIC LETTER ALEF + '\u0628' # 0x00c8 -> ARABIC LETTER BEH + '\u0629' # 0x00c9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0x00ca -> ARABIC LETTER TEH + '\u062b' # 0x00cb -> ARABIC LETTER THEH + '\u062c' # 0x00cc -> ARABIC LETTER JEEM + '\u062d' # 0x00cd -> ARABIC LETTER HAH + '\u062e' # 0x00ce -> ARABIC LETTER KHAH + '\u062f' # 0x00cf -> ARABIC LETTER DAL + '\u0630' # 0x00d0 -> ARABIC LETTER THAL + '\u0631' # 0x00d1 -> ARABIC LETTER REH + '\u0632' # 0x00d2 -> ARABIC LETTER ZAIN + '\u0633' # 0x00d3 -> ARABIC LETTER SEEN + '\u0634' # 0x00d4 -> ARABIC LETTER SHEEN + '\u0635' # 0x00d5 -> ARABIC LETTER SAD + '\u0636' # 0x00d6 -> ARABIC LETTER DAD + '\u0637' # 0x00d7 -> ARABIC LETTER TAH + '\u0638' # 0x00d8 -> ARABIC LETTER ZAH + '\u0639' # 0x00d9 -> ARABIC LETTER AIN + '\u063a' # 0x00da -> ARABIC LETTER GHAIN + '[' # 0x00db -> LEFT SQUARE BRACKET, right-left + '\\' # 0x00dc -> REVERSE SOLIDUS, right-left + ']' # 0x00dd -> RIGHT SQUARE BRACKET, right-left + '^' # 0x00de -> CIRCUMFLEX ACCENT, right-left + '_' # 0x00df -> LOW LINE, right-left + '\u0640' # 0x00e0 -> ARABIC TATWEEL + '\u0641' # 0x00e1 -> ARABIC LETTER FEH + '\u0642' # 0x00e2 -> ARABIC LETTER QAF + '\u0643' # 0x00e3 -> ARABIC LETTER KAF + '\u0644' # 0x00e4 -> ARABIC LETTER LAM + '\u0645' # 0x00e5 -> ARABIC LETTER MEEM + '\u0646' # 0x00e6 -> ARABIC LETTER NOON + '\u0647' # 0x00e7 -> ARABIC LETTER HEH + '\u0648' # 0x00e8 -> ARABIC LETTER WAW + '\u0649' # 0x00e9 -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0x00ea -> ARABIC LETTER YEH + '\u064b' # 0x00eb -> ARABIC FATHATAN + '\u064c' # 0x00ec -> ARABIC DAMMATAN + '\u064d' # 0x00ed -> ARABIC KASRATAN + '\u064e' # 0x00ee -> ARABIC FATHA + '\u064f' # 0x00ef -> ARABIC DAMMA + '\u0650' # 0x00f0 -> ARABIC KASRA + '\u0651' # 0x00f1 -> ARABIC SHADDA + '\u0652' # 0x00f2 -> ARABIC SUKUN + '\u067e' # 0x00f3 -> ARABIC LETTER PEH + '\u0679' # 0x00f4 -> ARABIC LETTER TTEH + '\u0686' # 0x00f5 -> ARABIC LETTER TCHEH + '\u06d5' # 0x00f6 -> ARABIC LETTER AE + '\u06a4' # 0x00f7 -> ARABIC LETTER VEH + '\u06af' # 0x00f8 -> ARABIC LETTER GAF + '\u0688' # 0x00f9 -> ARABIC LETTER DDAL + '\u0691' # 0x00fa -> ARABIC LETTER RREH + '{' # 0x00fb -> LEFT CURLY BRACKET, right-left + '|' # 0x00fc -> VERTICAL LINE, right-left + '}' # 0x00fd -> RIGHT CURLY BRACKET, right-left + '\u0698' # 0x00fe -> ARABIC LETTER JEH + '\u06d2' # 0x00ff -> ARABIC LETTER YEH BARREE +) + +### Encoding Map + +encoding_map = { + 0x0000: 0x0000, # CONTROL CHARACTER + 0x0001: 0x0001, # CONTROL CHARACTER + 0x0002: 0x0002, # CONTROL CHARACTER + 0x0003: 0x0003, # CONTROL CHARACTER + 0x0004: 0x0004, # CONTROL CHARACTER + 0x0005: 0x0005, # CONTROL CHARACTER + 0x0006: 0x0006, # CONTROL CHARACTER + 0x0007: 0x0007, # CONTROL CHARACTER + 0x0008: 0x0008, # CONTROL CHARACTER + 0x0009: 0x0009, # CONTROL CHARACTER + 0x000a: 0x000a, # CONTROL CHARACTER + 0x000b: 0x000b, # CONTROL CHARACTER + 0x000c: 0x000c, # CONTROL CHARACTER + 0x000d: 0x000d, # CONTROL CHARACTER + 0x000e: 0x000e, # CONTROL CHARACTER + 0x000f: 0x000f, # CONTROL CHARACTER + 0x0010: 0x0010, # CONTROL CHARACTER + 0x0011: 0x0011, # CONTROL CHARACTER + 0x0012: 0x0012, # CONTROL CHARACTER + 0x0013: 0x0013, # CONTROL CHARACTER + 0x0014: 0x0014, # CONTROL CHARACTER + 0x0015: 0x0015, # CONTROL CHARACTER + 0x0016: 0x0016, # CONTROL CHARACTER + 0x0017: 0x0017, # CONTROL CHARACTER + 0x0018: 0x0018, # CONTROL CHARACTER + 0x0019: 0x0019, # CONTROL CHARACTER + 0x001a: 0x001a, # CONTROL CHARACTER + 0x001b: 0x001b, # CONTROL CHARACTER + 0x001c: 0x001c, # CONTROL CHARACTER + 0x001d: 0x001d, # CONTROL CHARACTER + 0x001e: 0x001e, # CONTROL CHARACTER + 0x001f: 0x001f, # CONTROL CHARACTER + 0x0020: 0x0020, # SPACE, left-right + 0x0020: 0x00a0, # SPACE, right-left + 0x0021: 0x0021, # EXCLAMATION MARK, left-right + 0x0021: 0x00a1, # EXCLAMATION MARK, right-left + 0x0022: 0x0022, # QUOTATION MARK, left-right + 0x0022: 0x00a2, # QUOTATION MARK, right-left + 0x0023: 0x0023, # NUMBER SIGN, left-right + 0x0023: 0x00a3, # NUMBER SIGN, right-left + 0x0024: 0x0024, # DOLLAR SIGN, left-right + 0x0024: 0x00a4, # DOLLAR SIGN, right-left + 0x0025: 0x0025, # PERCENT SIGN, left-right + 0x0026: 0x0026, # AMPERSAND, left-right + 0x0026: 0x00a6, # AMPERSAND, right-left + 0x0027: 0x0027, # APOSTROPHE, left-right + 0x0027: 0x00a7, # APOSTROPHE, right-left + 0x0028: 0x0028, # LEFT PARENTHESIS, left-right + 0x0028: 0x00a8, # LEFT PARENTHESIS, right-left + 0x0029: 0x0029, # RIGHT PARENTHESIS, left-right + 0x0029: 0x00a9, # RIGHT PARENTHESIS, right-left + 0x002a: 0x002a, # ASTERISK, left-right + 0x002a: 0x00aa, # ASTERISK, right-left + 0x002b: 0x002b, # PLUS SIGN, left-right + 0x002b: 0x00ab, # PLUS SIGN, right-left + 0x002c: 0x002c, # COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + 0x002d: 0x002d, # HYPHEN-MINUS, left-right + 0x002d: 0x00ad, # HYPHEN-MINUS, right-left + 0x002e: 0x002e, # FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + 0x002e: 0x00ae, # FULL STOP, right-left + 0x002f: 0x002f, # SOLIDUS, left-right + 0x002f: 0x00af, # SOLIDUS, right-left + 0x0030: 0x0030, # DIGIT ZERO; in Arabic-script context, displayed as 0x0660 ARABIC-INDIC DIGIT ZERO + 0x0031: 0x0031, # DIGIT ONE; in Arabic-script context, displayed as 0x0661 ARABIC-INDIC DIGIT ONE + 0x0032: 0x0032, # DIGIT TWO; in Arabic-script context, displayed as 0x0662 ARABIC-INDIC DIGIT TWO + 0x0033: 0x0033, # DIGIT THREE; in Arabic-script context, displayed as 0x0663 ARABIC-INDIC DIGIT THREE + 0x0034: 0x0034, # DIGIT FOUR; in Arabic-script context, displayed as 0x0664 ARABIC-INDIC DIGIT FOUR + 0x0035: 0x0035, # DIGIT FIVE; in Arabic-script context, displayed as 0x0665 ARABIC-INDIC DIGIT FIVE + 0x0036: 0x0036, # DIGIT SIX; in Arabic-script context, displayed as 0x0666 ARABIC-INDIC DIGIT SIX + 0x0037: 0x0037, # DIGIT SEVEN; in Arabic-script context, displayed as 0x0667 ARABIC-INDIC DIGIT SEVEN + 0x0038: 0x0038, # DIGIT EIGHT; in Arabic-script context, displayed as 0x0668 ARABIC-INDIC DIGIT EIGHT + 0x0039: 0x0039, # DIGIT NINE; in Arabic-script context, displayed as 0x0669 ARABIC-INDIC DIGIT NINE + 0x003a: 0x003a, # COLON, left-right + 0x003a: 0x00ba, # COLON, right-left + 0x003b: 0x003b, # SEMICOLON, left-right + 0x003c: 0x003c, # LESS-THAN SIGN, left-right + 0x003c: 0x00bc, # LESS-THAN SIGN, right-left + 0x003d: 0x003d, # EQUALS SIGN, left-right + 0x003d: 0x00bd, # EQUALS SIGN, right-left + 0x003e: 0x003e, # GREATER-THAN SIGN, left-right + 0x003e: 0x00be, # GREATER-THAN SIGN, right-left + 0x003f: 0x003f, # QUESTION MARK, left-right + 0x0040: 0x0040, # COMMERCIAL AT + 0x0041: 0x0041, # LATIN CAPITAL LETTER A + 0x0042: 0x0042, # LATIN CAPITAL LETTER B + 0x0043: 0x0043, # LATIN CAPITAL LETTER C + 0x0044: 0x0044, # LATIN CAPITAL LETTER D + 0x0045: 0x0045, # LATIN CAPITAL LETTER E + 0x0046: 0x0046, # LATIN CAPITAL LETTER F + 0x0047: 0x0047, # LATIN CAPITAL LETTER G + 0x0048: 0x0048, # LATIN CAPITAL LETTER H + 0x0049: 0x0049, # LATIN CAPITAL LETTER I + 0x004a: 0x004a, # LATIN CAPITAL LETTER J + 0x004b: 0x004b, # LATIN CAPITAL LETTER K + 0x004c: 0x004c, # LATIN CAPITAL LETTER L + 0x004d: 0x004d, # LATIN CAPITAL LETTER M + 0x004e: 0x004e, # LATIN CAPITAL LETTER N + 0x004f: 0x004f, # LATIN CAPITAL LETTER O + 0x0050: 0x0050, # LATIN CAPITAL LETTER P + 0x0051: 0x0051, # LATIN CAPITAL LETTER Q + 0x0052: 0x0052, # LATIN CAPITAL LETTER R + 0x0053: 0x0053, # LATIN CAPITAL LETTER S + 0x0054: 0x0054, # LATIN CAPITAL LETTER T + 0x0055: 0x0055, # LATIN CAPITAL LETTER U + 0x0056: 0x0056, # LATIN CAPITAL LETTER V + 0x0057: 0x0057, # LATIN CAPITAL LETTER W + 0x0058: 0x0058, # LATIN CAPITAL LETTER X + 0x0059: 0x0059, # LATIN CAPITAL LETTER Y + 0x005a: 0x005a, # LATIN CAPITAL LETTER Z + 0x005b: 0x005b, # LEFT SQUARE BRACKET, left-right + 0x005b: 0x00db, # LEFT SQUARE BRACKET, right-left + 0x005c: 0x005c, # REVERSE SOLIDUS, left-right + 0x005c: 0x00dc, # REVERSE SOLIDUS, right-left + 0x005d: 0x005d, # RIGHT SQUARE BRACKET, left-right + 0x005d: 0x00dd, # RIGHT SQUARE BRACKET, right-left + 0x005e: 0x005e, # CIRCUMFLEX ACCENT, left-right + 0x005e: 0x00de, # CIRCUMFLEX ACCENT, right-left + 0x005f: 0x005f, # LOW LINE, left-right + 0x005f: 0x00df, # LOW LINE, right-left + 0x0060: 0x0060, # GRAVE ACCENT + 0x0061: 0x0061, # LATIN SMALL LETTER A + 0x0062: 0x0062, # LATIN SMALL LETTER B + 0x0063: 0x0063, # LATIN SMALL LETTER C + 0x0064: 0x0064, # LATIN SMALL LETTER D + 0x0065: 0x0065, # LATIN SMALL LETTER E + 0x0066: 0x0066, # LATIN SMALL LETTER F + 0x0067: 0x0067, # LATIN SMALL LETTER G + 0x0068: 0x0068, # LATIN SMALL LETTER H + 0x0069: 0x0069, # LATIN SMALL LETTER I + 0x006a: 0x006a, # LATIN SMALL LETTER J + 0x006b: 0x006b, # LATIN SMALL LETTER K + 0x006c: 0x006c, # LATIN SMALL LETTER L + 0x006d: 0x006d, # LATIN SMALL LETTER M + 0x006e: 0x006e, # LATIN SMALL LETTER N + 0x006f: 0x006f, # LATIN SMALL LETTER O + 0x0070: 0x0070, # LATIN SMALL LETTER P + 0x0071: 0x0071, # LATIN SMALL LETTER Q + 0x0072: 0x0072, # LATIN SMALL LETTER R + 0x0073: 0x0073, # LATIN SMALL LETTER S + 0x0074: 0x0074, # LATIN SMALL LETTER T + 0x0075: 0x0075, # LATIN SMALL LETTER U + 0x0076: 0x0076, # LATIN SMALL LETTER V + 0x0077: 0x0077, # LATIN SMALL LETTER W + 0x0078: 0x0078, # LATIN SMALL LETTER X + 0x0079: 0x0079, # LATIN SMALL LETTER Y + 0x007a: 0x007a, # LATIN SMALL LETTER Z + 0x007b: 0x007b, # LEFT CURLY BRACKET, left-right + 0x007b: 0x00fb, # LEFT CURLY BRACKET, right-left + 0x007c: 0x007c, # VERTICAL LINE, left-right + 0x007c: 0x00fc, # VERTICAL LINE, right-left + 0x007d: 0x007d, # RIGHT CURLY BRACKET, left-right + 0x007d: 0x00fd, # RIGHT CURLY BRACKET, right-left + 0x007e: 0x007e, # TILDE + 0x007f: 0x007f, # CONTROL CHARACTER + 0x00a0: 0x0081, # NO-BREAK SPACE, right-left + 0x00ab: 0x008c, # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x00bb: 0x0098, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + 0x00c4: 0x0080, # LATIN CAPITAL LETTER A WITH DIAERESIS + 0x00c7: 0x0082, # LATIN CAPITAL LETTER C WITH CEDILLA + 0x00c9: 0x0083, # LATIN CAPITAL LETTER E WITH ACUTE + 0x00d1: 0x0084, # LATIN CAPITAL LETTER N WITH TILDE + 0x00d6: 0x0085, # LATIN CAPITAL LETTER O WITH DIAERESIS + 0x00dc: 0x0086, # LATIN CAPITAL LETTER U WITH DIAERESIS + 0x00e0: 0x0088, # LATIN SMALL LETTER A WITH GRAVE + 0x00e1: 0x0087, # LATIN SMALL LETTER A WITH ACUTE + 0x00e2: 0x0089, # LATIN SMALL LETTER A WITH CIRCUMFLEX + 0x00e4: 0x008a, # LATIN SMALL LETTER A WITH DIAERESIS + 0x00e7: 0x008d, # LATIN SMALL LETTER C WITH CEDILLA + 0x00e8: 0x008f, # LATIN SMALL LETTER E WITH GRAVE + 0x00e9: 0x008e, # LATIN SMALL LETTER E WITH ACUTE + 0x00ea: 0x0090, # LATIN SMALL LETTER E WITH CIRCUMFLEX + 0x00eb: 0x0091, # LATIN SMALL LETTER E WITH DIAERESIS + 0x00ed: 0x0092, # LATIN SMALL LETTER I WITH ACUTE + 0x00ee: 0x0094, # LATIN SMALL LETTER I WITH CIRCUMFLEX + 0x00ef: 0x0095, # LATIN SMALL LETTER I WITH DIAERESIS + 0x00f1: 0x0096, # LATIN SMALL LETTER N WITH TILDE + 0x00f3: 0x0097, # LATIN SMALL LETTER O WITH ACUTE + 0x00f4: 0x0099, # LATIN SMALL LETTER O WITH CIRCUMFLEX + 0x00f6: 0x009a, # LATIN SMALL LETTER O WITH DIAERESIS + 0x00f7: 0x009b, # DIVISION SIGN, right-left + 0x00f9: 0x009d, # LATIN SMALL LETTER U WITH GRAVE + 0x00fa: 0x009c, # LATIN SMALL LETTER U WITH ACUTE + 0x00fb: 0x009e, # LATIN SMALL LETTER U WITH CIRCUMFLEX + 0x00fc: 0x009f, # LATIN SMALL LETTER U WITH DIAERESIS + 0x060c: 0x00ac, # ARABIC COMMA + 0x061b: 0x00bb, # ARABIC SEMICOLON + 0x061f: 0x00bf, # ARABIC QUESTION MARK + 0x0621: 0x00c1, # ARABIC LETTER HAMZA + 0x0622: 0x00c2, # ARABIC LETTER ALEF WITH MADDA ABOVE + 0x0623: 0x00c3, # ARABIC LETTER ALEF WITH HAMZA ABOVE + 0x0624: 0x00c4, # ARABIC LETTER WAW WITH HAMZA ABOVE + 0x0625: 0x00c5, # ARABIC LETTER ALEF WITH HAMZA BELOW + 0x0626: 0x00c6, # ARABIC LETTER YEH WITH HAMZA ABOVE + 0x0627: 0x00c7, # ARABIC LETTER ALEF + 0x0628: 0x00c8, # ARABIC LETTER BEH + 0x0629: 0x00c9, # ARABIC LETTER TEH MARBUTA + 0x062a: 0x00ca, # ARABIC LETTER TEH + 0x062b: 0x00cb, # ARABIC LETTER THEH + 0x062c: 0x00cc, # ARABIC LETTER JEEM + 0x062d: 0x00cd, # ARABIC LETTER HAH + 0x062e: 0x00ce, # ARABIC LETTER KHAH + 0x062f: 0x00cf, # ARABIC LETTER DAL + 0x0630: 0x00d0, # ARABIC LETTER THAL + 0x0631: 0x00d1, # ARABIC LETTER REH + 0x0632: 0x00d2, # ARABIC LETTER ZAIN + 0x0633: 0x00d3, # ARABIC LETTER SEEN + 0x0634: 0x00d4, # ARABIC LETTER SHEEN + 0x0635: 0x00d5, # ARABIC LETTER SAD + 0x0636: 0x00d6, # ARABIC LETTER DAD + 0x0637: 0x00d7, # ARABIC LETTER TAH + 0x0638: 0x00d8, # ARABIC LETTER ZAH + 0x0639: 0x00d9, # ARABIC LETTER AIN + 0x063a: 0x00da, # ARABIC LETTER GHAIN + 0x0640: 0x00e0, # ARABIC TATWEEL + 0x0641: 0x00e1, # ARABIC LETTER FEH + 0x0642: 0x00e2, # ARABIC LETTER QAF + 0x0643: 0x00e3, # ARABIC LETTER KAF + 0x0644: 0x00e4, # ARABIC LETTER LAM + 0x0645: 0x00e5, # ARABIC LETTER MEEM + 0x0646: 0x00e6, # ARABIC LETTER NOON + 0x0647: 0x00e7, # ARABIC LETTER HEH + 0x0648: 0x00e8, # ARABIC LETTER WAW + 0x0649: 0x00e9, # ARABIC LETTER ALEF MAKSURA + 0x064a: 0x00ea, # ARABIC LETTER YEH + 0x064b: 0x00eb, # ARABIC FATHATAN + 0x064c: 0x00ec, # ARABIC DAMMATAN + 0x064d: 0x00ed, # ARABIC KASRATAN + 0x064e: 0x00ee, # ARABIC FATHA + 0x064f: 0x00ef, # ARABIC DAMMA + 0x0650: 0x00f0, # ARABIC KASRA + 0x0651: 0x00f1, # ARABIC SHADDA + 0x0652: 0x00f2, # ARABIC SUKUN + 0x0660: 0x00b0, # ARABIC-INDIC DIGIT ZERO, right-left (need override) + 0x0661: 0x00b1, # ARABIC-INDIC DIGIT ONE, right-left (need override) + 0x0662: 0x00b2, # ARABIC-INDIC DIGIT TWO, right-left (need override) + 0x0663: 0x00b3, # ARABIC-INDIC DIGIT THREE, right-left (need override) + 0x0664: 0x00b4, # ARABIC-INDIC DIGIT FOUR, right-left (need override) + 0x0665: 0x00b5, # ARABIC-INDIC DIGIT FIVE, right-left (need override) + 0x0666: 0x00b6, # ARABIC-INDIC DIGIT SIX, right-left (need override) + 0x0667: 0x00b7, # ARABIC-INDIC DIGIT SEVEN, right-left (need override) + 0x0668: 0x00b8, # ARABIC-INDIC DIGIT EIGHT, right-left (need override) + 0x0669: 0x00b9, # ARABIC-INDIC DIGIT NINE, right-left (need override) + 0x066a: 0x00a5, # ARABIC PERCENT SIGN + 0x0679: 0x00f4, # ARABIC LETTER TTEH + 0x067e: 0x00f3, # ARABIC LETTER PEH + 0x0686: 0x00f5, # ARABIC LETTER TCHEH + 0x0688: 0x00f9, # ARABIC LETTER DDAL + 0x0691: 0x00fa, # ARABIC LETTER RREH + 0x0698: 0x00fe, # ARABIC LETTER JEH + 0x06a4: 0x00f7, # ARABIC LETTER VEH + 0x06af: 0x00f8, # ARABIC LETTER GAF + 0x06ba: 0x008b, # ARABIC LETTER NOON GHUNNA + 0x06d2: 0x00ff, # ARABIC LETTER YEH BARREE + 0x06d5: 0x00f6, # ARABIC LETTER AE + 0x2026: 0x0093, # HORIZONTAL ELLIPSIS, right-left + 0x274a: 0x00c0, # EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left +} diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_croatian.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_croatian.py new file mode 100644 index 0000000..4a92fe6 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_croatian.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_croatian generated from 'MAPPINGS/VENDORS/APPLE/CROATIAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-croatian', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\u0160' # 0xA9 -> LATIN CAPITAL LETTER S WITH CARON + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\u017d' # 0xAE -> LATIN CAPITAL LETTER Z WITH CARON + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\u2206' # 0xB4 -> INCREMENT + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u0161' # 0xB9 -> LATIN SMALL LETTER S WITH CARON + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\u017e' # 0xBE -> LATIN SMALL LETTER Z WITH CARON + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u0106' # 0xC6 -> LATIN CAPITAL LETTER C WITH ACUTE + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u010c' # 0xC8 -> LATIN CAPITAL LETTER C WITH CARON + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u0110' # 0xD0 -> LATIN CAPITAL LETTER D WITH STROKE + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\uf8ff' # 0xD8 -> Apple logo + '\xa9' # 0xD9 -> COPYRIGHT SIGN + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\xc6' # 0xDE -> LATIN CAPITAL LETTER AE + '\xbb' # 0xDF -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2013' # 0xE0 -> EN DASH + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\u0107' # 0xE6 -> LATIN SMALL LETTER C WITH ACUTE + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\u010d' # 0xE8 -> LATIN SMALL LETTER C WITH CARON + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u0111' # 0xF0 -> LATIN SMALL LETTER D WITH STROKE + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u03c0' # 0xF9 -> GREEK SMALL LETTER PI + '\xcb' # 0xFA -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\xca' # 0xFD -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xe6' # 0xFE -> LATIN SMALL LETTER AE + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_cyrillic.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_cyrillic.py new file mode 100644 index 0000000..d20272a --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_cyrillic.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_cyrillic generated from 'MAPPINGS/VENDORS/APPLE/CYRILLIC.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-cyrillic', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\u0410' # 0x80 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0x81 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0x82 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0x83 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0x84 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0x85 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0x86 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0x87 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0x88 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0x89 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0x8A -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0x8B -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0x8C -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0x8D -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0x8E -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0x8F -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0x90 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0x91 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0x92 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0x93 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0x94 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0x95 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0x96 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0x97 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0x98 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0x99 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0x9A -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0x9B -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0x9C -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0x9D -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0x9E -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0x9F -> CYRILLIC CAPITAL LETTER YA + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\u0490' # 0xA2 -> CYRILLIC CAPITAL LETTER GHE WITH UPTURN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\u0406' # 0xA7 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\u0402' # 0xAB -> CYRILLIC CAPITAL LETTER DJE + '\u0452' # 0xAC -> CYRILLIC SMALL LETTER DJE + '\u2260' # 0xAD -> NOT EQUAL TO + '\u0403' # 0xAE -> CYRILLIC CAPITAL LETTER GJE + '\u0453' # 0xAF -> CYRILLIC SMALL LETTER GJE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\u0456' # 0xB4 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\xb5' # 0xB5 -> MICRO SIGN + '\u0491' # 0xB6 -> CYRILLIC SMALL LETTER GHE WITH UPTURN + '\u0408' # 0xB7 -> CYRILLIC CAPITAL LETTER JE + '\u0404' # 0xB8 -> CYRILLIC CAPITAL LETTER UKRAINIAN IE + '\u0454' # 0xB9 -> CYRILLIC SMALL LETTER UKRAINIAN IE + '\u0407' # 0xBA -> CYRILLIC CAPITAL LETTER YI + '\u0457' # 0xBB -> CYRILLIC SMALL LETTER YI + '\u0409' # 0xBC -> CYRILLIC CAPITAL LETTER LJE + '\u0459' # 0xBD -> CYRILLIC SMALL LETTER LJE + '\u040a' # 0xBE -> CYRILLIC CAPITAL LETTER NJE + '\u045a' # 0xBF -> CYRILLIC SMALL LETTER NJE + '\u0458' # 0xC0 -> CYRILLIC SMALL LETTER JE + '\u0405' # 0xC1 -> CYRILLIC CAPITAL LETTER DZE + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\u040b' # 0xCB -> CYRILLIC CAPITAL LETTER TSHE + '\u045b' # 0xCC -> CYRILLIC SMALL LETTER TSHE + '\u040c' # 0xCD -> CYRILLIC CAPITAL LETTER KJE + '\u045c' # 0xCE -> CYRILLIC SMALL LETTER KJE + '\u0455' # 0xCF -> CYRILLIC SMALL LETTER DZE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u201e' # 0xD7 -> DOUBLE LOW-9 QUOTATION MARK + '\u040e' # 0xD8 -> CYRILLIC CAPITAL LETTER SHORT U + '\u045e' # 0xD9 -> CYRILLIC SMALL LETTER SHORT U + '\u040f' # 0xDA -> CYRILLIC CAPITAL LETTER DZHE + '\u045f' # 0xDB -> CYRILLIC SMALL LETTER DZHE + '\u2116' # 0xDC -> NUMERO SIGN + '\u0401' # 0xDD -> CYRILLIC CAPITAL LETTER IO + '\u0451' # 0xDE -> CYRILLIC SMALL LETTER IO + '\u044f' # 0xDF -> CYRILLIC SMALL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u20ac' # 0xFF -> EURO SIGN +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_farsi.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_farsi.py new file mode 100644 index 0000000..e357d43 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_farsi.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_farsi generated from 'MAPPINGS/VENDORS/APPLE/FARSI.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-farsi', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE, left-right + '!' # 0x21 -> EXCLAMATION MARK, left-right + '"' # 0x22 -> QUOTATION MARK, left-right + '#' # 0x23 -> NUMBER SIGN, left-right + '$' # 0x24 -> DOLLAR SIGN, left-right + '%' # 0x25 -> PERCENT SIGN, left-right + '&' # 0x26 -> AMPERSAND, left-right + "'" # 0x27 -> APOSTROPHE, left-right + '(' # 0x28 -> LEFT PARENTHESIS, left-right + ')' # 0x29 -> RIGHT PARENTHESIS, left-right + '*' # 0x2A -> ASTERISK, left-right + '+' # 0x2B -> PLUS SIGN, left-right + ',' # 0x2C -> COMMA, left-right; in Arabic-script context, displayed as 0x066C ARABIC THOUSANDS SEPARATOR + '-' # 0x2D -> HYPHEN-MINUS, left-right + '.' # 0x2E -> FULL STOP, left-right; in Arabic-script context, displayed as 0x066B ARABIC DECIMAL SEPARATOR + '/' # 0x2F -> SOLIDUS, left-right + '0' # 0x30 -> DIGIT ZERO; in Arabic-script context, displayed as 0x06F0 EXTENDED ARABIC-INDIC DIGIT ZERO + '1' # 0x31 -> DIGIT ONE; in Arabic-script context, displayed as 0x06F1 EXTENDED ARABIC-INDIC DIGIT ONE + '2' # 0x32 -> DIGIT TWO; in Arabic-script context, displayed as 0x06F2 EXTENDED ARABIC-INDIC DIGIT TWO + '3' # 0x33 -> DIGIT THREE; in Arabic-script context, displayed as 0x06F3 EXTENDED ARABIC-INDIC DIGIT THREE + '4' # 0x34 -> DIGIT FOUR; in Arabic-script context, displayed as 0x06F4 EXTENDED ARABIC-INDIC DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE; in Arabic-script context, displayed as 0x06F5 EXTENDED ARABIC-INDIC DIGIT FIVE + '6' # 0x36 -> DIGIT SIX; in Arabic-script context, displayed as 0x06F6 EXTENDED ARABIC-INDIC DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN; in Arabic-script context, displayed as 0x06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT; in Arabic-script context, displayed as 0x06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE; in Arabic-script context, displayed as 0x06F9 EXTENDED ARABIC-INDIC DIGIT NINE + ':' # 0x3A -> COLON, left-right + ';' # 0x3B -> SEMICOLON, left-right + '<' # 0x3C -> LESS-THAN SIGN, left-right + '=' # 0x3D -> EQUALS SIGN, left-right + '>' # 0x3E -> GREATER-THAN SIGN, left-right + '?' # 0x3F -> QUESTION MARK, left-right + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET, left-right + '\\' # 0x5C -> REVERSE SOLIDUS, left-right + ']' # 0x5D -> RIGHT SQUARE BRACKET, left-right + '^' # 0x5E -> CIRCUMFLEX ACCENT, left-right + '_' # 0x5F -> LOW LINE, left-right + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET, left-right + '|' # 0x7C -> VERTICAL LINE, left-right + '}' # 0x7D -> RIGHT CURLY BRACKET, left-right + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xa0' # 0x81 -> NO-BREAK SPACE, right-left + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\u06ba' # 0x8B -> ARABIC LETTER NOON GHUNNA + '\xab' # 0x8C -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\u2026' # 0x93 -> HORIZONTAL ELLIPSIS, right-left + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xbb' # 0x98 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK, right-left + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0x9B -> DIVISION SIGN, right-left + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + ' ' # 0xA0 -> SPACE, right-left + '!' # 0xA1 -> EXCLAMATION MARK, right-left + '"' # 0xA2 -> QUOTATION MARK, right-left + '#' # 0xA3 -> NUMBER SIGN, right-left + '$' # 0xA4 -> DOLLAR SIGN, right-left + '\u066a' # 0xA5 -> ARABIC PERCENT SIGN + '&' # 0xA6 -> AMPERSAND, right-left + "'" # 0xA7 -> APOSTROPHE, right-left + '(' # 0xA8 -> LEFT PARENTHESIS, right-left + ')' # 0xA9 -> RIGHT PARENTHESIS, right-left + '*' # 0xAA -> ASTERISK, right-left + '+' # 0xAB -> PLUS SIGN, right-left + '\u060c' # 0xAC -> ARABIC COMMA + '-' # 0xAD -> HYPHEN-MINUS, right-left + '.' # 0xAE -> FULL STOP, right-left + '/' # 0xAF -> SOLIDUS, right-left + '\u06f0' # 0xB0 -> EXTENDED ARABIC-INDIC DIGIT ZERO, right-left (need override) + '\u06f1' # 0xB1 -> EXTENDED ARABIC-INDIC DIGIT ONE, right-left (need override) + '\u06f2' # 0xB2 -> EXTENDED ARABIC-INDIC DIGIT TWO, right-left (need override) + '\u06f3' # 0xB3 -> EXTENDED ARABIC-INDIC DIGIT THREE, right-left (need override) + '\u06f4' # 0xB4 -> EXTENDED ARABIC-INDIC DIGIT FOUR, right-left (need override) + '\u06f5' # 0xB5 -> EXTENDED ARABIC-INDIC DIGIT FIVE, right-left (need override) + '\u06f6' # 0xB6 -> EXTENDED ARABIC-INDIC DIGIT SIX, right-left (need override) + '\u06f7' # 0xB7 -> EXTENDED ARABIC-INDIC DIGIT SEVEN, right-left (need override) + '\u06f8' # 0xB8 -> EXTENDED ARABIC-INDIC DIGIT EIGHT, right-left (need override) + '\u06f9' # 0xB9 -> EXTENDED ARABIC-INDIC DIGIT NINE, right-left (need override) + ':' # 0xBA -> COLON, right-left + '\u061b' # 0xBB -> ARABIC SEMICOLON + '<' # 0xBC -> LESS-THAN SIGN, right-left + '=' # 0xBD -> EQUALS SIGN, right-left + '>' # 0xBE -> GREATER-THAN SIGN, right-left + '\u061f' # 0xBF -> ARABIC QUESTION MARK + '\u274a' # 0xC0 -> EIGHT TEARDROP-SPOKED PROPELLER ASTERISK, right-left + '\u0621' # 0xC1 -> ARABIC LETTER HAMZA + '\u0622' # 0xC2 -> ARABIC LETTER ALEF WITH MADDA ABOVE + '\u0623' # 0xC3 -> ARABIC LETTER ALEF WITH HAMZA ABOVE + '\u0624' # 0xC4 -> ARABIC LETTER WAW WITH HAMZA ABOVE + '\u0625' # 0xC5 -> ARABIC LETTER ALEF WITH HAMZA BELOW + '\u0626' # 0xC6 -> ARABIC LETTER YEH WITH HAMZA ABOVE + '\u0627' # 0xC7 -> ARABIC LETTER ALEF + '\u0628' # 0xC8 -> ARABIC LETTER BEH + '\u0629' # 0xC9 -> ARABIC LETTER TEH MARBUTA + '\u062a' # 0xCA -> ARABIC LETTER TEH + '\u062b' # 0xCB -> ARABIC LETTER THEH + '\u062c' # 0xCC -> ARABIC LETTER JEEM + '\u062d' # 0xCD -> ARABIC LETTER HAH + '\u062e' # 0xCE -> ARABIC LETTER KHAH + '\u062f' # 0xCF -> ARABIC LETTER DAL + '\u0630' # 0xD0 -> ARABIC LETTER THAL + '\u0631' # 0xD1 -> ARABIC LETTER REH + '\u0632' # 0xD2 -> ARABIC LETTER ZAIN + '\u0633' # 0xD3 -> ARABIC LETTER SEEN + '\u0634' # 0xD4 -> ARABIC LETTER SHEEN + '\u0635' # 0xD5 -> ARABIC LETTER SAD + '\u0636' # 0xD6 -> ARABIC LETTER DAD + '\u0637' # 0xD7 -> ARABIC LETTER TAH + '\u0638' # 0xD8 -> ARABIC LETTER ZAH + '\u0639' # 0xD9 -> ARABIC LETTER AIN + '\u063a' # 0xDA -> ARABIC LETTER GHAIN + '[' # 0xDB -> LEFT SQUARE BRACKET, right-left + '\\' # 0xDC -> REVERSE SOLIDUS, right-left + ']' # 0xDD -> RIGHT SQUARE BRACKET, right-left + '^' # 0xDE -> CIRCUMFLEX ACCENT, right-left + '_' # 0xDF -> LOW LINE, right-left + '\u0640' # 0xE0 -> ARABIC TATWEEL + '\u0641' # 0xE1 -> ARABIC LETTER FEH + '\u0642' # 0xE2 -> ARABIC LETTER QAF + '\u0643' # 0xE3 -> ARABIC LETTER KAF + '\u0644' # 0xE4 -> ARABIC LETTER LAM + '\u0645' # 0xE5 -> ARABIC LETTER MEEM + '\u0646' # 0xE6 -> ARABIC LETTER NOON + '\u0647' # 0xE7 -> ARABIC LETTER HEH + '\u0648' # 0xE8 -> ARABIC LETTER WAW + '\u0649' # 0xE9 -> ARABIC LETTER ALEF MAKSURA + '\u064a' # 0xEA -> ARABIC LETTER YEH + '\u064b' # 0xEB -> ARABIC FATHATAN + '\u064c' # 0xEC -> ARABIC DAMMATAN + '\u064d' # 0xED -> ARABIC KASRATAN + '\u064e' # 0xEE -> ARABIC FATHA + '\u064f' # 0xEF -> ARABIC DAMMA + '\u0650' # 0xF0 -> ARABIC KASRA + '\u0651' # 0xF1 -> ARABIC SHADDA + '\u0652' # 0xF2 -> ARABIC SUKUN + '\u067e' # 0xF3 -> ARABIC LETTER PEH + '\u0679' # 0xF4 -> ARABIC LETTER TTEH + '\u0686' # 0xF5 -> ARABIC LETTER TCHEH + '\u06d5' # 0xF6 -> ARABIC LETTER AE + '\u06a4' # 0xF7 -> ARABIC LETTER VEH + '\u06af' # 0xF8 -> ARABIC LETTER GAF + '\u0688' # 0xF9 -> ARABIC LETTER DDAL + '\u0691' # 0xFA -> ARABIC LETTER RREH + '{' # 0xFB -> LEFT CURLY BRACKET, right-left + '|' # 0xFC -> VERTICAL LINE, right-left + '}' # 0xFD -> RIGHT CURLY BRACKET, right-left + '\u0698' # 0xFE -> ARABIC LETTER JEH + '\u06d2' # 0xFF -> ARABIC LETTER YEH BARREE +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_greek.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_greek.py new file mode 100644 index 0000000..d3d0c4f --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_greek.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_greek generated from 'MAPPINGS/VENDORS/APPLE/GREEK.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-greek', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xb9' # 0x81 -> SUPERSCRIPT ONE + '\xb2' # 0x82 -> SUPERSCRIPT TWO + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xb3' # 0x84 -> SUPERSCRIPT THREE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\u0385' # 0x87 -> GREEK DIALYTIKA TONOS + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\u0384' # 0x8B -> GREEK TONOS + '\xa8' # 0x8C -> DIAERESIS + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xa3' # 0x92 -> POUND SIGN + '\u2122' # 0x93 -> TRADE MARK SIGN + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\u2022' # 0x96 -> BULLET + '\xbd' # 0x97 -> VULGAR FRACTION ONE HALF + '\u2030' # 0x98 -> PER MILLE SIGN + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xa6' # 0x9B -> BROKEN BAR + '\u20ac' # 0x9C -> EURO SIGN # before Mac OS 9.2.2, was SOFT HYPHEN + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\u0393' # 0xA1 -> GREEK CAPITAL LETTER GAMMA + '\u0394' # 0xA2 -> GREEK CAPITAL LETTER DELTA + '\u0398' # 0xA3 -> GREEK CAPITAL LETTER THETA + '\u039b' # 0xA4 -> GREEK CAPITAL LETTER LAMDA + '\u039e' # 0xA5 -> GREEK CAPITAL LETTER XI + '\u03a0' # 0xA6 -> GREEK CAPITAL LETTER PI + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u03a3' # 0xAA -> GREEK CAPITAL LETTER SIGMA + '\u03aa' # 0xAB -> GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + '\xa7' # 0xAC -> SECTION SIGN + '\u2260' # 0xAD -> NOT EQUAL TO + '\xb0' # 0xAE -> DEGREE SIGN + '\xb7' # 0xAF -> MIDDLE DOT + '\u0391' # 0xB0 -> GREEK CAPITAL LETTER ALPHA + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\u0392' # 0xB5 -> GREEK CAPITAL LETTER BETA + '\u0395' # 0xB6 -> GREEK CAPITAL LETTER EPSILON + '\u0396' # 0xB7 -> GREEK CAPITAL LETTER ZETA + '\u0397' # 0xB8 -> GREEK CAPITAL LETTER ETA + '\u0399' # 0xB9 -> GREEK CAPITAL LETTER IOTA + '\u039a' # 0xBA -> GREEK CAPITAL LETTER KAPPA + '\u039c' # 0xBB -> GREEK CAPITAL LETTER MU + '\u03a6' # 0xBC -> GREEK CAPITAL LETTER PHI + '\u03ab' # 0xBD -> GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + '\u03a8' # 0xBE -> GREEK CAPITAL LETTER PSI + '\u03a9' # 0xBF -> GREEK CAPITAL LETTER OMEGA + '\u03ac' # 0xC0 -> GREEK SMALL LETTER ALPHA WITH TONOS + '\u039d' # 0xC1 -> GREEK CAPITAL LETTER NU + '\xac' # 0xC2 -> NOT SIGN + '\u039f' # 0xC3 -> GREEK CAPITAL LETTER OMICRON + '\u03a1' # 0xC4 -> GREEK CAPITAL LETTER RHO + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u03a4' # 0xC6 -> GREEK CAPITAL LETTER TAU + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\u03a5' # 0xCB -> GREEK CAPITAL LETTER UPSILON + '\u03a7' # 0xCC -> GREEK CAPITAL LETTER CHI + '\u0386' # 0xCD -> GREEK CAPITAL LETTER ALPHA WITH TONOS + '\u0388' # 0xCE -> GREEK CAPITAL LETTER EPSILON WITH TONOS + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2015' # 0xD1 -> HORIZONTAL BAR + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u0389' # 0xD7 -> GREEK CAPITAL LETTER ETA WITH TONOS + '\u038a' # 0xD8 -> GREEK CAPITAL LETTER IOTA WITH TONOS + '\u038c' # 0xD9 -> GREEK CAPITAL LETTER OMICRON WITH TONOS + '\u038e' # 0xDA -> GREEK CAPITAL LETTER UPSILON WITH TONOS + '\u03ad' # 0xDB -> GREEK SMALL LETTER EPSILON WITH TONOS + '\u03ae' # 0xDC -> GREEK SMALL LETTER ETA WITH TONOS + '\u03af' # 0xDD -> GREEK SMALL LETTER IOTA WITH TONOS + '\u03cc' # 0xDE -> GREEK SMALL LETTER OMICRON WITH TONOS + '\u038f' # 0xDF -> GREEK CAPITAL LETTER OMEGA WITH TONOS + '\u03cd' # 0xE0 -> GREEK SMALL LETTER UPSILON WITH TONOS + '\u03b1' # 0xE1 -> GREEK SMALL LETTER ALPHA + '\u03b2' # 0xE2 -> GREEK SMALL LETTER BETA + '\u03c8' # 0xE3 -> GREEK SMALL LETTER PSI + '\u03b4' # 0xE4 -> GREEK SMALL LETTER DELTA + '\u03b5' # 0xE5 -> GREEK SMALL LETTER EPSILON + '\u03c6' # 0xE6 -> GREEK SMALL LETTER PHI + '\u03b3' # 0xE7 -> GREEK SMALL LETTER GAMMA + '\u03b7' # 0xE8 -> GREEK SMALL LETTER ETA + '\u03b9' # 0xE9 -> GREEK SMALL LETTER IOTA + '\u03be' # 0xEA -> GREEK SMALL LETTER XI + '\u03ba' # 0xEB -> GREEK SMALL LETTER KAPPA + '\u03bb' # 0xEC -> GREEK SMALL LETTER LAMDA + '\u03bc' # 0xED -> GREEK SMALL LETTER MU + '\u03bd' # 0xEE -> GREEK SMALL LETTER NU + '\u03bf' # 0xEF -> GREEK SMALL LETTER OMICRON + '\u03c0' # 0xF0 -> GREEK SMALL LETTER PI + '\u03ce' # 0xF1 -> GREEK SMALL LETTER OMEGA WITH TONOS + '\u03c1' # 0xF2 -> GREEK SMALL LETTER RHO + '\u03c3' # 0xF3 -> GREEK SMALL LETTER SIGMA + '\u03c4' # 0xF4 -> GREEK SMALL LETTER TAU + '\u03b8' # 0xF5 -> GREEK SMALL LETTER THETA + '\u03c9' # 0xF6 -> GREEK SMALL LETTER OMEGA + '\u03c2' # 0xF7 -> GREEK SMALL LETTER FINAL SIGMA + '\u03c7' # 0xF8 -> GREEK SMALL LETTER CHI + '\u03c5' # 0xF9 -> GREEK SMALL LETTER UPSILON + '\u03b6' # 0xFA -> GREEK SMALL LETTER ZETA + '\u03ca' # 0xFB -> GREEK SMALL LETTER IOTA WITH DIALYTIKA + '\u03cb' # 0xFC -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA + '\u0390' # 0xFD -> GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + '\u03b0' # 0xFE -> GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + '\xad' # 0xFF -> SOFT HYPHEN # before Mac OS 9.2.2, was undefined +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_iceland.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_iceland.py new file mode 100644 index 0000000..add10f4 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_iceland.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_iceland generated from 'MAPPINGS/VENDORS/APPLE/ICELAND.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-iceland', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\xdd' # 0xA0 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\xe6' # 0xBE -> LATIN SMALL LETTER AE + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\xd0' # 0xDC -> LATIN CAPITAL LETTER ETH + '\xf0' # 0xDD -> LATIN SMALL LETTER ETH + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN + '\xfe' # 0xDF -> LATIN SMALL LETTER THORN + '\xfd' # 0xE0 -> LATIN SMALL LETTER Y WITH ACUTE + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_latin2.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_latin2.py new file mode 100644 index 0000000..da9d4b1 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_latin2.py @@ -0,0 +1,312 @@ +""" Python Character Mapping Codec mac_latin2 generated from 'MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT' with gencodec.py. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. +(c) Copyright 2000 Guido van Rossum. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-latin2', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\u0100' # 0x81 -> LATIN CAPITAL LETTER A WITH MACRON + '\u0101' # 0x82 -> LATIN SMALL LETTER A WITH MACRON + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\u0104' # 0x84 -> LATIN CAPITAL LETTER A WITH OGONEK + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\u0105' # 0x88 -> LATIN SMALL LETTER A WITH OGONEK + '\u010c' # 0x89 -> LATIN CAPITAL LETTER C WITH CARON + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\u010d' # 0x8B -> LATIN SMALL LETTER C WITH CARON + '\u0106' # 0x8C -> LATIN CAPITAL LETTER C WITH ACUTE + '\u0107' # 0x8D -> LATIN SMALL LETTER C WITH ACUTE + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\u0179' # 0x8F -> LATIN CAPITAL LETTER Z WITH ACUTE + '\u017a' # 0x90 -> LATIN SMALL LETTER Z WITH ACUTE + '\u010e' # 0x91 -> LATIN CAPITAL LETTER D WITH CARON + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\u010f' # 0x93 -> LATIN SMALL LETTER D WITH CARON + '\u0112' # 0x94 -> LATIN CAPITAL LETTER E WITH MACRON + '\u0113' # 0x95 -> LATIN SMALL LETTER E WITH MACRON + '\u0116' # 0x96 -> LATIN CAPITAL LETTER E WITH DOT ABOVE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\u0117' # 0x98 -> LATIN SMALL LETTER E WITH DOT ABOVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\u011a' # 0x9D -> LATIN CAPITAL LETTER E WITH CARON + '\u011b' # 0x9E -> LATIN SMALL LETTER E WITH CARON + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\u0118' # 0xA2 -> LATIN CAPITAL LETTER E WITH OGONEK + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\u0119' # 0xAB -> LATIN SMALL LETTER E WITH OGONEK + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\u0123' # 0xAE -> LATIN SMALL LETTER G WITH CEDILLA + '\u012e' # 0xAF -> LATIN CAPITAL LETTER I WITH OGONEK + '\u012f' # 0xB0 -> LATIN SMALL LETTER I WITH OGONEK + '\u012a' # 0xB1 -> LATIN CAPITAL LETTER I WITH MACRON + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\u012b' # 0xB4 -> LATIN SMALL LETTER I WITH MACRON + '\u0136' # 0xB5 -> LATIN CAPITAL LETTER K WITH CEDILLA + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u0142' # 0xB8 -> LATIN SMALL LETTER L WITH STROKE + '\u013b' # 0xB9 -> LATIN CAPITAL LETTER L WITH CEDILLA + '\u013c' # 0xBA -> LATIN SMALL LETTER L WITH CEDILLA + '\u013d' # 0xBB -> LATIN CAPITAL LETTER L WITH CARON + '\u013e' # 0xBC -> LATIN SMALL LETTER L WITH CARON + '\u0139' # 0xBD -> LATIN CAPITAL LETTER L WITH ACUTE + '\u013a' # 0xBE -> LATIN SMALL LETTER L WITH ACUTE + '\u0145' # 0xBF -> LATIN CAPITAL LETTER N WITH CEDILLA + '\u0146' # 0xC0 -> LATIN SMALL LETTER N WITH CEDILLA + '\u0143' # 0xC1 -> LATIN CAPITAL LETTER N WITH ACUTE + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0144' # 0xC4 -> LATIN SMALL LETTER N WITH ACUTE + '\u0147' # 0xC5 -> LATIN CAPITAL LETTER N WITH CARON + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\u0148' # 0xCB -> LATIN SMALL LETTER N WITH CARON + '\u0150' # 0xCC -> LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0151' # 0xCE -> LATIN SMALL LETTER O WITH DOUBLE ACUTE + '\u014c' # 0xCF -> LATIN CAPITAL LETTER O WITH MACRON + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\u014d' # 0xD8 -> LATIN SMALL LETTER O WITH MACRON + '\u0154' # 0xD9 -> LATIN CAPITAL LETTER R WITH ACUTE + '\u0155' # 0xDA -> LATIN SMALL LETTER R WITH ACUTE + '\u0158' # 0xDB -> LATIN CAPITAL LETTER R WITH CARON + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0159' # 0xDE -> LATIN SMALL LETTER R WITH CARON + '\u0156' # 0xDF -> LATIN CAPITAL LETTER R WITH CEDILLA + '\u0157' # 0xE0 -> LATIN SMALL LETTER R WITH CEDILLA + '\u0160' # 0xE1 -> LATIN CAPITAL LETTER S WITH CARON + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u0161' # 0xE4 -> LATIN SMALL LETTER S WITH CARON + '\u015a' # 0xE5 -> LATIN CAPITAL LETTER S WITH ACUTE + '\u015b' # 0xE6 -> LATIN SMALL LETTER S WITH ACUTE + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\u0164' # 0xE8 -> LATIN CAPITAL LETTER T WITH CARON + '\u0165' # 0xE9 -> LATIN SMALL LETTER T WITH CARON + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\u017d' # 0xEB -> LATIN CAPITAL LETTER Z WITH CARON + '\u017e' # 0xEC -> LATIN SMALL LETTER Z WITH CARON + '\u016a' # 0xED -> LATIN CAPITAL LETTER U WITH MACRON + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\u016b' # 0xF0 -> LATIN SMALL LETTER U WITH MACRON + '\u016e' # 0xF1 -> LATIN CAPITAL LETTER U WITH RING ABOVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\u016f' # 0xF3 -> LATIN SMALL LETTER U WITH RING ABOVE + '\u0170' # 0xF4 -> LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + '\u0171' # 0xF5 -> LATIN SMALL LETTER U WITH DOUBLE ACUTE + '\u0172' # 0xF6 -> LATIN CAPITAL LETTER U WITH OGONEK + '\u0173' # 0xF7 -> LATIN SMALL LETTER U WITH OGONEK + '\xdd' # 0xF8 -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xfd' # 0xF9 -> LATIN SMALL LETTER Y WITH ACUTE + '\u0137' # 0xFA -> LATIN SMALL LETTER K WITH CEDILLA + '\u017b' # 0xFB -> LATIN CAPITAL LETTER Z WITH DOT ABOVE + '\u0141' # 0xFC -> LATIN CAPITAL LETTER L WITH STROKE + '\u017c' # 0xFD -> LATIN SMALL LETTER Z WITH DOT ABOVE + '\u0122' # 0xFE -> LATIN CAPITAL LETTER G WITH CEDILLA + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_roman.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_roman.py new file mode 100644 index 0000000..b74b002 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_roman.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_roman generated from 'MAPPINGS/VENDORS/APPLE/ROMAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-roman', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\xe6' # 0xBE -> LATIN SMALL LETTER AE + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\ufb01' # 0xDE -> LATIN SMALL LIGATURE FI + '\ufb02' # 0xDF -> LATIN SMALL LIGATURE FL + '\u2021' # 0xE0 -> DOUBLE DAGGER + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_romanian.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_romanian.py new file mode 100644 index 0000000..d141b4c --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_romanian.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_romanian generated from 'MAPPINGS/VENDORS/APPLE/ROMANIAN.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-romanian', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\u0102' # 0xAE -> LATIN CAPITAL LETTER A WITH BREVE + '\u0218' # 0xAF -> LATIN CAPITAL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\u0103' # 0xBE -> LATIN SMALL LETTER A WITH BREVE + '\u0219' # 0xBF -> LATIN SMALL LETTER S WITH COMMA BELOW # for Unicode 3.0 and later + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u2044' # 0xDA -> FRACTION SLASH + '\u20ac' # 0xDB -> EURO SIGN + '\u2039' # 0xDC -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u203a' # 0xDD -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u021a' # 0xDE -> LATIN CAPITAL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later + '\u021b' # 0xDF -> LATIN SMALL LETTER T WITH COMMA BELOW # for Unicode 3.0 and later + '\u2021' # 0xE0 -> DOUBLE DAGGER + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\u0131' # 0xF5 -> LATIN SMALL LETTER DOTLESS I + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/mac_turkish.py b/crates/weavepy-vm/src/stdlib/python/encodings/mac_turkish.py new file mode 100644 index 0000000..044d4cb --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/mac_turkish.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec mac_turkish generated from 'MAPPINGS/VENDORS/APPLE/TURKISH.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='mac-turkish', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> CONTROL CHARACTER + '\x01' # 0x01 -> CONTROL CHARACTER + '\x02' # 0x02 -> CONTROL CHARACTER + '\x03' # 0x03 -> CONTROL CHARACTER + '\x04' # 0x04 -> CONTROL CHARACTER + '\x05' # 0x05 -> CONTROL CHARACTER + '\x06' # 0x06 -> CONTROL CHARACTER + '\x07' # 0x07 -> CONTROL CHARACTER + '\x08' # 0x08 -> CONTROL CHARACTER + '\t' # 0x09 -> CONTROL CHARACTER + '\n' # 0x0A -> CONTROL CHARACTER + '\x0b' # 0x0B -> CONTROL CHARACTER + '\x0c' # 0x0C -> CONTROL CHARACTER + '\r' # 0x0D -> CONTROL CHARACTER + '\x0e' # 0x0E -> CONTROL CHARACTER + '\x0f' # 0x0F -> CONTROL CHARACTER + '\x10' # 0x10 -> CONTROL CHARACTER + '\x11' # 0x11 -> CONTROL CHARACTER + '\x12' # 0x12 -> CONTROL CHARACTER + '\x13' # 0x13 -> CONTROL CHARACTER + '\x14' # 0x14 -> CONTROL CHARACTER + '\x15' # 0x15 -> CONTROL CHARACTER + '\x16' # 0x16 -> CONTROL CHARACTER + '\x17' # 0x17 -> CONTROL CHARACTER + '\x18' # 0x18 -> CONTROL CHARACTER + '\x19' # 0x19 -> CONTROL CHARACTER + '\x1a' # 0x1A -> CONTROL CHARACTER + '\x1b' # 0x1B -> CONTROL CHARACTER + '\x1c' # 0x1C -> CONTROL CHARACTER + '\x1d' # 0x1D -> CONTROL CHARACTER + '\x1e' # 0x1E -> CONTROL CHARACTER + '\x1f' # 0x1F -> CONTROL CHARACTER + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> CONTROL CHARACTER + '\xc4' # 0x80 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0x81 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc7' # 0x82 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc9' # 0x83 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xd1' # 0x84 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd6' # 0x85 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xdc' # 0x86 -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xe1' # 0x87 -> LATIN SMALL LETTER A WITH ACUTE + '\xe0' # 0x88 -> LATIN SMALL LETTER A WITH GRAVE + '\xe2' # 0x89 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe4' # 0x8A -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe3' # 0x8B -> LATIN SMALL LETTER A WITH TILDE + '\xe5' # 0x8C -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe7' # 0x8D -> LATIN SMALL LETTER C WITH CEDILLA + '\xe9' # 0x8E -> LATIN SMALL LETTER E WITH ACUTE + '\xe8' # 0x8F -> LATIN SMALL LETTER E WITH GRAVE + '\xea' # 0x90 -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0x91 -> LATIN SMALL LETTER E WITH DIAERESIS + '\xed' # 0x92 -> LATIN SMALL LETTER I WITH ACUTE + '\xec' # 0x93 -> LATIN SMALL LETTER I WITH GRAVE + '\xee' # 0x94 -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0x95 -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf1' # 0x96 -> LATIN SMALL LETTER N WITH TILDE + '\xf3' # 0x97 -> LATIN SMALL LETTER O WITH ACUTE + '\xf2' # 0x98 -> LATIN SMALL LETTER O WITH GRAVE + '\xf4' # 0x99 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf6' # 0x9A -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf5' # 0x9B -> LATIN SMALL LETTER O WITH TILDE + '\xfa' # 0x9C -> LATIN SMALL LETTER U WITH ACUTE + '\xf9' # 0x9D -> LATIN SMALL LETTER U WITH GRAVE + '\xfb' # 0x9E -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0x9F -> LATIN SMALL LETTER U WITH DIAERESIS + '\u2020' # 0xA0 -> DAGGER + '\xb0' # 0xA1 -> DEGREE SIGN + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa7' # 0xA4 -> SECTION SIGN + '\u2022' # 0xA5 -> BULLET + '\xb6' # 0xA6 -> PILCROW SIGN + '\xdf' # 0xA7 -> LATIN SMALL LETTER SHARP S + '\xae' # 0xA8 -> REGISTERED SIGN + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u2122' # 0xAA -> TRADE MARK SIGN + '\xb4' # 0xAB -> ACUTE ACCENT + '\xa8' # 0xAC -> DIAERESIS + '\u2260' # 0xAD -> NOT EQUAL TO + '\xc6' # 0xAE -> LATIN CAPITAL LETTER AE + '\xd8' # 0xAF -> LATIN CAPITAL LETTER O WITH STROKE + '\u221e' # 0xB0 -> INFINITY + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\u2264' # 0xB2 -> LESS-THAN OR EQUAL TO + '\u2265' # 0xB3 -> GREATER-THAN OR EQUAL TO + '\xa5' # 0xB4 -> YEN SIGN + '\xb5' # 0xB5 -> MICRO SIGN + '\u2202' # 0xB6 -> PARTIAL DIFFERENTIAL + '\u2211' # 0xB7 -> N-ARY SUMMATION + '\u220f' # 0xB8 -> N-ARY PRODUCT + '\u03c0' # 0xB9 -> GREEK SMALL LETTER PI + '\u222b' # 0xBA -> INTEGRAL + '\xaa' # 0xBB -> FEMININE ORDINAL INDICATOR + '\xba' # 0xBC -> MASCULINE ORDINAL INDICATOR + '\u03a9' # 0xBD -> GREEK CAPITAL LETTER OMEGA + '\xe6' # 0xBE -> LATIN SMALL LETTER AE + '\xf8' # 0xBF -> LATIN SMALL LETTER O WITH STROKE + '\xbf' # 0xC0 -> INVERTED QUESTION MARK + '\xa1' # 0xC1 -> INVERTED EXCLAMATION MARK + '\xac' # 0xC2 -> NOT SIGN + '\u221a' # 0xC3 -> SQUARE ROOT + '\u0192' # 0xC4 -> LATIN SMALL LETTER F WITH HOOK + '\u2248' # 0xC5 -> ALMOST EQUAL TO + '\u2206' # 0xC6 -> INCREMENT + '\xab' # 0xC7 -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbb' # 0xC8 -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u2026' # 0xC9 -> HORIZONTAL ELLIPSIS + '\xa0' # 0xCA -> NO-BREAK SPACE + '\xc0' # 0xCB -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc3' # 0xCC -> LATIN CAPITAL LETTER A WITH TILDE + '\xd5' # 0xCD -> LATIN CAPITAL LETTER O WITH TILDE + '\u0152' # 0xCE -> LATIN CAPITAL LIGATURE OE + '\u0153' # 0xCF -> LATIN SMALL LIGATURE OE + '\u2013' # 0xD0 -> EN DASH + '\u2014' # 0xD1 -> EM DASH + '\u201c' # 0xD2 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0xD3 -> RIGHT DOUBLE QUOTATION MARK + '\u2018' # 0xD4 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0xD5 -> RIGHT SINGLE QUOTATION MARK + '\xf7' # 0xD6 -> DIVISION SIGN + '\u25ca' # 0xD7 -> LOZENGE + '\xff' # 0xD8 -> LATIN SMALL LETTER Y WITH DIAERESIS + '\u0178' # 0xD9 -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\u011e' # 0xDA -> LATIN CAPITAL LETTER G WITH BREVE + '\u011f' # 0xDB -> LATIN SMALL LETTER G WITH BREVE + '\u0130' # 0xDC -> LATIN CAPITAL LETTER I WITH DOT ABOVE + '\u0131' # 0xDD -> LATIN SMALL LETTER DOTLESS I + '\u015e' # 0xDE -> LATIN CAPITAL LETTER S WITH CEDILLA + '\u015f' # 0xDF -> LATIN SMALL LETTER S WITH CEDILLA + '\u2021' # 0xE0 -> DOUBLE DAGGER + '\xb7' # 0xE1 -> MIDDLE DOT + '\u201a' # 0xE2 -> SINGLE LOW-9 QUOTATION MARK + '\u201e' # 0xE3 -> DOUBLE LOW-9 QUOTATION MARK + '\u2030' # 0xE4 -> PER MILLE SIGN + '\xc2' # 0xE5 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xca' # 0xE6 -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xc1' # 0xE7 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xcb' # 0xE8 -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xc8' # 0xE9 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xcd' # 0xEA -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xEB -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xEC -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xcc' # 0xED -> LATIN CAPITAL LETTER I WITH GRAVE + '\xd3' # 0xEE -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xEF -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\uf8ff' # 0xF0 -> Apple logo + '\xd2' # 0xF1 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xda' # 0xF2 -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xF3 -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xd9' # 0xF4 -> LATIN CAPITAL LETTER U WITH GRAVE + '\uf8a0' # 0xF5 -> undefined1 + '\u02c6' # 0xF6 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u02dc' # 0xF7 -> SMALL TILDE + '\xaf' # 0xF8 -> MACRON + '\u02d8' # 0xF9 -> BREVE + '\u02d9' # 0xFA -> DOT ABOVE + '\u02da' # 0xFB -> RING ABOVE + '\xb8' # 0xFC -> CEDILLA + '\u02dd' # 0xFD -> DOUBLE ACUTE ACCENT + '\u02db' # 0xFE -> OGONEK + '\u02c7' # 0xFF -> CARON +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/palmos.py b/crates/weavepy-vm/src/stdlib/python/encodings/palmos.py new file mode 100644 index 0000000..df164ca --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/palmos.py @@ -0,0 +1,308 @@ +""" Python Character Mapping Codec for PalmOS 3.5. + +Written by Sjoerd Mullender (sjoerd@acm.org); based on iso8859_15.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='palmos', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\u20ac' # 0x80 -> EURO SIGN + '\x81' # 0x81 -> + '\u201a' # 0x82 -> SINGLE LOW-9 QUOTATION MARK + '\u0192' # 0x83 -> LATIN SMALL LETTER F WITH HOOK + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u2020' # 0x86 -> DAGGER + '\u2021' # 0x87 -> DOUBLE DAGGER + '\u02c6' # 0x88 -> MODIFIER LETTER CIRCUMFLEX ACCENT + '\u2030' # 0x89 -> PER MILLE SIGN + '\u0160' # 0x8A -> LATIN CAPITAL LETTER S WITH CARON + '\u2039' # 0x8B -> SINGLE LEFT-POINTING ANGLE QUOTATION MARK + '\u0152' # 0x8C -> LATIN CAPITAL LIGATURE OE + '\u2666' # 0x8D -> BLACK DIAMOND SUIT + '\u2663' # 0x8E -> BLACK CLUB SUIT + '\u2665' # 0x8F -> BLACK HEART SUIT + '\u2660' # 0x90 -> BLACK SPADE SUIT + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u02dc' # 0x98 -> SMALL TILDE + '\u2122' # 0x99 -> TRADE MARK SIGN + '\u0161' # 0x9A -> LATIN SMALL LETTER S WITH CARON + '\u203a' # 0x9B -> SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + '\u0153' # 0x9C -> LATIN SMALL LIGATURE OE + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\u0178' # 0x9F -> LATIN CAPITAL LETTER Y WITH DIAERESIS + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\xa1' # 0xA1 -> INVERTED EXCLAMATION MARK + '\xa2' # 0xA2 -> CENT SIGN + '\xa3' # 0xA3 -> POUND SIGN + '\xa4' # 0xA4 -> CURRENCY SIGN + '\xa5' # 0xA5 -> YEN SIGN + '\xa6' # 0xA6 -> BROKEN BAR + '\xa7' # 0xA7 -> SECTION SIGN + '\xa8' # 0xA8 -> DIAERESIS + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\xaa' # 0xAA -> FEMININE ORDINAL INDICATOR + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\xad' # 0xAD -> SOFT HYPHEN + '\xae' # 0xAE -> REGISTERED SIGN + '\xaf' # 0xAF -> MACRON + '\xb0' # 0xB0 -> DEGREE SIGN + '\xb1' # 0xB1 -> PLUS-MINUS SIGN + '\xb2' # 0xB2 -> SUPERSCRIPT TWO + '\xb3' # 0xB3 -> SUPERSCRIPT THREE + '\xb4' # 0xB4 -> ACUTE ACCENT + '\xb5' # 0xB5 -> MICRO SIGN + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\xb8' # 0xB8 -> CEDILLA + '\xb9' # 0xB9 -> SUPERSCRIPT ONE + '\xba' # 0xBA -> MASCULINE ORDINAL INDICATOR + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xbc' # 0xBC -> VULGAR FRACTION ONE QUARTER + '\xbd' # 0xBD -> VULGAR FRACTION ONE HALF + '\xbe' # 0xBE -> VULGAR FRACTION THREE QUARTERS + '\xbf' # 0xBF -> INVERTED QUESTION MARK + '\xc0' # 0xC0 -> LATIN CAPITAL LETTER A WITH GRAVE + '\xc1' # 0xC1 -> LATIN CAPITAL LETTER A WITH ACUTE + '\xc2' # 0xC2 -> LATIN CAPITAL LETTER A WITH CIRCUMFLEX + '\xc3' # 0xC3 -> LATIN CAPITAL LETTER A WITH TILDE + '\xc4' # 0xC4 -> LATIN CAPITAL LETTER A WITH DIAERESIS + '\xc5' # 0xC5 -> LATIN CAPITAL LETTER A WITH RING ABOVE + '\xc6' # 0xC6 -> LATIN CAPITAL LETTER AE + '\xc7' # 0xC7 -> LATIN CAPITAL LETTER C WITH CEDILLA + '\xc8' # 0xC8 -> LATIN CAPITAL LETTER E WITH GRAVE + '\xc9' # 0xC9 -> LATIN CAPITAL LETTER E WITH ACUTE + '\xca' # 0xCA -> LATIN CAPITAL LETTER E WITH CIRCUMFLEX + '\xcb' # 0xCB -> LATIN CAPITAL LETTER E WITH DIAERESIS + '\xcc' # 0xCC -> LATIN CAPITAL LETTER I WITH GRAVE + '\xcd' # 0xCD -> LATIN CAPITAL LETTER I WITH ACUTE + '\xce' # 0xCE -> LATIN CAPITAL LETTER I WITH CIRCUMFLEX + '\xcf' # 0xCF -> LATIN CAPITAL LETTER I WITH DIAERESIS + '\xd0' # 0xD0 -> LATIN CAPITAL LETTER ETH (Icelandic) + '\xd1' # 0xD1 -> LATIN CAPITAL LETTER N WITH TILDE + '\xd2' # 0xD2 -> LATIN CAPITAL LETTER O WITH GRAVE + '\xd3' # 0xD3 -> LATIN CAPITAL LETTER O WITH ACUTE + '\xd4' # 0xD4 -> LATIN CAPITAL LETTER O WITH CIRCUMFLEX + '\xd5' # 0xD5 -> LATIN CAPITAL LETTER O WITH TILDE + '\xd6' # 0xD6 -> LATIN CAPITAL LETTER O WITH DIAERESIS + '\xd7' # 0xD7 -> MULTIPLICATION SIGN + '\xd8' # 0xD8 -> LATIN CAPITAL LETTER O WITH STROKE + '\xd9' # 0xD9 -> LATIN CAPITAL LETTER U WITH GRAVE + '\xda' # 0xDA -> LATIN CAPITAL LETTER U WITH ACUTE + '\xdb' # 0xDB -> LATIN CAPITAL LETTER U WITH CIRCUMFLEX + '\xdc' # 0xDC -> LATIN CAPITAL LETTER U WITH DIAERESIS + '\xdd' # 0xDD -> LATIN CAPITAL LETTER Y WITH ACUTE + '\xde' # 0xDE -> LATIN CAPITAL LETTER THORN (Icelandic) + '\xdf' # 0xDF -> LATIN SMALL LETTER SHARP S (German) + '\xe0' # 0xE0 -> LATIN SMALL LETTER A WITH GRAVE + '\xe1' # 0xE1 -> LATIN SMALL LETTER A WITH ACUTE + '\xe2' # 0xE2 -> LATIN SMALL LETTER A WITH CIRCUMFLEX + '\xe3' # 0xE3 -> LATIN SMALL LETTER A WITH TILDE + '\xe4' # 0xE4 -> LATIN SMALL LETTER A WITH DIAERESIS + '\xe5' # 0xE5 -> LATIN SMALL LETTER A WITH RING ABOVE + '\xe6' # 0xE6 -> LATIN SMALL LETTER AE + '\xe7' # 0xE7 -> LATIN SMALL LETTER C WITH CEDILLA + '\xe8' # 0xE8 -> LATIN SMALL LETTER E WITH GRAVE + '\xe9' # 0xE9 -> LATIN SMALL LETTER E WITH ACUTE + '\xea' # 0xEA -> LATIN SMALL LETTER E WITH CIRCUMFLEX + '\xeb' # 0xEB -> LATIN SMALL LETTER E WITH DIAERESIS + '\xec' # 0xEC -> LATIN SMALL LETTER I WITH GRAVE + '\xed' # 0xED -> LATIN SMALL LETTER I WITH ACUTE + '\xee' # 0xEE -> LATIN SMALL LETTER I WITH CIRCUMFLEX + '\xef' # 0xEF -> LATIN SMALL LETTER I WITH DIAERESIS + '\xf0' # 0xF0 -> LATIN SMALL LETTER ETH (Icelandic) + '\xf1' # 0xF1 -> LATIN SMALL LETTER N WITH TILDE + '\xf2' # 0xF2 -> LATIN SMALL LETTER O WITH GRAVE + '\xf3' # 0xF3 -> LATIN SMALL LETTER O WITH ACUTE + '\xf4' # 0xF4 -> LATIN SMALL LETTER O WITH CIRCUMFLEX + '\xf5' # 0xF5 -> LATIN SMALL LETTER O WITH TILDE + '\xf6' # 0xF6 -> LATIN SMALL LETTER O WITH DIAERESIS + '\xf7' # 0xF7 -> DIVISION SIGN + '\xf8' # 0xF8 -> LATIN SMALL LETTER O WITH STROKE + '\xf9' # 0xF9 -> LATIN SMALL LETTER U WITH GRAVE + '\xfa' # 0xFA -> LATIN SMALL LETTER U WITH ACUTE + '\xfb' # 0xFB -> LATIN SMALL LETTER U WITH CIRCUMFLEX + '\xfc' # 0xFC -> LATIN SMALL LETTER U WITH DIAERESIS + '\xfd' # 0xFD -> LATIN SMALL LETTER Y WITH ACUTE + '\xfe' # 0xFE -> LATIN SMALL LETTER THORN (Icelandic) + '\xff' # 0xFF -> LATIN SMALL LETTER Y WITH DIAERESIS +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/ptcp154.py b/crates/weavepy-vm/src/stdlib/python/encodings/ptcp154.py new file mode 100644 index 0000000..656b79d --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/ptcp154.py @@ -0,0 +1,312 @@ +""" Python Character Mapping Codec generated from 'PTCP154.txt' with gencodec.py. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. +(c) Copyright 2000 Guido van Rossum. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='ptcp154', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE (DEL) + '\u0496' # 0x80 -> CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER + '\u0492' # 0x81 -> CYRILLIC CAPITAL LETTER GHE WITH STROKE + '\u04ee' # 0x82 -> CYRILLIC CAPITAL LETTER U WITH MACRON + '\u0493' # 0x83 -> CYRILLIC SMALL LETTER GHE WITH STROKE + '\u201e' # 0x84 -> DOUBLE LOW-9 QUOTATION MARK + '\u2026' # 0x85 -> HORIZONTAL ELLIPSIS + '\u04b6' # 0x86 -> CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + '\u04ae' # 0x87 -> CYRILLIC CAPITAL LETTER STRAIGHT U + '\u04b2' # 0x88 -> CYRILLIC CAPITAL LETTER HA WITH DESCENDER + '\u04af' # 0x89 -> CYRILLIC SMALL LETTER STRAIGHT U + '\u04a0' # 0x8A -> CYRILLIC CAPITAL LETTER BASHKIR KA + '\u04e2' # 0x8B -> CYRILLIC CAPITAL LETTER I WITH MACRON + '\u04a2' # 0x8C -> CYRILLIC CAPITAL LETTER EN WITH DESCENDER + '\u049a' # 0x8D -> CYRILLIC CAPITAL LETTER KA WITH DESCENDER + '\u04ba' # 0x8E -> CYRILLIC CAPITAL LETTER SHHA + '\u04b8' # 0x8F -> CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE + '\u0497' # 0x90 -> CYRILLIC SMALL LETTER ZHE WITH DESCENDER + '\u2018' # 0x91 -> LEFT SINGLE QUOTATION MARK + '\u2019' # 0x92 -> RIGHT SINGLE QUOTATION MARK + '\u201c' # 0x93 -> LEFT DOUBLE QUOTATION MARK + '\u201d' # 0x94 -> RIGHT DOUBLE QUOTATION MARK + '\u2022' # 0x95 -> BULLET + '\u2013' # 0x96 -> EN DASH + '\u2014' # 0x97 -> EM DASH + '\u04b3' # 0x98 -> CYRILLIC SMALL LETTER HA WITH DESCENDER + '\u04b7' # 0x99 -> CYRILLIC SMALL LETTER CHE WITH DESCENDER + '\u04a1' # 0x9A -> CYRILLIC SMALL LETTER BASHKIR KA + '\u04e3' # 0x9B -> CYRILLIC SMALL LETTER I WITH MACRON + '\u04a3' # 0x9C -> CYRILLIC SMALL LETTER EN WITH DESCENDER + '\u049b' # 0x9D -> CYRILLIC SMALL LETTER KA WITH DESCENDER + '\u04bb' # 0x9E -> CYRILLIC SMALL LETTER SHHA + '\u04b9' # 0x9F -> CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE + '\xa0' # 0xA0 -> NO-BREAK SPACE + '\u040e' # 0xA1 -> CYRILLIC CAPITAL LETTER SHORT U (Byelorussian) + '\u045e' # 0xA2 -> CYRILLIC SMALL LETTER SHORT U (Byelorussian) + '\u0408' # 0xA3 -> CYRILLIC CAPITAL LETTER JE + '\u04e8' # 0xA4 -> CYRILLIC CAPITAL LETTER BARRED O + '\u0498' # 0xA5 -> CYRILLIC CAPITAL LETTER ZE WITH DESCENDER + '\u04b0' # 0xA6 -> CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + '\xa7' # 0xA7 -> SECTION SIGN + '\u0401' # 0xA8 -> CYRILLIC CAPITAL LETTER IO + '\xa9' # 0xA9 -> COPYRIGHT SIGN + '\u04d8' # 0xAA -> CYRILLIC CAPITAL LETTER SCHWA + '\xab' # 0xAB -> LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + '\xac' # 0xAC -> NOT SIGN + '\u04ef' # 0xAD -> CYRILLIC SMALL LETTER U WITH MACRON + '\xae' # 0xAE -> REGISTERED SIGN + '\u049c' # 0xAF -> CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE + '\xb0' # 0xB0 -> DEGREE SIGN + '\u04b1' # 0xB1 -> CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + '\u0406' # 0xB2 -> CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0456' # 0xB3 -> CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + '\u0499' # 0xB4 -> CYRILLIC SMALL LETTER ZE WITH DESCENDER + '\u04e9' # 0xB5 -> CYRILLIC SMALL LETTER BARRED O + '\xb6' # 0xB6 -> PILCROW SIGN + '\xb7' # 0xB7 -> MIDDLE DOT + '\u0451' # 0xB8 -> CYRILLIC SMALL LETTER IO + '\u2116' # 0xB9 -> NUMERO SIGN + '\u04d9' # 0xBA -> CYRILLIC SMALL LETTER SCHWA + '\xbb' # 0xBB -> RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + '\u0458' # 0xBC -> CYRILLIC SMALL LETTER JE + '\u04aa' # 0xBD -> CYRILLIC CAPITAL LETTER ES WITH DESCENDER + '\u04ab' # 0xBE -> CYRILLIC SMALL LETTER ES WITH DESCENDER + '\u049d' # 0xBF -> CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE + '\u0410' # 0xC0 -> CYRILLIC CAPITAL LETTER A + '\u0411' # 0xC1 -> CYRILLIC CAPITAL LETTER BE + '\u0412' # 0xC2 -> CYRILLIC CAPITAL LETTER VE + '\u0413' # 0xC3 -> CYRILLIC CAPITAL LETTER GHE + '\u0414' # 0xC4 -> CYRILLIC CAPITAL LETTER DE + '\u0415' # 0xC5 -> CYRILLIC CAPITAL LETTER IE + '\u0416' # 0xC6 -> CYRILLIC CAPITAL LETTER ZHE + '\u0417' # 0xC7 -> CYRILLIC CAPITAL LETTER ZE + '\u0418' # 0xC8 -> CYRILLIC CAPITAL LETTER I + '\u0419' # 0xC9 -> CYRILLIC CAPITAL LETTER SHORT I + '\u041a' # 0xCA -> CYRILLIC CAPITAL LETTER KA + '\u041b' # 0xCB -> CYRILLIC CAPITAL LETTER EL + '\u041c' # 0xCC -> CYRILLIC CAPITAL LETTER EM + '\u041d' # 0xCD -> CYRILLIC CAPITAL LETTER EN + '\u041e' # 0xCE -> CYRILLIC CAPITAL LETTER O + '\u041f' # 0xCF -> CYRILLIC CAPITAL LETTER PE + '\u0420' # 0xD0 -> CYRILLIC CAPITAL LETTER ER + '\u0421' # 0xD1 -> CYRILLIC CAPITAL LETTER ES + '\u0422' # 0xD2 -> CYRILLIC CAPITAL LETTER TE + '\u0423' # 0xD3 -> CYRILLIC CAPITAL LETTER U + '\u0424' # 0xD4 -> CYRILLIC CAPITAL LETTER EF + '\u0425' # 0xD5 -> CYRILLIC CAPITAL LETTER HA + '\u0426' # 0xD6 -> CYRILLIC CAPITAL LETTER TSE + '\u0427' # 0xD7 -> CYRILLIC CAPITAL LETTER CHE + '\u0428' # 0xD8 -> CYRILLIC CAPITAL LETTER SHA + '\u0429' # 0xD9 -> CYRILLIC CAPITAL LETTER SHCHA + '\u042a' # 0xDA -> CYRILLIC CAPITAL LETTER HARD SIGN + '\u042b' # 0xDB -> CYRILLIC CAPITAL LETTER YERU + '\u042c' # 0xDC -> CYRILLIC CAPITAL LETTER SOFT SIGN + '\u042d' # 0xDD -> CYRILLIC CAPITAL LETTER E + '\u042e' # 0xDE -> CYRILLIC CAPITAL LETTER YU + '\u042f' # 0xDF -> CYRILLIC CAPITAL LETTER YA + '\u0430' # 0xE0 -> CYRILLIC SMALL LETTER A + '\u0431' # 0xE1 -> CYRILLIC SMALL LETTER BE + '\u0432' # 0xE2 -> CYRILLIC SMALL LETTER VE + '\u0433' # 0xE3 -> CYRILLIC SMALL LETTER GHE + '\u0434' # 0xE4 -> CYRILLIC SMALL LETTER DE + '\u0435' # 0xE5 -> CYRILLIC SMALL LETTER IE + '\u0436' # 0xE6 -> CYRILLIC SMALL LETTER ZHE + '\u0437' # 0xE7 -> CYRILLIC SMALL LETTER ZE + '\u0438' # 0xE8 -> CYRILLIC SMALL LETTER I + '\u0439' # 0xE9 -> CYRILLIC SMALL LETTER SHORT I + '\u043a' # 0xEA -> CYRILLIC SMALL LETTER KA + '\u043b' # 0xEB -> CYRILLIC SMALL LETTER EL + '\u043c' # 0xEC -> CYRILLIC SMALL LETTER EM + '\u043d' # 0xED -> CYRILLIC SMALL LETTER EN + '\u043e' # 0xEE -> CYRILLIC SMALL LETTER O + '\u043f' # 0xEF -> CYRILLIC SMALL LETTER PE + '\u0440' # 0xF0 -> CYRILLIC SMALL LETTER ER + '\u0441' # 0xF1 -> CYRILLIC SMALL LETTER ES + '\u0442' # 0xF2 -> CYRILLIC SMALL LETTER TE + '\u0443' # 0xF3 -> CYRILLIC SMALL LETTER U + '\u0444' # 0xF4 -> CYRILLIC SMALL LETTER EF + '\u0445' # 0xF5 -> CYRILLIC SMALL LETTER HA + '\u0446' # 0xF6 -> CYRILLIC SMALL LETTER TSE + '\u0447' # 0xF7 -> CYRILLIC SMALL LETTER CHE + '\u0448' # 0xF8 -> CYRILLIC SMALL LETTER SHA + '\u0449' # 0xF9 -> CYRILLIC SMALL LETTER SHCHA + '\u044a' # 0xFA -> CYRILLIC SMALL LETTER HARD SIGN + '\u044b' # 0xFB -> CYRILLIC SMALL LETTER YERU + '\u044c' # 0xFC -> CYRILLIC SMALL LETTER SOFT SIGN + '\u044d' # 0xFD -> CYRILLIC SMALL LETTER E + '\u044e' # 0xFE -> CYRILLIC SMALL LETTER YU + '\u044f' # 0xFF -> CYRILLIC SMALL LETTER YA +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/rot_13.py b/crates/weavepy-vm/src/stdlib/python/encodings/rot_13.py new file mode 100644 index 0000000..5627bfb --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/rot_13.py @@ -0,0 +1,113 @@ +#!/usr/bin/env python +""" Python Character Mapping Codec for ROT13. + +This codec de/encodes from str to str. + +Written by Marc-Andre Lemburg (mal@lemburg.com). +""" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self, input, errors='strict'): + return (str.translate(input, rot13_map), len(input)) + + def decode(self, input, errors='strict'): + return (str.translate(input, rot13_map), len(input)) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return str.translate(input, rot13_map) + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return str.translate(input, rot13_map) + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='rot-13', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + _is_text_encoding=False, + ) + +### Map + +rot13_map = codecs.make_identity_dict(range(256)) +rot13_map.update({ + 0x0041: 0x004e, + 0x0042: 0x004f, + 0x0043: 0x0050, + 0x0044: 0x0051, + 0x0045: 0x0052, + 0x0046: 0x0053, + 0x0047: 0x0054, + 0x0048: 0x0055, + 0x0049: 0x0056, + 0x004a: 0x0057, + 0x004b: 0x0058, + 0x004c: 0x0059, + 0x004d: 0x005a, + 0x004e: 0x0041, + 0x004f: 0x0042, + 0x0050: 0x0043, + 0x0051: 0x0044, + 0x0052: 0x0045, + 0x0053: 0x0046, + 0x0054: 0x0047, + 0x0055: 0x0048, + 0x0056: 0x0049, + 0x0057: 0x004a, + 0x0058: 0x004b, + 0x0059: 0x004c, + 0x005a: 0x004d, + 0x0061: 0x006e, + 0x0062: 0x006f, + 0x0063: 0x0070, + 0x0064: 0x0071, + 0x0065: 0x0072, + 0x0066: 0x0073, + 0x0067: 0x0074, + 0x0068: 0x0075, + 0x0069: 0x0076, + 0x006a: 0x0077, + 0x006b: 0x0078, + 0x006c: 0x0079, + 0x006d: 0x007a, + 0x006e: 0x0061, + 0x006f: 0x0062, + 0x0070: 0x0063, + 0x0071: 0x0064, + 0x0072: 0x0065, + 0x0073: 0x0066, + 0x0074: 0x0067, + 0x0075: 0x0068, + 0x0076: 0x0069, + 0x0077: 0x006a, + 0x0078: 0x006b, + 0x0079: 0x006c, + 0x007a: 0x006d, +}) + +### Filter API + +def rot13(infile, outfile): + outfile.write(codecs.encode(infile.read(), 'rot-13')) + +if __name__ == '__main__': + import sys + rot13(sys.stdin, sys.stdout) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/tis_620.py b/crates/weavepy-vm/src/stdlib/python/encodings/tis_620.py new file mode 100644 index 0000000..e288386 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/tis_620.py @@ -0,0 +1,307 @@ +""" Python Character Mapping Codec tis_620 generated from 'python-mappings/TIS-620.TXT' with gencodec.py. + +"""#" + +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + return codecs.charmap_encode(input,errors,encoding_table) + + def decode(self,input,errors='strict'): + return codecs.charmap_decode(input,errors,decoding_table) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.charmap_encode(input,self.errors,encoding_table)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + return codecs.charmap_decode(input,self.errors,decoding_table)[0] + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='tis-620', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) + + +### Decoding Table + +decoding_table = ( + '\x00' # 0x00 -> NULL + '\x01' # 0x01 -> START OF HEADING + '\x02' # 0x02 -> START OF TEXT + '\x03' # 0x03 -> END OF TEXT + '\x04' # 0x04 -> END OF TRANSMISSION + '\x05' # 0x05 -> ENQUIRY + '\x06' # 0x06 -> ACKNOWLEDGE + '\x07' # 0x07 -> BELL + '\x08' # 0x08 -> BACKSPACE + '\t' # 0x09 -> HORIZONTAL TABULATION + '\n' # 0x0A -> LINE FEED + '\x0b' # 0x0B -> VERTICAL TABULATION + '\x0c' # 0x0C -> FORM FEED + '\r' # 0x0D -> CARRIAGE RETURN + '\x0e' # 0x0E -> SHIFT OUT + '\x0f' # 0x0F -> SHIFT IN + '\x10' # 0x10 -> DATA LINK ESCAPE + '\x11' # 0x11 -> DEVICE CONTROL ONE + '\x12' # 0x12 -> DEVICE CONTROL TWO + '\x13' # 0x13 -> DEVICE CONTROL THREE + '\x14' # 0x14 -> DEVICE CONTROL FOUR + '\x15' # 0x15 -> NEGATIVE ACKNOWLEDGE + '\x16' # 0x16 -> SYNCHRONOUS IDLE + '\x17' # 0x17 -> END OF TRANSMISSION BLOCK + '\x18' # 0x18 -> CANCEL + '\x19' # 0x19 -> END OF MEDIUM + '\x1a' # 0x1A -> SUBSTITUTE + '\x1b' # 0x1B -> ESCAPE + '\x1c' # 0x1C -> FILE SEPARATOR + '\x1d' # 0x1D -> GROUP SEPARATOR + '\x1e' # 0x1E -> RECORD SEPARATOR + '\x1f' # 0x1F -> UNIT SEPARATOR + ' ' # 0x20 -> SPACE + '!' # 0x21 -> EXCLAMATION MARK + '"' # 0x22 -> QUOTATION MARK + '#' # 0x23 -> NUMBER SIGN + '$' # 0x24 -> DOLLAR SIGN + '%' # 0x25 -> PERCENT SIGN + '&' # 0x26 -> AMPERSAND + "'" # 0x27 -> APOSTROPHE + '(' # 0x28 -> LEFT PARENTHESIS + ')' # 0x29 -> RIGHT PARENTHESIS + '*' # 0x2A -> ASTERISK + '+' # 0x2B -> PLUS SIGN + ',' # 0x2C -> COMMA + '-' # 0x2D -> HYPHEN-MINUS + '.' # 0x2E -> FULL STOP + '/' # 0x2F -> SOLIDUS + '0' # 0x30 -> DIGIT ZERO + '1' # 0x31 -> DIGIT ONE + '2' # 0x32 -> DIGIT TWO + '3' # 0x33 -> DIGIT THREE + '4' # 0x34 -> DIGIT FOUR + '5' # 0x35 -> DIGIT FIVE + '6' # 0x36 -> DIGIT SIX + '7' # 0x37 -> DIGIT SEVEN + '8' # 0x38 -> DIGIT EIGHT + '9' # 0x39 -> DIGIT NINE + ':' # 0x3A -> COLON + ';' # 0x3B -> SEMICOLON + '<' # 0x3C -> LESS-THAN SIGN + '=' # 0x3D -> EQUALS SIGN + '>' # 0x3E -> GREATER-THAN SIGN + '?' # 0x3F -> QUESTION MARK + '@' # 0x40 -> COMMERCIAL AT + 'A' # 0x41 -> LATIN CAPITAL LETTER A + 'B' # 0x42 -> LATIN CAPITAL LETTER B + 'C' # 0x43 -> LATIN CAPITAL LETTER C + 'D' # 0x44 -> LATIN CAPITAL LETTER D + 'E' # 0x45 -> LATIN CAPITAL LETTER E + 'F' # 0x46 -> LATIN CAPITAL LETTER F + 'G' # 0x47 -> LATIN CAPITAL LETTER G + 'H' # 0x48 -> LATIN CAPITAL LETTER H + 'I' # 0x49 -> LATIN CAPITAL LETTER I + 'J' # 0x4A -> LATIN CAPITAL LETTER J + 'K' # 0x4B -> LATIN CAPITAL LETTER K + 'L' # 0x4C -> LATIN CAPITAL LETTER L + 'M' # 0x4D -> LATIN CAPITAL LETTER M + 'N' # 0x4E -> LATIN CAPITAL LETTER N + 'O' # 0x4F -> LATIN CAPITAL LETTER O + 'P' # 0x50 -> LATIN CAPITAL LETTER P + 'Q' # 0x51 -> LATIN CAPITAL LETTER Q + 'R' # 0x52 -> LATIN CAPITAL LETTER R + 'S' # 0x53 -> LATIN CAPITAL LETTER S + 'T' # 0x54 -> LATIN CAPITAL LETTER T + 'U' # 0x55 -> LATIN CAPITAL LETTER U + 'V' # 0x56 -> LATIN CAPITAL LETTER V + 'W' # 0x57 -> LATIN CAPITAL LETTER W + 'X' # 0x58 -> LATIN CAPITAL LETTER X + 'Y' # 0x59 -> LATIN CAPITAL LETTER Y + 'Z' # 0x5A -> LATIN CAPITAL LETTER Z + '[' # 0x5B -> LEFT SQUARE BRACKET + '\\' # 0x5C -> REVERSE SOLIDUS + ']' # 0x5D -> RIGHT SQUARE BRACKET + '^' # 0x5E -> CIRCUMFLEX ACCENT + '_' # 0x5F -> LOW LINE + '`' # 0x60 -> GRAVE ACCENT + 'a' # 0x61 -> LATIN SMALL LETTER A + 'b' # 0x62 -> LATIN SMALL LETTER B + 'c' # 0x63 -> LATIN SMALL LETTER C + 'd' # 0x64 -> LATIN SMALL LETTER D + 'e' # 0x65 -> LATIN SMALL LETTER E + 'f' # 0x66 -> LATIN SMALL LETTER F + 'g' # 0x67 -> LATIN SMALL LETTER G + 'h' # 0x68 -> LATIN SMALL LETTER H + 'i' # 0x69 -> LATIN SMALL LETTER I + 'j' # 0x6A -> LATIN SMALL LETTER J + 'k' # 0x6B -> LATIN SMALL LETTER K + 'l' # 0x6C -> LATIN SMALL LETTER L + 'm' # 0x6D -> LATIN SMALL LETTER M + 'n' # 0x6E -> LATIN SMALL LETTER N + 'o' # 0x6F -> LATIN SMALL LETTER O + 'p' # 0x70 -> LATIN SMALL LETTER P + 'q' # 0x71 -> LATIN SMALL LETTER Q + 'r' # 0x72 -> LATIN SMALL LETTER R + 's' # 0x73 -> LATIN SMALL LETTER S + 't' # 0x74 -> LATIN SMALL LETTER T + 'u' # 0x75 -> LATIN SMALL LETTER U + 'v' # 0x76 -> LATIN SMALL LETTER V + 'w' # 0x77 -> LATIN SMALL LETTER W + 'x' # 0x78 -> LATIN SMALL LETTER X + 'y' # 0x79 -> LATIN SMALL LETTER Y + 'z' # 0x7A -> LATIN SMALL LETTER Z + '{' # 0x7B -> LEFT CURLY BRACKET + '|' # 0x7C -> VERTICAL LINE + '}' # 0x7D -> RIGHT CURLY BRACKET + '~' # 0x7E -> TILDE + '\x7f' # 0x7F -> DELETE + '\x80' # 0x80 -> + '\x81' # 0x81 -> + '\x82' # 0x82 -> + '\x83' # 0x83 -> + '\x84' # 0x84 -> + '\x85' # 0x85 -> + '\x86' # 0x86 -> + '\x87' # 0x87 -> + '\x88' # 0x88 -> + '\x89' # 0x89 -> + '\x8a' # 0x8A -> + '\x8b' # 0x8B -> + '\x8c' # 0x8C -> + '\x8d' # 0x8D -> + '\x8e' # 0x8E -> + '\x8f' # 0x8F -> + '\x90' # 0x90 -> + '\x91' # 0x91 -> + '\x92' # 0x92 -> + '\x93' # 0x93 -> + '\x94' # 0x94 -> + '\x95' # 0x95 -> + '\x96' # 0x96 -> + '\x97' # 0x97 -> + '\x98' # 0x98 -> + '\x99' # 0x99 -> + '\x9a' # 0x9A -> + '\x9b' # 0x9B -> + '\x9c' # 0x9C -> + '\x9d' # 0x9D -> + '\x9e' # 0x9E -> + '\x9f' # 0x9F -> + '\ufffe' + '\u0e01' # 0xA1 -> THAI CHARACTER KO KAI + '\u0e02' # 0xA2 -> THAI CHARACTER KHO KHAI + '\u0e03' # 0xA3 -> THAI CHARACTER KHO KHUAT + '\u0e04' # 0xA4 -> THAI CHARACTER KHO KHWAI + '\u0e05' # 0xA5 -> THAI CHARACTER KHO KHON + '\u0e06' # 0xA6 -> THAI CHARACTER KHO RAKHANG + '\u0e07' # 0xA7 -> THAI CHARACTER NGO NGU + '\u0e08' # 0xA8 -> THAI CHARACTER CHO CHAN + '\u0e09' # 0xA9 -> THAI CHARACTER CHO CHING + '\u0e0a' # 0xAA -> THAI CHARACTER CHO CHANG + '\u0e0b' # 0xAB -> THAI CHARACTER SO SO + '\u0e0c' # 0xAC -> THAI CHARACTER CHO CHOE + '\u0e0d' # 0xAD -> THAI CHARACTER YO YING + '\u0e0e' # 0xAE -> THAI CHARACTER DO CHADA + '\u0e0f' # 0xAF -> THAI CHARACTER TO PATAK + '\u0e10' # 0xB0 -> THAI CHARACTER THO THAN + '\u0e11' # 0xB1 -> THAI CHARACTER THO NANGMONTHO + '\u0e12' # 0xB2 -> THAI CHARACTER THO PHUTHAO + '\u0e13' # 0xB3 -> THAI CHARACTER NO NEN + '\u0e14' # 0xB4 -> THAI CHARACTER DO DEK + '\u0e15' # 0xB5 -> THAI CHARACTER TO TAO + '\u0e16' # 0xB6 -> THAI CHARACTER THO THUNG + '\u0e17' # 0xB7 -> THAI CHARACTER THO THAHAN + '\u0e18' # 0xB8 -> THAI CHARACTER THO THONG + '\u0e19' # 0xB9 -> THAI CHARACTER NO NU + '\u0e1a' # 0xBA -> THAI CHARACTER BO BAIMAI + '\u0e1b' # 0xBB -> THAI CHARACTER PO PLA + '\u0e1c' # 0xBC -> THAI CHARACTER PHO PHUNG + '\u0e1d' # 0xBD -> THAI CHARACTER FO FA + '\u0e1e' # 0xBE -> THAI CHARACTER PHO PHAN + '\u0e1f' # 0xBF -> THAI CHARACTER FO FAN + '\u0e20' # 0xC0 -> THAI CHARACTER PHO SAMPHAO + '\u0e21' # 0xC1 -> THAI CHARACTER MO MA + '\u0e22' # 0xC2 -> THAI CHARACTER YO YAK + '\u0e23' # 0xC3 -> THAI CHARACTER RO RUA + '\u0e24' # 0xC4 -> THAI CHARACTER RU + '\u0e25' # 0xC5 -> THAI CHARACTER LO LING + '\u0e26' # 0xC6 -> THAI CHARACTER LU + '\u0e27' # 0xC7 -> THAI CHARACTER WO WAEN + '\u0e28' # 0xC8 -> THAI CHARACTER SO SALA + '\u0e29' # 0xC9 -> THAI CHARACTER SO RUSI + '\u0e2a' # 0xCA -> THAI CHARACTER SO SUA + '\u0e2b' # 0xCB -> THAI CHARACTER HO HIP + '\u0e2c' # 0xCC -> THAI CHARACTER LO CHULA + '\u0e2d' # 0xCD -> THAI CHARACTER O ANG + '\u0e2e' # 0xCE -> THAI CHARACTER HO NOKHUK + '\u0e2f' # 0xCF -> THAI CHARACTER PAIYANNOI + '\u0e30' # 0xD0 -> THAI CHARACTER SARA A + '\u0e31' # 0xD1 -> THAI CHARACTER MAI HAN-AKAT + '\u0e32' # 0xD2 -> THAI CHARACTER SARA AA + '\u0e33' # 0xD3 -> THAI CHARACTER SARA AM + '\u0e34' # 0xD4 -> THAI CHARACTER SARA I + '\u0e35' # 0xD5 -> THAI CHARACTER SARA II + '\u0e36' # 0xD6 -> THAI CHARACTER SARA UE + '\u0e37' # 0xD7 -> THAI CHARACTER SARA UEE + '\u0e38' # 0xD8 -> THAI CHARACTER SARA U + '\u0e39' # 0xD9 -> THAI CHARACTER SARA UU + '\u0e3a' # 0xDA -> THAI CHARACTER PHINTHU + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' + '\u0e3f' # 0xDF -> THAI CURRENCY SYMBOL BAHT + '\u0e40' # 0xE0 -> THAI CHARACTER SARA E + '\u0e41' # 0xE1 -> THAI CHARACTER SARA AE + '\u0e42' # 0xE2 -> THAI CHARACTER SARA O + '\u0e43' # 0xE3 -> THAI CHARACTER SARA AI MAIMUAN + '\u0e44' # 0xE4 -> THAI CHARACTER SARA AI MAIMALAI + '\u0e45' # 0xE5 -> THAI CHARACTER LAKKHANGYAO + '\u0e46' # 0xE6 -> THAI CHARACTER MAIYAMOK + '\u0e47' # 0xE7 -> THAI CHARACTER MAITAIKHU + '\u0e48' # 0xE8 -> THAI CHARACTER MAI EK + '\u0e49' # 0xE9 -> THAI CHARACTER MAI THO + '\u0e4a' # 0xEA -> THAI CHARACTER MAI TRI + '\u0e4b' # 0xEB -> THAI CHARACTER MAI CHATTAWA + '\u0e4c' # 0xEC -> THAI CHARACTER THANTHAKHAT + '\u0e4d' # 0xED -> THAI CHARACTER NIKHAHIT + '\u0e4e' # 0xEE -> THAI CHARACTER YAMAKKAN + '\u0e4f' # 0xEF -> THAI CHARACTER FONGMAN + '\u0e50' # 0xF0 -> THAI DIGIT ZERO + '\u0e51' # 0xF1 -> THAI DIGIT ONE + '\u0e52' # 0xF2 -> THAI DIGIT TWO + '\u0e53' # 0xF3 -> THAI DIGIT THREE + '\u0e54' # 0xF4 -> THAI DIGIT FOUR + '\u0e55' # 0xF5 -> THAI DIGIT FIVE + '\u0e56' # 0xF6 -> THAI DIGIT SIX + '\u0e57' # 0xF7 -> THAI DIGIT SEVEN + '\u0e58' # 0xF8 -> THAI DIGIT EIGHT + '\u0e59' # 0xF9 -> THAI DIGIT NINE + '\u0e5a' # 0xFA -> THAI CHARACTER ANGKHANKHU + '\u0e5b' # 0xFB -> THAI CHARACTER KHOMUT + '\ufffe' + '\ufffe' + '\ufffe' + '\ufffe' +) + +### Encoding table +encoding_table=codecs.charmap_build(decoding_table) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/undefined.py b/crates/weavepy-vm/src/stdlib/python/encodings/undefined.py new file mode 100644 index 0000000..082771e --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/undefined.py @@ -0,0 +1,49 @@ +""" Python 'undefined' Codec + + This codec will always raise a UnicodeError exception when being + used. It is intended for use by the site.py file to switch off + automatic string to Unicode coercion. + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +class Codec(codecs.Codec): + + def encode(self,input,errors='strict'): + raise UnicodeError("undefined encoding") + + def decode(self,input,errors='strict'): + raise UnicodeError("undefined encoding") + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + raise UnicodeError("undefined encoding") + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, input, final=False): + raise UnicodeError("undefined encoding") + +class StreamWriter(Codec,codecs.StreamWriter): + pass + +class StreamReader(Codec,codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='undefined', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) diff --git a/crates/weavepy-vm/src/stdlib/python/encodings/utf_8.py b/crates/weavepy-vm/src/stdlib/python/encodings/utf_8.py new file mode 100644 index 0000000..1bf6336 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/python/encodings/utf_8.py @@ -0,0 +1,42 @@ +""" Python 'utf-8' Codec + + +Written by Marc-Andre Lemburg (mal@lemburg.com). + +(c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + +""" +import codecs + +### Codec APIs + +encode = codecs.utf_8_encode + +def decode(input, errors='strict'): + return codecs.utf_8_decode(input, errors, True) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, input, final=False): + return codecs.utf_8_encode(input, self.errors)[0] + +class IncrementalDecoder(codecs.BufferedIncrementalDecoder): + _buffer_decode = codecs.utf_8_decode + +class StreamWriter(codecs.StreamWriter): + encode = codecs.utf_8_encode + +class StreamReader(codecs.StreamReader): + decode = codecs.utf_8_decode + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='utf-8', + encode=encode, + decode=decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamreader=StreamReader, + streamwriter=StreamWriter, + ) diff --git a/crates/weavepy-vm/src/stdlib/python/linecache.py b/crates/weavepy-vm/src/stdlib/python/linecache.py index a9f1c97..88e6f6d 100644 --- a/crates/weavepy-vm/src/stdlib/python/linecache.py +++ b/crates/weavepy-vm/src/stdlib/python/linecache.py @@ -87,9 +87,8 @@ def getlines(filename, module_globals=None): return entry[2] try: return updatecache(filename, module_globals) or [] - except (MemoryError, KeyboardInterrupt): - raise - except Exception: + except MemoryError: + clearcache() return [] @@ -110,25 +109,29 @@ def checkcache(filename=None): continue try: stat = os.stat(name) - except OSError: + except (OSError, ValueError): cache.pop(f, None) continue if size != stat.st_size or mtime != stat.st_mtime: cache.pop(f, None) +def _materialize_lazy(filename, entry): + """Realise a lazy 1-tuple entry through the loader's get_source.""" + try: + data = entry[0]() + except (ImportError, OSError): + return None + if data is None: + return None + # CPython: every loader-sourced line gets a trailing newline appended. + lines = [line + "\n" for line in data.splitlines()] + cache[filename] = (len(data), None, lines, filename) + return lines + + def updatecache(filename, module_globals=None): entry = cache.pop(filename, None) - # Lazy 1-tuple — materialise through the loader's get_source. - if entry is not None and len(entry) == 1: - try: - data = entry[0]() - except (ImportError, OSError): - data = None - if data is not None: - lines = data.splitlines(keepends=True) - cache[filename] = (len(data), None, lines, filename) - return lines # WeavePy frozen stdlib modules carry `` filenames; # their source is recoverable through `_imp.find_frozen`. if filename.startswith(""): @@ -146,14 +149,23 @@ def updatecache(filename, module_globals=None): cache[filename] = (len(lines), None, lines, filename) return lines name = filename - # Try direct file system access. + # Try direct file system access first — like CPython, loader-based + # lazy entries are only consulted when the file isn't readable. try: stat = os.stat(name) - except OSError: + except (OSError, ValueError): + if entry is not None and len(entry) == 1: + lines = _materialize_lazy(filename, entry) + if lines is not None: + return lines # One more chance: a loader from module_globals (CPython tries # this when the file isn't directly readable). if lazycache(filename, module_globals): - return updatecache(filename, module_globals) + entry = cache.pop(filename, None) + if entry is not None and len(entry) == 1: + lines = _materialize_lazy(filename, entry) + if lines is not None: + return lines return [] try: with open(name, "rb") as f: @@ -161,9 +173,14 @@ def updatecache(filename, module_globals=None): data = _decode_source(raw) except (OSError, UnicodeDecodeError, LookupError): return [] - lines = data.splitlines(keepends=True) - if lines and not lines[-1].endswith("\n"): - lines[-1] += "\n" + # CPython reads with `tokenize.open(...).readlines()`: universal-newline + # translation then a split on '\n' only. `str.splitlines()` would also + # split on form feed / vertical tab, shifting every later line + # (`test_traceback.test_encoded_file` puts '\f' on the first line). + data = data.replace("\r\n", "\n").replace("\r", "\n") + lines = [line + "\n" for line in data.split("\n")] + if data.endswith("\n"): + lines.pop() cache[filename] = (stat.st_size, stat.st_mtime, lines, name) return lines @@ -224,13 +241,14 @@ def lazycache(filename, module_globals): return len(cache[filename]) == 1 if not filename or (filename.startswith("<") and filename.endswith(">")): return False - if module_globals is None: + if module_globals is None or "__name__" not in module_globals: return False - name = module_globals.get("__name__") - loader = module_globals.get("__loader__") + # CPython prefers the spec's name/loader over the module-level dunders. spec = module_globals.get("__spec__") - if loader is None and spec is not None: - loader = getattr(spec, "loader", None) + name = getattr(spec, "name", None) or module_globals["__name__"] + loader = getattr(spec, "loader", None) + if loader is None: + loader = module_globals.get("__loader__") get_source = getattr(loader, "get_source", None) if get_source is None: # WeavePy's import machinery doesn't install `__loader__` on diff --git a/crates/weavepy-vm/src/stdlib/python/locale.py b/crates/weavepy-vm/src/stdlib/python/locale.py index 0aa8ad6..db6d0ab 100644 --- a/crates/weavepy-vm/src/stdlib/python/locale.py +++ b/crates/weavepy-vm/src/stdlib/python/locale.py @@ -1,186 +1,1778 @@ -"""Minimal but faithful ``locale`` for the portable 'C'/'POSIX' locale. +"""Locale support module. + +The module provides low-level access to the C lib's locale APIs and adds high +level number formatting APIs as well as a locale aliasing engine to complement +these. + +The aliasing engine includes support for many commonly used locale names and +maps them to values suitable for passing to the C lib's setlocale() function. It +also includes default encodings for all supported locale names. -CPython backs :mod:`locale` with the C ``_locale`` extension. WeavePy ships -a pure-Python module implementing the public surface against the default -'C' locale: querying always succeeds, switching to ``''``/``'C'``/``'POSIX'`` -succeeds, and any other (uninstalled) locale raises :class:`Error` exactly -as CPython does on a host where that locale is unavailable (RFC 0037 WS8). """ -CHAR_MAX = 127 +import sys +import encodings +import encodings.aliases +import re +import _collections_abc +from builtins import str as _builtin_str +import functools -# Category constants. The numeric values are an internal, stable choice -# (CPython's come from the C library and are platform-specific); code should -# use the names, never the literals. -LC_CTYPE = 0 -LC_NUMERIC = 1 -LC_TIME = 2 -LC_COLLATE = 3 -LC_MONETARY = 4 -LC_MESSAGES = 5 -LC_ALL = 6 +# Try importing the _locale module. +# +# If this fails, fall back on a basic 'C' locale emulation. -_ALL_CATEGORIES = (LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY, - LC_MESSAGES) +# Yuck: LC_MESSAGES is non-standard: can't tell whether it exists before +# trying the import. So __all__ is also fiddled at the end of the file. +__all__ = ["getlocale", "getdefaultlocale", "getpreferredencoding", "Error", + "setlocale", "localeconv", "strcoll", "strxfrm", + "str", "atof", "atoi", "format_string", "currency", + "normalize", "LC_CTYPE", "LC_COLLATE", "LC_TIME", "LC_MONETARY", + "LC_NUMERIC", "LC_ALL", "CHAR_MAX", "getencoding"] + +def _strcoll(a,b): + """ strcoll(string,string) -> int. + Compares two strings according to the locale. + """ + return (a > b) - (a < b) -__all__ = [ - "getlocale", "getdefaultlocale", "getpreferredencoding", "Error", - "setlocale", "resetlocale", "localeconv", "strcoll", "strxfrm", - "str", "atof", "atoi", "format_string", "currency", "normalize", - "LC_CTYPE", "LC_NUMERIC", "LC_TIME", "LC_COLLATE", "LC_MONETARY", - "LC_MESSAGES", "LC_ALL", "CHAR_MAX", "delocalize", "localize", -] +def _strxfrm(s): + """ strxfrm(string) -> string. + Returns a string that behaves for cmp locale-aware. + """ + return s +try: -class Error(Exception): - pass + from _locale import * +except ImportError: -_state = {c: "C" for c in (LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, - LC_MONETARY, LC_MESSAGES, LC_ALL)} + # Locale emulation + CHAR_MAX = 127 + LC_ALL = 6 + LC_COLLATE = 3 + LC_CTYPE = 0 + LC_MESSAGES = 5 + LC_MONETARY = 4 + LC_NUMERIC = 1 + LC_TIME = 2 + Error = ValueError -def _norm_requested(value): - """Map a requested locale name to the only locale we can honour ('C') - or raise :class:`Error` for anything we cannot install — the same - observable contract as CPython on a host missing that locale.""" - if isinstance(value, tuple): - value = _build_localename(value) - if value in ("", "C", "POSIX"): - return "C" - raise Error("unsupported locale setting") + def localeconv(): + """ localeconv() -> dict. + Returns numeric and monetary locale-specific parameters. + """ + # 'C' locale default values + return {'grouping': [127], + 'currency_symbol': '', + 'n_sign_posn': 127, + 'p_cs_precedes': 127, + 'n_cs_precedes': 127, + 'mon_grouping': [], + 'n_sep_by_space': 127, + 'decimal_point': '.', + 'negative_sign': '', + 'positive_sign': '', + 'p_sep_by_space': 127, + 'int_curr_symbol': '', + 'p_sign_posn': 127, + 'thousands_sep': '', + 'mon_thousands_sep': '', + 'frac_digits': 127, + 'mon_decimal_point': '', + 'int_frac_digits': 127} + def setlocale(category, value=None): + """ setlocale(integer,string=None) -> string. + Activates/queries locale processing. + """ + if value not in (None, '', 'C'): + raise Error('_locale emulation only supports "C" locale') + return 'C' -def setlocale(category, locale=None): - if category not in (LC_ALL, *_ALL_CATEGORIES): - raise Error("invalid locale category") - if locale is None: - return _state.get(category, "C") - normalized = _norm_requested(locale) - if category == LC_ALL: - for c in (LC_ALL, *_ALL_CATEGORIES): - _state[c] = normalized - else: - _state[category] = normalized - return normalized +# These may or may not exist in _locale, so be sure to set them. +if 'strxfrm' not in globals(): + strxfrm = _strxfrm +if 'strcoll' not in globals(): + strcoll = _strcoll -def resetlocale(category=LC_ALL): - setlocale(category, "C") +_localeconv = localeconv +# With this dict, you can override some items of localeconv's return value. +# This is useful for testing purposes. +_override_localeconv = {} +@functools.wraps(_localeconv) def localeconv(): - """Return the lconv table for the 'C' locale.""" - return { - "decimal_point": ".", - "thousands_sep": "", - "grouping": [], - "int_curr_symbol": "", - "currency_symbol": "", - "mon_decimal_point": "", - "mon_thousands_sep": "", - "mon_grouping": [], - "positive_sign": "", - "negative_sign": "", - "int_frac_digits": CHAR_MAX, - "frac_digits": CHAR_MAX, - "p_cs_precedes": CHAR_MAX, - "p_sep_by_space": CHAR_MAX, - "n_cs_precedes": CHAR_MAX, - "n_sep_by_space": CHAR_MAX, - "p_sign_posn": CHAR_MAX, - "n_sign_posn": CHAR_MAX, - } + d = _localeconv() + if _override_localeconv: + d.update(_override_localeconv) + return d -def getlocale(category=LC_CTYPE): - """The 'C' locale carries no language/encoding pair.""" - return (None, None) +### Number formatting APIs + +# Author: Martin von Loewis +# improved by Georg Brandl + +# Iterate over grouping intervals +def _grouping_intervals(grouping): + last_interval = None + for interval in grouping: + # if grouping is -1, we are done + if interval == CHAR_MAX: + return + # 0: re-use last group ad infinitum + if interval == 0: + if last_interval is None: + raise ValueError("invalid grouping") + while True: + yield last_interval + yield interval + last_interval = interval + +#perform the grouping from right to left +def _group(s, monetary=False): + conv = localeconv() + thousands_sep = conv[monetary and 'mon_thousands_sep' or 'thousands_sep'] + grouping = conv[monetary and 'mon_grouping' or 'grouping'] + if not grouping: + return (s, 0) + if s[-1] == ' ': + stripped = s.rstrip() + right_spaces = s[len(stripped):] + s = stripped + else: + right_spaces = '' + left_spaces = '' + groups = [] + for interval in _grouping_intervals(grouping): + if not s or s[-1] not in "0123456789": + # only non-digit characters remain (sign, spaces) + left_spaces = s + s = '' + break + groups.append(s[-interval:]) + s = s[:-interval] + if s: + groups.append(s) + groups.reverse() + return ( + left_spaces + thousands_sep.join(groups) + right_spaces, + len(thousands_sep) * (len(groups) - 1) + ) + +# Strip a given amount of excess padding from the given string +def _strip_padding(s, amount): + lpos = 0 + while amount and s[lpos] == ' ': + lpos += 1 + amount -= 1 + rpos = len(s) - 1 + while amount and s[rpos] == ' ': + rpos -= 1 + amount -= 1 + return s[lpos:rpos+1] + +_percent_re = re.compile(r'%(?:\((?P.*?)\))?' + r'(?P[-#0-9 +*.hlL]*?)[eEfFgGdiouxXcrs%]') + +def _format(percent, value, grouping=False, monetary=False, *additional): + if additional: + formatted = percent % ((value,) + additional) + else: + formatted = percent % value + if percent[-1] in 'eEfFgGdiu': + formatted = _localize(formatted, grouping, monetary) + return formatted + +# Transform formatted as locale number according to the locale settings +def _localize(formatted, grouping=False, monetary=False): + # floats and decimal ints need special action! + if '.' in formatted: + seps = 0 + parts = formatted.split('.') + if grouping: + parts[0], seps = _group(parts[0], monetary=monetary) + decimal_point = localeconv()[monetary and 'mon_decimal_point' + or 'decimal_point'] + formatted = decimal_point.join(parts) + if seps: + formatted = _strip_padding(formatted, seps) + else: + seps = 0 + if grouping: + formatted, seps = _group(formatted, monetary=monetary) + if seps: + formatted = _strip_padding(formatted, seps) + return formatted + +def format_string(f, val, grouping=False, monetary=False): + """Formats a string in the same way that the % formatting would use, + but takes the current locale into account. + + Grouping is applied if the third parameter is true. + Conversion uses monetary thousands separator and grouping strings if + forth parameter monetary is true.""" + percents = list(_percent_re.finditer(f)) + new_f = _percent_re.sub('%s', f) + + if isinstance(val, _collections_abc.Mapping): + new_val = [] + for perc in percents: + if perc.group()[-1]=='%': + new_val.append('%') + else: + new_val.append(_format(perc.group(), val, grouping, monetary)) + else: + if not isinstance(val, tuple): + val = (val,) + new_val = [] + i = 0 + for perc in percents: + if perc.group()[-1]=='%': + new_val.append('%') + else: + starcount = perc.group('modifiers').count('*') + new_val.append(_format(perc.group(), + val[i], + grouping, + monetary, + *val[i+1:i+1+starcount])) + i += (1 + starcount) + val = tuple(new_val) + + return new_f % val + +def currency(val, symbol=True, grouping=False, international=False): + """Formats val according to the currency settings + in the current locale.""" + conv = localeconv() + # check for illegal values + digits = conv[international and 'int_frac_digits' or 'frac_digits'] + if digits == 127: + raise ValueError("Currency formatting is not possible using " + "the 'C' locale.") -def getdefaultlocale(envvars=("LC_ALL", "LC_CTYPE", "LANG", "LANGUAGE")): - return (None, None) + s = _localize(f'{abs(val):.{digits}f}', grouping, monetary=True) + # '<' and '>' are markers if the sign must be inserted between symbol and value + s = '<' + s + '>' + if symbol: + smb = conv[international and 'int_curr_symbol' or 'currency_symbol'] + precedes = conv[val<0 and 'n_cs_precedes' or 'p_cs_precedes'] + separated = conv[val<0 and 'n_sep_by_space' or 'p_sep_by_space'] -def getpreferredencoding(do_setlocale=True): - return "utf-8" + if precedes: + s = smb + (separated and ' ' or '') + s + else: + if international and smb[-1] == ' ': + smb = smb[:-1] + s = s + (separated and ' ' or '') + smb + sign_pos = conv[val<0 and 'n_sign_posn' or 'p_sign_posn'] + sign = conv[val<0 and 'negative_sign' or 'positive_sign'] -def getencoding(): - return "utf-8" + if sign_pos == 0: + s = '(' + s + ')' + elif sign_pos == 1: + s = sign + s + elif sign_pos == 2: + s = s + sign + elif sign_pos == 3: + s = s.replace('<', sign) + elif sign_pos == 4: + s = s.replace('>', sign) + else: + # the default if nothing specified; + # this should be the most fitting sign position + s = sign + s + + return s.replace('<', '').replace('>', '') + +def str(val): + """Convert float to string, taking the locale into account.""" + return _format("%.12g", val) + +def delocalize(string): + "Parses a string as a normalized number according to the locale settings." + + conv = localeconv() + + #First, get rid of the grouping + ts = conv['thousands_sep'] + if ts: + string = string.replace(ts, '') + #next, replace the decimal point with a dot + dd = conv['decimal_point'] + if dd: + string = string.replace(dd, '.') + return string + +def localize(string, grouping=False, monetary=False): + """Parses a string as locale number according to the locale settings.""" + return _localize(string, grouping, monetary) + +def atof(string, func=float): + "Parses a string as a float according to the locale settings." + return func(delocalize(string)) + +def atoi(string): + "Converts a string to an integer according to the locale settings." + return int(delocalize(string)) + +def _test(): + setlocale(LC_ALL, "") + #do grouping + s1 = format_string("%d", 123456789,1) + print(s1, "is", atoi(s1)) + #standard formatting + s1 = str(3.14) + print(s1, "is", atof(s1)) + +### Locale name aliasing engine + +# Author: Marc-Andre Lemburg, mal@lemburg.com +# Various tweaks by Fredrik Lundh + +# store away the low-level version of setlocale (it's +# overridden below) +_setlocale = setlocale + +def _replace_encoding(code, encoding): + if '.' in code: + langname = code[:code.index('.')] + else: + langname = code + # Convert the encoding to a C lib compatible encoding string + norm_encoding = encodings.normalize_encoding(encoding) + #print('norm encoding: %r' % norm_encoding) + norm_encoding = encodings.aliases.aliases.get(norm_encoding.lower(), + norm_encoding) + #print('aliased encoding: %r' % norm_encoding) + encoding = norm_encoding + norm_encoding = norm_encoding.lower() + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + else: + norm_encoding = norm_encoding.replace('_', '') + norm_encoding = norm_encoding.replace('-', '') + if norm_encoding in locale_encoding_alias: + encoding = locale_encoding_alias[norm_encoding] + #print('found encoding %r' % encoding) + return langname + '.' + encoding + +def _append_modifier(code, modifier): + if modifier == 'euro': + if '.' not in code: + return code + '.ISO8859-15' + _, _, encoding = code.partition('.') + if encoding in ('ISO8859-15', 'UTF-8'): + return code + if encoding == 'ISO8859-1': + return _replace_encoding(code, 'ISO8859-15') + return code + '@' + modifier def normalize(localename): - # Without the C alias table we only recognise the portable names. - name = localename.lower() - if name in ("c", "posix", ""): - return "C" + + """ Returns a normalized locale code for the given locale + name. + + The returned locale code is formatted for use with + setlocale(). + + If normalization fails, the original name is returned + unchanged. + + If the given encoding is not known, the function defaults to + the default encoding for the locale code just like setlocale() + does. + + """ + # Normalize the locale name and extract the encoding and modifier + code = localename.lower() + if ':' in code: + # ':' is sometimes used as encoding delimiter. + code = code.replace(':', '.') + if '@' in code: + code, modifier = code.split('@', 1) + else: + modifier = '' + if '.' in code: + langname, encoding = code.split('.')[:2] + else: + langname = code + encoding = '' + + # First lookup: fullname (possibly with encoding and modifier) + lang_enc = langname + if encoding: + norm_encoding = encoding.replace('-', '') + norm_encoding = norm_encoding.replace('_', '') + lang_enc += '.' + norm_encoding + lookup_name = lang_enc + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + return code + #print('first lookup failed') + + if modifier: + # Second try: fullname without modifier (possibly with encoding) + code = locale_alias.get(lang_enc, None) + if code is not None: + #print('lookup without modifier succeeded') + if '@' not in code: + return _append_modifier(code, modifier) + if code.split('@', 1)[1].lower() == modifier: + return code + #print('second lookup failed') + + if encoding: + # Third try: langname (without encoding, possibly with modifier) + lookup_name = langname + if modifier: + lookup_name += '@' + modifier + code = locale_alias.get(lookup_name, None) + if code is not None: + #print('lookup without encoding succeeded') + if '@' not in code: + return _replace_encoding(code, encoding) + code, modifier = code.split('@', 1) + return _replace_encoding(code, encoding) + '@' + modifier + + if modifier: + # Fourth try: langname (without encoding and modifier) + code = locale_alias.get(langname, None) + if code is not None: + #print('lookup without modifier and encoding succeeded') + if '@' not in code: + code = _replace_encoding(code, encoding) + return _append_modifier(code, modifier) + code, defmod = code.split('@', 1) + if defmod.lower() == modifier: + return _replace_encoding(code, encoding) + '@' + defmod + return localename +def _parse_localename(localename): + + """ Parses the locale code for localename and returns the + result as tuple (language code, encoding). + + The localename is normalized and passed through the locale + alias engine. A ValueError is raised in case the locale name + cannot be parsed. + + The language code corresponds to RFC 1766. code and encoding + can be None in case the values cannot be determined or are + unknown to this implementation. + + """ + code = normalize(localename) + if '@' in code: + # Deal with locale modifiers + code, modifier = code.split('@', 1) + if modifier == 'euro' and '.' not in code: + # Assume Latin-9 for @euro locales. This is bogus, + # since some systems may use other encodings for these + # locales. Also, we ignore other modifiers. + return code, 'iso-8859-15' + + if '.' in code: + return tuple(code.split('.')[:2]) + elif code == 'C': + return None, None + elif code == 'UTF-8': + # On macOS "LC_CTYPE=UTF-8" is a valid locale setting + # for getting UTF-8 handling for text. + return None, 'UTF-8' + raise ValueError('unknown locale: %s' % localename) def _build_localename(localetuple): + + """ Builds a locale code from the given tuple (language code, + encoding). + + No aliasing or normalizing takes place. + + """ try: language, encoding = localetuple + + if language is None: + language = 'C' + if encoding is None: + return language + else: + return language + '.' + encoding except (TypeError, ValueError): - raise TypeError("Locale must be None, a string, or an iterable of " - "two strings -- language code, encoding.") from None - if language is None: - language = "C" - if encoding is None: - return language - return language + "." + encoding + raise TypeError('Locale must be None, a string, or an iterable of ' + 'two strings -- language code, encoding.') from None +def getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): -def strcoll(a, b): - return (a > b) - (a < b) + """ Tries to determine the default locale settings and returns + them as tuple (language code, encoding). + According to POSIX, a program which has not called + setlocale(LC_ALL, "") runs using the portable 'C' locale. + Calling setlocale(LC_ALL, "") lets it use the default locale as + defined by the LANG variable. Since we don't want to interfere + with the current locale setting we thus emulate the behavior + in the way described above. -def strxfrm(s): - return s + To maintain compatibility with other platforms, not only the + LANG variable is tested, but a list of variables given as + envvars parameter. The first found to be defined will be + used. envvars defaults to the search path used in GNU gettext; + it must always contain the variable name 'LANG'. + Except for the code 'C', the language code corresponds to RFC + 1766. code and encoding can be None in case the values cannot + be determined. -# --- numeric helpers (C locale: '.' decimal point, no grouping) ----------- + """ -def localize(string, grouping=False, monetary=False): - return string + import warnings + warnings._deprecated( + "locale.getdefaultlocale", + "{name!r} is deprecated and slated for removal in Python {remove}. " + "Use setlocale(), getencoding() and getlocale() instead.", + remove=(3, 15)) + return _getdefaultlocale(envvars) -def delocalize(string): - return string +def _getdefaultlocale(envvars=('LC_ALL', 'LC_CTYPE', 'LANG', 'LANGUAGE')): + try: + # check if it's supported by the _locale module + import _locale + code, encoding = _locale._getdefaultlocale() + except (ImportError, AttributeError): + pass + else: + # make sure the code/encoding values are valid + if sys.platform == "win32" and code and code[:2] == "0x": + # map windows language identifier to language name + code = windows_locale.get(int(code, 0)) + # ...add other platform-specific processing here, if + # necessary... + return code, encoding + # fall back on POSIX behaviour + import os + lookup = os.environ.get + for variable in envvars: + localename = lookup(variable,None) + if localename: + if variable == 'LANGUAGE': + localename = localename.split(':')[0] + break + else: + localename = 'C' + return _parse_localename(localename) -def atof(string, func=float): - return func(delocalize(string)) +def getlocale(category=LC_CTYPE): -def atoi(string): - return int(delocalize(string)) + """ Returns the current setting for the given locale category as + tuple (language code, encoding). + category may be one of the LC_* value except LC_ALL. It + defaults to LC_CTYPE. -def str(val): - return format_string("%.12g", val) + Except for the code 'C', the language code corresponds to RFC + 1766. code and encoding can be None in case the values cannot + be determined. + + """ + localename = _setlocale(category) + if category == LC_ALL and ';' in localename: + raise TypeError('category LC_ALL is not supported') + return _parse_localename(localename) +def setlocale(category, locale=None): -def format_string(format, val, grouping=False, monetary=False): - import re as _re + """ Set the locale for the given category. The locale can be + a string, an iterable of two strings (language code and encoding), + or None. - def _strip(m): - return m.group(0) + Iterables are converted to strings using the locale aliasing + engine. Locale strings are passed directly to the C lib. - # In the 'C' locale there is no grouping or monetary decoration, so the - # conversion is just plain printf-style formatting. - if isinstance(val, tuple): - return format % val - return format % val + category may be given as one of the LC_* values. + """ + if locale and not isinstance(locale, _builtin_str): + # convert to string + locale = normalize(_build_localename(locale)) + return _setlocale(category, locale) -def format(percent, value, grouping=False, monetary=False, *additional): - if additional: - formatted = percent % ((value,) + additional) + +try: + from _locale import getencoding +except ImportError: + # When _locale.getencoding() is missing, locale.getencoding() uses the + # Python filesystem encoding. + def getencoding(): + return sys.getfilesystemencoding() + + +try: + CODESET +except NameError: + def getpreferredencoding(do_setlocale=True): + """Return the charset that the user is likely using.""" + if sys.flags.warn_default_encoding: + import warnings + warnings.warn( + "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.", + EncodingWarning, 2) + if sys.flags.utf8_mode: + return 'utf-8' + return getencoding() +else: + # On Unix, if CODESET is available, use that. + def getpreferredencoding(do_setlocale=True): + """Return the charset that the user is likely using, + according to the system configuration.""" + + if sys.flags.warn_default_encoding: + import warnings + warnings.warn( + "UTF-8 Mode affects locale.getpreferredencoding(). Consider locale.getencoding() instead.", + EncodingWarning, 2) + if sys.flags.utf8_mode: + return 'utf-8' + + if not do_setlocale: + return getencoding() + + old_loc = setlocale(LC_CTYPE) + try: + try: + setlocale(LC_CTYPE, "") + except Error: + pass + return getencoding() + finally: + setlocale(LC_CTYPE, old_loc) + + +### Database +# +# The following data was extracted from the locale.alias file which +# comes with X11 and then hand edited removing the explicit encoding +# definitions and adding some more aliases. The file is usually +# available as /usr/lib/X11/locale/locale.alias. +# + +# +# The local_encoding_alias table maps lowercase encoding alias names +# to C locale encoding names (case-sensitive). Note that normalize() +# first looks up the encoding in the encodings.aliases dictionary and +# then applies this mapping to find the correct C lib name for the +# encoding. +# +locale_encoding_alias = { + + # Mappings for non-standard encoding names used in locale names + '437': 'C', + 'c': 'C', + 'en': 'ISO8859-1', + 'jis': 'JIS7', + 'jis7': 'JIS7', + 'ajec': 'eucJP', + 'koi8c': 'KOI8-C', + 'microsoftcp1251': 'CP1251', + 'microsoftcp1255': 'CP1255', + 'microsoftcp1256': 'CP1256', + '88591': 'ISO8859-1', + '88592': 'ISO8859-2', + '88595': 'ISO8859-5', + '885915': 'ISO8859-15', + + # Mappings from Python codec names to C lib encoding names + 'ascii': 'ISO8859-1', + 'latin_1': 'ISO8859-1', + 'iso8859_1': 'ISO8859-1', + 'iso8859_10': 'ISO8859-10', + 'iso8859_11': 'ISO8859-11', + 'iso8859_13': 'ISO8859-13', + 'iso8859_14': 'ISO8859-14', + 'iso8859_15': 'ISO8859-15', + 'iso8859_16': 'ISO8859-16', + 'iso8859_2': 'ISO8859-2', + 'iso8859_3': 'ISO8859-3', + 'iso8859_4': 'ISO8859-4', + 'iso8859_5': 'ISO8859-5', + 'iso8859_6': 'ISO8859-6', + 'iso8859_7': 'ISO8859-7', + 'iso8859_8': 'ISO8859-8', + 'iso8859_9': 'ISO8859-9', + 'iso2022_jp': 'JIS7', + 'shift_jis': 'SJIS', + 'tactis': 'TACTIS', + 'euc_jp': 'eucJP', + 'euc_kr': 'eucKR', + 'utf_8': 'UTF-8', + 'koi8_r': 'KOI8-R', + 'koi8_t': 'KOI8-T', + 'koi8_u': 'KOI8-U', + 'kz1048': 'RK1048', + 'cp1251': 'CP1251', + 'cp1255': 'CP1255', + 'cp1256': 'CP1256', + + # XXX This list is still incomplete. If you know more + # mappings, please file a bug report. Thanks. +} + +for k, v in sorted(locale_encoding_alias.items()): + k = k.replace('_', '') + locale_encoding_alias.setdefault(k, v) +del k, v + +# +# The locale_alias table maps lowercase alias names to C locale names +# (case-sensitive). Encodings are always separated from the locale +# name using a dot ('.'); they should only be given in case the +# language name is needed to interpret the given encoding alias +# correctly (CJK codes often have this need). +# +# Note that the normalize() function which uses this tables +# removes '_' and '-' characters from the encoding part of the +# locale name before doing the lookup. This saves a lot of +# space in the table. +# +# MAL 2004-12-10: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.4 +# and older): +# +# updated 'bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'bg_bg' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'bulgarian' -> 'bg_BG.ISO8859-5' to 'bg_BG.CP1251' +# updated 'cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'cz_cz' -> 'cz_CZ.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'czech' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'dutch' -> 'nl_BE.ISO8859-1' to 'nl_NL.ISO8859-1' +# updated 'et' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' +# updated 'et_ee' -> 'et_EE.ISO8859-4' to 'et_EE.ISO8859-15' +# updated 'fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' +# updated 'fi_fi' -> 'fi_FI.ISO8859-1' to 'fi_FI.ISO8859-15' +# updated 'iw' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'iw_il' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'japanese' -> 'ja_JP.SJIS' to 'ja_JP.eucJP' +# updated 'lt' -> 'lt_LT.ISO8859-4' to 'lt_LT.ISO8859-13' +# updated 'lv' -> 'lv_LV.ISO8859-4' to 'lv_LV.ISO8859-13' +# updated 'sl' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' +# updated 'slovene' -> 'sl_CS.ISO8859-2' to 'sl_SI.ISO8859-2' +# updated 'th_th' -> 'th_TH.TACTIS' to 'th_TH.ISO8859-11' +# updated 'zh_cn' -> 'zh_CN.eucCN' to 'zh_CN.gb2312' +# updated 'zh_cn.big5' -> 'zh_TW.eucTW' to 'zh_TW.big5' +# updated 'zh_tw' -> 'zh_TW.eucTW' to 'zh_TW.big5' +# +# MAL 2008-05-30: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.5 +# and older): +# +# updated 'cs_cs.iso88592' -> 'cs_CZ.ISO8859-2' to 'cs_CS.ISO8859-2' +# updated 'serbocroatian' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh_hr.iso88592' -> 'sh_HR.ISO8859-2' to 'hr_HR.ISO8859-2' +# updated 'sh_sp' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sh_yu' -> 'sh_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sp' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sp_yu' -> 'sp_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_sp' -> 'sr_SP.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sr_yu' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.cp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' +# updated 'sr_yu.iso88592' -> 'sr_YU.ISO8859-2' to 'sr_CS.ISO8859-2' +# updated 'sr_yu.iso88595' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.iso88595@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# updated 'sr_yu.microsoftcp1251@cyrillic' -> 'sr_YU.CP1251' to 'sr_CS.CP1251' +# updated 'sr_yu.utf8@cyrillic' -> 'sr_YU.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_yu@cyrillic' -> 'sr_YU.ISO8859-5' to 'sr_CS.ISO8859-5' +# +# AP 2010-04-12: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 2.6.5 +# and older): +# +# updated 'ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' +# updated 'ru_ru' -> 'ru_RU.ISO8859-5' to 'ru_RU.UTF-8' +# updated 'serbocroatian' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sh' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sh_yu' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# updated 'sr@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# updated 'sr@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr_cs.utf8@latn' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_CS.ISO8859-2' to 'sr_RS.UTF-8@latin' +# updated 'sr_yu' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8@latin' +# updated 'sr_yu.utf8@cyrillic' -> 'sr_CS.UTF-8' to 'sr_RS.UTF-8' +# updated 'sr_yu@cyrillic' -> 'sr_CS.ISO8859-5' to 'sr_RS.UTF-8' +# +# SS 2013-12-20: +# Updated alias mapping to most recent locale.alias file +# from X.org distribution using makelocalealias.py. +# +# These are the differences compared to the old mapping (Python 3.3.3 +# and older): +# +# updated 'a3' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'a3_az.koi8c' -> 'a3_AZ.KOI8-C' to 'az_AZ.KOI8-C' +# updated 'cs_cs.iso88592' -> 'cs_CS.ISO8859-2' to 'cs_CZ.ISO8859-2' +# updated 'hebrew' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'hebrew.iso88598' -> 'iw_IL.ISO8859-8' to 'he_IL.ISO8859-8' +# updated 'sd' -> 'sd_IN@devanagari.UTF-8' to 'sd_IN.UTF-8' +# updated 'sr@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs' -> 'sr_RS.UTF-8' to 'sr_CS.UTF-8' +# updated 'sr_cs.utf8@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# updated 'sr_cs@latn' -> 'sr_RS.UTF-8@latin' to 'sr_CS.UTF-8@latin' +# +# SS 2014-10-01: +# Updated alias mapping with glibc 2.19 supported locales. +# +# SS 2018-05-05: +# Updated alias mapping with glibc 2.27 supported locales. +# +# These are the differences compared to the old mapping (Python 3.6.5 +# and older): +# +# updated 'ca_es@valencia' -> 'ca_ES.ISO8859-15@valencia' to 'ca_ES.UTF-8@valencia' +# updated 'kk_kz' -> 'kk_KZ.RK1048' to 'kk_KZ.ptcp154' +# updated 'russian' -> 'ru_RU.ISO8859-5' to 'ru_RU.KOI8-R' +# +# SS 2025-02-04: +# Updated alias mapping with glibc 2.41 supported locales and the latest +# X lib alias mapping. +# +# These are the differences compared to the old mapping (Python 3.13.1 +# and older): +# +# updated 'c.utf8' -> 'C.UTF-8' to 'en_US.UTF-8' +# updated 'de_it' -> 'de_IT.ISO8859-1' to 'de_IT.UTF-8' +# removed 'de_li.utf8' +# updated 'en_il' -> 'en_IL.UTF-8' to 'en_IL.ISO8859-1' +# removed 'english.iso88591' +# updated 'es_cu' -> 'es_CU.UTF-8' to 'es_CU.ISO8859-1' +# updated 'russian' -> 'ru_RU.KOI8-R' to 'ru_RU.ISO8859-5' +# updated 'sr@latn' -> 'sr_CS.UTF-8@latin' to 'sr_RS.UTF-8@latin' +# removed 'univ' +# removed 'universal' +# +# SS 2025-06-10: +# Remove 'c.utf8' -> 'en_US.UTF-8' because 'en_US.UTF-8' does not exist +# on all platforms. + +locale_alias = { + 'a3': 'az_AZ.KOI8-C', + 'a3_az': 'az_AZ.KOI8-C', + 'a3_az.koic': 'az_AZ.KOI8-C', + 'aa_dj': 'aa_DJ.ISO8859-1', + 'aa_er': 'aa_ER.UTF-8', + 'aa_et': 'aa_ET.UTF-8', + 'af': 'af_ZA.ISO8859-1', + 'af_za': 'af_ZA.ISO8859-1', + 'agr_pe': 'agr_PE.UTF-8', + 'ak_gh': 'ak_GH.UTF-8', + 'am': 'am_ET.UTF-8', + 'am_et': 'am_ET.UTF-8', + 'american': 'en_US.ISO8859-1', + 'an_es': 'an_ES.ISO8859-15', + 'anp_in': 'anp_IN.UTF-8', + 'ar': 'ar_AA.ISO8859-6', + 'ar_aa': 'ar_AA.ISO8859-6', + 'ar_ae': 'ar_AE.ISO8859-6', + 'ar_bh': 'ar_BH.ISO8859-6', + 'ar_dz': 'ar_DZ.ISO8859-6', + 'ar_eg': 'ar_EG.ISO8859-6', + 'ar_in': 'ar_IN.UTF-8', + 'ar_iq': 'ar_IQ.ISO8859-6', + 'ar_jo': 'ar_JO.ISO8859-6', + 'ar_kw': 'ar_KW.ISO8859-6', + 'ar_lb': 'ar_LB.ISO8859-6', + 'ar_ly': 'ar_LY.ISO8859-6', + 'ar_ma': 'ar_MA.ISO8859-6', + 'ar_om': 'ar_OM.ISO8859-6', + 'ar_qa': 'ar_QA.ISO8859-6', + 'ar_sa': 'ar_SA.ISO8859-6', + 'ar_sd': 'ar_SD.ISO8859-6', + 'ar_ss': 'ar_SS.UTF-8', + 'ar_sy': 'ar_SY.ISO8859-6', + 'ar_tn': 'ar_TN.ISO8859-6', + 'ar_ye': 'ar_YE.ISO8859-6', + 'arabic': 'ar_AA.ISO8859-6', + 'as': 'as_IN.UTF-8', + 'as_in': 'as_IN.UTF-8', + 'ast_es': 'ast_ES.ISO8859-15', + 'ayc_pe': 'ayc_PE.UTF-8', + 'az': 'az_AZ.ISO8859-9E', + 'az_az': 'az_AZ.ISO8859-9E', + 'az_az.iso88599e': 'az_AZ.ISO8859-9E', + 'az_ir': 'az_IR.UTF-8', + 'be': 'be_BY.CP1251', + 'be@latin': 'be_BY.UTF-8@latin', + 'be_bg.utf8': 'bg_BG.UTF-8', + 'be_by': 'be_BY.CP1251', + 'be_by@latin': 'be_BY.UTF-8@latin', + 'bem_zm': 'bem_ZM.UTF-8', + 'ber_dz': 'ber_DZ.UTF-8', + 'ber_ma': 'ber_MA.UTF-8', + 'bg': 'bg_BG.CP1251', + 'bg_bg': 'bg_BG.CP1251', + 'bhb_in.utf8': 'bhb_IN.UTF-8', + 'bho_in': 'bho_IN.UTF-8', + 'bho_np': 'bho_NP.UTF-8', + 'bi_vu': 'bi_VU.UTF-8', + 'bn_bd': 'bn_BD.UTF-8', + 'bn_in': 'bn_IN.UTF-8', + 'bo_cn': 'bo_CN.UTF-8', + 'bo_in': 'bo_IN.UTF-8', + 'bokmal': 'nb_NO.ISO8859-1', + 'bokm\xe5l': 'nb_NO.ISO8859-1', + 'br': 'br_FR.ISO8859-1', + 'br_fr': 'br_FR.ISO8859-1', + 'brx_in': 'brx_IN.UTF-8', + 'bs': 'bs_BA.ISO8859-2', + 'bs_ba': 'bs_BA.ISO8859-2', + 'bulgarian': 'bg_BG.CP1251', + 'byn_er': 'byn_ER.UTF-8', + 'c': 'C', + 'c-french': 'fr_CA.ISO8859-1', + 'c.ascii': 'C', + 'c.en': 'C', + 'c.iso88591': 'en_US.ISO8859-1', + 'c_c': 'C', + 'c_c.c': 'C', + 'ca': 'ca_ES.ISO8859-1', + 'ca_ad': 'ca_AD.ISO8859-1', + 'ca_es': 'ca_ES.ISO8859-1', + 'ca_es@valencia': 'ca_ES.UTF-8@valencia', + 'ca_fr': 'ca_FR.ISO8859-1', + 'ca_it': 'ca_IT.ISO8859-1', + 'catalan': 'ca_ES.ISO8859-1', + 'ce_ru': 'ce_RU.UTF-8', + 'cextend': 'en_US.ISO8859-1', + 'chinese-s': 'zh_CN.eucCN', + 'chinese-t': 'zh_TW.eucTW', + 'chr_us': 'chr_US.UTF-8', + 'ckb_iq': 'ckb_IQ.UTF-8', + 'cmn_tw': 'cmn_TW.UTF-8', + 'crh_ru': 'crh_RU.UTF-8', + 'crh_ua': 'crh_UA.UTF-8', + 'croatian': 'hr_HR.ISO8859-2', + 'cs': 'cs_CZ.ISO8859-2', + 'cs_cs': 'cs_CZ.ISO8859-2', + 'cs_cz': 'cs_CZ.ISO8859-2', + 'csb_pl': 'csb_PL.UTF-8', + 'cv_ru': 'cv_RU.UTF-8', + 'cy': 'cy_GB.ISO8859-1', + 'cy_gb': 'cy_GB.ISO8859-1', + 'cz': 'cs_CZ.ISO8859-2', + 'cz_cz': 'cs_CZ.ISO8859-2', + 'czech': 'cs_CZ.ISO8859-2', + 'da': 'da_DK.ISO8859-1', + 'da_dk': 'da_DK.ISO8859-1', + 'danish': 'da_DK.ISO8859-1', + 'dansk': 'da_DK.ISO8859-1', + 'de': 'de_DE.ISO8859-1', + 'de_at': 'de_AT.ISO8859-1', + 'de_be': 'de_BE.ISO8859-1', + 'de_ch': 'de_CH.ISO8859-1', + 'de_de': 'de_DE.ISO8859-1', + 'de_it': 'de_IT.UTF-8', + 'de_li': 'de_LI.ISO8859-1', + 'de_lu': 'de_LU.ISO8859-1', + 'deutsch': 'de_DE.ISO8859-1', + 'doi_in': 'doi_IN.UTF-8', + 'dsb_de': 'dsb_DE.UTF-8', + 'dutch': 'nl_NL.ISO8859-1', + 'dutch.iso88591': 'nl_BE.ISO8859-1', + 'dv_mv': 'dv_MV.UTF-8', + 'dz_bt': 'dz_BT.UTF-8', + 'ee': 'ee_EE.ISO8859-4', + 'ee_ee': 'ee_EE.ISO8859-4', + 'eesti': 'et_EE.ISO8859-1', + 'el': 'el_GR.ISO8859-7', + 'el_cy': 'el_CY.ISO8859-7', + 'el_gr': 'el_GR.ISO8859-7', + 'el_gr@euro': 'el_GR.ISO8859-15', + 'en': 'en_US.ISO8859-1', + 'en_ag': 'en_AG.UTF-8', + 'en_au': 'en_AU.ISO8859-1', + 'en_be': 'en_BE.ISO8859-1', + 'en_bw': 'en_BW.ISO8859-1', + 'en_ca': 'en_CA.ISO8859-1', + 'en_dk': 'en_DK.ISO8859-1', + 'en_dl.utf8': 'en_DL.UTF-8', + 'en_gb': 'en_GB.ISO8859-1', + 'en_hk': 'en_HK.ISO8859-1', + 'en_ie': 'en_IE.ISO8859-1', + 'en_il': 'en_IL.ISO8859-1', + 'en_in': 'en_IN.ISO8859-1', + 'en_ng': 'en_NG.UTF-8', + 'en_nz': 'en_NZ.ISO8859-1', + 'en_ph': 'en_PH.ISO8859-1', + 'en_sc.utf8': 'en_SC.UTF-8', + 'en_sg': 'en_SG.ISO8859-1', + 'en_uk': 'en_GB.ISO8859-1', + 'en_us': 'en_US.ISO8859-1', + 'en_us@euro@euro': 'en_US.ISO8859-15', + 'en_za': 'en_ZA.ISO8859-1', + 'en_zm': 'en_ZM.UTF-8', + 'en_zw': 'en_ZW.ISO8859-1', + 'en_zw.utf8': 'en_ZS.UTF-8', + 'eng_gb': 'en_GB.ISO8859-1', + 'english': 'en_EN.ISO8859-1', + 'english_uk': 'en_GB.ISO8859-1', + 'english_united-states': 'en_US.ISO8859-1', + 'english_united-states.437': 'C', + 'english_us': 'en_US.ISO8859-1', + 'eo': 'eo_XX.ISO8859-3', + 'eo.utf8': 'eo.UTF-8', + 'eo_eo': 'eo_EO.ISO8859-3', + 'eo_us.utf8': 'eo_US.UTF-8', + 'eo_xx': 'eo_XX.ISO8859-3', + 'es': 'es_ES.ISO8859-1', + 'es_ar': 'es_AR.ISO8859-1', + 'es_bo': 'es_BO.ISO8859-1', + 'es_cl': 'es_CL.ISO8859-1', + 'es_co': 'es_CO.ISO8859-1', + 'es_cr': 'es_CR.ISO8859-1', + 'es_cu': 'es_CU.ISO8859-1', + 'es_do': 'es_DO.ISO8859-1', + 'es_ec': 'es_EC.ISO8859-1', + 'es_es': 'es_ES.ISO8859-1', + 'es_gt': 'es_GT.ISO8859-1', + 'es_hn': 'es_HN.ISO8859-1', + 'es_mx': 'es_MX.ISO8859-1', + 'es_ni': 'es_NI.ISO8859-1', + 'es_pa': 'es_PA.ISO8859-1', + 'es_pe': 'es_PE.ISO8859-1', + 'es_pr': 'es_PR.ISO8859-1', + 'es_py': 'es_PY.ISO8859-1', + 'es_sv': 'es_SV.ISO8859-1', + 'es_us': 'es_US.ISO8859-1', + 'es_uy': 'es_UY.ISO8859-1', + 'es_ve': 'es_VE.ISO8859-1', + 'estonian': 'et_EE.ISO8859-1', + 'et': 'et_EE.ISO8859-15', + 'et_ee': 'et_EE.ISO8859-15', + 'eu': 'eu_ES.ISO8859-1', + 'eu_es': 'eu_ES.ISO8859-1', + 'eu_fr': 'eu_FR.ISO8859-1', + 'fa': 'fa_IR.UTF-8', + 'fa_ir': 'fa_IR.UTF-8', + 'fa_ir.isiri3342': 'fa_IR.ISIRI-3342', + 'ff_sn': 'ff_SN.UTF-8', + 'fi': 'fi_FI.ISO8859-15', + 'fi_fi': 'fi_FI.ISO8859-15', + 'fil_ph': 'fil_PH.UTF-8', + 'finnish': 'fi_FI.ISO8859-1', + 'fo': 'fo_FO.ISO8859-1', + 'fo_fo': 'fo_FO.ISO8859-1', + 'fr': 'fr_FR.ISO8859-1', + 'fr_be': 'fr_BE.ISO8859-1', + 'fr_ca': 'fr_CA.ISO8859-1', + 'fr_ch': 'fr_CH.ISO8859-1', + 'fr_fr': 'fr_FR.ISO8859-1', + 'fr_lu': 'fr_LU.ISO8859-1', + 'fran\xe7ais': 'fr_FR.ISO8859-1', + 'fre_fr': 'fr_FR.ISO8859-1', + 'french': 'fr_FR.ISO8859-1', + 'french.iso88591': 'fr_CH.ISO8859-1', + 'french_france': 'fr_FR.ISO8859-1', + 'fur_it': 'fur_IT.UTF-8', + 'fy_de': 'fy_DE.UTF-8', + 'fy_nl': 'fy_NL.UTF-8', + 'ga': 'ga_IE.ISO8859-1', + 'ga_ie': 'ga_IE.ISO8859-1', + 'galego': 'gl_ES.ISO8859-1', + 'galician': 'gl_ES.ISO8859-1', + 'gbm_in': 'gbm_IN.UTF-8', + 'gd': 'gd_GB.ISO8859-1', + 'gd_gb': 'gd_GB.ISO8859-1', + 'ger_de': 'de_DE.ISO8859-1', + 'german': 'de_DE.ISO8859-1', + 'german.iso88591': 'de_CH.ISO8859-1', + 'german_germany': 'de_DE.ISO8859-1', + 'gez_er': 'gez_ER.UTF-8', + 'gez_et': 'gez_ET.UTF-8', + 'gl': 'gl_ES.ISO8859-1', + 'gl_es': 'gl_ES.ISO8859-1', + 'greek': 'el_GR.ISO8859-7', + 'gu_in': 'gu_IN.UTF-8', + 'gv': 'gv_GB.ISO8859-1', + 'gv_gb': 'gv_GB.ISO8859-1', + 'ha_ng': 'ha_NG.UTF-8', + 'hak_tw': 'hak_TW.UTF-8', + 'he': 'he_IL.ISO8859-8', + 'he_il': 'he_IL.ISO8859-8', + 'hebrew': 'he_IL.ISO8859-8', + 'hi': 'hi_IN.ISCII-DEV', + 'hi_in': 'hi_IN.ISCII-DEV', + 'hi_in.isciidev': 'hi_IN.ISCII-DEV', + 'hif_fj': 'hif_FJ.UTF-8', + 'hne': 'hne_IN.UTF-8', + 'hne_in': 'hne_IN.UTF-8', + 'hr': 'hr_HR.ISO8859-2', + 'hr_hr': 'hr_HR.ISO8859-2', + 'hrvatski': 'hr_HR.ISO8859-2', + 'hsb_de': 'hsb_DE.ISO8859-2', + 'ht_ht': 'ht_HT.UTF-8', + 'hu': 'hu_HU.ISO8859-2', + 'hu_hu': 'hu_HU.ISO8859-2', + 'hungarian': 'hu_HU.ISO8859-2', + 'hy_am': 'hy_AM.UTF-8', + 'hy_am.armscii8': 'hy_AM.ARMSCII_8', + 'ia': 'ia.UTF-8', + 'ia_fr': 'ia_FR.UTF-8', + 'icelandic': 'is_IS.ISO8859-1', + 'id': 'id_ID.ISO8859-1', + 'id_id': 'id_ID.ISO8859-1', + 'ie': 'ie.UTF-8', + 'ig_ng': 'ig_NG.UTF-8', + 'ik_ca': 'ik_CA.UTF-8', + 'in': 'id_ID.ISO8859-1', + 'in_id': 'id_ID.ISO8859-1', + 'is': 'is_IS.ISO8859-1', + 'is_is': 'is_IS.ISO8859-1', + 'iso-8859-1': 'en_US.ISO8859-1', + 'iso-8859-15': 'en_US.ISO8859-15', + 'iso8859-1': 'en_US.ISO8859-1', + 'iso8859-15': 'en_US.ISO8859-15', + 'iso_8859_1': 'en_US.ISO8859-1', + 'iso_8859_15': 'en_US.ISO8859-15', + 'it': 'it_IT.ISO8859-1', + 'it_ch': 'it_CH.ISO8859-1', + 'it_it': 'it_IT.ISO8859-1', + 'italian': 'it_IT.ISO8859-1', + 'iu': 'iu_CA.NUNACOM-8', + 'iu_ca': 'iu_CA.NUNACOM-8', + 'iu_ca.nunacom8': 'iu_CA.NUNACOM-8', + 'iw': 'he_IL.ISO8859-8', + 'iw_il': 'he_IL.ISO8859-8', + 'iw_il.utf8': 'iw_IL.UTF-8', + 'ja': 'ja_JP.eucJP', + 'ja_jp': 'ja_JP.eucJP', + 'ja_jp.euc': 'ja_JP.eucJP', + 'ja_jp.mscode': 'ja_JP.SJIS', + 'ja_jp.pck': 'ja_JP.SJIS', + 'japan': 'ja_JP.eucJP', + 'japanese': 'ja_JP.eucJP', + 'japanese-euc': 'ja_JP.eucJP', + 'japanese.euc': 'ja_JP.eucJP', + 'jp_jp': 'ja_JP.eucJP', + 'ka': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge.georgianacademy': 'ka_GE.GEORGIAN-ACADEMY', + 'ka_ge.georgianps': 'ka_GE.GEORGIAN-PS', + 'ka_ge.georgianrs': 'ka_GE.GEORGIAN-ACADEMY', + 'kab_dz': 'kab_DZ.UTF-8', + 'kk_kz': 'kk_KZ.ptcp154', + 'kl': 'kl_GL.ISO8859-1', + 'kl_gl': 'kl_GL.ISO8859-1', + 'km_kh': 'km_KH.UTF-8', + 'kn': 'kn_IN.UTF-8', + 'kn_in': 'kn_IN.UTF-8', + 'ko': 'ko_KR.eucKR', + 'ko_kr': 'ko_KR.eucKR', + 'ko_kr.euc': 'ko_KR.eucKR', + 'kok_in': 'kok_IN.UTF-8', + 'korean': 'ko_KR.eucKR', + 'korean.euc': 'ko_KR.eucKR', + 'ks': 'ks_IN.UTF-8', + 'ks_in': 'ks_IN.UTF-8', + 'ks_in@devanagari.utf8': 'ks_IN.UTF-8@devanagari', + 'ku_tr': 'ku_TR.ISO8859-9', + 'kv_ru': 'kv_RU.UTF-8', + 'kw': 'kw_GB.ISO8859-1', + 'kw_gb': 'kw_GB.ISO8859-1', + 'ky': 'ky_KG.UTF-8', + 'ky_kg': 'ky_KG.UTF-8', + 'lb_lu': 'lb_LU.UTF-8', + 'lg_ug': 'lg_UG.ISO8859-10', + 'li_be': 'li_BE.UTF-8', + 'li_nl': 'li_NL.UTF-8', + 'lij_it': 'lij_IT.UTF-8', + 'lithuanian': 'lt_LT.ISO8859-13', + 'ln_cd': 'ln_CD.UTF-8', + 'lo': 'lo_LA.MULELAO-1', + 'lo_la': 'lo_LA.MULELAO-1', + 'lo_la.cp1133': 'lo_LA.IBM-CP1133', + 'lo_la.ibmcp1133': 'lo_LA.IBM-CP1133', + 'lo_la.mulelao1': 'lo_LA.MULELAO-1', + 'lt': 'lt_LT.ISO8859-13', + 'lt_lt': 'lt_LT.ISO8859-13', + 'ltg_lv.utf8': 'ltg_LV.UTF-8', + 'lv': 'lv_LV.ISO8859-13', + 'lv_lv': 'lv_LV.ISO8859-13', + 'lzh_tw': 'lzh_TW.UTF-8', + 'mag_in': 'mag_IN.UTF-8', + 'mai': 'mai_IN.UTF-8', + 'mai_in': 'mai_IN.UTF-8', + 'mai_np': 'mai_NP.UTF-8', + 'mdf_ru': 'mdf_RU.UTF-8', + 'mfe_mu': 'mfe_MU.UTF-8', + 'mg_mg': 'mg_MG.ISO8859-15', + 'mhr_ru': 'mhr_RU.UTF-8', + 'mi': 'mi_NZ.ISO8859-1', + 'mi_nz': 'mi_NZ.ISO8859-1', + 'miq_ni': 'miq_NI.UTF-8', + 'mjw_in': 'mjw_IN.UTF-8', + 'mk': 'mk_MK.ISO8859-5', + 'mk_mk': 'mk_MK.ISO8859-5', + 'ml': 'ml_IN.UTF-8', + 'ml_in': 'ml_IN.UTF-8', + 'mn_mn': 'mn_MN.UTF-8', + 'mni_in': 'mni_IN.UTF-8', + 'mnw_mm': 'mnw_MM.UTF-8', + 'mr': 'mr_IN.UTF-8', + 'mr_in': 'mr_IN.UTF-8', + 'ms': 'ms_MY.ISO8859-1', + 'ms_my': 'ms_MY.ISO8859-1', + 'mt': 'mt_MT.ISO8859-3', + 'mt_mt': 'mt_MT.ISO8859-3', + 'my_mm': 'my_MM.UTF-8', + 'nan_tw': 'nan_TW.UTF-8', + 'nb': 'nb_NO.ISO8859-1', + 'nb_no': 'nb_NO.ISO8859-1', + 'nds_de': 'nds_DE.UTF-8', + 'nds_nl': 'nds_NL.UTF-8', + 'ne_np': 'ne_NP.UTF-8', + 'nhn_mx': 'nhn_MX.UTF-8', + 'niu_nu': 'niu_NU.UTF-8', + 'niu_nz': 'niu_NZ.UTF-8', + 'nl': 'nl_NL.ISO8859-1', + 'nl_aw': 'nl_AW.UTF-8', + 'nl_be': 'nl_BE.ISO8859-1', + 'nl_nl': 'nl_NL.ISO8859-1', + 'nn': 'nn_NO.ISO8859-1', + 'nn_no': 'nn_NO.ISO8859-1', + 'no': 'no_NO.ISO8859-1', + 'no@nynorsk': 'ny_NO.ISO8859-1', + 'no_no': 'no_NO.ISO8859-1', + 'no_no.iso88591@bokmal': 'no_NO.ISO8859-1', + 'no_no.iso88591@nynorsk': 'no_NO.ISO8859-1', + 'norwegian': 'no_NO.ISO8859-1', + 'nr': 'nr_ZA.ISO8859-1', + 'nr_za': 'nr_ZA.ISO8859-1', + 'nso': 'nso_ZA.ISO8859-15', + 'nso_za': 'nso_ZA.ISO8859-15', + 'ny': 'ny_NO.ISO8859-1', + 'ny_no': 'ny_NO.ISO8859-1', + 'nynorsk': 'nn_NO.ISO8859-1', + 'oc': 'oc_FR.ISO8859-1', + 'oc_fr': 'oc_FR.ISO8859-1', + 'om_et': 'om_ET.UTF-8', + 'om_ke': 'om_KE.ISO8859-1', + 'or': 'or_IN.UTF-8', + 'or_in': 'or_IN.UTF-8', + 'os_ru': 'os_RU.UTF-8', + 'pa': 'pa_IN.UTF-8', + 'pa_in': 'pa_IN.UTF-8', + 'pa_pk': 'pa_PK.UTF-8', + 'pap_an': 'pap_AN.UTF-8', + 'pap_aw': 'pap_AW.UTF-8', + 'pap_cw': 'pap_CW.UTF-8', + 'pd': 'pd_US.ISO8859-1', + 'pd_de': 'pd_DE.ISO8859-1', + 'pd_us': 'pd_US.ISO8859-1', + 'ph': 'ph_PH.ISO8859-1', + 'ph_ph': 'ph_PH.ISO8859-1', + 'pl': 'pl_PL.ISO8859-2', + 'pl_pl': 'pl_PL.ISO8859-2', + 'polish': 'pl_PL.ISO8859-2', + 'portuguese': 'pt_PT.ISO8859-1', + 'portuguese_brazil': 'pt_BR.ISO8859-1', + 'posix': 'C', + 'posix-utf2': 'C', + 'pp': 'pp_AN.ISO8859-1', + 'pp_an': 'pp_AN.ISO8859-1', + 'ps_af': 'ps_AF.UTF-8', + 'pt': 'pt_PT.ISO8859-1', + 'pt_br': 'pt_BR.ISO8859-1', + 'pt_pt': 'pt_PT.ISO8859-1', + 'quz_pe': 'quz_PE.UTF-8', + 'raj_in': 'raj_IN.UTF-8', + 'rif_ma': 'rif_MA.UTF-8', + 'ro': 'ro_RO.ISO8859-2', + 'ro_ro': 'ro_RO.ISO8859-2', + 'romanian': 'ro_RO.ISO8859-2', + 'ru': 'ru_RU.UTF-8', + 'ru_ru': 'ru_RU.UTF-8', + 'ru_ua': 'ru_UA.KOI8-U', + 'rumanian': 'ro_RO.ISO8859-2', + 'russian': 'ru_RU.ISO8859-5', + 'rw': 'rw_RW.ISO8859-1', + 'rw_rw': 'rw_RW.ISO8859-1', + 'sa_in': 'sa_IN.UTF-8', + 'sah_ru': 'sah_RU.UTF-8', + 'sat_in': 'sat_IN.UTF-8', + 'sc_it': 'sc_IT.UTF-8', + 'scn_it': 'scn_IT.UTF-8', + 'sd': 'sd_IN.UTF-8', + 'sd_in': 'sd_IN.UTF-8', + 'sd_in@devanagari.utf8': 'sd_IN.UTF-8@devanagari', + 'sd_pk': 'sd_PK.UTF-8', + 'se_no': 'se_NO.UTF-8', + 'serbocroatian': 'sr_RS.UTF-8@latin', + 'sgs_lt': 'sgs_LT.UTF-8', + 'sh': 'sr_RS.UTF-8@latin', + 'sh_ba.iso88592@bosnia': 'sr_CS.ISO8859-2', + 'sh_hr': 'sh_HR.ISO8859-2', + 'sh_hr.iso88592': 'hr_HR.ISO8859-2', + 'sh_sp': 'sr_CS.ISO8859-2', + 'sh_yu': 'sr_RS.UTF-8@latin', + 'shn_mm': 'shn_MM.UTF-8', + 'shs_ca': 'shs_CA.UTF-8', + 'si': 'si_LK.UTF-8', + 'si_lk': 'si_LK.UTF-8', + 'sid_et': 'sid_ET.UTF-8', + 'sinhala': 'si_LK.UTF-8', + 'sk': 'sk_SK.ISO8859-2', + 'sk_sk': 'sk_SK.ISO8859-2', + 'sl': 'sl_SI.ISO8859-2', + 'sl_cs': 'sl_CS.ISO8859-2', + 'sl_si': 'sl_SI.ISO8859-2', + 'slovak': 'sk_SK.ISO8859-2', + 'slovene': 'sl_SI.ISO8859-2', + 'slovenian': 'sl_SI.ISO8859-2', + 'sm_ws': 'sm_WS.UTF-8', + 'so_dj': 'so_DJ.ISO8859-1', + 'so_et': 'so_ET.UTF-8', + 'so_ke': 'so_KE.ISO8859-1', + 'so_so': 'so_SO.ISO8859-1', + 'sp': 'sr_CS.ISO8859-5', + 'sp_yu': 'sr_CS.ISO8859-5', + 'spanish': 'es_ES.ISO8859-1', + 'spanish_spain': 'es_ES.ISO8859-1', + 'sq': 'sq_AL.ISO8859-2', + 'sq_al': 'sq_AL.ISO8859-2', + 'sq_mk': 'sq_MK.UTF-8', + 'sr': 'sr_RS.UTF-8', + 'sr@cyrillic': 'sr_RS.UTF-8', + 'sr@latn': 'sr_RS.UTF-8@latin', + 'sr_cs': 'sr_CS.UTF-8', + 'sr_cs.iso88592@latn': 'sr_CS.ISO8859-2', + 'sr_cs@latn': 'sr_CS.UTF-8@latin', + 'sr_me': 'sr_ME.UTF-8', + 'sr_rs': 'sr_RS.UTF-8', + 'sr_rs@latn': 'sr_RS.UTF-8@latin', + 'sr_sp': 'sr_CS.ISO8859-2', + 'sr_yu': 'sr_RS.UTF-8@latin', + 'sr_yu.cp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.iso88592': 'sr_CS.ISO8859-2', + 'sr_yu.iso88595': 'sr_CS.ISO8859-5', + 'sr_yu.iso88595@cyrillic': 'sr_CS.ISO8859-5', + 'sr_yu.microsoftcp1251@cyrillic': 'sr_CS.CP1251', + 'sr_yu.utf8': 'sr_RS.UTF-8', + 'sr_yu.utf8@cyrillic': 'sr_RS.UTF-8', + 'sr_yu@cyrillic': 'sr_RS.UTF-8', + 'ss': 'ss_ZA.ISO8859-1', + 'ss_za': 'ss_ZA.ISO8859-1', + 'ssy_er': 'ssy_ER.UTF-8', + 'st': 'st_ZA.ISO8859-1', + 'st_za': 'st_ZA.ISO8859-1', + 'su_id': 'su_ID.UTF-8', + 'sv': 'sv_SE.ISO8859-1', + 'sv_fi': 'sv_FI.ISO8859-1', + 'sv_se': 'sv_SE.ISO8859-1', + 'sw_ke': 'sw_KE.UTF-8', + 'sw_tz': 'sw_TZ.UTF-8', + 'swedish': 'sv_SE.ISO8859-1', + 'syr': 'syr.UTF-8', + 'szl_pl': 'szl_PL.UTF-8', + 'ta': 'ta_IN.TSCII-0', + 'ta_in': 'ta_IN.TSCII-0', + 'ta_in.tscii': 'ta_IN.TSCII-0', + 'ta_in.tscii0': 'ta_IN.TSCII-0', + 'ta_lk': 'ta_LK.UTF-8', + 'tcy_in.utf8': 'tcy_IN.UTF-8', + 'te': 'te_IN.UTF-8', + 'te_in': 'te_IN.UTF-8', + 'tg': 'tg_TJ.KOI8-C', + 'tg_tj': 'tg_TJ.KOI8-C', + 'th': 'th_TH.ISO8859-11', + 'th_th': 'th_TH.ISO8859-11', + 'th_th.tactis': 'th_TH.TIS620', + 'th_th.tis620': 'th_TH.TIS620', + 'thai': 'th_TH.ISO8859-11', + 'the_np': 'the_NP.UTF-8', + 'ti_er': 'ti_ER.UTF-8', + 'ti_et': 'ti_ET.UTF-8', + 'tig_er': 'tig_ER.UTF-8', + 'tk_tm': 'tk_TM.UTF-8', + 'tl': 'tl_PH.ISO8859-1', + 'tl_ph': 'tl_PH.ISO8859-1', + 'tn': 'tn_ZA.ISO8859-15', + 'tn_za': 'tn_ZA.ISO8859-15', + 'to_to': 'to_TO.UTF-8', + 'tok': 'tok.UTF-8', + 'tpi_pg': 'tpi_PG.UTF-8', + 'tr': 'tr_TR.ISO8859-9', + 'tr_cy': 'tr_CY.ISO8859-9', + 'tr_tr': 'tr_TR.ISO8859-9', + 'ts': 'ts_ZA.ISO8859-1', + 'ts_za': 'ts_ZA.ISO8859-1', + 'tt': 'tt_RU.TATAR-CYR', + 'tt_ru': 'tt_RU.TATAR-CYR', + 'tt_ru.tatarcyr': 'tt_RU.TATAR-CYR', + 'tt_ru@iqtelif': 'tt_RU.UTF-8@iqtelif', + 'turkish': 'tr_TR.ISO8859-9', + 'ug_cn': 'ug_CN.UTF-8', + 'uk': 'uk_UA.KOI8-U', + 'uk_ua': 'uk_UA.KOI8-U', + 'univ.utf8': 'en_US.UTF-8', + 'universal.utf8@ucs4': 'en_US.UTF-8', + 'unm_us': 'unm_US.UTF-8', + 'ur': 'ur_PK.CP1256', + 'ur_in': 'ur_IN.UTF-8', + 'ur_pk': 'ur_PK.CP1256', + 'uz': 'uz_UZ.UTF-8', + 'uz_uz': 'uz_UZ.UTF-8', + 'uz_uz@cyrillic': 'uz_UZ.UTF-8', + 've': 've_ZA.UTF-8', + 've_za': 've_ZA.UTF-8', + 'vi': 'vi_VN.TCVN', + 'vi_vn': 'vi_VN.TCVN', + 'vi_vn.tcvn': 'vi_VN.TCVN', + 'vi_vn.tcvn5712': 'vi_VN.TCVN', + 'vi_vn.viscii': 'vi_VN.VISCII', + 'vi_vn.viscii111': 'vi_VN.VISCII', + 'wa': 'wa_BE.ISO8859-1', + 'wa_be': 'wa_BE.ISO8859-1', + 'wae_ch': 'wae_CH.UTF-8', + 'wal_et': 'wal_ET.UTF-8', + 'wo_sn': 'wo_SN.UTF-8', + 'xh': 'xh_ZA.ISO8859-1', + 'xh_za': 'xh_ZA.ISO8859-1', + 'yi': 'yi_US.CP1255', + 'yi_us': 'yi_US.CP1255', + 'yo_ng': 'yo_NG.UTF-8', + 'yue_hk': 'yue_HK.UTF-8', + 'yuw_pg': 'yuw_PG.UTF-8', + 'zgh_ma': 'zgh_MA.UTF-8', + 'zh': 'zh_CN.eucCN', + 'zh_cn': 'zh_CN.gb2312', + 'zh_cn.big5': 'zh_TW.big5', + 'zh_cn.euc': 'zh_CN.eucCN', + 'zh_hk': 'zh_HK.big5hkscs', + 'zh_hk.big5hk': 'zh_HK.big5hkscs', + 'zh_sg': 'zh_SG.GB2312', + 'zh_sg.gbk': 'zh_SG.GBK', + 'zh_tw': 'zh_TW.big5', + 'zh_tw.euc': 'zh_TW.eucTW', + 'zh_tw.euctw': 'zh_TW.eucTW', + 'zu': 'zu_ZA.ISO8859-1', + 'zu_za': 'zu_ZA.ISO8859-1', +} + +# +# This maps Windows language identifiers to locale strings. +# +# This list has been updated from +# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/intl/nls_238z.asp +# to include every locale up to Windows Vista. +# +# NOTE: this mapping is incomplete. If your language is missing, please +# submit a bug report as detailed in the Python devguide at: +# https://devguide.python.org/triage/issue-tracker/ +# Make sure you include the missing language identifier and the suggested +# locale code. +# + +windows_locale = { + 0x0436: "af_ZA", # Afrikaans + 0x041c: "sq_AL", # Albanian + 0x0484: "gsw_FR",# Alsatian - France + 0x045e: "am_ET", # Amharic - Ethiopia + 0x0401: "ar_SA", # Arabic - Saudi Arabia + 0x0801: "ar_IQ", # Arabic - Iraq + 0x0c01: "ar_EG", # Arabic - Egypt + 0x1001: "ar_LY", # Arabic - Libya + 0x1401: "ar_DZ", # Arabic - Algeria + 0x1801: "ar_MA", # Arabic - Morocco + 0x1c01: "ar_TN", # Arabic - Tunisia + 0x2001: "ar_OM", # Arabic - Oman + 0x2401: "ar_YE", # Arabic - Yemen + 0x2801: "ar_SY", # Arabic - Syria + 0x2c01: "ar_JO", # Arabic - Jordan + 0x3001: "ar_LB", # Arabic - Lebanon + 0x3401: "ar_KW", # Arabic - Kuwait + 0x3801: "ar_AE", # Arabic - United Arab Emirates + 0x3c01: "ar_BH", # Arabic - Bahrain + 0x4001: "ar_QA", # Arabic - Qatar + 0x042b: "hy_AM", # Armenian + 0x044d: "as_IN", # Assamese - India + 0x042c: "az_AZ", # Azeri - Latin + 0x082c: "az_AZ", # Azeri - Cyrillic + 0x046d: "ba_RU", # Bashkir + 0x042d: "eu_ES", # Basque - Russia + 0x0423: "be_BY", # Belarusian + 0x0445: "bn_IN", # Begali + 0x201a: "bs_BA", # Bosnian - Cyrillic + 0x141a: "bs_BA", # Bosnian - Latin + 0x047e: "br_FR", # Breton - France + 0x0402: "bg_BG", # Bulgarian +# 0x0455: "my_MM", # Burmese - Not supported + 0x0403: "ca_ES", # Catalan + 0x0004: "zh_CHS",# Chinese - Simplified + 0x0404: "zh_TW", # Chinese - Taiwan + 0x0804: "zh_CN", # Chinese - PRC + 0x0c04: "zh_HK", # Chinese - Hong Kong S.A.R. + 0x1004: "zh_SG", # Chinese - Singapore + 0x1404: "zh_MO", # Chinese - Macao S.A.R. + 0x7c04: "zh_CHT",# Chinese - Traditional + 0x0483: "co_FR", # Corsican - France + 0x041a: "hr_HR", # Croatian + 0x101a: "hr_BA", # Croatian - Bosnia + 0x0405: "cs_CZ", # Czech + 0x0406: "da_DK", # Danish + 0x048c: "gbz_AF",# Dari - Afghanistan + 0x0465: "div_MV",# Divehi - Maldives + 0x0413: "nl_NL", # Dutch - The Netherlands + 0x0813: "nl_BE", # Dutch - Belgium + 0x0409: "en_US", # English - United States + 0x0809: "en_GB", # English - United Kingdom + 0x0c09: "en_AU", # English - Australia + 0x1009: "en_CA", # English - Canada + 0x1409: "en_NZ", # English - New Zealand + 0x1809: "en_IE", # English - Ireland + 0x1c09: "en_ZA", # English - South Africa + 0x2009: "en_JA", # English - Jamaica + 0x2409: "en_CB", # English - Caribbean + 0x2809: "en_BZ", # English - Belize + 0x2c09: "en_TT", # English - Trinidad + 0x3009: "en_ZW", # English - Zimbabwe + 0x3409: "en_PH", # English - Philippines + 0x4009: "en_IN", # English - India + 0x4409: "en_MY", # English - Malaysia + 0x4809: "en_IN", # English - Singapore + 0x0425: "et_EE", # Estonian + 0x0438: "fo_FO", # Faroese + 0x0464: "fil_PH",# Filipino + 0x040b: "fi_FI", # Finnish + 0x040c: "fr_FR", # French - France + 0x080c: "fr_BE", # French - Belgium + 0x0c0c: "fr_CA", # French - Canada + 0x100c: "fr_CH", # French - Switzerland + 0x140c: "fr_LU", # French - Luxembourg + 0x180c: "fr_MC", # French - Monaco + 0x0462: "fy_NL", # Frisian - Netherlands + 0x0456: "gl_ES", # Galician + 0x0437: "ka_GE", # Georgian + 0x0407: "de_DE", # German - Germany + 0x0807: "de_CH", # German - Switzerland + 0x0c07: "de_AT", # German - Austria + 0x1007: "de_LU", # German - Luxembourg + 0x1407: "de_LI", # German - Liechtenstein + 0x0408: "el_GR", # Greek + 0x046f: "kl_GL", # Greenlandic - Greenland + 0x0447: "gu_IN", # Gujarati + 0x0468: "ha_NG", # Hausa - Latin + 0x040d: "he_IL", # Hebrew + 0x0439: "hi_IN", # Hindi + 0x040e: "hu_HU", # Hungarian + 0x040f: "is_IS", # Icelandic + 0x0421: "id_ID", # Indonesian + 0x045d: "iu_CA", # Inuktitut - Syllabics + 0x085d: "iu_CA", # Inuktitut - Latin + 0x083c: "ga_IE", # Irish - Ireland + 0x0410: "it_IT", # Italian - Italy + 0x0810: "it_CH", # Italian - Switzerland + 0x0411: "ja_JP", # Japanese + 0x044b: "kn_IN", # Kannada - India + 0x043f: "kk_KZ", # Kazakh + 0x0453: "kh_KH", # Khmer - Cambodia + 0x0486: "qut_GT",# K'iche - Guatemala + 0x0487: "rw_RW", # Kinyarwanda - Rwanda + 0x0457: "kok_IN",# Konkani + 0x0412: "ko_KR", # Korean + 0x0440: "ky_KG", # Kyrgyz + 0x0454: "lo_LA", # Lao - Lao PDR + 0x0426: "lv_LV", # Latvian + 0x0427: "lt_LT", # Lithuanian + 0x082e: "dsb_DE",# Lower Sorbian - Germany + 0x046e: "lb_LU", # Luxembourgish + 0x042f: "mk_MK", # FYROM Macedonian + 0x043e: "ms_MY", # Malay - Malaysia + 0x083e: "ms_BN", # Malay - Brunei Darussalam + 0x044c: "ml_IN", # Malayalam - India + 0x043a: "mt_MT", # Maltese + 0x0481: "mi_NZ", # Maori + 0x047a: "arn_CL",# Mapudungun + 0x044e: "mr_IN", # Marathi + 0x047c: "moh_CA",# Mohawk - Canada + 0x0450: "mn_MN", # Mongolian - Cyrillic + 0x0850: "mn_CN", # Mongolian - PRC + 0x0461: "ne_NP", # Nepali + 0x0414: "nb_NO", # Norwegian - Bokmal + 0x0814: "nn_NO", # Norwegian - Nynorsk + 0x0482: "oc_FR", # Occitan - France + 0x0448: "or_IN", # Oriya - India + 0x0463: "ps_AF", # Pashto - Afghanistan + 0x0429: "fa_IR", # Persian + 0x0415: "pl_PL", # Polish + 0x0416: "pt_BR", # Portuguese - Brazil + 0x0816: "pt_PT", # Portuguese - Portugal + 0x0446: "pa_IN", # Punjabi + 0x046b: "quz_BO",# Quechua (Bolivia) + 0x086b: "quz_EC",# Quechua (Ecuador) + 0x0c6b: "quz_PE",# Quechua (Peru) + 0x0418: "ro_RO", # Romanian - Romania + 0x0417: "rm_CH", # Romansh + 0x0419: "ru_RU", # Russian + 0x243b: "smn_FI",# Sami Finland + 0x103b: "smj_NO",# Sami Norway + 0x143b: "smj_SE",# Sami Sweden + 0x043b: "se_NO", # Sami Northern Norway + 0x083b: "se_SE", # Sami Northern Sweden + 0x0c3b: "se_FI", # Sami Northern Finland + 0x203b: "sms_FI",# Sami Skolt + 0x183b: "sma_NO",# Sami Southern Norway + 0x1c3b: "sma_SE",# Sami Southern Sweden + 0x044f: "sa_IN", # Sanskrit + 0x0c1a: "sr_SP", # Serbian - Cyrillic + 0x1c1a: "sr_BA", # Serbian - Bosnia Cyrillic + 0x081a: "sr_SP", # Serbian - Latin + 0x181a: "sr_BA", # Serbian - Bosnia Latin + 0x045b: "si_LK", # Sinhala - Sri Lanka + 0x046c: "ns_ZA", # Northern Sotho + 0x0432: "tn_ZA", # Setswana - Southern Africa + 0x041b: "sk_SK", # Slovak + 0x0424: "sl_SI", # Slovenian + 0x040a: "es_ES", # Spanish - Spain + 0x080a: "es_MX", # Spanish - Mexico + 0x0c0a: "es_ES", # Spanish - Spain (Modern) + 0x100a: "es_GT", # Spanish - Guatemala + 0x140a: "es_CR", # Spanish - Costa Rica + 0x180a: "es_PA", # Spanish - Panama + 0x1c0a: "es_DO", # Spanish - Dominican Republic + 0x200a: "es_VE", # Spanish - Venezuela + 0x240a: "es_CO", # Spanish - Colombia + 0x280a: "es_PE", # Spanish - Peru + 0x2c0a: "es_AR", # Spanish - Argentina + 0x300a: "es_EC", # Spanish - Ecuador + 0x340a: "es_CL", # Spanish - Chile + 0x380a: "es_UR", # Spanish - Uruguay + 0x3c0a: "es_PY", # Spanish - Paraguay + 0x400a: "es_BO", # Spanish - Bolivia + 0x440a: "es_SV", # Spanish - El Salvador + 0x480a: "es_HN", # Spanish - Honduras + 0x4c0a: "es_NI", # Spanish - Nicaragua + 0x500a: "es_PR", # Spanish - Puerto Rico + 0x540a: "es_US", # Spanish - United States +# 0x0430: "", # Sutu - Not supported + 0x0441: "sw_KE", # Swahili + 0x041d: "sv_SE", # Swedish - Sweden + 0x081d: "sv_FI", # Swedish - Finland + 0x045a: "syr_SY",# Syriac + 0x0428: "tg_TJ", # Tajik - Cyrillic + 0x085f: "tmz_DZ",# Tamazight - Latin + 0x0449: "ta_IN", # Tamil + 0x0444: "tt_RU", # Tatar + 0x044a: "te_IN", # Telugu + 0x041e: "th_TH", # Thai + 0x0851: "bo_BT", # Tibetan - Bhutan + 0x0451: "bo_CN", # Tibetan - PRC + 0x041f: "tr_TR", # Turkish + 0x0442: "tk_TM", # Turkmen - Cyrillic + 0x0480: "ug_CN", # Uighur - Arabic + 0x0422: "uk_UA", # Ukrainian + 0x042e: "wen_DE",# Upper Sorbian - Germany + 0x0420: "ur_PK", # Urdu + 0x0820: "ur_IN", # Urdu - India + 0x0443: "uz_UZ", # Uzbek - Latin + 0x0843: "uz_UZ", # Uzbek - Cyrillic + 0x042a: "vi_VN", # Vietnamese + 0x0452: "cy_GB", # Welsh + 0x0488: "wo_SN", # Wolof - Senegal + 0x0434: "xh_ZA", # Xhosa - South Africa + 0x0485: "sah_RU",# Yakut - Cyrillic + 0x0478: "ii_CN", # Yi - PRC + 0x046a: "yo_NG", # Yoruba - Nigeria + 0x0435: "zu_ZA", # Zulu +} + +def _print_locale(): + + """ Test function. + """ + categories = {} + def _init_categories(categories=categories): + for k,v in globals().items(): + if k[:3] == 'LC_': + categories[k] = v + _init_categories() + del categories['LC_ALL'] + + print('Locale defaults as determined by getdefaultlocale():') + print('-'*72) + lang, enc = getdefaultlocale() + print('Language: ', lang or '(undefined)') + print('Encoding: ', enc or '(undefined)') + print() + + print('Locale settings on startup:') + print('-'*72) + for name,category in categories.items(): + print(name, '...') + lang, enc = getlocale(category) + print(' Language: ', lang or '(undefined)') + print(' Encoding: ', enc or '(undefined)') + print() + + try: + setlocale(LC_ALL, "") + except: + print('NOTE:') + print('setlocale(LC_ALL, "") does not support the default locale') + print('given in the OS environment variables.') else: - formatted = percent % value - return formatted + print() + print('Locale settings after calling setlocale(LC_ALL, ""):') + print('-'*72) + for name,category in categories.items(): + print(name, '...') + lang, enc = getlocale(category) + print(' Language: ', lang or '(undefined)') + print(' Encoding: ', enc or '(undefined)') + print() +### -def currency(val, symbol=True, grouping=False, international=False): - raise ValueError("Currency formatting is not possible in the 'C' locale.") +try: + LC_MESSAGES +except NameError: + pass +else: + __all__.append("LC_MESSAGES") + +if __name__=='__main__': + print('Locale aliasing:') + print() + _print_locale() + print() + print('Number formatting:') + print() + _test() diff --git a/crates/weavepy-vm/src/stdlib/testinternalcapi_mod.rs b/crates/weavepy-vm/src/stdlib/testinternalcapi_mod.rs index 510c3a2..a328d37 100644 --- a/crates/weavepy-vm/src/stdlib/testinternalcapi_mod.rs +++ b/crates/weavepy-vm/src/stdlib/testinternalcapi_mod.rs @@ -109,6 +109,103 @@ fn has_inline_values(args: &[Object]) -> Result { Ok(Object::Bool(inline)) } +/// Pull an attribute off a `RuntimeError::PyException`'s instance dict +/// (the Unicode error objects store `start`/`reason` there directly). +fn exc_attr(err: &RuntimeError, name: &'static str) -> Option { + match err { + RuntimeError::PyException(pyexc) => match &pyexc.instance { + Object::Instance(inst) => inst + .dict + .borrow() + .get(&DictKey(Object::from_static(name))) + .cloned(), + _ => None, + }, + _ => None, + } +} + +/// `_Py_EncodeLocaleEx`/`_Py_DecodeLocaleEx` only speak these handlers; +/// anything else is `ValueError('unsupported error handler')`. +fn locale_check_handler(errors: &str) -> Result<(), RuntimeError> { + match errors { + "strict" | "surrogateescape" | "surrogatepass" => Ok(()), + _ => Err(crate::error::value_error("unsupported error handler")), + } +} + +/// `EncodeLocaleEx(text, current_locale, errors)` — encode with the +/// filesystem encoding (UTF-8), reporting failures as CPython's +/// `RuntimeError("encode error: pos=N, reason=...")`. +fn encode_locale_ex(args: &[Object]) -> Result { + let cps: Vec = match args.first() { + Some(Object::Str(s)) => s.chars().map(|c| c as u32).collect(), + Some(Object::WStr(w)) => w.to_vec(), + _ => { + return Err(crate::error::type_error( + "EncodeLocaleEx() argument 'unicode' must be str", + )) + } + }; + let errors = match args.get(2) { + Some(Object::Str(s)) => s.to_string(), + None => "strict".to_owned(), + _ => return Err(crate::error::type_error("errors must be str")), + }; + locale_check_handler(&errors)?; + match crate::stdlib::codecs_engine::utf8_encode(&cps, &errors) { + Ok(b) => Ok(Object::Bytes(Rc::from(b.into_boxed_slice()))), + Err(e) => { + let pos = match exc_attr(&e, "start") { + Some(Object::Int(i)) => i, + _ => 0, + }; + let reason = match exc_attr(&e, "reason") { + Some(Object::Str(s)) => s.to_string(), + _ => "encoding error".to_owned(), + }; + Err(crate::error::runtime_error(format!( + "encode error: pos={pos}, reason={reason}" + ))) + } + } +} + +/// `DecodeLocaleEx(encoded, current_locale, errors)` — the decode +/// counterpart of [`encode_locale_ex`]. +fn decode_locale_ex(args: &[Object]) -> Result { + let data = match args.first().and_then(|o| o.as_bytes_view()) { + Some(b) => b, + None => { + return Err(crate::error::type_error( + "DecodeLocaleEx() argument 'str' must be bytes", + )) + } + }; + let errors = match args.get(2) { + Some(Object::Str(s)) => s.to_string(), + None => "strict".to_owned(), + _ => return Err(crate::error::type_error("errors must be str")), + }; + locale_check_handler(&errors)?; + match crate::stdlib::codecs_engine::utf8_decode(&data, &errors, true) { + Ok((obj, _)) => Ok(obj), + Err(e) => { + let pos = match exc_attr(&e, "start") { + Some(Object::Int(i)) => i, + _ => 0, + }; + let reason = match exc_attr(&e, "reason") { + Some(Object::Str(s)) => s.to_string(), + _ => "decoding error".to_owned(), + }; + Err(crate::error::runtime_error(format!( + "decode error: pos={pos}, reason={reason}" + ))) + } + } +} + pub fn build(_cache: &ModuleCache) -> Rc { let dict = Rc::new(RefCell::new(DictData::default())); { @@ -153,6 +250,27 @@ pub fn build(_cache: &ModuleCache) -> Rc { call_kw: None, })), ); + // `_Py_EncodeLocaleEx`/`_Py_DecodeLocaleEx` probes + // (`test_codecs.LocaleCodecTest`): the filesystem-encoding + // (UTF-8) coders with the locale-restricted handler set. + d.insert( + DictKey(Object::from_static("EncodeLocaleEx")), + Object::Builtin(Rc::new(BuiltinFn { + name: "EncodeLocaleEx", + binds_instance: false, + call: Box::new(encode_locale_ex), + call_kw: None, + })), + ); + d.insert( + DictKey(Object::from_static("DecodeLocaleEx")), + Object::Builtin(Rc::new(BuiltinFn { + name: "DecodeLocaleEx", + binds_instance: false, + call: Box::new(decode_locale_ex), + call_kw: None, + })), + ); // `get_recursion_depth()` — the live Python call depth on this // thread, read straight off the RFC 0037 recursion guard. // `test.support.get_recursion_depth()`/`infinite_recursion()` use it diff --git a/crates/weavepy-vm/src/stdlib/ucd/aliases.bin b/crates/weavepy-vm/src/stdlib/ucd/aliases.bin new file mode 100644 index 0000000000000000000000000000000000000000..632959a3b89453c57209fa0cfd4985ce1be35cf1 GIT binary patch literal 5791 zcmbW4=Y!nD8OCQ7*BuKzc~;l>flVBh7owKIcQe?DNy}&S*64oms}%lB9?t#+U-FF}7CZ zZkDTQM-8~^he;QnBGRDF*vM=s=eu$kipX~s#aQ15g` z@Cwh(ve4~vHRE}aC9vvVHj1($2s@aDBFDpclzKf(#Uz;thglct7`|9qVFEsAVX@sj zD@)WxxE9muySZC-t*3I~xqS{#@gqKtYCfM1J+68fsw|DvG$~!h_q2od59WguE`s_x zjQl<|^C06KKElSq7>s?wowUecBWkWk<%D-JRnuIZH}UY5#O-Y;*Wobnf-FtaLZ~6W z6rKWaBV(HuSy^hk>^y>4eeDUxmU(XC@d%`VHevBnrI`C+5yQYFmQv^OX2w>DqAl_; zFLI721y5V>4mnaF1+2e z!eiYmE&6lyVAZ?g5OnhZ^#&<|YcuYpnLk$zUOf|s9$Xx&#`G=_*GgnKF4rioqQnn3y<05H=LdtY5u0*e~81oQ$r+NWa z>A=l=_?W?YzMl>fm`XqLuR?-c5GxaFSqXu$1%aXu3ss7%@w$xTQv|1GkTqeB%$U{m z!Ki29HRTS*$|-k5mC2Ae;EhU8CbCH#4rWci7I|i2;WClHU0B?JgW|?@`1E~Ji^wxH zh5(X_xW4Q`7EZf4R||YAmOiYJdDf%`L+KaV4f_90G=J-xn^>}a#x-q+$y9I`x)-nPcX9N8# z&F7XmLJCg5Td`7Tna{5Xdp+3;t0ABuUEPLHnSHSwGFUj>#qEq8Ml;aO+k7p>Rh^}`Bk{Xqs+YNK25LSd2-icB(XNuq_6&wk9-n$T1JQ3c7MI}E4_Xnhl zq)e$W>mt7!yER1)!G1yt5<`*m7^hSmyNQpOk_zvhnfddEDh)EMdOyAwjl2DRM7t3g zDn-X;t0Szqeeb^V`qLKuhs!SxhWFRlM0tHkRGg4ud2c{EEbkTFz`HprNW-DrL! zRnU>{)P`m3I2;IV44o`d<;N(*Ay;HL>emCVuy7aCFe_!v7Z58FI<6E$|Tp4#rYli0s$SM7#s+)dT2J9Lw$$C(QF`H!r@d#!*%1dWgWZsHWx;31*&+KCtl~3od~Td=-><|>aIzPm z*5eMG7;I>D59T8zm@^U*DAvnUeZO>kh%jG3EZ6=T}M)hb)Edm#F2 zDov(FRHp16OpQXKEFOboQG9gu#CKLt{1`~z?@U%^dTeE;$Ej>-Qm(6$@uD~u{Zmv{ zA55KE6$($Q3WcXbIwCv+()YuO?QGkChsdqSFG8q1io!l_l4_?&yz)E=4rk+W=w--e zNNU&(aXXE|!`a%(^j#5m0z-SAlIRvVzF^`_Gm%N zX^)??lbw*^WdDEbufLCN9)|c9tj+TEA@+~FFqJE6&qHiej3oq~8U0@1#(AisINQq< zOku4Oy~6auIeDH7PU=IWH-m+)+Dvu~>@sWvO<7c`u&;(|c-L zaf#&}H}rAn?VGBC!JgW-{}E5RXYQ$Oo?l==J`2v;Q`>UDDER*strfMh0Rmep)i$dJ!akOM|o%@;_uj+bhmAhmg-)Yc27IxniU)p)T~&6TRRr5c`8)0b*- zsdh(dvn#a~NOi(WoyL?@ttVBFq#ChQGm&bgQtiIf=1EdpnN&yAMwgb^q>&S71%W#U|&GcypW)E5rK2D1gmigfp#f@ zei?yrIe~cvfpsN;eHB6TYJ%1^1kSY*?8bEj+Vuqb4FtxG1m;Zy*3AU=Ed(pt zK15(YM9};&LF*#~&chO%#zzUXj}hpP5EvgPFh491A+EO0{u?}#-9nyzYth|C9wZS(EK|=>mLNp bKP6a=e-UW^CeWWIFrFbWpCz!KBe4GqUiBIv literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/case_index1.bin b/crates/weavepy-vm/src/stdlib/ucd/case_index1.bin new file mode 100644 index 0000000000000000000000000000000000000000..27996c6ab4c66f6855ffab8cdefd4d3fd74c6674 GIT binary patch literal 17408 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 N2eAV!1G)9<{{SnRrJ4W$ literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/case_pool.bin b/crates/weavepy-vm/src/stdlib/ucd/case_pool.bin new file mode 100644 index 0000000000000000000000000000000000000000..515f1fef76da0560f792ac4d7ee1d2f4e4541604 GIT binary patch literal 1268 zcmYL}yGtEG7{xzlyuM;g;UC~5K9i`VNF^x@Dn^2Z5rUnMc;h=lE(Rf_NFi7SD@mEc zLJ%QUP$Xbsp+)|nR5|DV)+_9CzTcTMGdsJplio(?O1eKubX(RU8grz}6f+{pwq!b@ zRpxqC@{b%%IqGuc^ICOWtFG^=^r95ArLcUHtRPbn&o$I4G8Y~yRgiZPEuzoJJhF$3 zMf^#T77_mRr6G(rjF2hQgnnClbWGAs0B*U11LkSP(Abz zDnV^f1M~=Lga)8aXb|dxoVrn0erOe1fYzWzXdPODHlSr_ z6M7GAK`YQURE9o6AD|0JGNJdmgL#;%FZoxlzT|yK;>ancBK{nT`1?TmFh!+crpaIF zmN_IIpu!wSjQX454j_pmXPAn34n;f%ncsxkYSX2sT zn)I}3GD4T7EYWQdy+(8h*tE!egKT0-vP{CR%GF?&6qP((>Q%J52dy4L$Bq7ai~f3_ rI+pQLOzMn~>`E$#NN0ylogFqUqETc6(=tPMiMxNTb$>~6i=^Z~8?K=f literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/case_records.bin b/crates/weavepy-vm/src/stdlib/ucd/case_records.bin new file mode 100644 index 0000000000000000000000000000000000000000..85c5977fcb4731d97fe5fec80e96d97de1eaca1d GIT binary patch literal 41244 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≠YV?z1Ggar|Ri`($jjPU}>O6jIPpdlHR-GNk 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 literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/decomp.bin b/crates/weavepy-vm/src/stdlib/ucd/decomp.bin new file mode 100644 index 0000000000000000000000000000000000000000..6b0d44d25727ac57a1d1d7f672d563c86e957db7 GIT binary patch literal 153618 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 literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/index1.bin b/crates/weavepy-vm/src/stdlib/ucd/index1.bin new file mode 100644 index 0000000000000000000000000000000000000000..66271dbbc6b7abb3fee6cdd28f5e04cd120ac687 GIT binary patch literal 17408 zcmeI3WpEp542GY#%*@=T%*@PqWoAm5nVFd(r5qKGnVFfHnVGS-b`p0}+tc+Wp3BT> zG_%$xy({T^yld|d8$>$NlYxw6A~RXYN;a~SgPi0dH+jfQKJrt5f)t`KMJP%!ic^A; zl%h0cC`&nFC{G0{Qi;lr@3SgYr5e?#K}~8=n>y5`9`$KJLmJVTCN!lP&1pePTG5&| zw51*G=|D$1(U~rEr5oMp;n+p=q!+#ELtpyQp8*VH5Q7=QP=+y_5sYLMqZz|k#xb5) zmrZc_6J5Sr6S+T$$xLA?)0pnmoRL^}CbL`}W+(b{T(NVV<}#1@$ubLAm~8FSE((hH zqKgxwOMVC*&D_GR+{W$P!JXX2-Q2^y+{gVqz=J%*!#u*HJjUZZ!IM12 z(>%koJje6Az>B=Z%e=y?yvFOi!JE9r+q}cOyvO@|z=wRq$9%%4e8%T|!Iyl+*B7vF zh`xQxcYMze{K!xI%rE@PZ~V?5{K;SZ%~_C?PU)3F8I?(yl|@N;LM)mH<5pM*~g-?5<@Ig!Rr)|)js@BA2=dOR~+{iIo%rLa!8`jN(y=4q}L zYN=L%samUz+NzzB?xX0uwhvLigE|JLh;%opt?%TYue1Ny#nV(>)y*_J9*BJ1f@y*&-j=5-ILtJ{%cB0HT5 zyHZ>w+^%*x0~9wo!T~1+qP}nwr#sfZM*lbx=5N$x7*~$dCqh1%$)t^ zoZ0ux%&%S0;DRe|1S2>h2uUbH6Na#aBRmmsS1clth)fis5{>A@ASSVhO&sD9kN6}Y zA&E##5|WaPY)UG^8aR>B*o($%qyYGU+0^lbI}JB^%kvK~8d!n>^$tANeUj zK?+frA{3<<#T6?-NlH=LFjHNTYGo)(Im%Okid3R9Rj5ieJpYSTrv^2tWyn?A(AJ@@ zS@wELzrOM`F!PzOt|5&qK50x7i?OP0YU44FVB2qI(lvz-t?g_{pimC1~Q1j z3}Gn47|sYrGK$fRVJzbq&jcniiOEc1D$|(G3}!Nm+00=s^O(;97P5%NEMY0jSk4Mo zvWnHLVJ+)e&jvQKiOpW_xyE&FaFbgm$|~L4%5#U`m|MK)%zZ9kcEe&&l^_LXmZ=LbK1Rim-Z@%J8$!_izc_I)c+2>~JCIDvnA z{{Q~wkeNb22nYcoAOwVf5D)@FKnMr{As_^VfDjM@LO=)z0U;m+gn$qb0zyCt2mv7= z1cZPP5CTF#2nYcoAOwU!KnS=x{F~i?WD~6r5CTDofb;)-C>ex+5D1zC+%!RRU9u`6 LAOxIGz)kZDI(P_m literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/index2.bin b/crates/weavepy-vm/src/stdlib/ucd/index2.bin new file mode 100644 index 0000000000000000000000000000000000000000..1397dfdf9a699facaec18a4f38ffade245ba281b GIT binary patch literal 107008 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 C)A98H literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/index2_32.bin b/crates/weavepy-vm/src/stdlib/ucd/index2_32.bin new file mode 100644 index 0000000000000000000000000000000000000000..19926d37ff04ea16c5894a40f9e6a385be00ec0a GIT binary patch literal 66816 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 b_&>)QmDCfxZotaxjXRa^M8Ev~^Q`&8i literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/meta.rs b/crates/weavepy-vm/src/stdlib/ucd/meta.rs new file mode 100644 index 0000000..13d94b1 --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/ucd/meta.rs @@ -0,0 +1,51 @@ +// Generated by tools/gen_ucd_tables.py from CPython 3.13 +// (UCD 15.1.0). Do not edit. + +pub const SHIFT: u32 = 7; +pub const N_RECORDS: usize = 16659; +pub const CATEGORIES: &[&str] = &["Cc", "Zs", "Po", "Sc", "Ps", "Pe", "Sm", "Pd", "Nd", "Lu", "Sk", "Pc", "Ll", "So", "Lo", "Pi", "Cf", "No", "Pf", "Lt", "Lm", "Mn", "Cn", "Me", "Mc", "Nl", "Zl", "Zp", "Cs", "Co"]; +pub const BIDIRECTIONALS: &[&str] = &["BN", "S", "B", "WS", "ON", "ET", "ES", "CS", "EN", "L", "NSM", "", "R", "AN", "AL", "LRE", "RLE", "PDF", "LRO", "RLO", "LRI", "RLI", "FSI", "PDI"]; +pub const EASTASIANWIDTHS: &[&str] = &["N", "Na", "A", "W", "H", "F"]; +pub const DECOMP_PREFIXES: &[&str] = &["", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]; +/// Hex-suffixed algorithmic name ranges (prefix, first cp, last cp). +pub const ALGO_RANGES: &[(&str, u32, u32)] = &[ + ("CJK UNIFIED IDEOGRAPH-", 0x3400, 0x4DBF), + ("CJK UNIFIED IDEOGRAPH-", 0x4E00, 0x9FFF), + ("CJK COMPATIBILITY IDEOGRAPH-", 0xF900, 0xFA6D), + ("CJK COMPATIBILITY IDEOGRAPH-", 0xFA70, 0xFAD9), + ("KHITAN SMALL SCRIPT CHARACTER-", 0x18B00, 0x18CD5), + ("NUSHU CHARACTER-", 0x1B170, 0x1B2FB), + ("CJK UNIFIED IDEOGRAPH-", 0x20000, 0x2A6DF), + ("CJK UNIFIED IDEOGRAPH-", 0x2A700, 0x2B739), + ("CJK UNIFIED IDEOGRAPH-", 0x2B740, 0x2B81D), + ("CJK UNIFIED IDEOGRAPH-", 0x2B820, 0x2CEA1), + ("CJK UNIFIED IDEOGRAPH-", 0x2CEB0, 0x2EBE0), + ("CJK UNIFIED IDEOGRAPH-", 0x2EBF0, 0x2EE5D), + ("CJK COMPATIBILITY IDEOGRAPH-", 0x2F800, 0x2FA1D), + ("CJK UNIFIED IDEOGRAPH-", 0x30000, 0x3134A), + ("CJK UNIFIED IDEOGRAPH-", 0x31350, 0x323AF), +]; +/// HANGUL SYLLABLE ranges (first cp, last cp). +pub const HANGUL_RANGES: &[(u32, u32)] = &[ + (0xAC00, 0xD7A3), +]; +/// Hex-suffixed ranges `lookup()`/`\N` accept but `name()` does not generate. +pub const LOOKUP_ONLY_RANGES: &[(&str, u32, u32)] = &[ + ("TANGUT IDEOGRAPH-", 0x17000, 0x187F7), + ("TANGUT IDEOGRAPH-", 0x18D00, 0x18D08), +]; +// Ctype/case flag bits (case_records.bin u16). +pub const FLAG_ALPHA: u16 = 0x0001; +pub const FLAG_DECIMAL: u16 = 0x0002; +pub const FLAG_DIGIT: u16 = 0x0004; +pub const FLAG_NUMERIC: u16 = 0x0008; +pub const FLAG_SPACE: u16 = 0x0010; +pub const FLAG_LOWER: u16 = 0x0020; +pub const FLAG_UPPER: u16 = 0x0040; +pub const FLAG_TITLE: u16 = 0x0080; +pub const FLAG_CASED: u16 = 0x0100; +pub const FLAG_CASE_IGNORABLE: u16 = 0x0200; +pub const FLAG_ALNUM: u16 = 0x0400; +pub const FLAG_XID_START: u16 = 0x0800; +pub const FLAG_XID_CONTINUE: u16 = 0x1000; +pub const FLAG_PRINTABLE: u16 = 0x2000; diff --git a/crates/weavepy-vm/src/stdlib/ucd/mod.rs b/crates/weavepy-vm/src/stdlib/ucd/mod.rs new file mode 100644 index 0000000..8252aac --- /dev/null +++ b/crates/weavepy-vm/src/stdlib/ucd/mod.rs @@ -0,0 +1,677 @@ +//! Generated UCD 15.1.0 database — RFC 0050 WS4. +//! +//! Backing store for the `unicodedata` module: packed tables generated by +//! `tools/gen_ucd_tables.py` from host CPython 3.13 (whose database *is* +//! UCD 15.1.0), so every property answer — including the `ucd_3_2_0` +//! snapshot — is bit-identical to CPython's `Modules/unicodedata_db.h`. +//! +//! Layout notes live in the generator; in short: a two-level `splitbins` +//! index (`index1`/`index2`) maps a code point to one of ~16K unique +//! 12-byte property records, names are a sorted `(cp, len, bytes)` stream +//! plus algorithmic ranges (Hangul syllables + hex-suffixed ideographs), +//! and canonical composition pairs are probed with exclusions already +//! applied. + +use std::collections::HashMap; +use std::sync::OnceLock; + +// The generator emits every table `pub` with no knowledge of what this +// engine consumes (e.g. `HANGUL_RANGES` is folded into hardcoded Hangul +// arithmetic), hence the dead-code/unreachable-pub allowances. +#[allow(clippy::all, dead_code, unreachable_pub)] +mod meta { + include!("meta.rs"); +} + +pub use meta::{BIDIRECTIONALS, CATEGORIES, DECOMP_PREFIXES, EASTASIANWIDTHS}; + +static RECORDS: &[u8] = include_bytes!("records.bin"); +static INDEX1: &[u8] = include_bytes!("index1.bin"); +static INDEX2: &[u8] = include_bytes!("index2.bin"); +static INDEX1_32: &[u8] = include_bytes!("index1_32.bin"); +static INDEX2_32: &[u8] = include_bytes!("index2_32.bin"); +static NUMERIC: &[u8] = include_bytes!("numeric.bin"); +static DECOMP: &[u8] = include_bytes!("decomp.bin"); +static NAMES: &[u8] = include_bytes!("names.bin"); +static NAMES32: &[u8] = include_bytes!("names32.bin"); +static COMP: &[u8] = include_bytes!("comp.bin"); + +const RECORD_SIZE: usize = 12; +const SHIFT: u32 = meta::SHIFT; + +fn u16le(b: &[u8], off: usize) -> u16 { + u16::from_le_bytes([b[off], b[off + 1]]) +} + +fn u24le(b: &[u8], off: usize) -> u32 { + u32::from(b[off]) | (u32::from(b[off + 1]) << 8) | (u32::from(b[off + 2]) << 16) +} + +/// A resolved per-code-point property record. +#[derive(Clone, Copy, Debug)] +pub struct Record { + rec: &'static [u8], +} + +fn record_bytes(cp: u32, index1: &'static [u8], index2: &'static [u8]) -> &'static [u8] { + debug_assert!(cp < 0x0011_0000); + let block = u16le(index1, ((cp >> SHIFT) as usize) * 2) as usize; + let idx = (block << SHIFT) | (cp as usize & ((1 << SHIFT) - 1)); + let rid = u16le(index2, idx * 2) as usize; + &RECORDS[rid * RECORD_SIZE..(rid + 1) * RECORD_SIZE] +} + +/// Property record for `cp`; `old` selects the UCD 3.2.0 snapshot. +pub fn record(cp: u32, old: bool) -> Record { + let rec = if old { + record_bytes(cp, INDEX1_32, INDEX2_32) + } else { + record_bytes(cp, INDEX1, INDEX2) + }; + Record { rec } +} + +impl Record { + pub fn category(self) -> &'static str { + CATEGORIES[self.rec[0] as usize] + } + + pub fn bidirectional(self) -> &'static str { + BIDIRECTIONALS[self.rec[1] as usize] + } + + pub fn combining(self) -> u8 { + self.rec[2] + } + + pub fn mirrored(self) -> bool { + self.rec[3] != 0 + } + + pub fn east_asian_width(self) -> &'static str { + EASTASIANWIDTHS[self.rec[4] as usize] + } + + pub fn decimal(self) -> Option { + match self.rec[5] { + 0xFF => None, + d => Some(d), + } + } + + pub fn digit(self) -> Option { + match self.rec[6] { + 0xFF => None, + d => Some(d), + } + } + + pub fn numeric(self) -> Option { + match u16le(self.rec, 7) { + 0xFFFF => None, + i => { + let off = (i as usize) * 8; + Some(f64::from_le_bytes( + NUMERIC[off..off + 8].try_into().expect("8-byte f64"), + )) + } + } + } + + /// Raw decomposition: `(tag prefix, mapped code points)`, or `None`. + pub fn decomposition(self) -> Option<(&'static str, DecompCps)> { + match u24le(self.rec, 9) { + 0xFF_FFFF => None, + off => { + let off = off as usize; + let prefix = DECOMP_PREFIXES[DECOMP[off] as usize]; + let len = DECOMP[off + 1] as usize; + Some(( + prefix, + DecompCps { + off: off + 2, + len, + i: 0, + }, + )) + } + } + } + + /// CPython's `unicodedata.decomposition()` text form, e.g. + /// `" 0020 0301"` — empty string when there is none. + pub fn decomposition_string(self) -> String { + let Some((prefix, cps)) = self.decomposition() else { + return String::new(); + }; + let mut out = String::new(); + if !prefix.is_empty() { + out.push_str(prefix); + } + for cp in cps { + if !out.is_empty() { + out.push(' '); + } + out.push_str(&format!("{cp:04X}")); + } + out + } +} + +/// Iterator over a record's decomposition code points. +#[derive(Clone, Debug)] +pub struct DecompCps { + off: usize, + len: usize, + i: usize, +} + +impl Iterator for DecompCps { + type Item = u32; + + fn next(&mut self) -> Option { + if self.i >= self.len { + return None; + } + let cp = u24le(DECOMP, self.off + self.i * 3); + self.i += 1; + Some(cp) + } +} + +/// Whether `cp` was assigned (had a name) in UCD 3.2.0. +pub fn assigned_in_32(cp: u32) -> bool { + NAMES32[(cp >> 3) as usize] & (1 << (cp & 7)) != 0 +} + +// --------------------------------------------------------------------------- +// names +// --------------------------------------------------------------------------- + +// Hangul syllable name components (Jamo.txt short names). +const HANGUL_L: [&str; 19] = [ + "G", "GG", "N", "D", "DD", "R", "M", "B", "BB", "S", "SS", "", "J", "JJ", "C", "K", "T", "P", + "H", +]; +const HANGUL_V: [&str; 21] = [ + "A", "AE", "YA", "YAE", "EO", "E", "YEO", "YE", "O", "WA", "WAE", "OE", "YO", "U", "WEO", "WE", + "WI", "YU", "EU", "YI", "I", +]; +const HANGUL_T: [&str; 28] = [ + "", "G", "GG", "GS", "N", "NJ", "NH", "D", "L", "LG", "LM", "LB", "LS", "LT", "LP", "LH", "M", + "B", "BS", "S", "SS", "NG", "J", "C", "K", "T", "P", "H", +]; + +const S_BASE: u32 = 0xAC00; +const L_BASE: u32 = 0x1100; +const V_BASE: u32 = 0x1161; +const T_BASE: u32 = 0x11A7; +const V_COUNT: u32 = 21; +const T_COUNT: u32 = 28; +const S_COUNT: u32 = 19 * V_COUNT * T_COUNT; + +fn hangul_name(cp: u32) -> Option { + if !(S_BASE..S_BASE + S_COUNT).contains(&cp) { + return None; + } + let s = cp - S_BASE; + let l = (s / (V_COUNT * T_COUNT)) as usize; + let v = ((s % (V_COUNT * T_COUNT)) / T_COUNT) as usize; + let t = (s % T_COUNT) as usize; + Some(format!( + "HANGUL SYLLABLE {}{}{}", + HANGUL_L[l], HANGUL_V[v], HANGUL_T[t] + )) +} + +fn hangul_lookup(rest: &str) -> Option { + // Greedy longest-match on L, then V, then T (CPython _cpname parse). + let (l, rest) = longest_prefix(rest, &HANGUL_L)?; + let (v, rest) = longest_prefix(rest, &HANGUL_V)?; + let (t, rest) = longest_prefix(rest, &HANGUL_T)?; + if !rest.is_empty() { + return None; + } + Some(S_BASE + ((l as u32) * V_COUNT + v as u32) * T_COUNT + t as u32) +} + +fn longest_prefix<'a>(s: &'a str, table: &[&str]) -> Option<(usize, &'a str)> { + let mut best: Option<(usize, &'a str)> = None; + for (i, cand) in table.iter().enumerate() { + if let Some(rest) = s.strip_prefix(cand) { + match best { + Some((bi, _)) if table[bi].len() >= cand.len() => {} + _ => best = Some((i, rest)), + } + } + } + best +} + +struct NameIndex { + /// Sorted `(cp, byte-range in NAMES)` for the stored (non-algorithmic) + /// names. + by_cp: Vec<(u32, u32, u8)>, // (cp, offset of name bytes, len) + /// Normalized name -> cp (spaces/hyphens squeezed per CPython's loose + /// matching is NOT applied — CPython lookup is exact-with-aliases; we + /// index the exact uppercase names). + by_name: HashMap<&'static str, u32>, +} + +fn name_index() -> &'static NameIndex { + static IDX: OnceLock = OnceLock::new(); + IDX.get_or_init(|| { + let mut by_cp = Vec::with_capacity(40_000); + let mut by_name = HashMap::with_capacity(40_000); + let mut off = 0usize; + while off < NAMES.len() { + let cp = u24le(NAMES, off); + let len = NAMES[off + 3] as usize; + let start = off + 4; + let name = std::str::from_utf8(&NAMES[start..start + len]).expect("ascii name"); + by_cp.push((cp, start as u32, len as u8)); + by_name.insert(name, cp); + off = start + len; + } + NameIndex { by_cp, by_name } + }) +} + +/// UCD name for `cp` (algorithmic ranges included); `None` when unassigned +/// or nameless (controls). +pub fn name(cp: u32) -> Option { + if let Some(n) = hangul_name(cp) { + return Some(n); + } + for &(prefix, lo, hi) in meta::ALGO_RANGES { + if (lo..=hi).contains(&cp) { + return Some(format!("{prefix}{cp:04X}")); + } + } + let idx = name_index(); + match idx.by_cp.binary_search_by_key(&cp, |&(c, _, _)| c) { + Ok(i) => { + let (_, start, len) = idx.by_cp[i]; + Some( + std::str::from_utf8(&NAMES[start as usize..start as usize + len as usize]) + .expect("ascii name") + .to_owned(), + ) + } + Err(_) => None, + } +} + +/// Reverse lookup: exact (case-insensitive) UCD name -> code point, +/// canonical names only (stored + algorithmic, including the lookup-only +/// Tangut ranges). NameAliases entries live in [`lookup_with_aliases`] — +/// the `ucd_3_2_0` snapshot must reject them. +pub fn lookup(name_arg: &str) -> Option { + let upper = name_arg.to_ascii_uppercase(); + if let Some(rest) = upper.strip_prefix("HANGUL SYLLABLE ") { + return hangul_lookup(rest); + } + for &(prefix, lo, hi) in meta::ALGO_RANGES.iter().chain(meta::LOOKUP_ONLY_RANGES) { + if let Some(hex) = upper.strip_prefix(prefix) { + if let Ok(cp) = u32::from_str_radix(hex, 16) { + // The name must round-trip exactly (no leading zeros beyond + // the canonical %04X form) and land in the range. + if format!("{cp:04X}") == hex && (lo..=hi).contains(&cp) { + return Some(cp); + } + } + } + } + name_index().by_name.get(upper.as_str()).copied() +} + +/// [`lookup`] plus NameAliases.txt entries — what CPython's `getcode` +/// resolves for the *current* database (`unicodedata.lookup`, `\N{...}`). +pub fn lookup_with_aliases(name_arg: &str) -> Option { + lookup(name_arg).or_else(|| { + alias_index() + .get(name_arg.to_ascii_uppercase().as_str()) + .copied() + }) +} + +static ALIASES: &[u8] = include_bytes!("aliases.bin"); +static SEQS: &[u8] = include_bytes!("seqs.bin"); + +fn alias_index() -> &'static HashMap<&'static str, u32> { + static IDX: OnceLock> = OnceLock::new(); + IDX.get_or_init(|| { + let mut m = HashMap::with_capacity(512); + let mut off = 0usize; + while off < ALIASES.len() { + let cp = u24le(ALIASES, off); + let len = ALIASES[off + 3] as usize; + let name = std::str::from_utf8(&ALIASES[off + 4..off + 4 + len]).expect("ascii alias"); + m.insert(name, cp); + off += 4 + len; + } + m + }) +} + +fn seq_index() -> &'static HashMap<&'static str, Vec> { + static IDX: OnceLock>> = OnceLock::new(); + IDX.get_or_init(|| { + let mut m = HashMap::with_capacity(512); + let mut off = 0usize; + while off < SEQS.len() { + let n = SEQS[off] as usize; + let cps: Vec = (0..n).map(|i| u24le(SEQS, off + 1 + i * 3)).collect(); + off += 1 + n * 3; + let len = SEQS[off] as usize; + let name = + std::str::from_utf8(&SEQS[off + 1..off + 1 + len]).expect("ascii sequence name"); + m.insert(name, cps); + off += 1 + len; + } + m + }) +} + +/// NamedSequences.txt lookup (`unicodedata.lookup` only — `\N{...}` and +/// the `ucd_3_2_0` snapshot both reject named sequences). +pub fn lookup_named_sequence(name_arg: &str) -> Option<&'static [u32]> { + seq_index() + .get(name_arg.to_ascii_uppercase().as_str()) + .map(Vec::as_slice) +} + +// --------------------------------------------------------------------------- +// normalization +// --------------------------------------------------------------------------- + +fn comp_index() -> &'static HashMap<(u32, u32), u32> { + static IDX: OnceLock> = OnceLock::new(); + IDX.get_or_init(|| { + let mut m = HashMap::with_capacity(COMP.len() / 9); + let mut off = 0; + while off < COMP.len() { + let a = u24le(COMP, off); + let b = u24le(COMP, off + 3); + let c = u24le(COMP, off + 6); + m.insert((a, b), c); + off += 9; + } + m + }) +} + +fn hangul_decompose(cp: u32, out: &mut Vec) -> bool { + if !(S_BASE..S_BASE + S_COUNT).contains(&cp) { + return false; + } + let s = cp - S_BASE; + out.push(L_BASE + s / (V_COUNT * T_COUNT)); + out.push(V_BASE + (s % (V_COUNT * T_COUNT)) / T_COUNT); + let t = s % T_COUNT; + if t != 0 { + out.push(T_BASE + t); + } + true +} + +/// `unicodedata.c` `normalization_3_2_0`: NormalizationCorrections.txt — +/// decompositions that were *corrected* after 3.2.0, so the snapshot's +/// normalizer must use the old target (the property record keeps the +/// current text; only normalization consults this). +const NORM_CORRECTIONS_32: &[(u32, u32)] = &[ + (0xF951, 0x964B), + (0x2F868, 0x2136A), + (0x2F874, 0x5F33), + (0x2F91F, 0x43AB), + (0x2F95F, 0x7AAE), + (0x2F9BF, 0x4D57), +]; + +fn decompose_cp(cp: u32, compat: bool, old: bool, out: &mut Vec) { + if old { + if let Ok(i) = NORM_CORRECTIONS_32.binary_search_by_key(&cp, |&(c, _)| c) { + decompose_cp(NORM_CORRECTIONS_32[i].1, compat, old, out); + return; + } + } + if hangul_decompose(cp, out) { + return; + } + // Lone surrogates and unassigned code points are ccc=0 starters with no + // decomposition: they pass through. + if cp < 0x0011_0000 { + if let Some((prefix, cps)) = record(cp, old).decomposition() { + if prefix.is_empty() || compat { + for c in cps { + decompose_cp(c, compat, old, out); + } + return; + } + } + } + out.push(cp); +} + +fn combining_of(cp: u32, old: bool) -> u8 { + if cp < 0x0011_0000 { + record(cp, old).combining() + } else { + 0 + } +} + +/// Canonical-order a decomposed sequence (stable exchange on adjacent +/// out-of-order combining classes). +fn canonical_order(cps: &mut [u32], old: bool) { + let mut i = 1; + while i < cps.len() { + let cc = combining_of(cps[i], old); + if cc != 0 && combining_of(cps[i - 1], old) > cc { + cps.swap(i - 1, i); + if i > 1 { + i -= 1; + continue; + } + } + i += 1; + } +} + +fn hangul_compose(a: u32, b: u32) -> Option { + // L + V + if (L_BASE..L_BASE + 19).contains(&a) && (V_BASE..V_BASE + V_COUNT).contains(&b) { + return Some(S_BASE + ((a - L_BASE) * V_COUNT + (b - V_BASE)) * T_COUNT); + } + // LV + T + if (S_BASE..S_BASE + S_COUNT).contains(&a) + && (a - S_BASE).is_multiple_of(T_COUNT) + && (T_BASE + 1..T_BASE + T_COUNT).contains(&b) + { + return Some(a + (b - T_BASE)); + } + None +} + +fn compose(cps: &mut Vec, old: bool) { + if cps.is_empty() { + return; + } + let pairs = comp_index(); + let mut out: Vec = Vec::with_capacity(cps.len()); + let mut i = 0; + while i < cps.len() { + let starter = cps[i]; + if combining_of(starter, old) != 0 { + out.push(starter); + i += 1; + continue; + } + // Compose the run following this starter. + let mut composed = starter; + let mut pending: Vec = Vec::new(); + let mut last_cc: i32 = -1; + let mut j = i + 1; + while j < cps.len() { + let c = cps[j]; + let cc = i32::from(combining_of(c, old)); + if cc == 0 { + // Next starter: try starter-pair composition (only when no + // combining marks are pending after the current composite). + if pending.is_empty() && last_cc == -1 { + if let Some(newc) = + hangul_compose(composed, c).or_else(|| pairs.get(&(composed, c)).copied()) + { + composed = newc; + j += 1; + continue; + } + } + break; + } + if cc > last_cc { + if let Some(newc) = + hangul_compose(composed, c).or_else(|| pairs.get(&(composed, c)).copied()) + { + composed = newc; + j += 1; + continue; + } + } + pending.push(c); + last_cc = cc; + j += 1; + } + out.push(composed); + out.extend_from_slice(&pending); + i = j; + } + *cps = out; +} + +/// Normalize a code-point sequence. `form` must be one of +/// NFC/NFD/NFKC/NFKD (validated by the caller). +pub fn normalize(form: &str, cps: &[u32], old: bool) -> Vec { + let (compat, compose_after) = match form { + "NFC" => (false, true), + "NFD" => (false, false), + "NFKC" => (true, true), + "NFKD" => (true, false), + _ => unreachable!("caller validates the form"), + }; + let mut out = Vec::with_capacity(cps.len() + 8); + for &cp in cps { + decompose_cp(cp, compat, old, &mut out); + } + canonical_order(&mut out, old); + if compose_after { + compose(&mut out, old); + } + out +} + +// --------------------------------------------------------------------------- +// ctype flags + full case mappings (CPython's unicodectype.c equivalent) +// --------------------------------------------------------------------------- + +static CASE_RECORDS: &[u8] = include_bytes!("case_records.bin"); +static CASE_INDEX1: &[u8] = include_bytes!("case_index1.bin"); +static CASE_INDEX2: &[u8] = include_bytes!("case_index2.bin"); +static CASE_POOL: &[u8] = include_bytes!("case_pool.bin"); + +/// 14 bytes: u16 flags, then u24 lower/upper/title/casefold refs. +const CASE_RECORD_SIZE: usize = 14; +/// Ref sentinel: the mapping is the identity. +const CASE_IDENTITY: u32 = 0xFF_FFFF; + +pub use meta::{ + FLAG_ALNUM, FLAG_ALPHA, FLAG_CASED, FLAG_CASE_IGNORABLE, FLAG_DECIMAL, FLAG_DIGIT, FLAG_LOWER, + FLAG_NUMERIC, FLAG_PRINTABLE, FLAG_SPACE, FLAG_TITLE, FLAG_UPPER, FLAG_XID_CONTINUE, + FLAG_XID_START, +}; + +fn case_record(cp: u32) -> &'static [u8] { + debug_assert!(cp < 0x0011_0000); + let block = u16le(CASE_INDEX1, ((cp >> SHIFT) as usize) * 2) as usize; + let idx = (block << SHIFT) | (cp as usize & ((1 << SHIFT) - 1)); + let rid = u16le(CASE_INDEX2, idx * 2) as usize; + &CASE_RECORDS[rid * CASE_RECORD_SIZE..(rid + 1) * CASE_RECORD_SIZE] +} + +/// CPython-parity ctype predicate flags for `cp` (`FLAG_*`). +pub fn case_flags(cp: u32) -> u16 { + u16le(case_record(cp), 0) +} + +/// `_PyUnicode_IsCased` (DerivedCoreProperties `Cased`). +pub fn is_cased(cp: u32) -> bool { + case_flags(cp) & FLAG_CASED != 0 +} + +/// `_PyUnicode_IsCaseIgnorable` (DerivedCoreProperties `Case_Ignorable`). +pub fn is_case_ignorable(cp: u32) -> bool { + case_flags(cp) & FLAG_CASE_IGNORABLE != 0 +} + +/// A full case mapping: 1..=3 code points (SpecialCasing expansions such +/// as `ß` -> "SS" included). +#[derive(Clone, Copy, Debug)] +pub struct CaseMap { + buf: [u32; 3], + len: u8, +} + +impl CaseMap { + pub fn single(cp: u32) -> Self { + Self { + buf: [cp, 0, 0], + len: 1, + } + } + + pub fn as_slice(&self) -> &[u32] { + &self.buf[..self.len as usize] + } +} + +fn case_map(cp: u32, field: usize) -> CaseMap { + let r = u24le(case_record(cp), 2 + field * 3); + if r == CASE_IDENTITY { + return CaseMap::single(cp); + } + if r < 0x0011_0000 { + return CaseMap::single(r); + } + let off = (r - 0x0011_0000) as usize; + let len = CASE_POOL[off] as usize; + debug_assert!((2..=3).contains(&len)); + let mut buf = [0u32; 3]; + for (i, slot) in buf.iter_mut().take(len).enumerate() { + *slot = u24le(CASE_POOL, off + 1 + i * 3); + } + CaseMap { + buf, + len: len as u8, + } +} + +/// `_PyUnicode_ToLowercaseFull` (context-free; `str.lower()` adds the +/// Final_Sigma rule on top of this). +pub fn to_lower_full(cp: u32) -> CaseMap { + case_map(cp, 0) +} + +/// `_PyUnicode_ToUppercaseFull`. +pub fn to_upper_full(cp: u32) -> CaseMap { + case_map(cp, 1) +} + +/// `_PyUnicode_ToTitleFull`. +pub fn to_title_full(cp: u32) -> CaseMap { + case_map(cp, 2) +} + +/// `_PyUnicode_ToFoldedFull` (`str.casefold()`, no sigma context). +pub fn to_fold_full(cp: u32) -> CaseMap { + case_map(cp, 3) +} diff --git a/crates/weavepy-vm/src/stdlib/ucd/names.bin b/crates/weavepy-vm/src/stdlib/ucd/names.bin new file mode 100644 index 0000000000000000000000000000000000000000..c696c2190691ef0a4e0cfcb60bf9581f95932ec2 GIT binary patch literal 974590 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≷k{5$30_VE9tA~mo} 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

{nW9}{i6L;?H4c?&Q%tW+ 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 literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/names32.bin b/crates/weavepy-vm/src/stdlib/ucd/names32.bin new file mode 100644 index 0000000000000000000000000000000000000000..756a69cfc20a005403a0ff28b3c9e8ffa104c0e6 GIT binary patch literal 139264 zcmeI)J!@oD7y#fK0|pBjON)i6tX;4QOS~3>|H4?<`U@;>Kp}S9*`~K}_a9_skW`Xl zK?`NaLfFD=b|IiE`8dAsy)$!fFov)uOV&Jx?78Rr~s;WvKn#d0Gea$(k z<1#wktDZHE(fV$gzWw2|pGrB*!lsP|^_ia)FB0`~DY>GPtU1ZJynd4X569VaWn5Kn zRbNH*a6Wm!Io^qaj$wu>Fd!gBBP(A6&_ zTB2(m%@;nnjt1%2TU}>9;&1Yj>3sO7W%p?*zcg*OjW#z%M+Zq21_=;_anH=^AD7Yd zHW`YS6JnkWIanqKa}CFDhMBX|yThkY-9L-l;j2fnrS=(r@1v$`IL?B0mvJv#dFWR0 z^5WRgVZW*K9<4gn7Xm%vjA=H=uX!E!we3CKy(nk@wl_t-E-5BJ;Nk*#?{?wheY7M%fB*pk1PBngsRI4G$JtMC*9l_WEhc_IzY*a&(OU}v z0tEi=0_{P`jri_jlLQF-7l8}C7S^*?voq%5d`HQpHB^x=WD~GkW-asX8L#P zar~R1ourI2k*7S($)BYeO|xbgwgx9R!}8|n=;&6{RPPVhdKKxIv}sSF&alb(a#3{~ zUB&FiBtU=w0RjXF5FkK+009C72oNAZfB*pk1PI(bfjoNo_fWUzGx>?bGs5uC$X*z( zA9p%WPCtEAet$B{Z9kr7#pmls@j1y0hQ)`P&TBvEDqncvIuam2;1w4*?0(G1a>$fnV+{+@80EBOn&&-EGa-tg!a(#wx^NKm=OTC2kO>e5iDjB2Re#y9J>Fm<@k@?!*f37IUBLDyZ literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/ucd/records.bin b/crates/weavepy-vm/src/stdlib/ucd/records.bin new file mode 100644 index 0000000000000000000000000000000000000000..c6114afc0bae0388303b4393309e72238b42dcdf GIT binary patch literal 199908 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 literal 0 HcmV?d00001 diff --git a/crates/weavepy-vm/src/stdlib/unicode_decomp_data.rs b/crates/weavepy-vm/src/stdlib/unicode_decomp_data.rs deleted file mode 100644 index 63f5cb1..0000000 --- a/crates/weavepy-vm/src/stdlib/unicode_decomp_data.rs +++ /dev/null @@ -1,17039 +0,0 @@ -// @generated from CPython 3.13 `unicodedata.decomposition` — DO NOT EDIT. -// -// Maps a code point to its decomposition string in CPython's -// `unicodedata.decomposition()` format: a space-separated list of -// uppercase hex code points, with compatibility decompositions carrying a -// leading `` (e.g. ``, ``, ``). Canonical -// decompositions (including all Hangul syllables) have no tag. Sorted by -// code point for binary search. Regenerate via `tmp/gen_decomp.py`. -pub(crate) static DECOMPOSITIONS: &[(u32, &str)] = &[ - (0x00A0, " 0020"), - (0x00A8, " 0020 0308"), - (0x00AA, " 0061"), - (0x00AF, " 0020 0304"), - (0x00B2, " 0032"), - (0x00B3, " 0033"), - (0x00B4, " 0020 0301"), - (0x00B5, " 03BC"), - (0x00B8, " 0020 0327"), - (0x00B9, " 0031"), - (0x00BA, " 006F"), - (0x00BC, " 0031 2044 0034"), - (0x00BD, " 0031 2044 0032"), - (0x00BE, " 0033 2044 0034"), - (0x00C0, "0041 0300"), - (0x00C1, "0041 0301"), - (0x00C2, "0041 0302"), - (0x00C3, "0041 0303"), - (0x00C4, "0041 0308"), - (0x00C5, "0041 030A"), - (0x00C7, "0043 0327"), - (0x00C8, "0045 0300"), - (0x00C9, "0045 0301"), - (0x00CA, "0045 0302"), - (0x00CB, "0045 0308"), - (0x00CC, "0049 0300"), - (0x00CD, "0049 0301"), - (0x00CE, "0049 0302"), - (0x00CF, "0049 0308"), - (0x00D1, "004E 0303"), - (0x00D2, "004F 0300"), - (0x00D3, "004F 0301"), - (0x00D4, "004F 0302"), - (0x00D5, "004F 0303"), - (0x00D6, "004F 0308"), - (0x00D9, "0055 0300"), - (0x00DA, "0055 0301"), - (0x00DB, "0055 0302"), - (0x00DC, "0055 0308"), - (0x00DD, "0059 0301"), - (0x00E0, "0061 0300"), - (0x00E1, "0061 0301"), - (0x00E2, "0061 0302"), - (0x00E3, "0061 0303"), - (0x00E4, "0061 0308"), - (0x00E5, "0061 030A"), - (0x00E7, "0063 0327"), - (0x00E8, "0065 0300"), - (0x00E9, "0065 0301"), - (0x00EA, "0065 0302"), - (0x00EB, "0065 0308"), - (0x00EC, "0069 0300"), - (0x00ED, "0069 0301"), - (0x00EE, "0069 0302"), - (0x00EF, "0069 0308"), - (0x00F1, "006E 0303"), - (0x00F2, "006F 0300"), - (0x00F3, "006F 0301"), - (0x00F4, "006F 0302"), - (0x00F5, "006F 0303"), - (0x00F6, "006F 0308"), - (0x00F9, "0075 0300"), - (0x00FA, "0075 0301"), - (0x00FB, "0075 0302"), - (0x00FC, "0075 0308"), - (0x00FD, "0079 0301"), - (0x00FF, "0079 0308"), - (0x0100, "0041 0304"), - (0x0101, "0061 0304"), - (0x0102, "0041 0306"), - (0x0103, "0061 0306"), - (0x0104, "0041 0328"), - (0x0105, "0061 0328"), - (0x0106, "0043 0301"), - (0x0107, "0063 0301"), - (0x0108, "0043 0302"), - (0x0109, "0063 0302"), - (0x010A, "0043 0307"), - (0x010B, "0063 0307"), - (0x010C, "0043 030C"), - (0x010D, "0063 030C"), - (0x010E, "0044 030C"), - (0x010F, "0064 030C"), - (0x0112, "0045 0304"), - (0x0113, "0065 0304"), - (0x0114, "0045 0306"), - (0x0115, "0065 0306"), - (0x0116, "0045 0307"), - (0x0117, "0065 0307"), - (0x0118, "0045 0328"), - (0x0119, "0065 0328"), - (0x011A, "0045 030C"), - (0x011B, "0065 030C"), - (0x011C, "0047 0302"), - (0x011D, "0067 0302"), - (0x011E, "0047 0306"), - (0x011F, "0067 0306"), - (0x0120, "0047 0307"), - (0x0121, "0067 0307"), - (0x0122, "0047 0327"), - (0x0123, "0067 0327"), - (0x0124, "0048 0302"), - (0x0125, "0068 0302"), - (0x0128, "0049 0303"), - (0x0129, "0069 0303"), - (0x012A, "0049 0304"), - (0x012B, "0069 0304"), - (0x012C, "0049 0306"), - (0x012D, "0069 0306"), - (0x012E, "0049 0328"), - (0x012F, "0069 0328"), - (0x0130, "0049 0307"), - (0x0132, " 0049 004A"), - (0x0133, " 0069 006A"), - (0x0134, "004A 0302"), - (0x0135, "006A 0302"), - (0x0136, "004B 0327"), - (0x0137, "006B 0327"), - (0x0139, "004C 0301"), - (0x013A, "006C 0301"), - (0x013B, "004C 0327"), - (0x013C, "006C 0327"), - (0x013D, "004C 030C"), - (0x013E, "006C 030C"), - (0x013F, " 004C 00B7"), - (0x0140, " 006C 00B7"), - (0x0143, "004E 0301"), - (0x0144, "006E 0301"), - (0x0145, "004E 0327"), - (0x0146, "006E 0327"), - (0x0147, "004E 030C"), - (0x0148, "006E 030C"), - (0x0149, " 02BC 006E"), - (0x014C, "004F 0304"), - (0x014D, "006F 0304"), - (0x014E, "004F 0306"), - (0x014F, "006F 0306"), - (0x0150, "004F 030B"), - (0x0151, "006F 030B"), - (0x0154, "0052 0301"), - (0x0155, "0072 0301"), - (0x0156, "0052 0327"), - (0x0157, "0072 0327"), - (0x0158, "0052 030C"), - (0x0159, "0072 030C"), - (0x015A, "0053 0301"), - (0x015B, "0073 0301"), - (0x015C, "0053 0302"), - (0x015D, "0073 0302"), - (0x015E, "0053 0327"), - (0x015F, "0073 0327"), - (0x0160, "0053 030C"), - (0x0161, "0073 030C"), - (0x0162, "0054 0327"), - (0x0163, "0074 0327"), - (0x0164, "0054 030C"), - (0x0165, "0074 030C"), - (0x0168, "0055 0303"), - (0x0169, "0075 0303"), - (0x016A, "0055 0304"), - (0x016B, "0075 0304"), - (0x016C, "0055 0306"), - (0x016D, "0075 0306"), - (0x016E, "0055 030A"), - (0x016F, "0075 030A"), - (0x0170, "0055 030B"), - (0x0171, "0075 030B"), - (0x0172, "0055 0328"), - (0x0173, "0075 0328"), - (0x0174, "0057 0302"), - (0x0175, "0077 0302"), - (0x0176, "0059 0302"), - (0x0177, "0079 0302"), - (0x0178, "0059 0308"), - (0x0179, "005A 0301"), - (0x017A, "007A 0301"), - (0x017B, "005A 0307"), - (0x017C, "007A 0307"), - (0x017D, "005A 030C"), - (0x017E, "007A 030C"), - (0x017F, " 0073"), - (0x01A0, "004F 031B"), - (0x01A1, "006F 031B"), - (0x01AF, "0055 031B"), - (0x01B0, "0075 031B"), - (0x01C4, " 0044 017D"), - (0x01C5, " 0044 017E"), - (0x01C6, " 0064 017E"), - (0x01C7, " 004C 004A"), - (0x01C8, " 004C 006A"), - (0x01C9, " 006C 006A"), - (0x01CA, " 004E 004A"), - (0x01CB, " 004E 006A"), - (0x01CC, " 006E 006A"), - (0x01CD, "0041 030C"), - (0x01CE, "0061 030C"), - (0x01CF, "0049 030C"), - (0x01D0, "0069 030C"), - (0x01D1, "004F 030C"), - (0x01D2, "006F 030C"), - (0x01D3, "0055 030C"), - (0x01D4, "0075 030C"), - (0x01D5, "00DC 0304"), - (0x01D6, "00FC 0304"), - (0x01D7, "00DC 0301"), - (0x01D8, "00FC 0301"), - (0x01D9, "00DC 030C"), - (0x01DA, "00FC 030C"), - (0x01DB, "00DC 0300"), - (0x01DC, "00FC 0300"), - (0x01DE, "00C4 0304"), - (0x01DF, "00E4 0304"), - (0x01E0, "0226 0304"), - (0x01E1, "0227 0304"), - (0x01E2, "00C6 0304"), - (0x01E3, "00E6 0304"), - (0x01E6, "0047 030C"), - (0x01E7, "0067 030C"), - (0x01E8, "004B 030C"), - (0x01E9, "006B 030C"), - (0x01EA, "004F 0328"), - (0x01EB, "006F 0328"), - (0x01EC, "01EA 0304"), - (0x01ED, "01EB 0304"), - (0x01EE, "01B7 030C"), - (0x01EF, "0292 030C"), - (0x01F0, "006A 030C"), - (0x01F1, " 0044 005A"), - (0x01F2, " 0044 007A"), - (0x01F3, " 0064 007A"), - (0x01F4, "0047 0301"), - (0x01F5, "0067 0301"), - (0x01F8, "004E 0300"), - (0x01F9, "006E 0300"), - (0x01FA, "00C5 0301"), - (0x01FB, "00E5 0301"), - (0x01FC, "00C6 0301"), - (0x01FD, "00E6 0301"), - (0x01FE, "00D8 0301"), - (0x01FF, "00F8 0301"), - (0x0200, "0041 030F"), - (0x0201, "0061 030F"), - (0x0202, "0041 0311"), - (0x0203, "0061 0311"), - (0x0204, "0045 030F"), - (0x0205, "0065 030F"), - (0x0206, "0045 0311"), - (0x0207, "0065 0311"), - (0x0208, "0049 030F"), - (0x0209, "0069 030F"), - (0x020A, "0049 0311"), - (0x020B, "0069 0311"), - (0x020C, "004F 030F"), - (0x020D, "006F 030F"), - (0x020E, "004F 0311"), - (0x020F, "006F 0311"), - (0x0210, "0052 030F"), - (0x0211, "0072 030F"), - (0x0212, "0052 0311"), - (0x0213, "0072 0311"), - (0x0214, "0055 030F"), - (0x0215, "0075 030F"), - (0x0216, "0055 0311"), - (0x0217, "0075 0311"), - (0x0218, "0053 0326"), - (0x0219, "0073 0326"), - (0x021A, "0054 0326"), - (0x021B, "0074 0326"), - (0x021E, "0048 030C"), - (0x021F, "0068 030C"), - (0x0226, "0041 0307"), - (0x0227, "0061 0307"), - (0x0228, "0045 0327"), - (0x0229, "0065 0327"), - (0x022A, "00D6 0304"), - (0x022B, "00F6 0304"), - (0x022C, "00D5 0304"), - (0x022D, "00F5 0304"), - (0x022E, "004F 0307"), - (0x022F, "006F 0307"), - (0x0230, "022E 0304"), - (0x0231, "022F 0304"), - (0x0232, "0059 0304"), - (0x0233, "0079 0304"), - (0x02B0, " 0068"), - (0x02B1, " 0266"), - (0x02B2, " 006A"), - (0x02B3, " 0072"), - (0x02B4, " 0279"), - (0x02B5, " 027B"), - (0x02B6, " 0281"), - (0x02B7, " 0077"), - (0x02B8, " 0079"), - (0x02D8, " 0020 0306"), - (0x02D9, " 0020 0307"), - (0x02DA, " 0020 030A"), - (0x02DB, " 0020 0328"), - (0x02DC, " 0020 0303"), - (0x02DD, " 0020 030B"), - (0x02E0, " 0263"), - (0x02E1, " 006C"), - (0x02E2, " 0073"), - (0x02E3, " 0078"), - (0x02E4, " 0295"), - (0x0340, "0300"), - (0x0341, "0301"), - (0x0343, "0313"), - (0x0344, "0308 0301"), - (0x0374, "02B9"), - (0x037A, " 0020 0345"), - (0x037E, "003B"), - (0x0384, " 0020 0301"), - (0x0385, "00A8 0301"), - (0x0386, "0391 0301"), - (0x0387, "00B7"), - (0x0388, "0395 0301"), - (0x0389, "0397 0301"), - (0x038A, "0399 0301"), - (0x038C, "039F 0301"), - (0x038E, "03A5 0301"), - (0x038F, "03A9 0301"), - (0x0390, "03CA 0301"), - (0x03AA, "0399 0308"), - (0x03AB, "03A5 0308"), - (0x03AC, "03B1 0301"), - (0x03AD, "03B5 0301"), - (0x03AE, "03B7 0301"), - (0x03AF, "03B9 0301"), - (0x03B0, "03CB 0301"), - (0x03CA, "03B9 0308"), - (0x03CB, "03C5 0308"), - (0x03CC, "03BF 0301"), - (0x03CD, "03C5 0301"), - (0x03CE, "03C9 0301"), - (0x03D0, " 03B2"), - (0x03D1, " 03B8"), - (0x03D2, " 03A5"), - (0x03D3, "03D2 0301"), - (0x03D4, "03D2 0308"), - (0x03D5, " 03C6"), - (0x03D6, " 03C0"), - (0x03F0, " 03BA"), - (0x03F1, " 03C1"), - (0x03F2, " 03C2"), - (0x03F4, " 0398"), - (0x03F5, " 03B5"), - (0x03F9, " 03A3"), - (0x0400, "0415 0300"), - (0x0401, "0415 0308"), - (0x0403, "0413 0301"), - (0x0407, "0406 0308"), - (0x040C, "041A 0301"), - (0x040D, "0418 0300"), - (0x040E, "0423 0306"), - (0x0419, "0418 0306"), - (0x0439, "0438 0306"), - (0x0450, "0435 0300"), - (0x0451, "0435 0308"), - (0x0453, "0433 0301"), - (0x0457, "0456 0308"), - (0x045C, "043A 0301"), - (0x045D, "0438 0300"), - (0x045E, "0443 0306"), - (0x0476, "0474 030F"), - (0x0477, "0475 030F"), - (0x04C1, "0416 0306"), - (0x04C2, "0436 0306"), - (0x04D0, "0410 0306"), - (0x04D1, "0430 0306"), - (0x04D2, "0410 0308"), - (0x04D3, "0430 0308"), - (0x04D6, "0415 0306"), - (0x04D7, "0435 0306"), - (0x04DA, "04D8 0308"), - (0x04DB, "04D9 0308"), - (0x04DC, "0416 0308"), - (0x04DD, "0436 0308"), - (0x04DE, "0417 0308"), - (0x04DF, "0437 0308"), - (0x04E2, "0418 0304"), - (0x04E3, "0438 0304"), - (0x04E4, "0418 0308"), - (0x04E5, "0438 0308"), - (0x04E6, "041E 0308"), - (0x04E7, "043E 0308"), - (0x04EA, "04E8 0308"), - (0x04EB, "04E9 0308"), - (0x04EC, "042D 0308"), - (0x04ED, "044D 0308"), - (0x04EE, "0423 0304"), - (0x04EF, "0443 0304"), - (0x04F0, "0423 0308"), - (0x04F1, "0443 0308"), - (0x04F2, "0423 030B"), - (0x04F3, "0443 030B"), - (0x04F4, "0427 0308"), - (0x04F5, "0447 0308"), - (0x04F8, "042B 0308"), - (0x04F9, "044B 0308"), - (0x0587, " 0565 0582"), - (0x0622, "0627 0653"), - (0x0623, "0627 0654"), - (0x0624, "0648 0654"), - (0x0625, "0627 0655"), - (0x0626, "064A 0654"), - (0x0675, " 0627 0674"), - (0x0676, " 0648 0674"), - (0x0677, " 06C7 0674"), - (0x0678, " 064A 0674"), - (0x06C0, "06D5 0654"), - (0x06C2, "06C1 0654"), - (0x06D3, "06D2 0654"), - (0x0929, "0928 093C"), - (0x0931, "0930 093C"), - (0x0934, "0933 093C"), - (0x0958, "0915 093C"), - (0x0959, "0916 093C"), - (0x095A, "0917 093C"), - (0x095B, "091C 093C"), - (0x095C, "0921 093C"), - (0x095D, "0922 093C"), - (0x095E, "092B 093C"), - (0x095F, "092F 093C"), - (0x09CB, "09C7 09BE"), - (0x09CC, "09C7 09D7"), - (0x09DC, "09A1 09BC"), - (0x09DD, "09A2 09BC"), - (0x09DF, "09AF 09BC"), - (0x0A33, "0A32 0A3C"), - (0x0A36, "0A38 0A3C"), - (0x0A59, "0A16 0A3C"), - (0x0A5A, "0A17 0A3C"), - (0x0A5B, "0A1C 0A3C"), - (0x0A5E, "0A2B 0A3C"), - (0x0B48, "0B47 0B56"), - (0x0B4B, "0B47 0B3E"), - (0x0B4C, "0B47 0B57"), - (0x0B5C, "0B21 0B3C"), - (0x0B5D, "0B22 0B3C"), - (0x0B94, "0B92 0BD7"), - (0x0BCA, "0BC6 0BBE"), - (0x0BCB, "0BC7 0BBE"), - (0x0BCC, "0BC6 0BD7"), - (0x0C48, "0C46 0C56"), - (0x0CC0, "0CBF 0CD5"), - (0x0CC7, "0CC6 0CD5"), - (0x0CC8, "0CC6 0CD6"), - (0x0CCA, "0CC6 0CC2"), - (0x0CCB, "0CCA 0CD5"), - (0x0D4A, "0D46 0D3E"), - (0x0D4B, "0D47 0D3E"), - (0x0D4C, "0D46 0D57"), - (0x0DDA, "0DD9 0DCA"), - (0x0DDC, "0DD9 0DCF"), - (0x0DDD, "0DDC 0DCA"), - (0x0DDE, "0DD9 0DDF"), - (0x0E33, " 0E4D 0E32"), - (0x0EB3, " 0ECD 0EB2"), - (0x0EDC, " 0EAB 0E99"), - (0x0EDD, " 0EAB 0EA1"), - (0x0F0C, " 0F0B"), - (0x0F43, "0F42 0FB7"), - (0x0F4D, "0F4C 0FB7"), - (0x0F52, "0F51 0FB7"), - (0x0F57, "0F56 0FB7"), - (0x0F5C, "0F5B 0FB7"), - (0x0F69, "0F40 0FB5"), - (0x0F73, "0F71 0F72"), - (0x0F75, "0F71 0F74"), - (0x0F76, "0FB2 0F80"), - (0x0F77, " 0FB2 0F81"), - (0x0F78, "0FB3 0F80"), - (0x0F79, " 0FB3 0F81"), - (0x0F81, "0F71 0F80"), - (0x0F93, "0F92 0FB7"), - (0x0F9D, "0F9C 0FB7"), - (0x0FA2, "0FA1 0FB7"), - (0x0FA7, "0FA6 0FB7"), - (0x0FAC, "0FAB 0FB7"), - (0x0FB9, "0F90 0FB5"), - (0x1026, "1025 102E"), - (0x10FC, " 10DC"), - (0x1B06, "1B05 1B35"), - (0x1B08, "1B07 1B35"), - (0x1B0A, "1B09 1B35"), - (0x1B0C, "1B0B 1B35"), - (0x1B0E, "1B0D 1B35"), - (0x1B12, "1B11 1B35"), - (0x1B3B, "1B3A 1B35"), - (0x1B3D, "1B3C 1B35"), - (0x1B40, "1B3E 1B35"), - (0x1B41, "1B3F 1B35"), - (0x1B43, "1B42 1B35"), - (0x1D2C, " 0041"), - (0x1D2D, " 00C6"), - (0x1D2E, " 0042"), - (0x1D30, " 0044"), - (0x1D31, " 0045"), - (0x1D32, " 018E"), - (0x1D33, " 0047"), - (0x1D34, " 0048"), - (0x1D35, " 0049"), - (0x1D36, " 004A"), - (0x1D37, " 004B"), - (0x1D38, " 004C"), - (0x1D39, " 004D"), - (0x1D3A, " 004E"), - (0x1D3C, " 004F"), - (0x1D3D, " 0222"), - (0x1D3E, " 0050"), - (0x1D3F, " 0052"), - (0x1D40, " 0054"), - (0x1D41, " 0055"), - (0x1D42, " 0057"), - (0x1D43, " 0061"), - (0x1D44, " 0250"), - (0x1D45, " 0251"), - (0x1D46, " 1D02"), - (0x1D47, " 0062"), - (0x1D48, " 0064"), - (0x1D49, " 0065"), - (0x1D4A, " 0259"), - (0x1D4B, " 025B"), - (0x1D4C, " 025C"), - (0x1D4D, " 0067"), - (0x1D4F, " 006B"), - (0x1D50, " 006D"), - (0x1D51, " 014B"), - (0x1D52, " 006F"), - (0x1D53, " 0254"), - (0x1D54, " 1D16"), - (0x1D55, " 1D17"), - (0x1D56, " 0070"), - (0x1D57, " 0074"), - (0x1D58, " 0075"), - (0x1D59, " 1D1D"), - (0x1D5A, " 026F"), - (0x1D5B, " 0076"), - (0x1D5C, " 1D25"), - (0x1D5D, " 03B2"), - (0x1D5E, " 03B3"), - (0x1D5F, " 03B4"), - (0x1D60, " 03C6"), - (0x1D61, " 03C7"), - (0x1D62, " 0069"), - (0x1D63, " 0072"), - (0x1D64, " 0075"), - (0x1D65, " 0076"), - (0x1D66, " 03B2"), - (0x1D67, " 03B3"), - (0x1D68, " 03C1"), - (0x1D69, " 03C6"), - (0x1D6A, " 03C7"), - (0x1D78, " 043D"), - (0x1D9B, " 0252"), - (0x1D9C, " 0063"), - (0x1D9D, " 0255"), - (0x1D9E, " 00F0"), - (0x1D9F, " 025C"), - (0x1DA0, " 0066"), - (0x1DA1, " 025F"), - (0x1DA2, " 0261"), - (0x1DA3, " 0265"), - (0x1DA4, " 0268"), - (0x1DA5, " 0269"), - (0x1DA6, " 026A"), - (0x1DA7, " 1D7B"), - (0x1DA8, " 029D"), - (0x1DA9, " 026D"), - (0x1DAA, " 1D85"), - (0x1DAB, " 029F"), - (0x1DAC, " 0271"), - (0x1DAD, " 0270"), - (0x1DAE, " 0272"), - (0x1DAF, " 0273"), - (0x1DB0, " 0274"), - (0x1DB1, " 0275"), - (0x1DB2, " 0278"), - (0x1DB3, " 0282"), - (0x1DB4, " 0283"), - (0x1DB5, " 01AB"), - (0x1DB6, " 0289"), - (0x1DB7, " 028A"), - (0x1DB8, " 1D1C"), - (0x1DB9, " 028B"), - (0x1DBA, " 028C"), - (0x1DBB, " 007A"), - (0x1DBC, " 0290"), - (0x1DBD, " 0291"), - (0x1DBE, " 0292"), - (0x1DBF, " 03B8"), - (0x1E00, "0041 0325"), - (0x1E01, "0061 0325"), - (0x1E02, "0042 0307"), - (0x1E03, "0062 0307"), - (0x1E04, "0042 0323"), - (0x1E05, "0062 0323"), - (0x1E06, "0042 0331"), - (0x1E07, "0062 0331"), - (0x1E08, "00C7 0301"), - (0x1E09, "00E7 0301"), - (0x1E0A, "0044 0307"), - (0x1E0B, "0064 0307"), - (0x1E0C, "0044 0323"), - (0x1E0D, "0064 0323"), - (0x1E0E, "0044 0331"), - (0x1E0F, "0064 0331"), - (0x1E10, "0044 0327"), - (0x1E11, "0064 0327"), - (0x1E12, "0044 032D"), - (0x1E13, "0064 032D"), - (0x1E14, "0112 0300"), - (0x1E15, "0113 0300"), - (0x1E16, "0112 0301"), - (0x1E17, "0113 0301"), - (0x1E18, "0045 032D"), - (0x1E19, "0065 032D"), - (0x1E1A, "0045 0330"), - (0x1E1B, "0065 0330"), - (0x1E1C, "0228 0306"), - (0x1E1D, "0229 0306"), - (0x1E1E, "0046 0307"), - (0x1E1F, "0066 0307"), - (0x1E20, "0047 0304"), - (0x1E21, "0067 0304"), - (0x1E22, "0048 0307"), - (0x1E23, "0068 0307"), - (0x1E24, "0048 0323"), - (0x1E25, "0068 0323"), - (0x1E26, "0048 0308"), - (0x1E27, "0068 0308"), - (0x1E28, "0048 0327"), - (0x1E29, "0068 0327"), - (0x1E2A, "0048 032E"), - (0x1E2B, "0068 032E"), - (0x1E2C, "0049 0330"), - (0x1E2D, "0069 0330"), - (0x1E2E, "00CF 0301"), - (0x1E2F, "00EF 0301"), - (0x1E30, "004B 0301"), - (0x1E31, "006B 0301"), - (0x1E32, "004B 0323"), - (0x1E33, "006B 0323"), - (0x1E34, "004B 0331"), - (0x1E35, "006B 0331"), - (0x1E36, "004C 0323"), - (0x1E37, "006C 0323"), - (0x1E38, "1E36 0304"), - (0x1E39, "1E37 0304"), - (0x1E3A, "004C 0331"), - (0x1E3B, "006C 0331"), - (0x1E3C, "004C 032D"), - (0x1E3D, "006C 032D"), - (0x1E3E, "004D 0301"), - (0x1E3F, "006D 0301"), - (0x1E40, "004D 0307"), - (0x1E41, "006D 0307"), - (0x1E42, "004D 0323"), - (0x1E43, "006D 0323"), - (0x1E44, "004E 0307"), - (0x1E45, "006E 0307"), - (0x1E46, "004E 0323"), - (0x1E47, "006E 0323"), - (0x1E48, "004E 0331"), - (0x1E49, "006E 0331"), - (0x1E4A, "004E 032D"), - (0x1E4B, "006E 032D"), - (0x1E4C, "00D5 0301"), - (0x1E4D, "00F5 0301"), - (0x1E4E, "00D5 0308"), - (0x1E4F, "00F5 0308"), - (0x1E50, "014C 0300"), - (0x1E51, "014D 0300"), - (0x1E52, "014C 0301"), - (0x1E53, "014D 0301"), - (0x1E54, "0050 0301"), - (0x1E55, "0070 0301"), - (0x1E56, "0050 0307"), - (0x1E57, "0070 0307"), - (0x1E58, "0052 0307"), - (0x1E59, "0072 0307"), - (0x1E5A, "0052 0323"), - (0x1E5B, "0072 0323"), - (0x1E5C, "1E5A 0304"), - (0x1E5D, "1E5B 0304"), - (0x1E5E, "0052 0331"), - (0x1E5F, "0072 0331"), - (0x1E60, "0053 0307"), - (0x1E61, "0073 0307"), - (0x1E62, "0053 0323"), - (0x1E63, "0073 0323"), - (0x1E64, "015A 0307"), - (0x1E65, "015B 0307"), - (0x1E66, "0160 0307"), - (0x1E67, "0161 0307"), - (0x1E68, "1E62 0307"), - (0x1E69, "1E63 0307"), - (0x1E6A, "0054 0307"), - (0x1E6B, "0074 0307"), - (0x1E6C, "0054 0323"), - (0x1E6D, "0074 0323"), - (0x1E6E, "0054 0331"), - (0x1E6F, "0074 0331"), - (0x1E70, "0054 032D"), - (0x1E71, "0074 032D"), - (0x1E72, "0055 0324"), - (0x1E73, "0075 0324"), - (0x1E74, "0055 0330"), - (0x1E75, "0075 0330"), - (0x1E76, "0055 032D"), - (0x1E77, "0075 032D"), - (0x1E78, "0168 0301"), - (0x1E79, "0169 0301"), - (0x1E7A, "016A 0308"), - (0x1E7B, "016B 0308"), - (0x1E7C, "0056 0303"), - (0x1E7D, "0076 0303"), - (0x1E7E, "0056 0323"), - (0x1E7F, "0076 0323"), - (0x1E80, "0057 0300"), - (0x1E81, "0077 0300"), - (0x1E82, "0057 0301"), - (0x1E83, "0077 0301"), - (0x1E84, "0057 0308"), - (0x1E85, "0077 0308"), - (0x1E86, "0057 0307"), - (0x1E87, "0077 0307"), - (0x1E88, "0057 0323"), - (0x1E89, "0077 0323"), - (0x1E8A, "0058 0307"), - (0x1E8B, "0078 0307"), - (0x1E8C, "0058 0308"), - (0x1E8D, "0078 0308"), - (0x1E8E, "0059 0307"), - (0x1E8F, "0079 0307"), - (0x1E90, "005A 0302"), - (0x1E91, "007A 0302"), - (0x1E92, "005A 0323"), - (0x1E93, "007A 0323"), - (0x1E94, "005A 0331"), - (0x1E95, "007A 0331"), - (0x1E96, "0068 0331"), - (0x1E97, "0074 0308"), - (0x1E98, "0077 030A"), - (0x1E99, "0079 030A"), - (0x1E9A, " 0061 02BE"), - (0x1E9B, "017F 0307"), - (0x1EA0, "0041 0323"), - (0x1EA1, "0061 0323"), - (0x1EA2, "0041 0309"), - (0x1EA3, "0061 0309"), - (0x1EA4, "00C2 0301"), - (0x1EA5, "00E2 0301"), - (0x1EA6, "00C2 0300"), - (0x1EA7, "00E2 0300"), - (0x1EA8, "00C2 0309"), - (0x1EA9, "00E2 0309"), - (0x1EAA, "00C2 0303"), - (0x1EAB, "00E2 0303"), - (0x1EAC, "1EA0 0302"), - (0x1EAD, "1EA1 0302"), - (0x1EAE, "0102 0301"), - (0x1EAF, "0103 0301"), - (0x1EB0, "0102 0300"), - (0x1EB1, "0103 0300"), - (0x1EB2, "0102 0309"), - (0x1EB3, "0103 0309"), - (0x1EB4, "0102 0303"), - (0x1EB5, "0103 0303"), - (0x1EB6, "1EA0 0306"), - (0x1EB7, "1EA1 0306"), - (0x1EB8, "0045 0323"), - (0x1EB9, "0065 0323"), - (0x1EBA, "0045 0309"), - (0x1EBB, "0065 0309"), - (0x1EBC, "0045 0303"), - (0x1EBD, "0065 0303"), - (0x1EBE, "00CA 0301"), - (0x1EBF, "00EA 0301"), - (0x1EC0, "00CA 0300"), - (0x1EC1, "00EA 0300"), - (0x1EC2, "00CA 0309"), - (0x1EC3, "00EA 0309"), - (0x1EC4, "00CA 0303"), - (0x1EC5, "00EA 0303"), - (0x1EC6, "1EB8 0302"), - (0x1EC7, "1EB9 0302"), - (0x1EC8, "0049 0309"), - (0x1EC9, "0069 0309"), - (0x1ECA, "0049 0323"), - (0x1ECB, "0069 0323"), - (0x1ECC, "004F 0323"), - (0x1ECD, "006F 0323"), - (0x1ECE, "004F 0309"), - (0x1ECF, "006F 0309"), - (0x1ED0, "00D4 0301"), - (0x1ED1, "00F4 0301"), - (0x1ED2, "00D4 0300"), - (0x1ED3, "00F4 0300"), - (0x1ED4, "00D4 0309"), - (0x1ED5, "00F4 0309"), - (0x1ED6, "00D4 0303"), - (0x1ED7, "00F4 0303"), - (0x1ED8, "1ECC 0302"), - (0x1ED9, "1ECD 0302"), - (0x1EDA, "01A0 0301"), - (0x1EDB, "01A1 0301"), - (0x1EDC, "01A0 0300"), - (0x1EDD, "01A1 0300"), - (0x1EDE, "01A0 0309"), - (0x1EDF, "01A1 0309"), - (0x1EE0, "01A0 0303"), - (0x1EE1, "01A1 0303"), - (0x1EE2, "01A0 0323"), - (0x1EE3, "01A1 0323"), - (0x1EE4, "0055 0323"), - (0x1EE5, "0075 0323"), - (0x1EE6, "0055 0309"), - (0x1EE7, "0075 0309"), - (0x1EE8, "01AF 0301"), - (0x1EE9, "01B0 0301"), - (0x1EEA, "01AF 0300"), - (0x1EEB, "01B0 0300"), - (0x1EEC, "01AF 0309"), - (0x1EED, "01B0 0309"), - (0x1EEE, "01AF 0303"), - (0x1EEF, "01B0 0303"), - (0x1EF0, "01AF 0323"), - (0x1EF1, "01B0 0323"), - (0x1EF2, "0059 0300"), - (0x1EF3, "0079 0300"), - (0x1EF4, "0059 0323"), - (0x1EF5, "0079 0323"), - (0x1EF6, "0059 0309"), - (0x1EF7, "0079 0309"), - (0x1EF8, "0059 0303"), - (0x1EF9, "0079 0303"), - (0x1F00, "03B1 0313"), - (0x1F01, "03B1 0314"), - (0x1F02, "1F00 0300"), - (0x1F03, "1F01 0300"), - (0x1F04, "1F00 0301"), - (0x1F05, "1F01 0301"), - (0x1F06, "1F00 0342"), - (0x1F07, "1F01 0342"), - (0x1F08, "0391 0313"), - (0x1F09, "0391 0314"), - (0x1F0A, "1F08 0300"), - (0x1F0B, "1F09 0300"), - (0x1F0C, "1F08 0301"), - (0x1F0D, "1F09 0301"), - (0x1F0E, "1F08 0342"), - (0x1F0F, "1F09 0342"), - (0x1F10, "03B5 0313"), - (0x1F11, "03B5 0314"), - (0x1F12, "1F10 0300"), - (0x1F13, "1F11 0300"), - (0x1F14, "1F10 0301"), - (0x1F15, "1F11 0301"), - (0x1F18, "0395 0313"), - (0x1F19, "0395 0314"), - (0x1F1A, "1F18 0300"), - (0x1F1B, "1F19 0300"), - (0x1F1C, "1F18 0301"), - (0x1F1D, "1F19 0301"), - (0x1F20, "03B7 0313"), - (0x1F21, "03B7 0314"), - (0x1F22, "1F20 0300"), - (0x1F23, "1F21 0300"), - (0x1F24, "1F20 0301"), - (0x1F25, "1F21 0301"), - (0x1F26, "1F20 0342"), - (0x1F27, "1F21 0342"), - (0x1F28, "0397 0313"), - (0x1F29, "0397 0314"), - (0x1F2A, "1F28 0300"), - (0x1F2B, "1F29 0300"), - (0x1F2C, "1F28 0301"), - (0x1F2D, "1F29 0301"), - (0x1F2E, "1F28 0342"), - (0x1F2F, "1F29 0342"), - (0x1F30, "03B9 0313"), - (0x1F31, "03B9 0314"), - (0x1F32, "1F30 0300"), - (0x1F33, "1F31 0300"), - (0x1F34, "1F30 0301"), - (0x1F35, "1F31 0301"), - (0x1F36, "1F30 0342"), - (0x1F37, "1F31 0342"), - (0x1F38, "0399 0313"), - (0x1F39, "0399 0314"), - (0x1F3A, "1F38 0300"), - (0x1F3B, "1F39 0300"), - (0x1F3C, "1F38 0301"), - (0x1F3D, "1F39 0301"), - (0x1F3E, "1F38 0342"), - (0x1F3F, "1F39 0342"), - (0x1F40, "03BF 0313"), - (0x1F41, "03BF 0314"), - (0x1F42, "1F40 0300"), - (0x1F43, "1F41 0300"), - (0x1F44, "1F40 0301"), - (0x1F45, "1F41 0301"), - (0x1F48, "039F 0313"), - (0x1F49, "039F 0314"), - (0x1F4A, "1F48 0300"), - (0x1F4B, "1F49 0300"), - (0x1F4C, "1F48 0301"), - (0x1F4D, "1F49 0301"), - (0x1F50, "03C5 0313"), - (0x1F51, "03C5 0314"), - (0x1F52, "1F50 0300"), - (0x1F53, "1F51 0300"), - (0x1F54, "1F50 0301"), - (0x1F55, "1F51 0301"), - (0x1F56, "1F50 0342"), - (0x1F57, "1F51 0342"), - (0x1F59, "03A5 0314"), - (0x1F5B, "1F59 0300"), - (0x1F5D, "1F59 0301"), - (0x1F5F, "1F59 0342"), - (0x1F60, "03C9 0313"), - (0x1F61, "03C9 0314"), - (0x1F62, "1F60 0300"), - (0x1F63, "1F61 0300"), - (0x1F64, "1F60 0301"), - (0x1F65, "1F61 0301"), - (0x1F66, "1F60 0342"), - (0x1F67, "1F61 0342"), - (0x1F68, "03A9 0313"), - (0x1F69, "03A9 0314"), - (0x1F6A, "1F68 0300"), - (0x1F6B, "1F69 0300"), - (0x1F6C, "1F68 0301"), - (0x1F6D, "1F69 0301"), - (0x1F6E, "1F68 0342"), - (0x1F6F, "1F69 0342"), - (0x1F70, "03B1 0300"), - (0x1F71, "03AC"), - (0x1F72, "03B5 0300"), - (0x1F73, "03AD"), - (0x1F74, "03B7 0300"), - (0x1F75, "03AE"), - (0x1F76, "03B9 0300"), - (0x1F77, "03AF"), - (0x1F78, "03BF 0300"), - (0x1F79, "03CC"), - (0x1F7A, "03C5 0300"), - (0x1F7B, "03CD"), - (0x1F7C, "03C9 0300"), - (0x1F7D, "03CE"), - (0x1F80, "1F00 0345"), - (0x1F81, "1F01 0345"), - (0x1F82, "1F02 0345"), - (0x1F83, "1F03 0345"), - (0x1F84, "1F04 0345"), - (0x1F85, "1F05 0345"), - (0x1F86, "1F06 0345"), - (0x1F87, "1F07 0345"), - (0x1F88, "1F08 0345"), - (0x1F89, "1F09 0345"), - (0x1F8A, "1F0A 0345"), - (0x1F8B, "1F0B 0345"), - (0x1F8C, "1F0C 0345"), - (0x1F8D, "1F0D 0345"), - (0x1F8E, "1F0E 0345"), - (0x1F8F, "1F0F 0345"), - (0x1F90, "1F20 0345"), - (0x1F91, "1F21 0345"), - (0x1F92, "1F22 0345"), - (0x1F93, "1F23 0345"), - (0x1F94, "1F24 0345"), - (0x1F95, "1F25 0345"), - (0x1F96, "1F26 0345"), - (0x1F97, "1F27 0345"), - (0x1F98, "1F28 0345"), - (0x1F99, "1F29 0345"), - (0x1F9A, "1F2A 0345"), - (0x1F9B, "1F2B 0345"), - (0x1F9C, "1F2C 0345"), - (0x1F9D, "1F2D 0345"), - (0x1F9E, "1F2E 0345"), - (0x1F9F, "1F2F 0345"), - (0x1FA0, "1F60 0345"), - (0x1FA1, "1F61 0345"), - (0x1FA2, "1F62 0345"), - (0x1FA3, "1F63 0345"), - (0x1FA4, "1F64 0345"), - (0x1FA5, "1F65 0345"), - (0x1FA6, "1F66 0345"), - (0x1FA7, "1F67 0345"), - (0x1FA8, "1F68 0345"), - (0x1FA9, "1F69 0345"), - (0x1FAA, "1F6A 0345"), - (0x1FAB, "1F6B 0345"), - (0x1FAC, "1F6C 0345"), - (0x1FAD, "1F6D 0345"), - (0x1FAE, "1F6E 0345"), - (0x1FAF, "1F6F 0345"), - (0x1FB0, "03B1 0306"), - (0x1FB1, "03B1 0304"), - (0x1FB2, "1F70 0345"), - (0x1FB3, "03B1 0345"), - (0x1FB4, "03AC 0345"), - (0x1FB6, "03B1 0342"), - (0x1FB7, "1FB6 0345"), - (0x1FB8, "0391 0306"), - (0x1FB9, "0391 0304"), - (0x1FBA, "0391 0300"), - (0x1FBB, "0386"), - (0x1FBC, "0391 0345"), - (0x1FBD, " 0020 0313"), - (0x1FBE, "03B9"), - (0x1FBF, " 0020 0313"), - (0x1FC0, " 0020 0342"), - (0x1FC1, "00A8 0342"), - (0x1FC2, "1F74 0345"), - (0x1FC3, "03B7 0345"), - (0x1FC4, "03AE 0345"), - (0x1FC6, "03B7 0342"), - (0x1FC7, "1FC6 0345"), - (0x1FC8, "0395 0300"), - (0x1FC9, "0388"), - (0x1FCA, "0397 0300"), - (0x1FCB, "0389"), - (0x1FCC, "0397 0345"), - (0x1FCD, "1FBF 0300"), - (0x1FCE, "1FBF 0301"), - (0x1FCF, "1FBF 0342"), - (0x1FD0, "03B9 0306"), - (0x1FD1, "03B9 0304"), - (0x1FD2, "03CA 0300"), - (0x1FD3, "0390"), - (0x1FD6, "03B9 0342"), - (0x1FD7, "03CA 0342"), - (0x1FD8, "0399 0306"), - (0x1FD9, "0399 0304"), - (0x1FDA, "0399 0300"), - (0x1FDB, "038A"), - (0x1FDD, "1FFE 0300"), - (0x1FDE, "1FFE 0301"), - (0x1FDF, "1FFE 0342"), - (0x1FE0, "03C5 0306"), - (0x1FE1, "03C5 0304"), - (0x1FE2, "03CB 0300"), - (0x1FE3, "03B0"), - (0x1FE4, "03C1 0313"), - (0x1FE5, "03C1 0314"), - (0x1FE6, "03C5 0342"), - (0x1FE7, "03CB 0342"), - (0x1FE8, "03A5 0306"), - (0x1FE9, "03A5 0304"), - (0x1FEA, "03A5 0300"), - (0x1FEB, "038E"), - (0x1FEC, "03A1 0314"), - (0x1FED, "00A8 0300"), - (0x1FEE, "0385"), - (0x1FEF, "0060"), - (0x1FF2, "1F7C 0345"), - (0x1FF3, "03C9 0345"), - (0x1FF4, "03CE 0345"), - (0x1FF6, "03C9 0342"), - (0x1FF7, "1FF6 0345"), - (0x1FF8, "039F 0300"), - (0x1FF9, "038C"), - (0x1FFA, "03A9 0300"), - (0x1FFB, "038F"), - (0x1FFC, "03A9 0345"), - (0x1FFD, "00B4"), - (0x1FFE, " 0020 0314"), - (0x2000, "2002"), - (0x2001, "2003"), - (0x2002, " 0020"), - (0x2003, " 0020"), - (0x2004, " 0020"), - (0x2005, " 0020"), - (0x2006, " 0020"), - (0x2007, " 0020"), - (0x2008, " 0020"), - (0x2009, " 0020"), - (0x200A, " 0020"), - (0x2011, " 2010"), - (0x2017, " 0020 0333"), - (0x2024, " 002E"), - (0x2025, " 002E 002E"), - (0x2026, " 002E 002E 002E"), - (0x202F, " 0020"), - (0x2033, " 2032 2032"), - (0x2034, " 2032 2032 2032"), - (0x2036, " 2035 2035"), - (0x2037, " 2035 2035 2035"), - (0x203C, " 0021 0021"), - (0x203E, " 0020 0305"), - (0x2047, " 003F 003F"), - (0x2048, " 003F 0021"), - (0x2049, " 0021 003F"), - (0x2057, " 2032 2032 2032 2032"), - (0x205F, " 0020"), - (0x2070, " 0030"), - (0x2071, " 0069"), - (0x2074, " 0034"), - (0x2075, " 0035"), - (0x2076, " 0036"), - (0x2077, " 0037"), - (0x2078, " 0038"), - (0x2079, " 0039"), - (0x207A, " 002B"), - (0x207B, " 2212"), - (0x207C, " 003D"), - (0x207D, " 0028"), - (0x207E, " 0029"), - (0x207F, " 006E"), - (0x2080, " 0030"), - (0x2081, " 0031"), - (0x2082, " 0032"), - (0x2083, " 0033"), - (0x2084, " 0034"), - (0x2085, " 0035"), - (0x2086, " 0036"), - (0x2087, " 0037"), - (0x2088, " 0038"), - (0x2089, " 0039"), - (0x208A, " 002B"), - (0x208B, " 2212"), - (0x208C, " 003D"), - (0x208D, " 0028"), - (0x208E, " 0029"), - (0x2090, " 0061"), - (0x2091, " 0065"), - (0x2092, " 006F"), - (0x2093, " 0078"), - (0x2094, " 0259"), - (0x2095, " 0068"), - (0x2096, " 006B"), - (0x2097, " 006C"), - (0x2098, " 006D"), - (0x2099, " 006E"), - (0x209A, " 0070"), - (0x209B, " 0073"), - (0x209C, " 0074"), - (0x20A8, " 0052 0073"), - (0x2100, " 0061 002F 0063"), - (0x2101, " 0061 002F 0073"), - (0x2102, " 0043"), - (0x2103, " 00B0 0043"), - (0x2105, " 0063 002F 006F"), - (0x2106, " 0063 002F 0075"), - (0x2107, " 0190"), - (0x2109, " 00B0 0046"), - (0x210A, " 0067"), - (0x210B, " 0048"), - (0x210C, " 0048"), - (0x210D, " 0048"), - (0x210E, " 0068"), - (0x210F, " 0127"), - (0x2110, " 0049"), - (0x2111, " 0049"), - (0x2112, " 004C"), - (0x2113, " 006C"), - (0x2115, " 004E"), - (0x2116, " 004E 006F"), - (0x2119, " 0050"), - (0x211A, " 0051"), - (0x211B, " 0052"), - (0x211C, " 0052"), - (0x211D, " 0052"), - (0x2120, " 0053 004D"), - (0x2121, " 0054 0045 004C"), - (0x2122, " 0054 004D"), - (0x2124, " 005A"), - (0x2126, "03A9"), - (0x2128, " 005A"), - (0x212A, "004B"), - (0x212B, "00C5"), - (0x212C, " 0042"), - (0x212D, " 0043"), - (0x212F, " 0065"), - (0x2130, " 0045"), - (0x2131, " 0046"), - (0x2133, " 004D"), - (0x2134, " 006F"), - (0x2135, " 05D0"), - (0x2136, " 05D1"), - (0x2137, " 05D2"), - (0x2138, " 05D3"), - (0x2139, " 0069"), - (0x213B, " 0046 0041 0058"), - (0x213C, " 03C0"), - (0x213D, " 03B3"), - (0x213E, " 0393"), - (0x213F, " 03A0"), - (0x2140, " 2211"), - (0x2145, " 0044"), - (0x2146, " 0064"), - (0x2147, " 0065"), - (0x2148, " 0069"), - (0x2149, " 006A"), - (0x2150, " 0031 2044 0037"), - (0x2151, " 0031 2044 0039"), - (0x2152, " 0031 2044 0031 0030"), - (0x2153, " 0031 2044 0033"), - (0x2154, " 0032 2044 0033"), - (0x2155, " 0031 2044 0035"), - (0x2156, " 0032 2044 0035"), - (0x2157, " 0033 2044 0035"), - (0x2158, " 0034 2044 0035"), - (0x2159, " 0031 2044 0036"), - (0x215A, " 0035 2044 0036"), - (0x215B, " 0031 2044 0038"), - (0x215C, " 0033 2044 0038"), - (0x215D, " 0035 2044 0038"), - (0x215E, " 0037 2044 0038"), - (0x215F, " 0031 2044"), - (0x2160, " 0049"), - (0x2161, " 0049 0049"), - (0x2162, " 0049 0049 0049"), - (0x2163, " 0049 0056"), - (0x2164, " 0056"), - (0x2165, " 0056 0049"), - (0x2166, " 0056 0049 0049"), - (0x2167, " 0056 0049 0049 0049"), - (0x2168, " 0049 0058"), - (0x2169, " 0058"), - (0x216A, " 0058 0049"), - (0x216B, " 0058 0049 0049"), - (0x216C, " 004C"), - (0x216D, " 0043"), - (0x216E, " 0044"), - (0x216F, " 004D"), - (0x2170, " 0069"), - (0x2171, " 0069 0069"), - (0x2172, " 0069 0069 0069"), - (0x2173, " 0069 0076"), - (0x2174, " 0076"), - (0x2175, " 0076 0069"), - (0x2176, " 0076 0069 0069"), - (0x2177, " 0076 0069 0069 0069"), - (0x2178, " 0069 0078"), - (0x2179, " 0078"), - (0x217A, " 0078 0069"), - (0x217B, " 0078 0069 0069"), - (0x217C, " 006C"), - (0x217D, " 0063"), - (0x217E, " 0064"), - (0x217F, " 006D"), - (0x2189, " 0030 2044 0033"), - (0x219A, "2190 0338"), - (0x219B, "2192 0338"), - (0x21AE, "2194 0338"), - (0x21CD, "21D0 0338"), - (0x21CE, "21D4 0338"), - (0x21CF, "21D2 0338"), - (0x2204, "2203 0338"), - (0x2209, "2208 0338"), - (0x220C, "220B 0338"), - (0x2224, "2223 0338"), - (0x2226, "2225 0338"), - (0x222C, " 222B 222B"), - (0x222D, " 222B 222B 222B"), - (0x222F, " 222E 222E"), - (0x2230, " 222E 222E 222E"), - (0x2241, "223C 0338"), - (0x2244, "2243 0338"), - (0x2247, "2245 0338"), - (0x2249, "2248 0338"), - (0x2260, "003D 0338"), - (0x2262, "2261 0338"), - (0x226D, "224D 0338"), - (0x226E, "003C 0338"), - (0x226F, "003E 0338"), - (0x2270, "2264 0338"), - (0x2271, "2265 0338"), - (0x2274, "2272 0338"), - (0x2275, "2273 0338"), - (0x2278, "2276 0338"), - (0x2279, "2277 0338"), - (0x2280, "227A 0338"), - (0x2281, "227B 0338"), - (0x2284, "2282 0338"), - (0x2285, "2283 0338"), - (0x2288, "2286 0338"), - (0x2289, "2287 0338"), - (0x22AC, "22A2 0338"), - (0x22AD, "22A8 0338"), - (0x22AE, "22A9 0338"), - (0x22AF, "22AB 0338"), - (0x22E0, "227C 0338"), - (0x22E1, "227D 0338"), - (0x22E2, "2291 0338"), - (0x22E3, "2292 0338"), - (0x22EA, "22B2 0338"), - (0x22EB, "22B3 0338"), - (0x22EC, "22B4 0338"), - (0x22ED, "22B5 0338"), - (0x2329, "3008"), - (0x232A, "3009"), - (0x2460, " 0031"), - (0x2461, " 0032"), - (0x2462, " 0033"), - (0x2463, " 0034"), - (0x2464, " 0035"), - (0x2465, " 0036"), - (0x2466, " 0037"), - (0x2467, " 0038"), - (0x2468, " 0039"), - (0x2469, " 0031 0030"), - (0x246A, " 0031 0031"), - (0x246B, " 0031 0032"), - (0x246C, " 0031 0033"), - (0x246D, " 0031 0034"), - (0x246E, " 0031 0035"), - (0x246F, " 0031 0036"), - (0x2470, " 0031 0037"), - (0x2471, " 0031 0038"), - (0x2472, " 0031 0039"), - (0x2473, " 0032 0030"), - (0x2474, " 0028 0031 0029"), - (0x2475, " 0028 0032 0029"), - (0x2476, " 0028 0033 0029"), - (0x2477, " 0028 0034 0029"), - (0x2478, " 0028 0035 0029"), - (0x2479, " 0028 0036 0029"), - (0x247A, " 0028 0037 0029"), - (0x247B, " 0028 0038 0029"), - (0x247C, " 0028 0039 0029"), - (0x247D, " 0028 0031 0030 0029"), - (0x247E, " 0028 0031 0031 0029"), - (0x247F, " 0028 0031 0032 0029"), - (0x2480, " 0028 0031 0033 0029"), - (0x2481, " 0028 0031 0034 0029"), - (0x2482, " 0028 0031 0035 0029"), - (0x2483, " 0028 0031 0036 0029"), - (0x2484, " 0028 0031 0037 0029"), - (0x2485, " 0028 0031 0038 0029"), - (0x2486, " 0028 0031 0039 0029"), - (0x2487, " 0028 0032 0030 0029"), - (0x2488, " 0031 002E"), - (0x2489, " 0032 002E"), - (0x248A, " 0033 002E"), - (0x248B, " 0034 002E"), - (0x248C, " 0035 002E"), - (0x248D, " 0036 002E"), - (0x248E, " 0037 002E"), - (0x248F, " 0038 002E"), - (0x2490, " 0039 002E"), - (0x2491, " 0031 0030 002E"), - (0x2492, " 0031 0031 002E"), - (0x2493, " 0031 0032 002E"), - (0x2494, " 0031 0033 002E"), - (0x2495, " 0031 0034 002E"), - (0x2496, " 0031 0035 002E"), - (0x2497, " 0031 0036 002E"), - (0x2498, " 0031 0037 002E"), - (0x2499, " 0031 0038 002E"), - (0x249A, " 0031 0039 002E"), - (0x249B, " 0032 0030 002E"), - (0x249C, " 0028 0061 0029"), - (0x249D, " 0028 0062 0029"), - (0x249E, " 0028 0063 0029"), - (0x249F, " 0028 0064 0029"), - (0x24A0, " 0028 0065 0029"), - (0x24A1, " 0028 0066 0029"), - (0x24A2, " 0028 0067 0029"), - (0x24A3, " 0028 0068 0029"), - (0x24A4, " 0028 0069 0029"), - (0x24A5, " 0028 006A 0029"), - (0x24A6, " 0028 006B 0029"), - (0x24A7, " 0028 006C 0029"), - (0x24A8, " 0028 006D 0029"), - (0x24A9, " 0028 006E 0029"), - (0x24AA, " 0028 006F 0029"), - (0x24AB, " 0028 0070 0029"), - (0x24AC, " 0028 0071 0029"), - (0x24AD, " 0028 0072 0029"), - (0x24AE, " 0028 0073 0029"), - (0x24AF, " 0028 0074 0029"), - (0x24B0, " 0028 0075 0029"), - (0x24B1, " 0028 0076 0029"), - (0x24B2, " 0028 0077 0029"), - (0x24B3, " 0028 0078 0029"), - (0x24B4, " 0028 0079 0029"), - (0x24B5, " 0028 007A 0029"), - (0x24B6, " 0041"), - (0x24B7, " 0042"), - (0x24B8, " 0043"), - (0x24B9, " 0044"), - (0x24BA, " 0045"), - (0x24BB, " 0046"), - (0x24BC, " 0047"), - (0x24BD, " 0048"), - (0x24BE, " 0049"), - (0x24BF, " 004A"), - (0x24C0, " 004B"), - (0x24C1, " 004C"), - (0x24C2, " 004D"), - (0x24C3, " 004E"), - (0x24C4, " 004F"), - (0x24C5, " 0050"), - (0x24C6, " 0051"), - (0x24C7, " 0052"), - (0x24C8, " 0053"), - (0x24C9, " 0054"), - (0x24CA, " 0055"), - (0x24CB, " 0056"), - (0x24CC, " 0057"), - (0x24CD, " 0058"), - (0x24CE, " 0059"), - (0x24CF, " 005A"), - (0x24D0, " 0061"), - (0x24D1, " 0062"), - (0x24D2, " 0063"), - (0x24D3, " 0064"), - (0x24D4, " 0065"), - (0x24D5, " 0066"), - (0x24D6, " 0067"), - (0x24D7, " 0068"), - (0x24D8, " 0069"), - (0x24D9, " 006A"), - (0x24DA, " 006B"), - (0x24DB, " 006C"), - (0x24DC, " 006D"), - (0x24DD, " 006E"), - (0x24DE, " 006F"), - (0x24DF, " 0070"), - (0x24E0, " 0071"), - (0x24E1, " 0072"), - (0x24E2, " 0073"), - (0x24E3, " 0074"), - (0x24E4, " 0075"), - (0x24E5, " 0076"), - (0x24E6, " 0077"), - (0x24E7, " 0078"), - (0x24E8, " 0079"), - (0x24E9, " 007A"), - (0x24EA, " 0030"), - (0x2A0C, " 222B 222B 222B 222B"), - (0x2A74, " 003A 003A 003D"), - (0x2A75, " 003D 003D"), - (0x2A76, " 003D 003D 003D"), - (0x2ADC, "2ADD 0338"), - (0x2C7C, " 006A"), - (0x2C7D, " 0056"), - (0x2D6F, " 2D61"), - (0x2E9F, " 6BCD"), - (0x2EF3, " 9F9F"), - (0x2F00, " 4E00"), - (0x2F01, " 4E28"), - (0x2F02, " 4E36"), - (0x2F03, " 4E3F"), - (0x2F04, " 4E59"), - (0x2F05, " 4E85"), - (0x2F06, " 4E8C"), - (0x2F07, " 4EA0"), - (0x2F08, " 4EBA"), - (0x2F09, " 513F"), - (0x2F0A, " 5165"), - (0x2F0B, " 516B"), - (0x2F0C, " 5182"), - (0x2F0D, " 5196"), - (0x2F0E, " 51AB"), - (0x2F0F, " 51E0"), - (0x2F10, " 51F5"), - (0x2F11, " 5200"), - (0x2F12, " 529B"), - (0x2F13, " 52F9"), - (0x2F14, " 5315"), - (0x2F15, " 531A"), - (0x2F16, " 5338"), - (0x2F17, " 5341"), - (0x2F18, " 535C"), - (0x2F19, " 5369"), - (0x2F1A, " 5382"), - (0x2F1B, " 53B6"), - (0x2F1C, " 53C8"), - (0x2F1D, " 53E3"), - (0x2F1E, " 56D7"), - (0x2F1F, " 571F"), - (0x2F20, " 58EB"), - (0x2F21, " 5902"), - (0x2F22, " 590A"), - (0x2F23, " 5915"), - (0x2F24, " 5927"), - (0x2F25, " 5973"), - (0x2F26, " 5B50"), - (0x2F27, " 5B80"), - (0x2F28, " 5BF8"), - (0x2F29, " 5C0F"), - (0x2F2A, " 5C22"), - (0x2F2B, " 5C38"), - (0x2F2C, " 5C6E"), - (0x2F2D, " 5C71"), - (0x2F2E, " 5DDB"), - (0x2F2F, " 5DE5"), - (0x2F30, " 5DF1"), - (0x2F31, " 5DFE"), - (0x2F32, " 5E72"), - (0x2F33, " 5E7A"), - (0x2F34, " 5E7F"), - (0x2F35, " 5EF4"), - (0x2F36, " 5EFE"), - (0x2F37, " 5F0B"), - (0x2F38, " 5F13"), - (0x2F39, " 5F50"), - (0x2F3A, " 5F61"), - (0x2F3B, " 5F73"), - (0x2F3C, " 5FC3"), - (0x2F3D, " 6208"), - (0x2F3E, " 6236"), - (0x2F3F, " 624B"), - (0x2F40, " 652F"), - (0x2F41, " 6534"), - (0x2F42, " 6587"), - (0x2F43, " 6597"), - (0x2F44, " 65A4"), - (0x2F45, " 65B9"), - (0x2F46, " 65E0"), - (0x2F47, " 65E5"), - (0x2F48, " 66F0"), - (0x2F49, " 6708"), - (0x2F4A, " 6728"), - (0x2F4B, " 6B20"), - (0x2F4C, " 6B62"), - (0x2F4D, " 6B79"), - (0x2F4E, " 6BB3"), - (0x2F4F, " 6BCB"), - (0x2F50, " 6BD4"), - (0x2F51, " 6BDB"), - (0x2F52, " 6C0F"), - (0x2F53, " 6C14"), - (0x2F54, " 6C34"), - (0x2F55, " 706B"), - (0x2F56, " 722A"), - (0x2F57, " 7236"), - (0x2F58, " 723B"), - (0x2F59, " 723F"), - (0x2F5A, " 7247"), - (0x2F5B, " 7259"), - (0x2F5C, " 725B"), - (0x2F5D, " 72AC"), - (0x2F5E, " 7384"), - (0x2F5F, " 7389"), - (0x2F60, " 74DC"), - (0x2F61, " 74E6"), - (0x2F62, " 7518"), - (0x2F63, " 751F"), - (0x2F64, " 7528"), - (0x2F65, " 7530"), - (0x2F66, " 758B"), - (0x2F67, " 7592"), - (0x2F68, " 7676"), - (0x2F69, " 767D"), - (0x2F6A, " 76AE"), - (0x2F6B, " 76BF"), - (0x2F6C, " 76EE"), - (0x2F6D, " 77DB"), - (0x2F6E, " 77E2"), - (0x2F6F, " 77F3"), - (0x2F70, " 793A"), - (0x2F71, " 79B8"), - (0x2F72, " 79BE"), - (0x2F73, " 7A74"), - (0x2F74, " 7ACB"), - (0x2F75, " 7AF9"), - (0x2F76, " 7C73"), - (0x2F77, " 7CF8"), - (0x2F78, " 7F36"), - (0x2F79, " 7F51"), - (0x2F7A, " 7F8A"), - (0x2F7B, " 7FBD"), - (0x2F7C, " 8001"), - (0x2F7D, " 800C"), - (0x2F7E, " 8012"), - (0x2F7F, " 8033"), - (0x2F80, " 807F"), - (0x2F81, " 8089"), - (0x2F82, " 81E3"), - (0x2F83, " 81EA"), - (0x2F84, " 81F3"), - (0x2F85, " 81FC"), - (0x2F86, " 820C"), - (0x2F87, " 821B"), - (0x2F88, " 821F"), - (0x2F89, " 826E"), - (0x2F8A, " 8272"), - (0x2F8B, " 8278"), - (0x2F8C, " 864D"), - (0x2F8D, " 866B"), - (0x2F8E, " 8840"), - (0x2F8F, " 884C"), - (0x2F90, " 8863"), - (0x2F91, " 897E"), - (0x2F92, " 898B"), - (0x2F93, " 89D2"), - (0x2F94, " 8A00"), - (0x2F95, " 8C37"), - (0x2F96, " 8C46"), - (0x2F97, " 8C55"), - (0x2F98, " 8C78"), - (0x2F99, " 8C9D"), - (0x2F9A, " 8D64"), - (0x2F9B, " 8D70"), - (0x2F9C, " 8DB3"), - (0x2F9D, " 8EAB"), - (0x2F9E, " 8ECA"), - (0x2F9F, " 8F9B"), - (0x2FA0, " 8FB0"), - (0x2FA1, " 8FB5"), - (0x2FA2, " 9091"), - (0x2FA3, " 9149"), - (0x2FA4, " 91C6"), - (0x2FA5, " 91CC"), - (0x2FA6, " 91D1"), - (0x2FA7, " 9577"), - (0x2FA8, " 9580"), - (0x2FA9, " 961C"), - (0x2FAA, " 96B6"), - (0x2FAB, " 96B9"), - (0x2FAC, " 96E8"), - (0x2FAD, " 9751"), - (0x2FAE, " 975E"), - (0x2FAF, " 9762"), - (0x2FB0, " 9769"), - (0x2FB1, " 97CB"), - (0x2FB2, " 97ED"), - (0x2FB3, " 97F3"), - (0x2FB4, " 9801"), - (0x2FB5, " 98A8"), - (0x2FB6, " 98DB"), - (0x2FB7, " 98DF"), - (0x2FB8, " 9996"), - (0x2FB9, " 9999"), - (0x2FBA, " 99AC"), - (0x2FBB, " 9AA8"), - (0x2FBC, " 9AD8"), - (0x2FBD, " 9ADF"), - (0x2FBE, " 9B25"), - (0x2FBF, " 9B2F"), - (0x2FC0, " 9B32"), - (0x2FC1, " 9B3C"), - (0x2FC2, " 9B5A"), - (0x2FC3, " 9CE5"), - (0x2FC4, " 9E75"), - (0x2FC5, " 9E7F"), - (0x2FC6, " 9EA5"), - (0x2FC7, " 9EBB"), - (0x2FC8, " 9EC3"), - (0x2FC9, " 9ECD"), - (0x2FCA, " 9ED1"), - (0x2FCB, " 9EF9"), - (0x2FCC, " 9EFD"), - (0x2FCD, " 9F0E"), - (0x2FCE, " 9F13"), - (0x2FCF, " 9F20"), - (0x2FD0, " 9F3B"), - (0x2FD1, " 9F4A"), - (0x2FD2, " 9F52"), - (0x2FD3, " 9F8D"), - (0x2FD4, " 9F9C"), - (0x2FD5, " 9FA0"), - (0x3000, " 0020"), - (0x3036, " 3012"), - (0x3038, " 5341"), - (0x3039, " 5344"), - (0x303A, " 5345"), - (0x304C, "304B 3099"), - (0x304E, "304D 3099"), - (0x3050, "304F 3099"), - (0x3052, "3051 3099"), - (0x3054, "3053 3099"), - (0x3056, "3055 3099"), - (0x3058, "3057 3099"), - (0x305A, "3059 3099"), - (0x305C, "305B 3099"), - (0x305E, "305D 3099"), - (0x3060, "305F 3099"), - (0x3062, "3061 3099"), - (0x3065, "3064 3099"), - (0x3067, "3066 3099"), - (0x3069, "3068 3099"), - (0x3070, "306F 3099"), - (0x3071, "306F 309A"), - (0x3073, "3072 3099"), - (0x3074, "3072 309A"), - (0x3076, "3075 3099"), - (0x3077, "3075 309A"), - (0x3079, "3078 3099"), - (0x307A, "3078 309A"), - (0x307C, "307B 3099"), - (0x307D, "307B 309A"), - (0x3094, "3046 3099"), - (0x309B, " 0020 3099"), - (0x309C, " 0020 309A"), - (0x309E, "309D 3099"), - (0x309F, " 3088 308A"), - (0x30AC, "30AB 3099"), - (0x30AE, "30AD 3099"), - (0x30B0, "30AF 3099"), - (0x30B2, "30B1 3099"), - (0x30B4, "30B3 3099"), - (0x30B6, "30B5 3099"), - (0x30B8, "30B7 3099"), - (0x30BA, "30B9 3099"), - (0x30BC, "30BB 3099"), - (0x30BE, "30BD 3099"), - (0x30C0, "30BF 3099"), - (0x30C2, "30C1 3099"), - (0x30C5, "30C4 3099"), - (0x30C7, "30C6 3099"), - (0x30C9, "30C8 3099"), - (0x30D0, "30CF 3099"), - (0x30D1, "30CF 309A"), - (0x30D3, "30D2 3099"), - (0x30D4, "30D2 309A"), - (0x30D6, "30D5 3099"), - (0x30D7, "30D5 309A"), - (0x30D9, "30D8 3099"), - (0x30DA, "30D8 309A"), - (0x30DC, "30DB 3099"), - (0x30DD, "30DB 309A"), - (0x30F4, "30A6 3099"), - (0x30F7, "30EF 3099"), - (0x30F8, "30F0 3099"), - (0x30F9, "30F1 3099"), - (0x30FA, "30F2 3099"), - (0x30FE, "30FD 3099"), - (0x30FF, " 30B3 30C8"), - (0x3131, " 1100"), - (0x3132, " 1101"), - (0x3133, " 11AA"), - (0x3134, " 1102"), - (0x3135, " 11AC"), - (0x3136, " 11AD"), - (0x3137, " 1103"), - (0x3138, " 1104"), - (0x3139, " 1105"), - (0x313A, " 11B0"), - (0x313B, " 11B1"), - (0x313C, " 11B2"), - (0x313D, " 11B3"), - (0x313E, " 11B4"), - (0x313F, " 11B5"), - (0x3140, " 111A"), - (0x3141, " 1106"), - (0x3142, " 1107"), - (0x3143, " 1108"), - (0x3144, " 1121"), - (0x3145, " 1109"), - (0x3146, " 110A"), - (0x3147, " 110B"), - (0x3148, " 110C"), - (0x3149, " 110D"), - (0x314A, " 110E"), - (0x314B, " 110F"), - (0x314C, " 1110"), - (0x314D, " 1111"), - (0x314E, " 1112"), - (0x314F, " 1161"), - (0x3150, " 1162"), - (0x3151, " 1163"), - (0x3152, " 1164"), - (0x3153, " 1165"), - (0x3154, " 1166"), - (0x3155, " 1167"), - (0x3156, " 1168"), - (0x3157, " 1169"), - (0x3158, " 116A"), - (0x3159, " 116B"), - (0x315A, " 116C"), - (0x315B, " 116D"), - (0x315C, " 116E"), - (0x315D, " 116F"), - (0x315E, " 1170"), - (0x315F, " 1171"), - (0x3160, " 1172"), - (0x3161, " 1173"), - (0x3162, " 1174"), - (0x3163, " 1175"), - (0x3164, " 1160"), - (0x3165, " 1114"), - (0x3166, " 1115"), - (0x3167, " 11C7"), - (0x3168, " 11C8"), - (0x3169, " 11CC"), - (0x316A, " 11CE"), - (0x316B, " 11D3"), - (0x316C, " 11D7"), - (0x316D, " 11D9"), - (0x316E, " 111C"), - (0x316F, " 11DD"), - (0x3170, " 11DF"), - (0x3171, " 111D"), - (0x3172, " 111E"), - (0x3173, " 1120"), - (0x3174, " 1122"), - (0x3175, " 1123"), - (0x3176, " 1127"), - (0x3177, " 1129"), - (0x3178, " 112B"), - (0x3179, " 112C"), - (0x317A, " 112D"), - (0x317B, " 112E"), - (0x317C, " 112F"), - (0x317D, " 1132"), - (0x317E, " 1136"), - (0x317F, " 1140"), - (0x3180, " 1147"), - (0x3181, " 114C"), - (0x3182, " 11F1"), - (0x3183, " 11F2"), - (0x3184, " 1157"), - (0x3185, " 1158"), - (0x3186, " 1159"), - (0x3187, " 1184"), - (0x3188, " 1185"), - (0x3189, " 1188"), - (0x318A, " 1191"), - (0x318B, " 1192"), - (0x318C, " 1194"), - (0x318D, " 119E"), - (0x318E, " 11A1"), - (0x3192, " 4E00"), - (0x3193, " 4E8C"), - (0x3194, " 4E09"), - (0x3195, " 56DB"), - (0x3196, " 4E0A"), - (0x3197, " 4E2D"), - (0x3198, " 4E0B"), - (0x3199, " 7532"), - (0x319A, " 4E59"), - (0x319B, " 4E19"), - (0x319C, " 4E01"), - (0x319D, " 5929"), - (0x319E, " 5730"), - (0x319F, " 4EBA"), - (0x3200, " 0028 1100 0029"), - (0x3201, " 0028 1102 0029"), - (0x3202, " 0028 1103 0029"), - (0x3203, " 0028 1105 0029"), - (0x3204, " 0028 1106 0029"), - (0x3205, " 0028 1107 0029"), - (0x3206, " 0028 1109 0029"), - (0x3207, " 0028 110B 0029"), - (0x3208, " 0028 110C 0029"), - (0x3209, " 0028 110E 0029"), - (0x320A, " 0028 110F 0029"), - (0x320B, " 0028 1110 0029"), - (0x320C, " 0028 1111 0029"), - (0x320D, " 0028 1112 0029"), - (0x320E, " 0028 1100 1161 0029"), - (0x320F, " 0028 1102 1161 0029"), - (0x3210, " 0028 1103 1161 0029"), - (0x3211, " 0028 1105 1161 0029"), - (0x3212, " 0028 1106 1161 0029"), - (0x3213, " 0028 1107 1161 0029"), - (0x3214, " 0028 1109 1161 0029"), - (0x3215, " 0028 110B 1161 0029"), - (0x3216, " 0028 110C 1161 0029"), - (0x3217, " 0028 110E 1161 0029"), - (0x3218, " 0028 110F 1161 0029"), - (0x3219, " 0028 1110 1161 0029"), - (0x321A, " 0028 1111 1161 0029"), - (0x321B, " 0028 1112 1161 0029"), - (0x321C, " 0028 110C 116E 0029"), - (0x321D, " 0028 110B 1169 110C 1165 11AB 0029"), - (0x321E, " 0028 110B 1169 1112 116E 0029"), - (0x3220, " 0028 4E00 0029"), - (0x3221, " 0028 4E8C 0029"), - (0x3222, " 0028 4E09 0029"), - (0x3223, " 0028 56DB 0029"), - (0x3224, " 0028 4E94 0029"), - (0x3225, " 0028 516D 0029"), - (0x3226, " 0028 4E03 0029"), - (0x3227, " 0028 516B 0029"), - (0x3228, " 0028 4E5D 0029"), - (0x3229, " 0028 5341 0029"), - (0x322A, " 0028 6708 0029"), - (0x322B, " 0028 706B 0029"), - (0x322C, " 0028 6C34 0029"), - (0x322D, " 0028 6728 0029"), - (0x322E, " 0028 91D1 0029"), - (0x322F, " 0028 571F 0029"), - (0x3230, " 0028 65E5 0029"), - (0x3231, " 0028 682A 0029"), - (0x3232, " 0028 6709 0029"), - (0x3233, " 0028 793E 0029"), - (0x3234, " 0028 540D 0029"), - (0x3235, " 0028 7279 0029"), - (0x3236, " 0028 8CA1 0029"), - (0x3237, " 0028 795D 0029"), - (0x3238, " 0028 52B4 0029"), - (0x3239, " 0028 4EE3 0029"), - (0x323A, " 0028 547C 0029"), - (0x323B, " 0028 5B66 0029"), - (0x323C, " 0028 76E3 0029"), - (0x323D, " 0028 4F01 0029"), - (0x323E, " 0028 8CC7 0029"), - (0x323F, " 0028 5354 0029"), - (0x3240, " 0028 796D 0029"), - (0x3241, " 0028 4F11 0029"), - (0x3242, " 0028 81EA 0029"), - (0x3243, " 0028 81F3 0029"), - (0x3244, " 554F"), - (0x3245, " 5E7C"), - (0x3246, " 6587"), - (0x3247, " 7B8F"), - (0x3250, " 0050 0054 0045"), - (0x3251, " 0032 0031"), - (0x3252, " 0032 0032"), - (0x3253, " 0032 0033"), - (0x3254, " 0032 0034"), - (0x3255, " 0032 0035"), - (0x3256, " 0032 0036"), - (0x3257, " 0032 0037"), - (0x3258, " 0032 0038"), - (0x3259, " 0032 0039"), - (0x325A, " 0033 0030"), - (0x325B, " 0033 0031"), - (0x325C, " 0033 0032"), - (0x325D, " 0033 0033"), - (0x325E, " 0033 0034"), - (0x325F, " 0033 0035"), - (0x3260, " 1100"), - (0x3261, " 1102"), - (0x3262, " 1103"), - (0x3263, " 1105"), - (0x3264, " 1106"), - (0x3265, " 1107"), - (0x3266, " 1109"), - (0x3267, " 110B"), - (0x3268, " 110C"), - (0x3269, " 110E"), - (0x326A, " 110F"), - (0x326B, " 1110"), - (0x326C, " 1111"), - (0x326D, " 1112"), - (0x326E, " 1100 1161"), - (0x326F, " 1102 1161"), - (0x3270, " 1103 1161"), - (0x3271, " 1105 1161"), - (0x3272, " 1106 1161"), - (0x3273, " 1107 1161"), - (0x3274, " 1109 1161"), - (0x3275, " 110B 1161"), - (0x3276, " 110C 1161"), - (0x3277, " 110E 1161"), - (0x3278, " 110F 1161"), - (0x3279, " 1110 1161"), - (0x327A, " 1111 1161"), - (0x327B, " 1112 1161"), - (0x327C, " 110E 1161 11B7 1100 1169"), - (0x327D, " 110C 116E 110B 1174"), - (0x327E, " 110B 116E"), - (0x3280, " 4E00"), - (0x3281, " 4E8C"), - (0x3282, " 4E09"), - (0x3283, " 56DB"), - (0x3284, " 4E94"), - (0x3285, " 516D"), - (0x3286, " 4E03"), - (0x3287, " 516B"), - (0x3288, " 4E5D"), - (0x3289, " 5341"), - (0x328A, " 6708"), - (0x328B, " 706B"), - (0x328C, " 6C34"), - (0x328D, " 6728"), - (0x328E, " 91D1"), - (0x328F, " 571F"), - (0x3290, " 65E5"), - (0x3291, " 682A"), - (0x3292, " 6709"), - (0x3293, " 793E"), - (0x3294, " 540D"), - (0x3295, " 7279"), - (0x3296, " 8CA1"), - (0x3297, " 795D"), - (0x3298, " 52B4"), - (0x3299, " 79D8"), - (0x329A, " 7537"), - (0x329B, " 5973"), - (0x329C, " 9069"), - (0x329D, " 512A"), - (0x329E, " 5370"), - (0x329F, " 6CE8"), - (0x32A0, " 9805"), - (0x32A1, " 4F11"), - (0x32A2, " 5199"), - (0x32A3, " 6B63"), - (0x32A4, " 4E0A"), - (0x32A5, " 4E2D"), - (0x32A6, " 4E0B"), - (0x32A7, " 5DE6"), - (0x32A8, " 53F3"), - (0x32A9, " 533B"), - (0x32AA, " 5B97"), - (0x32AB, " 5B66"), - (0x32AC, " 76E3"), - (0x32AD, " 4F01"), - (0x32AE, " 8CC7"), - (0x32AF, " 5354"), - (0x32B0, " 591C"), - (0x32B1, " 0033 0036"), - (0x32B2, " 0033 0037"), - (0x32B3, " 0033 0038"), - (0x32B4, " 0033 0039"), - (0x32B5, " 0034 0030"), - (0x32B6, " 0034 0031"), - (0x32B7, " 0034 0032"), - (0x32B8, " 0034 0033"), - (0x32B9, " 0034 0034"), - (0x32BA, " 0034 0035"), - (0x32BB, " 0034 0036"), - (0x32BC, " 0034 0037"), - (0x32BD, " 0034 0038"), - (0x32BE, " 0034 0039"), - (0x32BF, " 0035 0030"), - (0x32C0, " 0031 6708"), - (0x32C1, " 0032 6708"), - (0x32C2, " 0033 6708"), - (0x32C3, " 0034 6708"), - (0x32C4, " 0035 6708"), - (0x32C5, " 0036 6708"), - (0x32C6, " 0037 6708"), - (0x32C7, " 0038 6708"), - (0x32C8, " 0039 6708"), - (0x32C9, " 0031 0030 6708"), - (0x32CA, " 0031 0031 6708"), - (0x32CB, " 0031 0032 6708"), - (0x32CC, " 0048 0067"), - (0x32CD, " 0065 0072 0067"), - (0x32CE, " 0065 0056"), - (0x32CF, " 004C 0054 0044"), - (0x32D0, " 30A2"), - (0x32D1, " 30A4"), - (0x32D2, " 30A6"), - (0x32D3, " 30A8"), - (0x32D4, " 30AA"), - (0x32D5, " 30AB"), - (0x32D6, " 30AD"), - (0x32D7, " 30AF"), - (0x32D8, " 30B1"), - (0x32D9, " 30B3"), - (0x32DA, " 30B5"), - (0x32DB, " 30B7"), - (0x32DC, " 30B9"), - (0x32DD, " 30BB"), - (0x32DE, " 30BD"), - (0x32DF, " 30BF"), - (0x32E0, " 30C1"), - (0x32E1, " 30C4"), - (0x32E2, " 30C6"), - (0x32E3, " 30C8"), - (0x32E4, " 30CA"), - (0x32E5, " 30CB"), - (0x32E6, " 30CC"), - (0x32E7, " 30CD"), - (0x32E8, " 30CE"), - (0x32E9, " 30CF"), - (0x32EA, " 30D2"), - (0x32EB, " 30D5"), - (0x32EC, " 30D8"), - (0x32ED, " 30DB"), - (0x32EE, " 30DE"), - (0x32EF, " 30DF"), - (0x32F0, " 30E0"), - (0x32F1, " 30E1"), - (0x32F2, " 30E2"), - (0x32F3, " 30E4"), - (0x32F4, " 30E6"), - (0x32F5, " 30E8"), - (0x32F6, " 30E9"), - (0x32F7, " 30EA"), - (0x32F8, " 30EB"), - (0x32F9, " 30EC"), - (0x32FA, " 30ED"), - (0x32FB, " 30EF"), - (0x32FC, " 30F0"), - (0x32FD, " 30F1"), - (0x32FE, " 30F2"), - (0x32FF, " 4EE4 548C"), - (0x3300, " 30A2 30D1 30FC 30C8"), - (0x3301, " 30A2 30EB 30D5 30A1"), - (0x3302, " 30A2 30F3 30DA 30A2"), - (0x3303, " 30A2 30FC 30EB"), - (0x3304, " 30A4 30CB 30F3 30B0"), - (0x3305, " 30A4 30F3 30C1"), - (0x3306, " 30A6 30A9 30F3"), - (0x3307, " 30A8 30B9 30AF 30FC 30C9"), - (0x3308, " 30A8 30FC 30AB 30FC"), - (0x3309, " 30AA 30F3 30B9"), - (0x330A, " 30AA 30FC 30E0"), - (0x330B, " 30AB 30A4 30EA"), - (0x330C, " 30AB 30E9 30C3 30C8"), - (0x330D, " 30AB 30ED 30EA 30FC"), - (0x330E, " 30AC 30ED 30F3"), - (0x330F, " 30AC 30F3 30DE"), - (0x3310, " 30AE 30AC"), - (0x3311, " 30AE 30CB 30FC"), - (0x3312, " 30AD 30E5 30EA 30FC"), - (0x3313, " 30AE 30EB 30C0 30FC"), - (0x3314, " 30AD 30ED"), - (0x3315, " 30AD 30ED 30B0 30E9 30E0"), - (0x3316, " 30AD 30ED 30E1 30FC 30C8 30EB"), - (0x3317, " 30AD 30ED 30EF 30C3 30C8"), - (0x3318, " 30B0 30E9 30E0"), - (0x3319, " 30B0 30E9 30E0 30C8 30F3"), - (0x331A, " 30AF 30EB 30BC 30A4 30ED"), - (0x331B, " 30AF 30ED 30FC 30CD"), - (0x331C, " 30B1 30FC 30B9"), - (0x331D, " 30B3 30EB 30CA"), - (0x331E, " 30B3 30FC 30DD"), - (0x331F, " 30B5 30A4 30AF 30EB"), - (0x3320, " 30B5 30F3 30C1 30FC 30E0"), - (0x3321, " 30B7 30EA 30F3 30B0"), - (0x3322, " 30BB 30F3 30C1"), - (0x3323, " 30BB 30F3 30C8"), - (0x3324, " 30C0 30FC 30B9"), - (0x3325, " 30C7 30B7"), - (0x3326, " 30C9 30EB"), - (0x3327, " 30C8 30F3"), - (0x3328, " 30CA 30CE"), - (0x3329, " 30CE 30C3 30C8"), - (0x332A, " 30CF 30A4 30C4"), - (0x332B, " 30D1 30FC 30BB 30F3 30C8"), - (0x332C, " 30D1 30FC 30C4"), - (0x332D, " 30D0 30FC 30EC 30EB"), - (0x332E, " 30D4 30A2 30B9 30C8 30EB"), - (0x332F, " 30D4 30AF 30EB"), - (0x3330, " 30D4 30B3"), - (0x3331, " 30D3 30EB"), - (0x3332, " 30D5 30A1 30E9 30C3 30C9"), - (0x3333, " 30D5 30A3 30FC 30C8"), - (0x3334, " 30D6 30C3 30B7 30A7 30EB"), - (0x3335, " 30D5 30E9 30F3"), - (0x3336, " 30D8 30AF 30BF 30FC 30EB"), - (0x3337, " 30DA 30BD"), - (0x3338, " 30DA 30CB 30D2"), - (0x3339, " 30D8 30EB 30C4"), - (0x333A, " 30DA 30F3 30B9"), - (0x333B, " 30DA 30FC 30B8"), - (0x333C, " 30D9 30FC 30BF"), - (0x333D, " 30DD 30A4 30F3 30C8"), - (0x333E, " 30DC 30EB 30C8"), - (0x333F, " 30DB 30F3"), - (0x3340, " 30DD 30F3 30C9"), - (0x3341, " 30DB 30FC 30EB"), - (0x3342, " 30DB 30FC 30F3"), - (0x3343, " 30DE 30A4 30AF 30ED"), - (0x3344, " 30DE 30A4 30EB"), - (0x3345, " 30DE 30C3 30CF"), - (0x3346, " 30DE 30EB 30AF"), - (0x3347, " 30DE 30F3 30B7 30E7 30F3"), - (0x3348, " 30DF 30AF 30ED 30F3"), - (0x3349, " 30DF 30EA"), - (0x334A, " 30DF 30EA 30D0 30FC 30EB"), - (0x334B, " 30E1 30AC"), - (0x334C, " 30E1 30AC 30C8 30F3"), - (0x334D, " 30E1 30FC 30C8 30EB"), - (0x334E, " 30E4 30FC 30C9"), - (0x334F, " 30E4 30FC 30EB"), - (0x3350, " 30E6 30A2 30F3"), - (0x3351, " 30EA 30C3 30C8 30EB"), - (0x3352, " 30EA 30E9"), - (0x3353, " 30EB 30D4 30FC"), - (0x3354, " 30EB 30FC 30D6 30EB"), - (0x3355, " 30EC 30E0"), - (0x3356, " 30EC 30F3 30C8 30B2 30F3"), - (0x3357, " 30EF 30C3 30C8"), - (0x3358, " 0030 70B9"), - (0x3359, " 0031 70B9"), - (0x335A, " 0032 70B9"), - (0x335B, " 0033 70B9"), - (0x335C, " 0034 70B9"), - (0x335D, " 0035 70B9"), - (0x335E, " 0036 70B9"), - (0x335F, " 0037 70B9"), - (0x3360, " 0038 70B9"), - (0x3361, " 0039 70B9"), - (0x3362, " 0031 0030 70B9"), - (0x3363, " 0031 0031 70B9"), - (0x3364, " 0031 0032 70B9"), - (0x3365, " 0031 0033 70B9"), - (0x3366, " 0031 0034 70B9"), - (0x3367, " 0031 0035 70B9"), - (0x3368, " 0031 0036 70B9"), - (0x3369, " 0031 0037 70B9"), - (0x336A, " 0031 0038 70B9"), - (0x336B, " 0031 0039 70B9"), - (0x336C, " 0032 0030 70B9"), - (0x336D, " 0032 0031 70B9"), - (0x336E, " 0032 0032 70B9"), - (0x336F, " 0032 0033 70B9"), - (0x3370, " 0032 0034 70B9"), - (0x3371, " 0068 0050 0061"), - (0x3372, " 0064 0061"), - (0x3373, " 0041 0055"), - (0x3374, " 0062 0061 0072"), - (0x3375, " 006F 0056"), - (0x3376, " 0070 0063"), - (0x3377, " 0064 006D"), - (0x3378, " 0064 006D 00B2"), - (0x3379, " 0064 006D 00B3"), - (0x337A, " 0049 0055"), - (0x337B, " 5E73 6210"), - (0x337C, " 662D 548C"), - (0x337D, " 5927 6B63"), - (0x337E, " 660E 6CBB"), - (0x337F, " 682A 5F0F 4F1A 793E"), - (0x3380, " 0070 0041"), - (0x3381, " 006E 0041"), - (0x3382, " 03BC 0041"), - (0x3383, " 006D 0041"), - (0x3384, " 006B 0041"), - (0x3385, " 004B 0042"), - (0x3386, " 004D 0042"), - (0x3387, " 0047 0042"), - (0x3388, " 0063 0061 006C"), - (0x3389, " 006B 0063 0061 006C"), - (0x338A, " 0070 0046"), - (0x338B, " 006E 0046"), - (0x338C, " 03BC 0046"), - (0x338D, " 03BC 0067"), - (0x338E, " 006D 0067"), - (0x338F, " 006B 0067"), - (0x3390, " 0048 007A"), - (0x3391, " 006B 0048 007A"), - (0x3392, " 004D 0048 007A"), - (0x3393, " 0047 0048 007A"), - (0x3394, " 0054 0048 007A"), - (0x3395, " 03BC 2113"), - (0x3396, " 006D 2113"), - (0x3397, " 0064 2113"), - (0x3398, " 006B 2113"), - (0x3399, " 0066 006D"), - (0x339A, " 006E 006D"), - (0x339B, " 03BC 006D"), - (0x339C, " 006D 006D"), - (0x339D, " 0063 006D"), - (0x339E, " 006B 006D"), - (0x339F, " 006D 006D 00B2"), - (0x33A0, " 0063 006D 00B2"), - (0x33A1, " 006D 00B2"), - (0x33A2, " 006B 006D 00B2"), - (0x33A3, " 006D 006D 00B3"), - (0x33A4, " 0063 006D 00B3"), - (0x33A5, " 006D 00B3"), - (0x33A6, " 006B 006D 00B3"), - (0x33A7, " 006D 2215 0073"), - (0x33A8, " 006D 2215 0073 00B2"), - (0x33A9, " 0050 0061"), - (0x33AA, " 006B 0050 0061"), - (0x33AB, " 004D 0050 0061"), - (0x33AC, " 0047 0050 0061"), - (0x33AD, " 0072 0061 0064"), - (0x33AE, " 0072 0061 0064 2215 0073"), - (0x33AF, " 0072 0061 0064 2215 0073 00B2"), - (0x33B0, " 0070 0073"), - (0x33B1, " 006E 0073"), - (0x33B2, " 03BC 0073"), - (0x33B3, " 006D 0073"), - (0x33B4, " 0070 0056"), - (0x33B5, " 006E 0056"), - (0x33B6, " 03BC 0056"), - (0x33B7, " 006D 0056"), - (0x33B8, " 006B 0056"), - (0x33B9, " 004D 0056"), - (0x33BA, " 0070 0057"), - (0x33BB, " 006E 0057"), - (0x33BC, " 03BC 0057"), - (0x33BD, " 006D 0057"), - (0x33BE, " 006B 0057"), - (0x33BF, " 004D 0057"), - (0x33C0, " 006B 03A9"), - (0x33C1, " 004D 03A9"), - (0x33C2, " 0061 002E 006D 002E"), - (0x33C3, " 0042 0071"), - (0x33C4, " 0063 0063"), - (0x33C5, " 0063 0064"), - (0x33C6, " 0043 2215 006B 0067"), - (0x33C7, " 0043 006F 002E"), - (0x33C8, " 0064 0042"), - (0x33C9, " 0047 0079"), - (0x33CA, " 0068 0061"), - (0x33CB, " 0048 0050"), - (0x33CC, " 0069 006E"), - (0x33CD, " 004B 004B"), - (0x33CE, " 004B 004D"), - (0x33CF, " 006B 0074"), - (0x33D0, " 006C 006D"), - (0x33D1, " 006C 006E"), - (0x33D2, " 006C 006F 0067"), - (0x33D3, " 006C 0078"), - (0x33D4, " 006D 0062"), - (0x33D5, " 006D 0069 006C"), - (0x33D6, " 006D 006F 006C"), - (0x33D7, " 0050 0048"), - (0x33D8, " 0070 002E 006D 002E"), - (0x33D9, " 0050 0050 004D"), - (0x33DA, " 0050 0052"), - (0x33DB, " 0073 0072"), - (0x33DC, " 0053 0076"), - (0x33DD, " 0057 0062"), - (0x33DE, " 0056 2215 006D"), - (0x33DF, " 0041 2215 006D"), - (0x33E0, " 0031 65E5"), - (0x33E1, " 0032 65E5"), - (0x33E2, " 0033 65E5"), - (0x33E3, " 0034 65E5"), - (0x33E4, " 0035 65E5"), - (0x33E5, " 0036 65E5"), - (0x33E6, " 0037 65E5"), - (0x33E7, " 0038 65E5"), - (0x33E8, " 0039 65E5"), - (0x33E9, " 0031 0030 65E5"), - (0x33EA, " 0031 0031 65E5"), - (0x33EB, " 0031 0032 65E5"), - (0x33EC, " 0031 0033 65E5"), - (0x33ED, " 0031 0034 65E5"), - (0x33EE, " 0031 0035 65E5"), - (0x33EF, " 0031 0036 65E5"), - (0x33F0, " 0031 0037 65E5"), - (0x33F1, " 0031 0038 65E5"), - (0x33F2, " 0031 0039 65E5"), - (0x33F3, " 0032 0030 65E5"), - (0x33F4, " 0032 0031 65E5"), - (0x33F5, " 0032 0032 65E5"), - (0x33F6, " 0032 0033 65E5"), - (0x33F7, " 0032 0034 65E5"), - (0x33F8, " 0032 0035 65E5"), - (0x33F9, " 0032 0036 65E5"), - (0x33FA, " 0032 0037 65E5"), - (0x33FB, " 0032 0038 65E5"), - (0x33FC, " 0032 0039 65E5"), - (0x33FD, " 0033 0030 65E5"), - (0x33FE, " 0033 0031 65E5"), - (0x33FF, " 0067 0061 006C"), - (0xA69C, " 044A"), - (0xA69D, " 044C"), - (0xA770, " A76F"), - (0xA7F2, " 0043"), - (0xA7F3, " 0046"), - (0xA7F4, " 0051"), - (0xA7F8, " 0126"), - (0xA7F9, " 0153"), - (0xAB5C, " A727"), - (0xAB5D, " AB37"), - (0xAB5E, " 026B"), - (0xAB5F, " AB52"), - (0xAB69, " 028D"), - (0xAC00, "1100 1161"), - (0xAC01, "1100 1161 11A8"), - (0xAC02, "1100 1161 11A9"), - (0xAC03, "1100 1161 11AA"), - (0xAC04, "1100 1161 11AB"), - (0xAC05, "1100 1161 11AC"), - (0xAC06, "1100 1161 11AD"), - (0xAC07, "1100 1161 11AE"), - (0xAC08, "1100 1161 11AF"), - (0xAC09, "1100 1161 11B0"), - (0xAC0A, "1100 1161 11B1"), - (0xAC0B, "1100 1161 11B2"), - (0xAC0C, "1100 1161 11B3"), - (0xAC0D, "1100 1161 11B4"), - (0xAC0E, "1100 1161 11B5"), - (0xAC0F, "1100 1161 11B6"), - (0xAC10, "1100 1161 11B7"), - (0xAC11, "1100 1161 11B8"), - (0xAC12, "1100 1161 11B9"), - (0xAC13, "1100 1161 11BA"), - (0xAC14, "1100 1161 11BB"), - (0xAC15, "1100 1161 11BC"), - (0xAC16, "1100 1161 11BD"), - (0xAC17, "1100 1161 11BE"), - (0xAC18, "1100 1161 11BF"), - (0xAC19, "1100 1161 11C0"), - (0xAC1A, "1100 1161 11C1"), - (0xAC1B, "1100 1161 11C2"), - (0xAC1C, "1100 1162"), - (0xAC1D, "1100 1162 11A8"), - (0xAC1E, "1100 1162 11A9"), - (0xAC1F, "1100 1162 11AA"), - (0xAC20, "1100 1162 11AB"), - (0xAC21, "1100 1162 11AC"), - (0xAC22, "1100 1162 11AD"), - (0xAC23, "1100 1162 11AE"), - (0xAC24, "1100 1162 11AF"), - (0xAC25, "1100 1162 11B0"), - (0xAC26, "1100 1162 11B1"), - (0xAC27, "1100 1162 11B2"), - (0xAC28, "1100 1162 11B3"), - (0xAC29, "1100 1162 11B4"), - (0xAC2A, "1100 1162 11B5"), - (0xAC2B, "1100 1162 11B6"), - (0xAC2C, "1100 1162 11B7"), - (0xAC2D, "1100 1162 11B8"), - (0xAC2E, "1100 1162 11B9"), - (0xAC2F, "1100 1162 11BA"), - (0xAC30, "1100 1162 11BB"), - (0xAC31, "1100 1162 11BC"), - (0xAC32, "1100 1162 11BD"), - (0xAC33, "1100 1162 11BE"), - (0xAC34, "1100 1162 11BF"), - (0xAC35, "1100 1162 11C0"), - (0xAC36, "1100 1162 11C1"), - (0xAC37, "1100 1162 11C2"), - (0xAC38, "1100 1163"), - (0xAC39, "1100 1163 11A8"), - (0xAC3A, "1100 1163 11A9"), - (0xAC3B, "1100 1163 11AA"), - (0xAC3C, "1100 1163 11AB"), - (0xAC3D, "1100 1163 11AC"), - (0xAC3E, "1100 1163 11AD"), - (0xAC3F, "1100 1163 11AE"), - (0xAC40, "1100 1163 11AF"), - (0xAC41, "1100 1163 11B0"), - (0xAC42, "1100 1163 11B1"), - (0xAC43, "1100 1163 11B2"), - (0xAC44, "1100 1163 11B3"), - (0xAC45, "1100 1163 11B4"), - (0xAC46, "1100 1163 11B5"), - (0xAC47, "1100 1163 11B6"), - (0xAC48, "1100 1163 11B7"), - (0xAC49, "1100 1163 11B8"), - (0xAC4A, "1100 1163 11B9"), - (0xAC4B, "1100 1163 11BA"), - (0xAC4C, "1100 1163 11BB"), - (0xAC4D, "1100 1163 11BC"), - (0xAC4E, "1100 1163 11BD"), - (0xAC4F, "1100 1163 11BE"), - (0xAC50, "1100 1163 11BF"), - (0xAC51, "1100 1163 11C0"), - (0xAC52, "1100 1163 11C1"), - (0xAC53, "1100 1163 11C2"), - (0xAC54, "1100 1164"), - (0xAC55, "1100 1164 11A8"), - (0xAC56, "1100 1164 11A9"), - (0xAC57, "1100 1164 11AA"), - (0xAC58, "1100 1164 11AB"), - (0xAC59, "1100 1164 11AC"), - (0xAC5A, "1100 1164 11AD"), - (0xAC5B, "1100 1164 11AE"), - (0xAC5C, "1100 1164 11AF"), - (0xAC5D, "1100 1164 11B0"), - (0xAC5E, "1100 1164 11B1"), - (0xAC5F, "1100 1164 11B2"), - (0xAC60, "1100 1164 11B3"), - (0xAC61, "1100 1164 11B4"), - (0xAC62, "1100 1164 11B5"), - (0xAC63, "1100 1164 11B6"), - (0xAC64, "1100 1164 11B7"), - (0xAC65, "1100 1164 11B8"), - (0xAC66, "1100 1164 11B9"), - (0xAC67, "1100 1164 11BA"), - (0xAC68, "1100 1164 11BB"), - (0xAC69, "1100 1164 11BC"), - (0xAC6A, "1100 1164 11BD"), - (0xAC6B, "1100 1164 11BE"), - (0xAC6C, "1100 1164 11BF"), - (0xAC6D, "1100 1164 11C0"), - (0xAC6E, "1100 1164 11C1"), - (0xAC6F, "1100 1164 11C2"), - (0xAC70, "1100 1165"), - (0xAC71, "1100 1165 11A8"), - (0xAC72, "1100 1165 11A9"), - (0xAC73, "1100 1165 11AA"), - (0xAC74, "1100 1165 11AB"), - (0xAC75, "1100 1165 11AC"), - (0xAC76, "1100 1165 11AD"), - (0xAC77, "1100 1165 11AE"), - (0xAC78, "1100 1165 11AF"), - (0xAC79, "1100 1165 11B0"), - (0xAC7A, "1100 1165 11B1"), - (0xAC7B, "1100 1165 11B2"), - (0xAC7C, "1100 1165 11B3"), - (0xAC7D, "1100 1165 11B4"), - (0xAC7E, "1100 1165 11B5"), - (0xAC7F, "1100 1165 11B6"), - (0xAC80, "1100 1165 11B7"), - (0xAC81, "1100 1165 11B8"), - (0xAC82, "1100 1165 11B9"), - (0xAC83, "1100 1165 11BA"), - (0xAC84, "1100 1165 11BB"), - (0xAC85, "1100 1165 11BC"), - (0xAC86, "1100 1165 11BD"), - (0xAC87, "1100 1165 11BE"), - (0xAC88, "1100 1165 11BF"), - (0xAC89, "1100 1165 11C0"), - (0xAC8A, "1100 1165 11C1"), - (0xAC8B, "1100 1165 11C2"), - (0xAC8C, "1100 1166"), - (0xAC8D, "1100 1166 11A8"), - (0xAC8E, "1100 1166 11A9"), - (0xAC8F, "1100 1166 11AA"), - (0xAC90, "1100 1166 11AB"), - (0xAC91, "1100 1166 11AC"), - (0xAC92, "1100 1166 11AD"), - (0xAC93, "1100 1166 11AE"), - (0xAC94, "1100 1166 11AF"), - (0xAC95, "1100 1166 11B0"), - (0xAC96, "1100 1166 11B1"), - (0xAC97, "1100 1166 11B2"), - (0xAC98, "1100 1166 11B3"), - (0xAC99, "1100 1166 11B4"), - (0xAC9A, "1100 1166 11B5"), - (0xAC9B, "1100 1166 11B6"), - (0xAC9C, "1100 1166 11B7"), - (0xAC9D, "1100 1166 11B8"), - (0xAC9E, "1100 1166 11B9"), - (0xAC9F, "1100 1166 11BA"), - (0xACA0, "1100 1166 11BB"), - (0xACA1, "1100 1166 11BC"), - (0xACA2, "1100 1166 11BD"), - (0xACA3, "1100 1166 11BE"), - (0xACA4, "1100 1166 11BF"), - (0xACA5, "1100 1166 11C0"), - (0xACA6, "1100 1166 11C1"), - (0xACA7, "1100 1166 11C2"), - (0xACA8, "1100 1167"), - (0xACA9, "1100 1167 11A8"), - (0xACAA, "1100 1167 11A9"), - (0xACAB, "1100 1167 11AA"), - (0xACAC, "1100 1167 11AB"), - (0xACAD, "1100 1167 11AC"), - (0xACAE, "1100 1167 11AD"), - (0xACAF, "1100 1167 11AE"), - (0xACB0, "1100 1167 11AF"), - (0xACB1, "1100 1167 11B0"), - (0xACB2, "1100 1167 11B1"), - (0xACB3, "1100 1167 11B2"), - (0xACB4, "1100 1167 11B3"), - (0xACB5, "1100 1167 11B4"), - (0xACB6, "1100 1167 11B5"), - (0xACB7, "1100 1167 11B6"), - (0xACB8, "1100 1167 11B7"), - (0xACB9, "1100 1167 11B8"), - (0xACBA, "1100 1167 11B9"), - (0xACBB, "1100 1167 11BA"), - (0xACBC, "1100 1167 11BB"), - (0xACBD, "1100 1167 11BC"), - (0xACBE, "1100 1167 11BD"), - (0xACBF, "1100 1167 11BE"), - (0xACC0, "1100 1167 11BF"), - (0xACC1, "1100 1167 11C0"), - (0xACC2, "1100 1167 11C1"), - (0xACC3, "1100 1167 11C2"), - (0xACC4, "1100 1168"), - (0xACC5, "1100 1168 11A8"), - (0xACC6, "1100 1168 11A9"), - (0xACC7, "1100 1168 11AA"), - (0xACC8, "1100 1168 11AB"), - (0xACC9, "1100 1168 11AC"), - (0xACCA, "1100 1168 11AD"), - (0xACCB, "1100 1168 11AE"), - (0xACCC, "1100 1168 11AF"), - (0xACCD, "1100 1168 11B0"), - (0xACCE, "1100 1168 11B1"), - (0xACCF, "1100 1168 11B2"), - (0xACD0, "1100 1168 11B3"), - (0xACD1, "1100 1168 11B4"), - (0xACD2, "1100 1168 11B5"), - (0xACD3, "1100 1168 11B6"), - (0xACD4, "1100 1168 11B7"), - (0xACD5, "1100 1168 11B8"), - (0xACD6, "1100 1168 11B9"), - (0xACD7, "1100 1168 11BA"), - (0xACD8, "1100 1168 11BB"), - (0xACD9, "1100 1168 11BC"), - (0xACDA, "1100 1168 11BD"), - (0xACDB, "1100 1168 11BE"), - (0xACDC, "1100 1168 11BF"), - (0xACDD, "1100 1168 11C0"), - (0xACDE, "1100 1168 11C1"), - (0xACDF, "1100 1168 11C2"), - (0xACE0, "1100 1169"), - (0xACE1, "1100 1169 11A8"), - (0xACE2, "1100 1169 11A9"), - (0xACE3, "1100 1169 11AA"), - (0xACE4, "1100 1169 11AB"), - (0xACE5, "1100 1169 11AC"), - (0xACE6, "1100 1169 11AD"), - (0xACE7, "1100 1169 11AE"), - (0xACE8, "1100 1169 11AF"), - (0xACE9, "1100 1169 11B0"), - (0xACEA, "1100 1169 11B1"), - (0xACEB, "1100 1169 11B2"), - (0xACEC, "1100 1169 11B3"), - (0xACED, "1100 1169 11B4"), - (0xACEE, "1100 1169 11B5"), - (0xACEF, "1100 1169 11B6"), - (0xACF0, "1100 1169 11B7"), - (0xACF1, "1100 1169 11B8"), - (0xACF2, "1100 1169 11B9"), - (0xACF3, "1100 1169 11BA"), - (0xACF4, "1100 1169 11BB"), - (0xACF5, "1100 1169 11BC"), - (0xACF6, "1100 1169 11BD"), - (0xACF7, "1100 1169 11BE"), - (0xACF8, "1100 1169 11BF"), - (0xACF9, "1100 1169 11C0"), - (0xACFA, "1100 1169 11C1"), - (0xACFB, "1100 1169 11C2"), - (0xACFC, "1100 116A"), - (0xACFD, "1100 116A 11A8"), - (0xACFE, "1100 116A 11A9"), - (0xACFF, "1100 116A 11AA"), - (0xAD00, "1100 116A 11AB"), - (0xAD01, "1100 116A 11AC"), - (0xAD02, "1100 116A 11AD"), - (0xAD03, "1100 116A 11AE"), - (0xAD04, "1100 116A 11AF"), - (0xAD05, "1100 116A 11B0"), - (0xAD06, "1100 116A 11B1"), - (0xAD07, "1100 116A 11B2"), - (0xAD08, "1100 116A 11B3"), - (0xAD09, "1100 116A 11B4"), - (0xAD0A, "1100 116A 11B5"), - (0xAD0B, "1100 116A 11B6"), - (0xAD0C, "1100 116A 11B7"), - (0xAD0D, "1100 116A 11B8"), - (0xAD0E, "1100 116A 11B9"), - (0xAD0F, "1100 116A 11BA"), - (0xAD10, "1100 116A 11BB"), - (0xAD11, "1100 116A 11BC"), - (0xAD12, "1100 116A 11BD"), - (0xAD13, "1100 116A 11BE"), - (0xAD14, "1100 116A 11BF"), - (0xAD15, "1100 116A 11C0"), - (0xAD16, "1100 116A 11C1"), - (0xAD17, "1100 116A 11C2"), - (0xAD18, "1100 116B"), - (0xAD19, "1100 116B 11A8"), - (0xAD1A, "1100 116B 11A9"), - (0xAD1B, "1100 116B 11AA"), - (0xAD1C, "1100 116B 11AB"), - (0xAD1D, "1100 116B 11AC"), - (0xAD1E, "1100 116B 11AD"), - (0xAD1F, "1100 116B 11AE"), - (0xAD20, "1100 116B 11AF"), - (0xAD21, "1100 116B 11B0"), - (0xAD22, "1100 116B 11B1"), - (0xAD23, "1100 116B 11B2"), - (0xAD24, "1100 116B 11B3"), - (0xAD25, "1100 116B 11B4"), - (0xAD26, "1100 116B 11B5"), - (0xAD27, "1100 116B 11B6"), - (0xAD28, "1100 116B 11B7"), - (0xAD29, "1100 116B 11B8"), - (0xAD2A, "1100 116B 11B9"), - (0xAD2B, "1100 116B 11BA"), - (0xAD2C, "1100 116B 11BB"), - (0xAD2D, "1100 116B 11BC"), - (0xAD2E, "1100 116B 11BD"), - (0xAD2F, "1100 116B 11BE"), - (0xAD30, "1100 116B 11BF"), - (0xAD31, "1100 116B 11C0"), - (0xAD32, "1100 116B 11C1"), - (0xAD33, "1100 116B 11C2"), - (0xAD34, "1100 116C"), - (0xAD35, "1100 116C 11A8"), - (0xAD36, "1100 116C 11A9"), - (0xAD37, "1100 116C 11AA"), - (0xAD38, "1100 116C 11AB"), - (0xAD39, "1100 116C 11AC"), - (0xAD3A, "1100 116C 11AD"), - (0xAD3B, "1100 116C 11AE"), - (0xAD3C, "1100 116C 11AF"), - (0xAD3D, "1100 116C 11B0"), - (0xAD3E, "1100 116C 11B1"), - (0xAD3F, "1100 116C 11B2"), - (0xAD40, "1100 116C 11B3"), - (0xAD41, "1100 116C 11B4"), - (0xAD42, "1100 116C 11B5"), - (0xAD43, "1100 116C 11B6"), - (0xAD44, "1100 116C 11B7"), - (0xAD45, "1100 116C 11B8"), - (0xAD46, "1100 116C 11B9"), - (0xAD47, "1100 116C 11BA"), - (0xAD48, "1100 116C 11BB"), - (0xAD49, "1100 116C 11BC"), - (0xAD4A, "1100 116C 11BD"), - (0xAD4B, "1100 116C 11BE"), - (0xAD4C, "1100 116C 11BF"), - (0xAD4D, "1100 116C 11C0"), - (0xAD4E, "1100 116C 11C1"), - (0xAD4F, "1100 116C 11C2"), - (0xAD50, "1100 116D"), - (0xAD51, "1100 116D 11A8"), - (0xAD52, "1100 116D 11A9"), - (0xAD53, "1100 116D 11AA"), - (0xAD54, "1100 116D 11AB"), - (0xAD55, "1100 116D 11AC"), - (0xAD56, "1100 116D 11AD"), - (0xAD57, "1100 116D 11AE"), - (0xAD58, "1100 116D 11AF"), - (0xAD59, "1100 116D 11B0"), - (0xAD5A, "1100 116D 11B1"), - (0xAD5B, "1100 116D 11B2"), - (0xAD5C, "1100 116D 11B3"), - (0xAD5D, "1100 116D 11B4"), - (0xAD5E, "1100 116D 11B5"), - (0xAD5F, "1100 116D 11B6"), - (0xAD60, "1100 116D 11B7"), - (0xAD61, "1100 116D 11B8"), - (0xAD62, "1100 116D 11B9"), - (0xAD63, "1100 116D 11BA"), - (0xAD64, "1100 116D 11BB"), - (0xAD65, "1100 116D 11BC"), - (0xAD66, "1100 116D 11BD"), - (0xAD67, "1100 116D 11BE"), - (0xAD68, "1100 116D 11BF"), - (0xAD69, "1100 116D 11C0"), - (0xAD6A, "1100 116D 11C1"), - (0xAD6B, "1100 116D 11C2"), - (0xAD6C, "1100 116E"), - (0xAD6D, "1100 116E 11A8"), - (0xAD6E, "1100 116E 11A9"), - (0xAD6F, "1100 116E 11AA"), - (0xAD70, "1100 116E 11AB"), - (0xAD71, "1100 116E 11AC"), - (0xAD72, "1100 116E 11AD"), - (0xAD73, "1100 116E 11AE"), - (0xAD74, "1100 116E 11AF"), - (0xAD75, "1100 116E 11B0"), - (0xAD76, "1100 116E 11B1"), - (0xAD77, "1100 116E 11B2"), - (0xAD78, "1100 116E 11B3"), - (0xAD79, "1100 116E 11B4"), - (0xAD7A, "1100 116E 11B5"), - (0xAD7B, "1100 116E 11B6"), - (0xAD7C, "1100 116E 11B7"), - (0xAD7D, "1100 116E 11B8"), - (0xAD7E, "1100 116E 11B9"), - (0xAD7F, "1100 116E 11BA"), - (0xAD80, "1100 116E 11BB"), - (0xAD81, "1100 116E 11BC"), - (0xAD82, "1100 116E 11BD"), - (0xAD83, "1100 116E 11BE"), - (0xAD84, "1100 116E 11BF"), - (0xAD85, "1100 116E 11C0"), - (0xAD86, "1100 116E 11C1"), - (0xAD87, "1100 116E 11C2"), - (0xAD88, "1100 116F"), - (0xAD89, "1100 116F 11A8"), - (0xAD8A, "1100 116F 11A9"), - (0xAD8B, "1100 116F 11AA"), - (0xAD8C, "1100 116F 11AB"), - (0xAD8D, "1100 116F 11AC"), - (0xAD8E, "1100 116F 11AD"), - (0xAD8F, "1100 116F 11AE"), - (0xAD90, "1100 116F 11AF"), - (0xAD91, "1100 116F 11B0"), - (0xAD92, "1100 116F 11B1"), - (0xAD93, "1100 116F 11B2"), - (0xAD94, "1100 116F 11B3"), - (0xAD95, "1100 116F 11B4"), - (0xAD96, "1100 116F 11B5"), - (0xAD97, "1100 116F 11B6"), - (0xAD98, "1100 116F 11B7"), - (0xAD99, "1100 116F 11B8"), - (0xAD9A, "1100 116F 11B9"), - (0xAD9B, "1100 116F 11BA"), - (0xAD9C, "1100 116F 11BB"), - (0xAD9D, "1100 116F 11BC"), - (0xAD9E, "1100 116F 11BD"), - (0xAD9F, "1100 116F 11BE"), - (0xADA0, "1100 116F 11BF"), - (0xADA1, "1100 116F 11C0"), - (0xADA2, "1100 116F 11C1"), - (0xADA3, "1100 116F 11C2"), - (0xADA4, "1100 1170"), - (0xADA5, "1100 1170 11A8"), - (0xADA6, "1100 1170 11A9"), - (0xADA7, "1100 1170 11AA"), - (0xADA8, "1100 1170 11AB"), - (0xADA9, "1100 1170 11AC"), - (0xADAA, "1100 1170 11AD"), - (0xADAB, "1100 1170 11AE"), - (0xADAC, "1100 1170 11AF"), - (0xADAD, "1100 1170 11B0"), - (0xADAE, "1100 1170 11B1"), - (0xADAF, "1100 1170 11B2"), - (0xADB0, "1100 1170 11B3"), - (0xADB1, "1100 1170 11B4"), - (0xADB2, "1100 1170 11B5"), - (0xADB3, "1100 1170 11B6"), - (0xADB4, "1100 1170 11B7"), - (0xADB5, "1100 1170 11B8"), - (0xADB6, "1100 1170 11B9"), - (0xADB7, "1100 1170 11BA"), - (0xADB8, "1100 1170 11BB"), - (0xADB9, "1100 1170 11BC"), - (0xADBA, "1100 1170 11BD"), - (0xADBB, "1100 1170 11BE"), - (0xADBC, "1100 1170 11BF"), - (0xADBD, "1100 1170 11C0"), - (0xADBE, "1100 1170 11C1"), - (0xADBF, "1100 1170 11C2"), - (0xADC0, "1100 1171"), - (0xADC1, "1100 1171 11A8"), - (0xADC2, "1100 1171 11A9"), - (0xADC3, "1100 1171 11AA"), - (0xADC4, "1100 1171 11AB"), - (0xADC5, "1100 1171 11AC"), - (0xADC6, "1100 1171 11AD"), - (0xADC7, "1100 1171 11AE"), - (0xADC8, "1100 1171 11AF"), - (0xADC9, "1100 1171 11B0"), - (0xADCA, "1100 1171 11B1"), - (0xADCB, "1100 1171 11B2"), - (0xADCC, "1100 1171 11B3"), - (0xADCD, "1100 1171 11B4"), - (0xADCE, "1100 1171 11B5"), - (0xADCF, "1100 1171 11B6"), - (0xADD0, "1100 1171 11B7"), - (0xADD1, "1100 1171 11B8"), - (0xADD2, "1100 1171 11B9"), - (0xADD3, "1100 1171 11BA"), - (0xADD4, "1100 1171 11BB"), - (0xADD5, "1100 1171 11BC"), - (0xADD6, "1100 1171 11BD"), - (0xADD7, "1100 1171 11BE"), - (0xADD8, "1100 1171 11BF"), - (0xADD9, "1100 1171 11C0"), - (0xADDA, "1100 1171 11C1"), - (0xADDB, "1100 1171 11C2"), - (0xADDC, "1100 1172"), - (0xADDD, "1100 1172 11A8"), - (0xADDE, "1100 1172 11A9"), - (0xADDF, "1100 1172 11AA"), - (0xADE0, "1100 1172 11AB"), - (0xADE1, "1100 1172 11AC"), - (0xADE2, "1100 1172 11AD"), - (0xADE3, "1100 1172 11AE"), - (0xADE4, "1100 1172 11AF"), - (0xADE5, "1100 1172 11B0"), - (0xADE6, "1100 1172 11B1"), - (0xADE7, "1100 1172 11B2"), - (0xADE8, "1100 1172 11B3"), - (0xADE9, "1100 1172 11B4"), - (0xADEA, "1100 1172 11B5"), - (0xADEB, "1100 1172 11B6"), - (0xADEC, "1100 1172 11B7"), - (0xADED, "1100 1172 11B8"), - (0xADEE, "1100 1172 11B9"), - (0xADEF, "1100 1172 11BA"), - (0xADF0, "1100 1172 11BB"), - (0xADF1, "1100 1172 11BC"), - (0xADF2, "1100 1172 11BD"), - (0xADF3, "1100 1172 11BE"), - (0xADF4, "1100 1172 11BF"), - (0xADF5, "1100 1172 11C0"), - (0xADF6, "1100 1172 11C1"), - (0xADF7, "1100 1172 11C2"), - (0xADF8, "1100 1173"), - (0xADF9, "1100 1173 11A8"), - (0xADFA, "1100 1173 11A9"), - (0xADFB, "1100 1173 11AA"), - (0xADFC, "1100 1173 11AB"), - (0xADFD, "1100 1173 11AC"), - (0xADFE, "1100 1173 11AD"), - (0xADFF, "1100 1173 11AE"), - (0xAE00, "1100 1173 11AF"), - (0xAE01, "1100 1173 11B0"), - (0xAE02, "1100 1173 11B1"), - (0xAE03, "1100 1173 11B2"), - (0xAE04, "1100 1173 11B3"), - (0xAE05, "1100 1173 11B4"), - (0xAE06, "1100 1173 11B5"), - (0xAE07, "1100 1173 11B6"), - (0xAE08, "1100 1173 11B7"), - (0xAE09, "1100 1173 11B8"), - (0xAE0A, "1100 1173 11B9"), - (0xAE0B, "1100 1173 11BA"), - (0xAE0C, "1100 1173 11BB"), - (0xAE0D, "1100 1173 11BC"), - (0xAE0E, "1100 1173 11BD"), - (0xAE0F, "1100 1173 11BE"), - (0xAE10, "1100 1173 11BF"), - (0xAE11, "1100 1173 11C0"), - (0xAE12, "1100 1173 11C1"), - (0xAE13, "1100 1173 11C2"), - (0xAE14, "1100 1174"), - (0xAE15, "1100 1174 11A8"), - (0xAE16, "1100 1174 11A9"), - (0xAE17, "1100 1174 11AA"), - (0xAE18, "1100 1174 11AB"), - (0xAE19, "1100 1174 11AC"), - (0xAE1A, "1100 1174 11AD"), - (0xAE1B, "1100 1174 11AE"), - (0xAE1C, "1100 1174 11AF"), - (0xAE1D, "1100 1174 11B0"), - (0xAE1E, "1100 1174 11B1"), - (0xAE1F, "1100 1174 11B2"), - (0xAE20, "1100 1174 11B3"), - (0xAE21, "1100 1174 11B4"), - (0xAE22, "1100 1174 11B5"), - (0xAE23, "1100 1174 11B6"), - (0xAE24, "1100 1174 11B7"), - (0xAE25, "1100 1174 11B8"), - (0xAE26, "1100 1174 11B9"), - (0xAE27, "1100 1174 11BA"), - (0xAE28, "1100 1174 11BB"), - (0xAE29, "1100 1174 11BC"), - (0xAE2A, "1100 1174 11BD"), - (0xAE2B, "1100 1174 11BE"), - (0xAE2C, "1100 1174 11BF"), - (0xAE2D, "1100 1174 11C0"), - (0xAE2E, "1100 1174 11C1"), - (0xAE2F, "1100 1174 11C2"), - (0xAE30, "1100 1175"), - (0xAE31, "1100 1175 11A8"), - (0xAE32, "1100 1175 11A9"), - (0xAE33, "1100 1175 11AA"), - (0xAE34, "1100 1175 11AB"), - (0xAE35, "1100 1175 11AC"), - (0xAE36, "1100 1175 11AD"), - (0xAE37, "1100 1175 11AE"), - (0xAE38, "1100 1175 11AF"), - (0xAE39, "1100 1175 11B0"), - (0xAE3A, "1100 1175 11B1"), - (0xAE3B, "1100 1175 11B2"), - (0xAE3C, "1100 1175 11B3"), - (0xAE3D, "1100 1175 11B4"), - (0xAE3E, "1100 1175 11B5"), - (0xAE3F, "1100 1175 11B6"), - (0xAE40, "1100 1175 11B7"), - (0xAE41, "1100 1175 11B8"), - (0xAE42, "1100 1175 11B9"), - (0xAE43, "1100 1175 11BA"), - (0xAE44, "1100 1175 11BB"), - (0xAE45, "1100 1175 11BC"), - (0xAE46, "1100 1175 11BD"), - (0xAE47, "1100 1175 11BE"), - (0xAE48, "1100 1175 11BF"), - (0xAE49, "1100 1175 11C0"), - (0xAE4A, "1100 1175 11C1"), - (0xAE4B, "1100 1175 11C2"), - (0xAE4C, "1101 1161"), - (0xAE4D, "1101 1161 11A8"), - (0xAE4E, "1101 1161 11A9"), - (0xAE4F, "1101 1161 11AA"), - (0xAE50, "1101 1161 11AB"), - (0xAE51, "1101 1161 11AC"), - (0xAE52, "1101 1161 11AD"), - (0xAE53, "1101 1161 11AE"), - (0xAE54, "1101 1161 11AF"), - (0xAE55, "1101 1161 11B0"), - (0xAE56, "1101 1161 11B1"), - (0xAE57, "1101 1161 11B2"), - (0xAE58, "1101 1161 11B3"), - (0xAE59, "1101 1161 11B4"), - (0xAE5A, "1101 1161 11B5"), - (0xAE5B, "1101 1161 11B6"), - (0xAE5C, "1101 1161 11B7"), - (0xAE5D, "1101 1161 11B8"), - (0xAE5E, "1101 1161 11B9"), - (0xAE5F, "1101 1161 11BA"), - (0xAE60, "1101 1161 11BB"), - (0xAE61, "1101 1161 11BC"), - (0xAE62, "1101 1161 11BD"), - (0xAE63, "1101 1161 11BE"), - (0xAE64, "1101 1161 11BF"), - (0xAE65, "1101 1161 11C0"), - (0xAE66, "1101 1161 11C1"), - (0xAE67, "1101 1161 11C2"), - (0xAE68, "1101 1162"), - (0xAE69, "1101 1162 11A8"), - (0xAE6A, "1101 1162 11A9"), - (0xAE6B, "1101 1162 11AA"), - (0xAE6C, "1101 1162 11AB"), - (0xAE6D, "1101 1162 11AC"), - (0xAE6E, "1101 1162 11AD"), - (0xAE6F, "1101 1162 11AE"), - (0xAE70, "1101 1162 11AF"), - (0xAE71, "1101 1162 11B0"), - (0xAE72, "1101 1162 11B1"), - (0xAE73, "1101 1162 11B2"), - (0xAE74, "1101 1162 11B3"), - (0xAE75, "1101 1162 11B4"), - (0xAE76, "1101 1162 11B5"), - (0xAE77, "1101 1162 11B6"), - (0xAE78, "1101 1162 11B7"), - (0xAE79, "1101 1162 11B8"), - (0xAE7A, "1101 1162 11B9"), - (0xAE7B, "1101 1162 11BA"), - (0xAE7C, "1101 1162 11BB"), - (0xAE7D, "1101 1162 11BC"), - (0xAE7E, "1101 1162 11BD"), - (0xAE7F, "1101 1162 11BE"), - (0xAE80, "1101 1162 11BF"), - (0xAE81, "1101 1162 11C0"), - (0xAE82, "1101 1162 11C1"), - (0xAE83, "1101 1162 11C2"), - (0xAE84, "1101 1163"), - (0xAE85, "1101 1163 11A8"), - (0xAE86, "1101 1163 11A9"), - (0xAE87, "1101 1163 11AA"), - (0xAE88, "1101 1163 11AB"), - (0xAE89, "1101 1163 11AC"), - (0xAE8A, "1101 1163 11AD"), - (0xAE8B, "1101 1163 11AE"), - (0xAE8C, "1101 1163 11AF"), - (0xAE8D, "1101 1163 11B0"), - (0xAE8E, "1101 1163 11B1"), - (0xAE8F, "1101 1163 11B2"), - (0xAE90, "1101 1163 11B3"), - (0xAE91, "1101 1163 11B4"), - (0xAE92, "1101 1163 11B5"), - (0xAE93, "1101 1163 11B6"), - (0xAE94, "1101 1163 11B7"), - (0xAE95, "1101 1163 11B8"), - (0xAE96, "1101 1163 11B9"), - (0xAE97, "1101 1163 11BA"), - (0xAE98, "1101 1163 11BB"), - (0xAE99, "1101 1163 11BC"), - (0xAE9A, "1101 1163 11BD"), - (0xAE9B, "1101 1163 11BE"), - (0xAE9C, "1101 1163 11BF"), - (0xAE9D, "1101 1163 11C0"), - (0xAE9E, "1101 1163 11C1"), - (0xAE9F, "1101 1163 11C2"), - (0xAEA0, "1101 1164"), - (0xAEA1, "1101 1164 11A8"), - (0xAEA2, "1101 1164 11A9"), - (0xAEA3, "1101 1164 11AA"), - (0xAEA4, "1101 1164 11AB"), - (0xAEA5, "1101 1164 11AC"), - (0xAEA6, "1101 1164 11AD"), - (0xAEA7, "1101 1164 11AE"), - (0xAEA8, "1101 1164 11AF"), - (0xAEA9, "1101 1164 11B0"), - (0xAEAA, "1101 1164 11B1"), - (0xAEAB, "1101 1164 11B2"), - (0xAEAC, "1101 1164 11B3"), - (0xAEAD, "1101 1164 11B4"), - (0xAEAE, "1101 1164 11B5"), - (0xAEAF, "1101 1164 11B6"), - (0xAEB0, "1101 1164 11B7"), - (0xAEB1, "1101 1164 11B8"), - (0xAEB2, "1101 1164 11B9"), - (0xAEB3, "1101 1164 11BA"), - (0xAEB4, "1101 1164 11BB"), - (0xAEB5, "1101 1164 11BC"), - (0xAEB6, "1101 1164 11BD"), - (0xAEB7, "1101 1164 11BE"), - (0xAEB8, "1101 1164 11BF"), - (0xAEB9, "1101 1164 11C0"), - (0xAEBA, "1101 1164 11C1"), - (0xAEBB, "1101 1164 11C2"), - (0xAEBC, "1101 1165"), - (0xAEBD, "1101 1165 11A8"), - (0xAEBE, "1101 1165 11A9"), - (0xAEBF, "1101 1165 11AA"), - (0xAEC0, "1101 1165 11AB"), - (0xAEC1, "1101 1165 11AC"), - (0xAEC2, "1101 1165 11AD"), - (0xAEC3, "1101 1165 11AE"), - (0xAEC4, "1101 1165 11AF"), - (0xAEC5, "1101 1165 11B0"), - (0xAEC6, "1101 1165 11B1"), - (0xAEC7, "1101 1165 11B2"), - (0xAEC8, "1101 1165 11B3"), - (0xAEC9, "1101 1165 11B4"), - (0xAECA, "1101 1165 11B5"), - (0xAECB, "1101 1165 11B6"), - (0xAECC, "1101 1165 11B7"), - (0xAECD, "1101 1165 11B8"), - (0xAECE, "1101 1165 11B9"), - (0xAECF, "1101 1165 11BA"), - (0xAED0, "1101 1165 11BB"), - (0xAED1, "1101 1165 11BC"), - (0xAED2, "1101 1165 11BD"), - (0xAED3, "1101 1165 11BE"), - (0xAED4, "1101 1165 11BF"), - (0xAED5, "1101 1165 11C0"), - (0xAED6, "1101 1165 11C1"), - (0xAED7, "1101 1165 11C2"), - (0xAED8, "1101 1166"), - (0xAED9, "1101 1166 11A8"), - (0xAEDA, "1101 1166 11A9"), - (0xAEDB, "1101 1166 11AA"), - (0xAEDC, "1101 1166 11AB"), - (0xAEDD, "1101 1166 11AC"), - (0xAEDE, "1101 1166 11AD"), - (0xAEDF, "1101 1166 11AE"), - (0xAEE0, "1101 1166 11AF"), - (0xAEE1, "1101 1166 11B0"), - (0xAEE2, "1101 1166 11B1"), - (0xAEE3, "1101 1166 11B2"), - (0xAEE4, "1101 1166 11B3"), - (0xAEE5, "1101 1166 11B4"), - (0xAEE6, "1101 1166 11B5"), - (0xAEE7, "1101 1166 11B6"), - (0xAEE8, "1101 1166 11B7"), - (0xAEE9, "1101 1166 11B8"), - (0xAEEA, "1101 1166 11B9"), - (0xAEEB, "1101 1166 11BA"), - (0xAEEC, "1101 1166 11BB"), - (0xAEED, "1101 1166 11BC"), - (0xAEEE, "1101 1166 11BD"), - (0xAEEF, "1101 1166 11BE"), - (0xAEF0, "1101 1166 11BF"), - (0xAEF1, "1101 1166 11C0"), - (0xAEF2, "1101 1166 11C1"), - (0xAEF3, "1101 1166 11C2"), - (0xAEF4, "1101 1167"), - (0xAEF5, "1101 1167 11A8"), - (0xAEF6, "1101 1167 11A9"), - (0xAEF7, "1101 1167 11AA"), - (0xAEF8, "1101 1167 11AB"), - (0xAEF9, "1101 1167 11AC"), - (0xAEFA, "1101 1167 11AD"), - (0xAEFB, "1101 1167 11AE"), - (0xAEFC, "1101 1167 11AF"), - (0xAEFD, "1101 1167 11B0"), - (0xAEFE, "1101 1167 11B1"), - (0xAEFF, "1101 1167 11B2"), - (0xAF00, "1101 1167 11B3"), - (0xAF01, "1101 1167 11B4"), - (0xAF02, "1101 1167 11B5"), - (0xAF03, "1101 1167 11B6"), - (0xAF04, "1101 1167 11B7"), - (0xAF05, "1101 1167 11B8"), - (0xAF06, "1101 1167 11B9"), - (0xAF07, "1101 1167 11BA"), - (0xAF08, "1101 1167 11BB"), - (0xAF09, "1101 1167 11BC"), - (0xAF0A, "1101 1167 11BD"), - (0xAF0B, "1101 1167 11BE"), - (0xAF0C, "1101 1167 11BF"), - (0xAF0D, "1101 1167 11C0"), - (0xAF0E, "1101 1167 11C1"), - (0xAF0F, "1101 1167 11C2"), - (0xAF10, "1101 1168"), - (0xAF11, "1101 1168 11A8"), - (0xAF12, "1101 1168 11A9"), - (0xAF13, "1101 1168 11AA"), - (0xAF14, "1101 1168 11AB"), - (0xAF15, "1101 1168 11AC"), - (0xAF16, "1101 1168 11AD"), - (0xAF17, "1101 1168 11AE"), - (0xAF18, "1101 1168 11AF"), - (0xAF19, "1101 1168 11B0"), - (0xAF1A, "1101 1168 11B1"), - (0xAF1B, "1101 1168 11B2"), - (0xAF1C, "1101 1168 11B3"), - (0xAF1D, "1101 1168 11B4"), - (0xAF1E, "1101 1168 11B5"), - (0xAF1F, "1101 1168 11B6"), - (0xAF20, "1101 1168 11B7"), - (0xAF21, "1101 1168 11B8"), - (0xAF22, "1101 1168 11B9"), - (0xAF23, "1101 1168 11BA"), - (0xAF24, "1101 1168 11BB"), - (0xAF25, "1101 1168 11BC"), - (0xAF26, "1101 1168 11BD"), - (0xAF27, "1101 1168 11BE"), - (0xAF28, "1101 1168 11BF"), - (0xAF29, "1101 1168 11C0"), - (0xAF2A, "1101 1168 11C1"), - (0xAF2B, "1101 1168 11C2"), - (0xAF2C, "1101 1169"), - (0xAF2D, "1101 1169 11A8"), - (0xAF2E, "1101 1169 11A9"), - (0xAF2F, "1101 1169 11AA"), - (0xAF30, "1101 1169 11AB"), - (0xAF31, "1101 1169 11AC"), - (0xAF32, "1101 1169 11AD"), - (0xAF33, "1101 1169 11AE"), - (0xAF34, "1101 1169 11AF"), - (0xAF35, "1101 1169 11B0"), - (0xAF36, "1101 1169 11B1"), - (0xAF37, "1101 1169 11B2"), - (0xAF38, "1101 1169 11B3"), - (0xAF39, "1101 1169 11B4"), - (0xAF3A, "1101 1169 11B5"), - (0xAF3B, "1101 1169 11B6"), - (0xAF3C, "1101 1169 11B7"), - (0xAF3D, "1101 1169 11B8"), - (0xAF3E, "1101 1169 11B9"), - (0xAF3F, "1101 1169 11BA"), - (0xAF40, "1101 1169 11BB"), - (0xAF41, "1101 1169 11BC"), - (0xAF42, "1101 1169 11BD"), - (0xAF43, "1101 1169 11BE"), - (0xAF44, "1101 1169 11BF"), - (0xAF45, "1101 1169 11C0"), - (0xAF46, "1101 1169 11C1"), - (0xAF47, "1101 1169 11C2"), - (0xAF48, "1101 116A"), - (0xAF49, "1101 116A 11A8"), - (0xAF4A, "1101 116A 11A9"), - (0xAF4B, "1101 116A 11AA"), - (0xAF4C, "1101 116A 11AB"), - (0xAF4D, "1101 116A 11AC"), - (0xAF4E, "1101 116A 11AD"), - (0xAF4F, "1101 116A 11AE"), - (0xAF50, "1101 116A 11AF"), - (0xAF51, "1101 116A 11B0"), - (0xAF52, "1101 116A 11B1"), - (0xAF53, "1101 116A 11B2"), - (0xAF54, "1101 116A 11B3"), - (0xAF55, "1101 116A 11B4"), - (0xAF56, "1101 116A 11B5"), - (0xAF57, "1101 116A 11B6"), - (0xAF58, "1101 116A 11B7"), - (0xAF59, "1101 116A 11B8"), - (0xAF5A, "1101 116A 11B9"), - (0xAF5B, "1101 116A 11BA"), - (0xAF5C, "1101 116A 11BB"), - (0xAF5D, "1101 116A 11BC"), - (0xAF5E, "1101 116A 11BD"), - (0xAF5F, "1101 116A 11BE"), - (0xAF60, "1101 116A 11BF"), - (0xAF61, "1101 116A 11C0"), - (0xAF62, "1101 116A 11C1"), - (0xAF63, "1101 116A 11C2"), - (0xAF64, "1101 116B"), - (0xAF65, "1101 116B 11A8"), - (0xAF66, "1101 116B 11A9"), - (0xAF67, "1101 116B 11AA"), - (0xAF68, "1101 116B 11AB"), - (0xAF69, "1101 116B 11AC"), - (0xAF6A, "1101 116B 11AD"), - (0xAF6B, "1101 116B 11AE"), - (0xAF6C, "1101 116B 11AF"), - (0xAF6D, "1101 116B 11B0"), - (0xAF6E, "1101 116B 11B1"), - (0xAF6F, "1101 116B 11B2"), - (0xAF70, "1101 116B 11B3"), - (0xAF71, "1101 116B 11B4"), - (0xAF72, "1101 116B 11B5"), - (0xAF73, "1101 116B 11B6"), - (0xAF74, "1101 116B 11B7"), - (0xAF75, "1101 116B 11B8"), - (0xAF76, "1101 116B 11B9"), - (0xAF77, "1101 116B 11BA"), - (0xAF78, "1101 116B 11BB"), - (0xAF79, "1101 116B 11BC"), - (0xAF7A, "1101 116B 11BD"), - (0xAF7B, "1101 116B 11BE"), - (0xAF7C, "1101 116B 11BF"), - (0xAF7D, "1101 116B 11C0"), - (0xAF7E, "1101 116B 11C1"), - (0xAF7F, "1101 116B 11C2"), - (0xAF80, "1101 116C"), - (0xAF81, "1101 116C 11A8"), - (0xAF82, "1101 116C 11A9"), - (0xAF83, "1101 116C 11AA"), - (0xAF84, "1101 116C 11AB"), - (0xAF85, "1101 116C 11AC"), - (0xAF86, "1101 116C 11AD"), - (0xAF87, "1101 116C 11AE"), - (0xAF88, "1101 116C 11AF"), - (0xAF89, "1101 116C 11B0"), - (0xAF8A, "1101 116C 11B1"), - (0xAF8B, "1101 116C 11B2"), - (0xAF8C, "1101 116C 11B3"), - (0xAF8D, "1101 116C 11B4"), - (0xAF8E, "1101 116C 11B5"), - (0xAF8F, "1101 116C 11B6"), - (0xAF90, "1101 116C 11B7"), - (0xAF91, "1101 116C 11B8"), - (0xAF92, "1101 116C 11B9"), - (0xAF93, "1101 116C 11BA"), - (0xAF94, "1101 116C 11BB"), - (0xAF95, "1101 116C 11BC"), - (0xAF96, "1101 116C 11BD"), - (0xAF97, "1101 116C 11BE"), - (0xAF98, "1101 116C 11BF"), - (0xAF99, "1101 116C 11C0"), - (0xAF9A, "1101 116C 11C1"), - (0xAF9B, "1101 116C 11C2"), - (0xAF9C, "1101 116D"), - (0xAF9D, "1101 116D 11A8"), - (0xAF9E, "1101 116D 11A9"), - (0xAF9F, "1101 116D 11AA"), - (0xAFA0, "1101 116D 11AB"), - (0xAFA1, "1101 116D 11AC"), - (0xAFA2, "1101 116D 11AD"), - (0xAFA3, "1101 116D 11AE"), - (0xAFA4, "1101 116D 11AF"), - (0xAFA5, "1101 116D 11B0"), - (0xAFA6, "1101 116D 11B1"), - (0xAFA7, "1101 116D 11B2"), - (0xAFA8, "1101 116D 11B3"), - (0xAFA9, "1101 116D 11B4"), - (0xAFAA, "1101 116D 11B5"), - (0xAFAB, "1101 116D 11B6"), - (0xAFAC, "1101 116D 11B7"), - (0xAFAD, "1101 116D 11B8"), - (0xAFAE, "1101 116D 11B9"), - (0xAFAF, "1101 116D 11BA"), - (0xAFB0, "1101 116D 11BB"), - (0xAFB1, "1101 116D 11BC"), - (0xAFB2, "1101 116D 11BD"), - (0xAFB3, "1101 116D 11BE"), - (0xAFB4, "1101 116D 11BF"), - (0xAFB5, "1101 116D 11C0"), - (0xAFB6, "1101 116D 11C1"), - (0xAFB7, "1101 116D 11C2"), - (0xAFB8, "1101 116E"), - (0xAFB9, "1101 116E 11A8"), - (0xAFBA, "1101 116E 11A9"), - (0xAFBB, "1101 116E 11AA"), - (0xAFBC, "1101 116E 11AB"), - (0xAFBD, "1101 116E 11AC"), - (0xAFBE, "1101 116E 11AD"), - (0xAFBF, "1101 116E 11AE"), - (0xAFC0, "1101 116E 11AF"), - (0xAFC1, "1101 116E 11B0"), - (0xAFC2, "1101 116E 11B1"), - (0xAFC3, "1101 116E 11B2"), - (0xAFC4, "1101 116E 11B3"), - (0xAFC5, "1101 116E 11B4"), - (0xAFC6, "1101 116E 11B5"), - (0xAFC7, "1101 116E 11B6"), - (0xAFC8, "1101 116E 11B7"), - (0xAFC9, "1101 116E 11B8"), - (0xAFCA, "1101 116E 11B9"), - (0xAFCB, "1101 116E 11BA"), - (0xAFCC, "1101 116E 11BB"), - (0xAFCD, "1101 116E 11BC"), - (0xAFCE, "1101 116E 11BD"), - (0xAFCF, "1101 116E 11BE"), - (0xAFD0, "1101 116E 11BF"), - (0xAFD1, "1101 116E 11C0"), - (0xAFD2, "1101 116E 11C1"), - (0xAFD3, "1101 116E 11C2"), - (0xAFD4, "1101 116F"), - (0xAFD5, "1101 116F 11A8"), - (0xAFD6, "1101 116F 11A9"), - (0xAFD7, "1101 116F 11AA"), - (0xAFD8, "1101 116F 11AB"), - (0xAFD9, "1101 116F 11AC"), - (0xAFDA, "1101 116F 11AD"), - (0xAFDB, "1101 116F 11AE"), - (0xAFDC, "1101 116F 11AF"), - (0xAFDD, "1101 116F 11B0"), - (0xAFDE, "1101 116F 11B1"), - (0xAFDF, "1101 116F 11B2"), - (0xAFE0, "1101 116F 11B3"), - (0xAFE1, "1101 116F 11B4"), - (0xAFE2, "1101 116F 11B5"), - (0xAFE3, "1101 116F 11B6"), - (0xAFE4, "1101 116F 11B7"), - (0xAFE5, "1101 116F 11B8"), - (0xAFE6, "1101 116F 11B9"), - (0xAFE7, "1101 116F 11BA"), - (0xAFE8, "1101 116F 11BB"), - (0xAFE9, "1101 116F 11BC"), - (0xAFEA, "1101 116F 11BD"), - (0xAFEB, "1101 116F 11BE"), - (0xAFEC, "1101 116F 11BF"), - (0xAFED, "1101 116F 11C0"), - (0xAFEE, "1101 116F 11C1"), - (0xAFEF, "1101 116F 11C2"), - (0xAFF0, "1101 1170"), - (0xAFF1, "1101 1170 11A8"), - (0xAFF2, "1101 1170 11A9"), - (0xAFF3, "1101 1170 11AA"), - (0xAFF4, "1101 1170 11AB"), - (0xAFF5, "1101 1170 11AC"), - (0xAFF6, "1101 1170 11AD"), - (0xAFF7, "1101 1170 11AE"), - (0xAFF8, "1101 1170 11AF"), - (0xAFF9, "1101 1170 11B0"), - (0xAFFA, "1101 1170 11B1"), - (0xAFFB, "1101 1170 11B2"), - (0xAFFC, "1101 1170 11B3"), - (0xAFFD, "1101 1170 11B4"), - (0xAFFE, "1101 1170 11B5"), - (0xAFFF, "1101 1170 11B6"), - (0xB000, "1101 1170 11B7"), - (0xB001, "1101 1170 11B8"), - (0xB002, "1101 1170 11B9"), - (0xB003, "1101 1170 11BA"), - (0xB004, "1101 1170 11BB"), - (0xB005, "1101 1170 11BC"), - (0xB006, "1101 1170 11BD"), - (0xB007, "1101 1170 11BE"), - (0xB008, "1101 1170 11BF"), - (0xB009, "1101 1170 11C0"), - (0xB00A, "1101 1170 11C1"), - (0xB00B, "1101 1170 11C2"), - (0xB00C, "1101 1171"), - (0xB00D, "1101 1171 11A8"), - (0xB00E, "1101 1171 11A9"), - (0xB00F, "1101 1171 11AA"), - (0xB010, "1101 1171 11AB"), - (0xB011, "1101 1171 11AC"), - (0xB012, "1101 1171 11AD"), - (0xB013, "1101 1171 11AE"), - (0xB014, "1101 1171 11AF"), - (0xB015, "1101 1171 11B0"), - (0xB016, "1101 1171 11B1"), - (0xB017, "1101 1171 11B2"), - (0xB018, "1101 1171 11B3"), - (0xB019, "1101 1171 11B4"), - (0xB01A, "1101 1171 11B5"), - (0xB01B, "1101 1171 11B6"), - (0xB01C, "1101 1171 11B7"), - (0xB01D, "1101 1171 11B8"), - (0xB01E, "1101 1171 11B9"), - (0xB01F, "1101 1171 11BA"), - (0xB020, "1101 1171 11BB"), - (0xB021, "1101 1171 11BC"), - (0xB022, "1101 1171 11BD"), - (0xB023, "1101 1171 11BE"), - (0xB024, "1101 1171 11BF"), - (0xB025, "1101 1171 11C0"), - (0xB026, "1101 1171 11C1"), - (0xB027, "1101 1171 11C2"), - (0xB028, "1101 1172"), - (0xB029, "1101 1172 11A8"), - (0xB02A, "1101 1172 11A9"), - (0xB02B, "1101 1172 11AA"), - (0xB02C, "1101 1172 11AB"), - (0xB02D, "1101 1172 11AC"), - (0xB02E, "1101 1172 11AD"), - (0xB02F, "1101 1172 11AE"), - (0xB030, "1101 1172 11AF"), - (0xB031, "1101 1172 11B0"), - (0xB032, "1101 1172 11B1"), - (0xB033, "1101 1172 11B2"), - (0xB034, "1101 1172 11B3"), - (0xB035, "1101 1172 11B4"), - (0xB036, "1101 1172 11B5"), - (0xB037, "1101 1172 11B6"), - (0xB038, "1101 1172 11B7"), - (0xB039, "1101 1172 11B8"), - (0xB03A, "1101 1172 11B9"), - (0xB03B, "1101 1172 11BA"), - (0xB03C, "1101 1172 11BB"), - (0xB03D, "1101 1172 11BC"), - (0xB03E, "1101 1172 11BD"), - (0xB03F, "1101 1172 11BE"), - (0xB040, "1101 1172 11BF"), - (0xB041, "1101 1172 11C0"), - (0xB042, "1101 1172 11C1"), - (0xB043, "1101 1172 11C2"), - (0xB044, "1101 1173"), - (0xB045, "1101 1173 11A8"), - (0xB046, "1101 1173 11A9"), - (0xB047, "1101 1173 11AA"), - (0xB048, "1101 1173 11AB"), - (0xB049, "1101 1173 11AC"), - (0xB04A, "1101 1173 11AD"), - (0xB04B, "1101 1173 11AE"), - (0xB04C, "1101 1173 11AF"), - (0xB04D, "1101 1173 11B0"), - (0xB04E, "1101 1173 11B1"), - (0xB04F, "1101 1173 11B2"), - (0xB050, "1101 1173 11B3"), - (0xB051, "1101 1173 11B4"), - (0xB052, "1101 1173 11B5"), - (0xB053, "1101 1173 11B6"), - (0xB054, "1101 1173 11B7"), - (0xB055, "1101 1173 11B8"), - (0xB056, "1101 1173 11B9"), - (0xB057, "1101 1173 11BA"), - (0xB058, "1101 1173 11BB"), - (0xB059, "1101 1173 11BC"), - (0xB05A, "1101 1173 11BD"), - (0xB05B, "1101 1173 11BE"), - (0xB05C, "1101 1173 11BF"), - (0xB05D, "1101 1173 11C0"), - (0xB05E, "1101 1173 11C1"), - (0xB05F, "1101 1173 11C2"), - (0xB060, "1101 1174"), - (0xB061, "1101 1174 11A8"), - (0xB062, "1101 1174 11A9"), - (0xB063, "1101 1174 11AA"), - (0xB064, "1101 1174 11AB"), - (0xB065, "1101 1174 11AC"), - (0xB066, "1101 1174 11AD"), - (0xB067, "1101 1174 11AE"), - (0xB068, "1101 1174 11AF"), - (0xB069, "1101 1174 11B0"), - (0xB06A, "1101 1174 11B1"), - (0xB06B, "1101 1174 11B2"), - (0xB06C, "1101 1174 11B3"), - (0xB06D, "1101 1174 11B4"), - (0xB06E, "1101 1174 11B5"), - (0xB06F, "1101 1174 11B6"), - (0xB070, "1101 1174 11B7"), - (0xB071, "1101 1174 11B8"), - (0xB072, "1101 1174 11B9"), - (0xB073, "1101 1174 11BA"), - (0xB074, "1101 1174 11BB"), - (0xB075, "1101 1174 11BC"), - (0xB076, "1101 1174 11BD"), - (0xB077, "1101 1174 11BE"), - (0xB078, "1101 1174 11BF"), - (0xB079, "1101 1174 11C0"), - (0xB07A, "1101 1174 11C1"), - (0xB07B, "1101 1174 11C2"), - (0xB07C, "1101 1175"), - (0xB07D, "1101 1175 11A8"), - (0xB07E, "1101 1175 11A9"), - (0xB07F, "1101 1175 11AA"), - (0xB080, "1101 1175 11AB"), - (0xB081, "1101 1175 11AC"), - (0xB082, "1101 1175 11AD"), - (0xB083, "1101 1175 11AE"), - (0xB084, "1101 1175 11AF"), - (0xB085, "1101 1175 11B0"), - (0xB086, "1101 1175 11B1"), - (0xB087, "1101 1175 11B2"), - (0xB088, "1101 1175 11B3"), - (0xB089, "1101 1175 11B4"), - (0xB08A, "1101 1175 11B5"), - (0xB08B, "1101 1175 11B6"), - (0xB08C, "1101 1175 11B7"), - (0xB08D, "1101 1175 11B8"), - (0xB08E, "1101 1175 11B9"), - (0xB08F, "1101 1175 11BA"), - (0xB090, "1101 1175 11BB"), - (0xB091, "1101 1175 11BC"), - (0xB092, "1101 1175 11BD"), - (0xB093, "1101 1175 11BE"), - (0xB094, "1101 1175 11BF"), - (0xB095, "1101 1175 11C0"), - (0xB096, "1101 1175 11C1"), - (0xB097, "1101 1175 11C2"), - (0xB098, "1102 1161"), - (0xB099, "1102 1161 11A8"), - (0xB09A, "1102 1161 11A9"), - (0xB09B, "1102 1161 11AA"), - (0xB09C, "1102 1161 11AB"), - (0xB09D, "1102 1161 11AC"), - (0xB09E, "1102 1161 11AD"), - (0xB09F, "1102 1161 11AE"), - (0xB0A0, "1102 1161 11AF"), - (0xB0A1, "1102 1161 11B0"), - (0xB0A2, "1102 1161 11B1"), - (0xB0A3, "1102 1161 11B2"), - (0xB0A4, "1102 1161 11B3"), - (0xB0A5, "1102 1161 11B4"), - (0xB0A6, "1102 1161 11B5"), - (0xB0A7, "1102 1161 11B6"), - (0xB0A8, "1102 1161 11B7"), - (0xB0A9, "1102 1161 11B8"), - (0xB0AA, "1102 1161 11B9"), - (0xB0AB, "1102 1161 11BA"), - (0xB0AC, "1102 1161 11BB"), - (0xB0AD, "1102 1161 11BC"), - (0xB0AE, "1102 1161 11BD"), - (0xB0AF, "1102 1161 11BE"), - (0xB0B0, "1102 1161 11BF"), - (0xB0B1, "1102 1161 11C0"), - (0xB0B2, "1102 1161 11C1"), - (0xB0B3, "1102 1161 11C2"), - (0xB0B4, "1102 1162"), - (0xB0B5, "1102 1162 11A8"), - (0xB0B6, "1102 1162 11A9"), - (0xB0B7, "1102 1162 11AA"), - (0xB0B8, "1102 1162 11AB"), - (0xB0B9, "1102 1162 11AC"), - (0xB0BA, "1102 1162 11AD"), - (0xB0BB, "1102 1162 11AE"), - (0xB0BC, "1102 1162 11AF"), - (0xB0BD, "1102 1162 11B0"), - (0xB0BE, "1102 1162 11B1"), - (0xB0BF, "1102 1162 11B2"), - (0xB0C0, "1102 1162 11B3"), - (0xB0C1, "1102 1162 11B4"), - (0xB0C2, "1102 1162 11B5"), - (0xB0C3, "1102 1162 11B6"), - (0xB0C4, "1102 1162 11B7"), - (0xB0C5, "1102 1162 11B8"), - (0xB0C6, "1102 1162 11B9"), - (0xB0C7, "1102 1162 11BA"), - (0xB0C8, "1102 1162 11BB"), - (0xB0C9, "1102 1162 11BC"), - (0xB0CA, "1102 1162 11BD"), - (0xB0CB, "1102 1162 11BE"), - (0xB0CC, "1102 1162 11BF"), - (0xB0CD, "1102 1162 11C0"), - (0xB0CE, "1102 1162 11C1"), - (0xB0CF, "1102 1162 11C2"), - (0xB0D0, "1102 1163"), - (0xB0D1, "1102 1163 11A8"), - (0xB0D2, "1102 1163 11A9"), - (0xB0D3, "1102 1163 11AA"), - (0xB0D4, "1102 1163 11AB"), - (0xB0D5, "1102 1163 11AC"), - (0xB0D6, "1102 1163 11AD"), - (0xB0D7, "1102 1163 11AE"), - (0xB0D8, "1102 1163 11AF"), - (0xB0D9, "1102 1163 11B0"), - (0xB0DA, "1102 1163 11B1"), - (0xB0DB, "1102 1163 11B2"), - (0xB0DC, "1102 1163 11B3"), - (0xB0DD, "1102 1163 11B4"), - (0xB0DE, "1102 1163 11B5"), - (0xB0DF, "1102 1163 11B6"), - (0xB0E0, "1102 1163 11B7"), - (0xB0E1, "1102 1163 11B8"), - (0xB0E2, "1102 1163 11B9"), - (0xB0E3, "1102 1163 11BA"), - (0xB0E4, "1102 1163 11BB"), - (0xB0E5, "1102 1163 11BC"), - (0xB0E6, "1102 1163 11BD"), - (0xB0E7, "1102 1163 11BE"), - (0xB0E8, "1102 1163 11BF"), - (0xB0E9, "1102 1163 11C0"), - (0xB0EA, "1102 1163 11C1"), - (0xB0EB, "1102 1163 11C2"), - (0xB0EC, "1102 1164"), - (0xB0ED, "1102 1164 11A8"), - (0xB0EE, "1102 1164 11A9"), - (0xB0EF, "1102 1164 11AA"), - (0xB0F0, "1102 1164 11AB"), - (0xB0F1, "1102 1164 11AC"), - (0xB0F2, "1102 1164 11AD"), - (0xB0F3, "1102 1164 11AE"), - (0xB0F4, "1102 1164 11AF"), - (0xB0F5, "1102 1164 11B0"), - (0xB0F6, "1102 1164 11B1"), - (0xB0F7, "1102 1164 11B2"), - (0xB0F8, "1102 1164 11B3"), - (0xB0F9, "1102 1164 11B4"), - (0xB0FA, "1102 1164 11B5"), - (0xB0FB, "1102 1164 11B6"), - (0xB0FC, "1102 1164 11B7"), - (0xB0FD, "1102 1164 11B8"), - (0xB0FE, "1102 1164 11B9"), - (0xB0FF, "1102 1164 11BA"), - (0xB100, "1102 1164 11BB"), - (0xB101, "1102 1164 11BC"), - (0xB102, "1102 1164 11BD"), - (0xB103, "1102 1164 11BE"), - (0xB104, "1102 1164 11BF"), - (0xB105, "1102 1164 11C0"), - (0xB106, "1102 1164 11C1"), - (0xB107, "1102 1164 11C2"), - (0xB108, "1102 1165"), - (0xB109, "1102 1165 11A8"), - (0xB10A, "1102 1165 11A9"), - (0xB10B, "1102 1165 11AA"), - (0xB10C, "1102 1165 11AB"), - (0xB10D, "1102 1165 11AC"), - (0xB10E, "1102 1165 11AD"), - (0xB10F, "1102 1165 11AE"), - (0xB110, "1102 1165 11AF"), - (0xB111, "1102 1165 11B0"), - (0xB112, "1102 1165 11B1"), - (0xB113, "1102 1165 11B2"), - (0xB114, "1102 1165 11B3"), - (0xB115, "1102 1165 11B4"), - (0xB116, "1102 1165 11B5"), - (0xB117, "1102 1165 11B6"), - (0xB118, "1102 1165 11B7"), - (0xB119, "1102 1165 11B8"), - (0xB11A, "1102 1165 11B9"), - (0xB11B, "1102 1165 11BA"), - (0xB11C, "1102 1165 11BB"), - (0xB11D, "1102 1165 11BC"), - (0xB11E, "1102 1165 11BD"), - (0xB11F, "1102 1165 11BE"), - (0xB120, "1102 1165 11BF"), - (0xB121, "1102 1165 11C0"), - (0xB122, "1102 1165 11C1"), - (0xB123, "1102 1165 11C2"), - (0xB124, "1102 1166"), - (0xB125, "1102 1166 11A8"), - (0xB126, "1102 1166 11A9"), - (0xB127, "1102 1166 11AA"), - (0xB128, "1102 1166 11AB"), - (0xB129, "1102 1166 11AC"), - (0xB12A, "1102 1166 11AD"), - (0xB12B, "1102 1166 11AE"), - (0xB12C, "1102 1166 11AF"), - (0xB12D, "1102 1166 11B0"), - (0xB12E, "1102 1166 11B1"), - (0xB12F, "1102 1166 11B2"), - (0xB130, "1102 1166 11B3"), - (0xB131, "1102 1166 11B4"), - (0xB132, "1102 1166 11B5"), - (0xB133, "1102 1166 11B6"), - (0xB134, "1102 1166 11B7"), - (0xB135, "1102 1166 11B8"), - (0xB136, "1102 1166 11B9"), - (0xB137, "1102 1166 11BA"), - (0xB138, "1102 1166 11BB"), - (0xB139, "1102 1166 11BC"), - (0xB13A, "1102 1166 11BD"), - (0xB13B, "1102 1166 11BE"), - (0xB13C, "1102 1166 11BF"), - (0xB13D, "1102 1166 11C0"), - (0xB13E, "1102 1166 11C1"), - (0xB13F, "1102 1166 11C2"), - (0xB140, "1102 1167"), - (0xB141, "1102 1167 11A8"), - (0xB142, "1102 1167 11A9"), - (0xB143, "1102 1167 11AA"), - (0xB144, "1102 1167 11AB"), - (0xB145, "1102 1167 11AC"), - (0xB146, "1102 1167 11AD"), - (0xB147, "1102 1167 11AE"), - (0xB148, "1102 1167 11AF"), - (0xB149, "1102 1167 11B0"), - (0xB14A, "1102 1167 11B1"), - (0xB14B, "1102 1167 11B2"), - (0xB14C, "1102 1167 11B3"), - (0xB14D, "1102 1167 11B4"), - (0xB14E, "1102 1167 11B5"), - (0xB14F, "1102 1167 11B6"), - (0xB150, "1102 1167 11B7"), - (0xB151, "1102 1167 11B8"), - (0xB152, "1102 1167 11B9"), - (0xB153, "1102 1167 11BA"), - (0xB154, "1102 1167 11BB"), - (0xB155, "1102 1167 11BC"), - (0xB156, "1102 1167 11BD"), - (0xB157, "1102 1167 11BE"), - (0xB158, "1102 1167 11BF"), - (0xB159, "1102 1167 11C0"), - (0xB15A, "1102 1167 11C1"), - (0xB15B, "1102 1167 11C2"), - (0xB15C, "1102 1168"), - (0xB15D, "1102 1168 11A8"), - (0xB15E, "1102 1168 11A9"), - (0xB15F, "1102 1168 11AA"), - (0xB160, "1102 1168 11AB"), - (0xB161, "1102 1168 11AC"), - (0xB162, "1102 1168 11AD"), - (0xB163, "1102 1168 11AE"), - (0xB164, "1102 1168 11AF"), - (0xB165, "1102 1168 11B0"), - (0xB166, "1102 1168 11B1"), - (0xB167, "1102 1168 11B2"), - (0xB168, "1102 1168 11B3"), - (0xB169, "1102 1168 11B4"), - (0xB16A, "1102 1168 11B5"), - (0xB16B, "1102 1168 11B6"), - (0xB16C, "1102 1168 11B7"), - (0xB16D, "1102 1168 11B8"), - (0xB16E, "1102 1168 11B9"), - (0xB16F, "1102 1168 11BA"), - (0xB170, "1102 1168 11BB"), - (0xB171, "1102 1168 11BC"), - (0xB172, "1102 1168 11BD"), - (0xB173, "1102 1168 11BE"), - (0xB174, "1102 1168 11BF"), - (0xB175, "1102 1168 11C0"), - (0xB176, "1102 1168 11C1"), - (0xB177, "1102 1168 11C2"), - (0xB178, "1102 1169"), - (0xB179, "1102 1169 11A8"), - (0xB17A, "1102 1169 11A9"), - (0xB17B, "1102 1169 11AA"), - (0xB17C, "1102 1169 11AB"), - (0xB17D, "1102 1169 11AC"), - (0xB17E, "1102 1169 11AD"), - (0xB17F, "1102 1169 11AE"), - (0xB180, "1102 1169 11AF"), - (0xB181, "1102 1169 11B0"), - (0xB182, "1102 1169 11B1"), - (0xB183, "1102 1169 11B2"), - (0xB184, "1102 1169 11B3"), - (0xB185, "1102 1169 11B4"), - (0xB186, "1102 1169 11B5"), - (0xB187, "1102 1169 11B6"), - (0xB188, "1102 1169 11B7"), - (0xB189, "1102 1169 11B8"), - (0xB18A, "1102 1169 11B9"), - (0xB18B, "1102 1169 11BA"), - (0xB18C, "1102 1169 11BB"), - (0xB18D, "1102 1169 11BC"), - (0xB18E, "1102 1169 11BD"), - (0xB18F, "1102 1169 11BE"), - (0xB190, "1102 1169 11BF"), - (0xB191, "1102 1169 11C0"), - (0xB192, "1102 1169 11C1"), - (0xB193, "1102 1169 11C2"), - (0xB194, "1102 116A"), - (0xB195, "1102 116A 11A8"), - (0xB196, "1102 116A 11A9"), - (0xB197, "1102 116A 11AA"), - (0xB198, "1102 116A 11AB"), - (0xB199, "1102 116A 11AC"), - (0xB19A, "1102 116A 11AD"), - (0xB19B, "1102 116A 11AE"), - (0xB19C, "1102 116A 11AF"), - (0xB19D, "1102 116A 11B0"), - (0xB19E, "1102 116A 11B1"), - (0xB19F, "1102 116A 11B2"), - (0xB1A0, "1102 116A 11B3"), - (0xB1A1, "1102 116A 11B4"), - (0xB1A2, "1102 116A 11B5"), - (0xB1A3, "1102 116A 11B6"), - (0xB1A4, "1102 116A 11B7"), - (0xB1A5, "1102 116A 11B8"), - (0xB1A6, "1102 116A 11B9"), - (0xB1A7, "1102 116A 11BA"), - (0xB1A8, "1102 116A 11BB"), - (0xB1A9, "1102 116A 11BC"), - (0xB1AA, "1102 116A 11BD"), - (0xB1AB, "1102 116A 11BE"), - (0xB1AC, "1102 116A 11BF"), - (0xB1AD, "1102 116A 11C0"), - (0xB1AE, "1102 116A 11C1"), - (0xB1AF, "1102 116A 11C2"), - (0xB1B0, "1102 116B"), - (0xB1B1, "1102 116B 11A8"), - (0xB1B2, "1102 116B 11A9"), - (0xB1B3, "1102 116B 11AA"), - (0xB1B4, "1102 116B 11AB"), - (0xB1B5, "1102 116B 11AC"), - (0xB1B6, "1102 116B 11AD"), - (0xB1B7, "1102 116B 11AE"), - (0xB1B8, "1102 116B 11AF"), - (0xB1B9, "1102 116B 11B0"), - (0xB1BA, "1102 116B 11B1"), - (0xB1BB, "1102 116B 11B2"), - (0xB1BC, "1102 116B 11B3"), - (0xB1BD, "1102 116B 11B4"), - (0xB1BE, "1102 116B 11B5"), - (0xB1BF, "1102 116B 11B6"), - (0xB1C0, "1102 116B 11B7"), - (0xB1C1, "1102 116B 11B8"), - (0xB1C2, "1102 116B 11B9"), - (0xB1C3, "1102 116B 11BA"), - (0xB1C4, "1102 116B 11BB"), - (0xB1C5, "1102 116B 11BC"), - (0xB1C6, "1102 116B 11BD"), - (0xB1C7, "1102 116B 11BE"), - (0xB1C8, "1102 116B 11BF"), - (0xB1C9, "1102 116B 11C0"), - (0xB1CA, "1102 116B 11C1"), - (0xB1CB, "1102 116B 11C2"), - (0xB1CC, "1102 116C"), - (0xB1CD, "1102 116C 11A8"), - (0xB1CE, "1102 116C 11A9"), - (0xB1CF, "1102 116C 11AA"), - (0xB1D0, "1102 116C 11AB"), - (0xB1D1, "1102 116C 11AC"), - (0xB1D2, "1102 116C 11AD"), - (0xB1D3, "1102 116C 11AE"), - (0xB1D4, "1102 116C 11AF"), - (0xB1D5, "1102 116C 11B0"), - (0xB1D6, "1102 116C 11B1"), - (0xB1D7, "1102 116C 11B2"), - (0xB1D8, "1102 116C 11B3"), - (0xB1D9, "1102 116C 11B4"), - (0xB1DA, "1102 116C 11B5"), - (0xB1DB, "1102 116C 11B6"), - (0xB1DC, "1102 116C 11B7"), - (0xB1DD, "1102 116C 11B8"), - (0xB1DE, "1102 116C 11B9"), - (0xB1DF, "1102 116C 11BA"), - (0xB1E0, "1102 116C 11BB"), - (0xB1E1, "1102 116C 11BC"), - (0xB1E2, "1102 116C 11BD"), - (0xB1E3, "1102 116C 11BE"), - (0xB1E4, "1102 116C 11BF"), - (0xB1E5, "1102 116C 11C0"), - (0xB1E6, "1102 116C 11C1"), - (0xB1E7, "1102 116C 11C2"), - (0xB1E8, "1102 116D"), - (0xB1E9, "1102 116D 11A8"), - (0xB1EA, "1102 116D 11A9"), - (0xB1EB, "1102 116D 11AA"), - (0xB1EC, "1102 116D 11AB"), - (0xB1ED, "1102 116D 11AC"), - (0xB1EE, "1102 116D 11AD"), - (0xB1EF, "1102 116D 11AE"), - (0xB1F0, "1102 116D 11AF"), - (0xB1F1, "1102 116D 11B0"), - (0xB1F2, "1102 116D 11B1"), - (0xB1F3, "1102 116D 11B2"), - (0xB1F4, "1102 116D 11B3"), - (0xB1F5, "1102 116D 11B4"), - (0xB1F6, "1102 116D 11B5"), - (0xB1F7, "1102 116D 11B6"), - (0xB1F8, "1102 116D 11B7"), - (0xB1F9, "1102 116D 11B8"), - (0xB1FA, "1102 116D 11B9"), - (0xB1FB, "1102 116D 11BA"), - (0xB1FC, "1102 116D 11BB"), - (0xB1FD, "1102 116D 11BC"), - (0xB1FE, "1102 116D 11BD"), - (0xB1FF, "1102 116D 11BE"), - (0xB200, "1102 116D 11BF"), - (0xB201, "1102 116D 11C0"), - (0xB202, "1102 116D 11C1"), - (0xB203, "1102 116D 11C2"), - (0xB204, "1102 116E"), - (0xB205, "1102 116E 11A8"), - (0xB206, "1102 116E 11A9"), - (0xB207, "1102 116E 11AA"), - (0xB208, "1102 116E 11AB"), - (0xB209, "1102 116E 11AC"), - (0xB20A, "1102 116E 11AD"), - (0xB20B, "1102 116E 11AE"), - (0xB20C, "1102 116E 11AF"), - (0xB20D, "1102 116E 11B0"), - (0xB20E, "1102 116E 11B1"), - (0xB20F, "1102 116E 11B2"), - (0xB210, "1102 116E 11B3"), - (0xB211, "1102 116E 11B4"), - (0xB212, "1102 116E 11B5"), - (0xB213, "1102 116E 11B6"), - (0xB214, "1102 116E 11B7"), - (0xB215, "1102 116E 11B8"), - (0xB216, "1102 116E 11B9"), - (0xB217, "1102 116E 11BA"), - (0xB218, "1102 116E 11BB"), - (0xB219, "1102 116E 11BC"), - (0xB21A, "1102 116E 11BD"), - (0xB21B, "1102 116E 11BE"), - (0xB21C, "1102 116E 11BF"), - (0xB21D, "1102 116E 11C0"), - (0xB21E, "1102 116E 11C1"), - (0xB21F, "1102 116E 11C2"), - (0xB220, "1102 116F"), - (0xB221, "1102 116F 11A8"), - (0xB222, "1102 116F 11A9"), - (0xB223, "1102 116F 11AA"), - (0xB224, "1102 116F 11AB"), - (0xB225, "1102 116F 11AC"), - (0xB226, "1102 116F 11AD"), - (0xB227, "1102 116F 11AE"), - (0xB228, "1102 116F 11AF"), - (0xB229, "1102 116F 11B0"), - (0xB22A, "1102 116F 11B1"), - (0xB22B, "1102 116F 11B2"), - (0xB22C, "1102 116F 11B3"), - (0xB22D, "1102 116F 11B4"), - (0xB22E, "1102 116F 11B5"), - (0xB22F, "1102 116F 11B6"), - (0xB230, "1102 116F 11B7"), - (0xB231, "1102 116F 11B8"), - (0xB232, "1102 116F 11B9"), - (0xB233, "1102 116F 11BA"), - (0xB234, "1102 116F 11BB"), - (0xB235, "1102 116F 11BC"), - (0xB236, "1102 116F 11BD"), - (0xB237, "1102 116F 11BE"), - (0xB238, "1102 116F 11BF"), - (0xB239, "1102 116F 11C0"), - (0xB23A, "1102 116F 11C1"), - (0xB23B, "1102 116F 11C2"), - (0xB23C, "1102 1170"), - (0xB23D, "1102 1170 11A8"), - (0xB23E, "1102 1170 11A9"), - (0xB23F, "1102 1170 11AA"), - (0xB240, "1102 1170 11AB"), - (0xB241, "1102 1170 11AC"), - (0xB242, "1102 1170 11AD"), - (0xB243, "1102 1170 11AE"), - (0xB244, "1102 1170 11AF"), - (0xB245, "1102 1170 11B0"), - (0xB246, "1102 1170 11B1"), - (0xB247, "1102 1170 11B2"), - (0xB248, "1102 1170 11B3"), - (0xB249, "1102 1170 11B4"), - (0xB24A, "1102 1170 11B5"), - (0xB24B, "1102 1170 11B6"), - (0xB24C, "1102 1170 11B7"), - (0xB24D, "1102 1170 11B8"), - (0xB24E, "1102 1170 11B9"), - (0xB24F, "1102 1170 11BA"), - (0xB250, "1102 1170 11BB"), - (0xB251, "1102 1170 11BC"), - (0xB252, "1102 1170 11BD"), - (0xB253, "1102 1170 11BE"), - (0xB254, "1102 1170 11BF"), - (0xB255, "1102 1170 11C0"), - (0xB256, "1102 1170 11C1"), - (0xB257, "1102 1170 11C2"), - (0xB258, "1102 1171"), - (0xB259, "1102 1171 11A8"), - (0xB25A, "1102 1171 11A9"), - (0xB25B, "1102 1171 11AA"), - (0xB25C, "1102 1171 11AB"), - (0xB25D, "1102 1171 11AC"), - (0xB25E, "1102 1171 11AD"), - (0xB25F, "1102 1171 11AE"), - (0xB260, "1102 1171 11AF"), - (0xB261, "1102 1171 11B0"), - (0xB262, "1102 1171 11B1"), - (0xB263, "1102 1171 11B2"), - (0xB264, "1102 1171 11B3"), - (0xB265, "1102 1171 11B4"), - (0xB266, "1102 1171 11B5"), - (0xB267, "1102 1171 11B6"), - (0xB268, "1102 1171 11B7"), - (0xB269, "1102 1171 11B8"), - (0xB26A, "1102 1171 11B9"), - (0xB26B, "1102 1171 11BA"), - (0xB26C, "1102 1171 11BB"), - (0xB26D, "1102 1171 11BC"), - (0xB26E, "1102 1171 11BD"), - (0xB26F, "1102 1171 11BE"), - (0xB270, "1102 1171 11BF"), - (0xB271, "1102 1171 11C0"), - (0xB272, "1102 1171 11C1"), - (0xB273, "1102 1171 11C2"), - (0xB274, "1102 1172"), - (0xB275, "1102 1172 11A8"), - (0xB276, "1102 1172 11A9"), - (0xB277, "1102 1172 11AA"), - (0xB278, "1102 1172 11AB"), - (0xB279, "1102 1172 11AC"), - (0xB27A, "1102 1172 11AD"), - (0xB27B, "1102 1172 11AE"), - (0xB27C, "1102 1172 11AF"), - (0xB27D, "1102 1172 11B0"), - (0xB27E, "1102 1172 11B1"), - (0xB27F, "1102 1172 11B2"), - (0xB280, "1102 1172 11B3"), - (0xB281, "1102 1172 11B4"), - (0xB282, "1102 1172 11B5"), - (0xB283, "1102 1172 11B6"), - (0xB284, "1102 1172 11B7"), - (0xB285, "1102 1172 11B8"), - (0xB286, "1102 1172 11B9"), - (0xB287, "1102 1172 11BA"), - (0xB288, "1102 1172 11BB"), - (0xB289, "1102 1172 11BC"), - (0xB28A, "1102 1172 11BD"), - (0xB28B, "1102 1172 11BE"), - (0xB28C, "1102 1172 11BF"), - (0xB28D, "1102 1172 11C0"), - (0xB28E, "1102 1172 11C1"), - (0xB28F, "1102 1172 11C2"), - (0xB290, "1102 1173"), - (0xB291, "1102 1173 11A8"), - (0xB292, "1102 1173 11A9"), - (0xB293, "1102 1173 11AA"), - (0xB294, "1102 1173 11AB"), - (0xB295, "1102 1173 11AC"), - (0xB296, "1102 1173 11AD"), - (0xB297, "1102 1173 11AE"), - (0xB298, "1102 1173 11AF"), - (0xB299, "1102 1173 11B0"), - (0xB29A, "1102 1173 11B1"), - (0xB29B, "1102 1173 11B2"), - (0xB29C, "1102 1173 11B3"), - (0xB29D, "1102 1173 11B4"), - (0xB29E, "1102 1173 11B5"), - (0xB29F, "1102 1173 11B6"), - (0xB2A0, "1102 1173 11B7"), - (0xB2A1, "1102 1173 11B8"), - (0xB2A2, "1102 1173 11B9"), - (0xB2A3, "1102 1173 11BA"), - (0xB2A4, "1102 1173 11BB"), - (0xB2A5, "1102 1173 11BC"), - (0xB2A6, "1102 1173 11BD"), - (0xB2A7, "1102 1173 11BE"), - (0xB2A8, "1102 1173 11BF"), - (0xB2A9, "1102 1173 11C0"), - (0xB2AA, "1102 1173 11C1"), - (0xB2AB, "1102 1173 11C2"), - (0xB2AC, "1102 1174"), - (0xB2AD, "1102 1174 11A8"), - (0xB2AE, "1102 1174 11A9"), - (0xB2AF, "1102 1174 11AA"), - (0xB2B0, "1102 1174 11AB"), - (0xB2B1, "1102 1174 11AC"), - (0xB2B2, "1102 1174 11AD"), - (0xB2B3, "1102 1174 11AE"), - (0xB2B4, "1102 1174 11AF"), - (0xB2B5, "1102 1174 11B0"), - (0xB2B6, "1102 1174 11B1"), - (0xB2B7, "1102 1174 11B2"), - (0xB2B8, "1102 1174 11B3"), - (0xB2B9, "1102 1174 11B4"), - (0xB2BA, "1102 1174 11B5"), - (0xB2BB, "1102 1174 11B6"), - (0xB2BC, "1102 1174 11B7"), - (0xB2BD, "1102 1174 11B8"), - (0xB2BE, "1102 1174 11B9"), - (0xB2BF, "1102 1174 11BA"), - (0xB2C0, "1102 1174 11BB"), - (0xB2C1, "1102 1174 11BC"), - (0xB2C2, "1102 1174 11BD"), - (0xB2C3, "1102 1174 11BE"), - (0xB2C4, "1102 1174 11BF"), - (0xB2C5, "1102 1174 11C0"), - (0xB2C6, "1102 1174 11C1"), - (0xB2C7, "1102 1174 11C2"), - (0xB2C8, "1102 1175"), - (0xB2C9, "1102 1175 11A8"), - (0xB2CA, "1102 1175 11A9"), - (0xB2CB, "1102 1175 11AA"), - (0xB2CC, "1102 1175 11AB"), - (0xB2CD, "1102 1175 11AC"), - (0xB2CE, "1102 1175 11AD"), - (0xB2CF, "1102 1175 11AE"), - (0xB2D0, "1102 1175 11AF"), - (0xB2D1, "1102 1175 11B0"), - (0xB2D2, "1102 1175 11B1"), - (0xB2D3, "1102 1175 11B2"), - (0xB2D4, "1102 1175 11B3"), - (0xB2D5, "1102 1175 11B4"), - (0xB2D6, "1102 1175 11B5"), - (0xB2D7, "1102 1175 11B6"), - (0xB2D8, "1102 1175 11B7"), - (0xB2D9, "1102 1175 11B8"), - (0xB2DA, "1102 1175 11B9"), - (0xB2DB, "1102 1175 11BA"), - (0xB2DC, "1102 1175 11BB"), - (0xB2DD, "1102 1175 11BC"), - (0xB2DE, "1102 1175 11BD"), - (0xB2DF, "1102 1175 11BE"), - (0xB2E0, "1102 1175 11BF"), - (0xB2E1, "1102 1175 11C0"), - (0xB2E2, "1102 1175 11C1"), - (0xB2E3, "1102 1175 11C2"), - (0xB2E4, "1103 1161"), - (0xB2E5, "1103 1161 11A8"), - (0xB2E6, "1103 1161 11A9"), - (0xB2E7, "1103 1161 11AA"), - (0xB2E8, "1103 1161 11AB"), - (0xB2E9, "1103 1161 11AC"), - (0xB2EA, "1103 1161 11AD"), - (0xB2EB, "1103 1161 11AE"), - (0xB2EC, "1103 1161 11AF"), - (0xB2ED, "1103 1161 11B0"), - (0xB2EE, "1103 1161 11B1"), - (0xB2EF, "1103 1161 11B2"), - (0xB2F0, "1103 1161 11B3"), - (0xB2F1, "1103 1161 11B4"), - (0xB2F2, "1103 1161 11B5"), - (0xB2F3, "1103 1161 11B6"), - (0xB2F4, "1103 1161 11B7"), - (0xB2F5, "1103 1161 11B8"), - (0xB2F6, "1103 1161 11B9"), - (0xB2F7, "1103 1161 11BA"), - (0xB2F8, "1103 1161 11BB"), - (0xB2F9, "1103 1161 11BC"), - (0xB2FA, "1103 1161 11BD"), - (0xB2FB, "1103 1161 11BE"), - (0xB2FC, "1103 1161 11BF"), - (0xB2FD, "1103 1161 11C0"), - (0xB2FE, "1103 1161 11C1"), - (0xB2FF, "1103 1161 11C2"), - (0xB300, "1103 1162"), - (0xB301, "1103 1162 11A8"), - (0xB302, "1103 1162 11A9"), - (0xB303, "1103 1162 11AA"), - (0xB304, "1103 1162 11AB"), - (0xB305, "1103 1162 11AC"), - (0xB306, "1103 1162 11AD"), - (0xB307, "1103 1162 11AE"), - (0xB308, "1103 1162 11AF"), - (0xB309, "1103 1162 11B0"), - (0xB30A, "1103 1162 11B1"), - (0xB30B, "1103 1162 11B2"), - (0xB30C, "1103 1162 11B3"), - (0xB30D, "1103 1162 11B4"), - (0xB30E, "1103 1162 11B5"), - (0xB30F, "1103 1162 11B6"), - (0xB310, "1103 1162 11B7"), - (0xB311, "1103 1162 11B8"), - (0xB312, "1103 1162 11B9"), - (0xB313, "1103 1162 11BA"), - (0xB314, "1103 1162 11BB"), - (0xB315, "1103 1162 11BC"), - (0xB316, "1103 1162 11BD"), - (0xB317, "1103 1162 11BE"), - (0xB318, "1103 1162 11BF"), - (0xB319, "1103 1162 11C0"), - (0xB31A, "1103 1162 11C1"), - (0xB31B, "1103 1162 11C2"), - (0xB31C, "1103 1163"), - (0xB31D, "1103 1163 11A8"), - (0xB31E, "1103 1163 11A9"), - (0xB31F, "1103 1163 11AA"), - (0xB320, "1103 1163 11AB"), - (0xB321, "1103 1163 11AC"), - (0xB322, "1103 1163 11AD"), - (0xB323, "1103 1163 11AE"), - (0xB324, "1103 1163 11AF"), - (0xB325, "1103 1163 11B0"), - (0xB326, "1103 1163 11B1"), - (0xB327, "1103 1163 11B2"), - (0xB328, "1103 1163 11B3"), - (0xB329, "1103 1163 11B4"), - (0xB32A, "1103 1163 11B5"), - (0xB32B, "1103 1163 11B6"), - (0xB32C, "1103 1163 11B7"), - (0xB32D, "1103 1163 11B8"), - (0xB32E, "1103 1163 11B9"), - (0xB32F, "1103 1163 11BA"), - (0xB330, "1103 1163 11BB"), - (0xB331, "1103 1163 11BC"), - (0xB332, "1103 1163 11BD"), - (0xB333, "1103 1163 11BE"), - (0xB334, "1103 1163 11BF"), - (0xB335, "1103 1163 11C0"), - (0xB336, "1103 1163 11C1"), - (0xB337, "1103 1163 11C2"), - (0xB338, "1103 1164"), - (0xB339, "1103 1164 11A8"), - (0xB33A, "1103 1164 11A9"), - (0xB33B, "1103 1164 11AA"), - (0xB33C, "1103 1164 11AB"), - (0xB33D, "1103 1164 11AC"), - (0xB33E, "1103 1164 11AD"), - (0xB33F, "1103 1164 11AE"), - (0xB340, "1103 1164 11AF"), - (0xB341, "1103 1164 11B0"), - (0xB342, "1103 1164 11B1"), - (0xB343, "1103 1164 11B2"), - (0xB344, "1103 1164 11B3"), - (0xB345, "1103 1164 11B4"), - (0xB346, "1103 1164 11B5"), - (0xB347, "1103 1164 11B6"), - (0xB348, "1103 1164 11B7"), - (0xB349, "1103 1164 11B8"), - (0xB34A, "1103 1164 11B9"), - (0xB34B, "1103 1164 11BA"), - (0xB34C, "1103 1164 11BB"), - (0xB34D, "1103 1164 11BC"), - (0xB34E, "1103 1164 11BD"), - (0xB34F, "1103 1164 11BE"), - (0xB350, "1103 1164 11BF"), - (0xB351, "1103 1164 11C0"), - (0xB352, "1103 1164 11C1"), - (0xB353, "1103 1164 11C2"), - (0xB354, "1103 1165"), - (0xB355, "1103 1165 11A8"), - (0xB356, "1103 1165 11A9"), - (0xB357, "1103 1165 11AA"), - (0xB358, "1103 1165 11AB"), - (0xB359, "1103 1165 11AC"), - (0xB35A, "1103 1165 11AD"), - (0xB35B, "1103 1165 11AE"), - (0xB35C, "1103 1165 11AF"), - (0xB35D, "1103 1165 11B0"), - (0xB35E, "1103 1165 11B1"), - (0xB35F, "1103 1165 11B2"), - (0xB360, "1103 1165 11B3"), - (0xB361, "1103 1165 11B4"), - (0xB362, "1103 1165 11B5"), - (0xB363, "1103 1165 11B6"), - (0xB364, "1103 1165 11B7"), - (0xB365, "1103 1165 11B8"), - (0xB366, "1103 1165 11B9"), - (0xB367, "1103 1165 11BA"), - (0xB368, "1103 1165 11BB"), - (0xB369, "1103 1165 11BC"), - (0xB36A, "1103 1165 11BD"), - (0xB36B, "1103 1165 11BE"), - (0xB36C, "1103 1165 11BF"), - (0xB36D, "1103 1165 11C0"), - (0xB36E, "1103 1165 11C1"), - (0xB36F, "1103 1165 11C2"), - (0xB370, "1103 1166"), - (0xB371, "1103 1166 11A8"), - (0xB372, "1103 1166 11A9"), - (0xB373, "1103 1166 11AA"), - (0xB374, "1103 1166 11AB"), - (0xB375, "1103 1166 11AC"), - (0xB376, "1103 1166 11AD"), - (0xB377, "1103 1166 11AE"), - (0xB378, "1103 1166 11AF"), - (0xB379, "1103 1166 11B0"), - (0xB37A, "1103 1166 11B1"), - (0xB37B, "1103 1166 11B2"), - (0xB37C, "1103 1166 11B3"), - (0xB37D, "1103 1166 11B4"), - (0xB37E, "1103 1166 11B5"), - (0xB37F, "1103 1166 11B6"), - (0xB380, "1103 1166 11B7"), - (0xB381, "1103 1166 11B8"), - (0xB382, "1103 1166 11B9"), - (0xB383, "1103 1166 11BA"), - (0xB384, "1103 1166 11BB"), - (0xB385, "1103 1166 11BC"), - (0xB386, "1103 1166 11BD"), - (0xB387, "1103 1166 11BE"), - (0xB388, "1103 1166 11BF"), - (0xB389, "1103 1166 11C0"), - (0xB38A, "1103 1166 11C1"), - (0xB38B, "1103 1166 11C2"), - (0xB38C, "1103 1167"), - (0xB38D, "1103 1167 11A8"), - (0xB38E, "1103 1167 11A9"), - (0xB38F, "1103 1167 11AA"), - (0xB390, "1103 1167 11AB"), - (0xB391, "1103 1167 11AC"), - (0xB392, "1103 1167 11AD"), - (0xB393, "1103 1167 11AE"), - (0xB394, "1103 1167 11AF"), - (0xB395, "1103 1167 11B0"), - (0xB396, "1103 1167 11B1"), - (0xB397, "1103 1167 11B2"), - (0xB398, "1103 1167 11B3"), - (0xB399, "1103 1167 11B4"), - (0xB39A, "1103 1167 11B5"), - (0xB39B, "1103 1167 11B6"), - (0xB39C, "1103 1167 11B7"), - (0xB39D, "1103 1167 11B8"), - (0xB39E, "1103 1167 11B9"), - (0xB39F, "1103 1167 11BA"), - (0xB3A0, "1103 1167 11BB"), - (0xB3A1, "1103 1167 11BC"), - (0xB3A2, "1103 1167 11BD"), - (0xB3A3, "1103 1167 11BE"), - (0xB3A4, "1103 1167 11BF"), - (0xB3A5, "1103 1167 11C0"), - (0xB3A6, "1103 1167 11C1"), - (0xB3A7, "1103 1167 11C2"), - (0xB3A8, "1103 1168"), - (0xB3A9, "1103 1168 11A8"), - (0xB3AA, "1103 1168 11A9"), - (0xB3AB, "1103 1168 11AA"), - (0xB3AC, "1103 1168 11AB"), - (0xB3AD, "1103 1168 11AC"), - (0xB3AE, "1103 1168 11AD"), - (0xB3AF, "1103 1168 11AE"), - (0xB3B0, "1103 1168 11AF"), - (0xB3B1, "1103 1168 11B0"), - (0xB3B2, "1103 1168 11B1"), - (0xB3B3, "1103 1168 11B2"), - (0xB3B4, "1103 1168 11B3"), - (0xB3B5, "1103 1168 11B4"), - (0xB3B6, "1103 1168 11B5"), - (0xB3B7, "1103 1168 11B6"), - (0xB3B8, "1103 1168 11B7"), - (0xB3B9, "1103 1168 11B8"), - (0xB3BA, "1103 1168 11B9"), - (0xB3BB, "1103 1168 11BA"), - (0xB3BC, "1103 1168 11BB"), - (0xB3BD, "1103 1168 11BC"), - (0xB3BE, "1103 1168 11BD"), - (0xB3BF, "1103 1168 11BE"), - (0xB3C0, "1103 1168 11BF"), - (0xB3C1, "1103 1168 11C0"), - (0xB3C2, "1103 1168 11C1"), - (0xB3C3, "1103 1168 11C2"), - (0xB3C4, "1103 1169"), - (0xB3C5, "1103 1169 11A8"), - (0xB3C6, "1103 1169 11A9"), - (0xB3C7, "1103 1169 11AA"), - (0xB3C8, "1103 1169 11AB"), - (0xB3C9, "1103 1169 11AC"), - (0xB3CA, "1103 1169 11AD"), - (0xB3CB, "1103 1169 11AE"), - (0xB3CC, "1103 1169 11AF"), - (0xB3CD, "1103 1169 11B0"), - (0xB3CE, "1103 1169 11B1"), - (0xB3CF, "1103 1169 11B2"), - (0xB3D0, "1103 1169 11B3"), - (0xB3D1, "1103 1169 11B4"), - (0xB3D2, "1103 1169 11B5"), - (0xB3D3, "1103 1169 11B6"), - (0xB3D4, "1103 1169 11B7"), - (0xB3D5, "1103 1169 11B8"), - (0xB3D6, "1103 1169 11B9"), - (0xB3D7, "1103 1169 11BA"), - (0xB3D8, "1103 1169 11BB"), - (0xB3D9, "1103 1169 11BC"), - (0xB3DA, "1103 1169 11BD"), - (0xB3DB, "1103 1169 11BE"), - (0xB3DC, "1103 1169 11BF"), - (0xB3DD, "1103 1169 11C0"), - (0xB3DE, "1103 1169 11C1"), - (0xB3DF, "1103 1169 11C2"), - (0xB3E0, "1103 116A"), - (0xB3E1, "1103 116A 11A8"), - (0xB3E2, "1103 116A 11A9"), - (0xB3E3, "1103 116A 11AA"), - (0xB3E4, "1103 116A 11AB"), - (0xB3E5, "1103 116A 11AC"), - (0xB3E6, "1103 116A 11AD"), - (0xB3E7, "1103 116A 11AE"), - (0xB3E8, "1103 116A 11AF"), - (0xB3E9, "1103 116A 11B0"), - (0xB3EA, "1103 116A 11B1"), - (0xB3EB, "1103 116A 11B2"), - (0xB3EC, "1103 116A 11B3"), - (0xB3ED, "1103 116A 11B4"), - (0xB3EE, "1103 116A 11B5"), - (0xB3EF, "1103 116A 11B6"), - (0xB3F0, "1103 116A 11B7"), - (0xB3F1, "1103 116A 11B8"), - (0xB3F2, "1103 116A 11B9"), - (0xB3F3, "1103 116A 11BA"), - (0xB3F4, "1103 116A 11BB"), - (0xB3F5, "1103 116A 11BC"), - (0xB3F6, "1103 116A 11BD"), - (0xB3F7, "1103 116A 11BE"), - (0xB3F8, "1103 116A 11BF"), - (0xB3F9, "1103 116A 11C0"), - (0xB3FA, "1103 116A 11C1"), - (0xB3FB, "1103 116A 11C2"), - (0xB3FC, "1103 116B"), - (0xB3FD, "1103 116B 11A8"), - (0xB3FE, "1103 116B 11A9"), - (0xB3FF, "1103 116B 11AA"), - (0xB400, "1103 116B 11AB"), - (0xB401, "1103 116B 11AC"), - (0xB402, "1103 116B 11AD"), - (0xB403, "1103 116B 11AE"), - (0xB404, "1103 116B 11AF"), - (0xB405, "1103 116B 11B0"), - (0xB406, "1103 116B 11B1"), - (0xB407, "1103 116B 11B2"), - (0xB408, "1103 116B 11B3"), - (0xB409, "1103 116B 11B4"), - (0xB40A, "1103 116B 11B5"), - (0xB40B, "1103 116B 11B6"), - (0xB40C, "1103 116B 11B7"), - (0xB40D, "1103 116B 11B8"), - (0xB40E, "1103 116B 11B9"), - (0xB40F, "1103 116B 11BA"), - (0xB410, "1103 116B 11BB"), - (0xB411, "1103 116B 11BC"), - (0xB412, "1103 116B 11BD"), - (0xB413, "1103 116B 11BE"), - (0xB414, "1103 116B 11BF"), - (0xB415, "1103 116B 11C0"), - (0xB416, "1103 116B 11C1"), - (0xB417, "1103 116B 11C2"), - (0xB418, "1103 116C"), - (0xB419, "1103 116C 11A8"), - (0xB41A, "1103 116C 11A9"), - (0xB41B, "1103 116C 11AA"), - (0xB41C, "1103 116C 11AB"), - (0xB41D, "1103 116C 11AC"), - (0xB41E, "1103 116C 11AD"), - (0xB41F, "1103 116C 11AE"), - (0xB420, "1103 116C 11AF"), - (0xB421, "1103 116C 11B0"), - (0xB422, "1103 116C 11B1"), - (0xB423, "1103 116C 11B2"), - (0xB424, "1103 116C 11B3"), - (0xB425, "1103 116C 11B4"), - (0xB426, "1103 116C 11B5"), - (0xB427, "1103 116C 11B6"), - (0xB428, "1103 116C 11B7"), - (0xB429, "1103 116C 11B8"), - (0xB42A, "1103 116C 11B9"), - (0xB42B, "1103 116C 11BA"), - (0xB42C, "1103 116C 11BB"), - (0xB42D, "1103 116C 11BC"), - (0xB42E, "1103 116C 11BD"), - (0xB42F, "1103 116C 11BE"), - (0xB430, "1103 116C 11BF"), - (0xB431, "1103 116C 11C0"), - (0xB432, "1103 116C 11C1"), - (0xB433, "1103 116C 11C2"), - (0xB434, "1103 116D"), - (0xB435, "1103 116D 11A8"), - (0xB436, "1103 116D 11A9"), - (0xB437, "1103 116D 11AA"), - (0xB438, "1103 116D 11AB"), - (0xB439, "1103 116D 11AC"), - (0xB43A, "1103 116D 11AD"), - (0xB43B, "1103 116D 11AE"), - (0xB43C, "1103 116D 11AF"), - (0xB43D, "1103 116D 11B0"), - (0xB43E, "1103 116D 11B1"), - (0xB43F, "1103 116D 11B2"), - (0xB440, "1103 116D 11B3"), - (0xB441, "1103 116D 11B4"), - (0xB442, "1103 116D 11B5"), - (0xB443, "1103 116D 11B6"), - (0xB444, "1103 116D 11B7"), - (0xB445, "1103 116D 11B8"), - (0xB446, "1103 116D 11B9"), - (0xB447, "1103 116D 11BA"), - (0xB448, "1103 116D 11BB"), - (0xB449, "1103 116D 11BC"), - (0xB44A, "1103 116D 11BD"), - (0xB44B, "1103 116D 11BE"), - (0xB44C, "1103 116D 11BF"), - (0xB44D, "1103 116D 11C0"), - (0xB44E, "1103 116D 11C1"), - (0xB44F, "1103 116D 11C2"), - (0xB450, "1103 116E"), - (0xB451, "1103 116E 11A8"), - (0xB452, "1103 116E 11A9"), - (0xB453, "1103 116E 11AA"), - (0xB454, "1103 116E 11AB"), - (0xB455, "1103 116E 11AC"), - (0xB456, "1103 116E 11AD"), - (0xB457, "1103 116E 11AE"), - (0xB458, "1103 116E 11AF"), - (0xB459, "1103 116E 11B0"), - (0xB45A, "1103 116E 11B1"), - (0xB45B, "1103 116E 11B2"), - (0xB45C, "1103 116E 11B3"), - (0xB45D, "1103 116E 11B4"), - (0xB45E, "1103 116E 11B5"), - (0xB45F, "1103 116E 11B6"), - (0xB460, "1103 116E 11B7"), - (0xB461, "1103 116E 11B8"), - (0xB462, "1103 116E 11B9"), - (0xB463, "1103 116E 11BA"), - (0xB464, "1103 116E 11BB"), - (0xB465, "1103 116E 11BC"), - (0xB466, "1103 116E 11BD"), - (0xB467, "1103 116E 11BE"), - (0xB468, "1103 116E 11BF"), - (0xB469, "1103 116E 11C0"), - (0xB46A, "1103 116E 11C1"), - (0xB46B, "1103 116E 11C2"), - (0xB46C, "1103 116F"), - (0xB46D, "1103 116F 11A8"), - (0xB46E, "1103 116F 11A9"), - (0xB46F, "1103 116F 11AA"), - (0xB470, "1103 116F 11AB"), - (0xB471, "1103 116F 11AC"), - (0xB472, "1103 116F 11AD"), - (0xB473, "1103 116F 11AE"), - (0xB474, "1103 116F 11AF"), - (0xB475, "1103 116F 11B0"), - (0xB476, "1103 116F 11B1"), - (0xB477, "1103 116F 11B2"), - (0xB478, "1103 116F 11B3"), - (0xB479, "1103 116F 11B4"), - (0xB47A, "1103 116F 11B5"), - (0xB47B, "1103 116F 11B6"), - (0xB47C, "1103 116F 11B7"), - (0xB47D, "1103 116F 11B8"), - (0xB47E, "1103 116F 11B9"), - (0xB47F, "1103 116F 11BA"), - (0xB480, "1103 116F 11BB"), - (0xB481, "1103 116F 11BC"), - (0xB482, "1103 116F 11BD"), - (0xB483, "1103 116F 11BE"), - (0xB484, "1103 116F 11BF"), - (0xB485, "1103 116F 11C0"), - (0xB486, "1103 116F 11C1"), - (0xB487, "1103 116F 11C2"), - (0xB488, "1103 1170"), - (0xB489, "1103 1170 11A8"), - (0xB48A, "1103 1170 11A9"), - (0xB48B, "1103 1170 11AA"), - (0xB48C, "1103 1170 11AB"), - (0xB48D, "1103 1170 11AC"), - (0xB48E, "1103 1170 11AD"), - (0xB48F, "1103 1170 11AE"), - (0xB490, "1103 1170 11AF"), - (0xB491, "1103 1170 11B0"), - (0xB492, "1103 1170 11B1"), - (0xB493, "1103 1170 11B2"), - (0xB494, "1103 1170 11B3"), - (0xB495, "1103 1170 11B4"), - (0xB496, "1103 1170 11B5"), - (0xB497, "1103 1170 11B6"), - (0xB498, "1103 1170 11B7"), - (0xB499, "1103 1170 11B8"), - (0xB49A, "1103 1170 11B9"), - (0xB49B, "1103 1170 11BA"), - (0xB49C, "1103 1170 11BB"), - (0xB49D, "1103 1170 11BC"), - (0xB49E, "1103 1170 11BD"), - (0xB49F, "1103 1170 11BE"), - (0xB4A0, "1103 1170 11BF"), - (0xB4A1, "1103 1170 11C0"), - (0xB4A2, "1103 1170 11C1"), - (0xB4A3, "1103 1170 11C2"), - (0xB4A4, "1103 1171"), - (0xB4A5, "1103 1171 11A8"), - (0xB4A6, "1103 1171 11A9"), - (0xB4A7, "1103 1171 11AA"), - (0xB4A8, "1103 1171 11AB"), - (0xB4A9, "1103 1171 11AC"), - (0xB4AA, "1103 1171 11AD"), - (0xB4AB, "1103 1171 11AE"), - (0xB4AC, "1103 1171 11AF"), - (0xB4AD, "1103 1171 11B0"), - (0xB4AE, "1103 1171 11B1"), - (0xB4AF, "1103 1171 11B2"), - (0xB4B0, "1103 1171 11B3"), - (0xB4B1, "1103 1171 11B4"), - (0xB4B2, "1103 1171 11B5"), - (0xB4B3, "1103 1171 11B6"), - (0xB4B4, "1103 1171 11B7"), - (0xB4B5, "1103 1171 11B8"), - (0xB4B6, "1103 1171 11B9"), - (0xB4B7, "1103 1171 11BA"), - (0xB4B8, "1103 1171 11BB"), - (0xB4B9, "1103 1171 11BC"), - (0xB4BA, "1103 1171 11BD"), - (0xB4BB, "1103 1171 11BE"), - (0xB4BC, "1103 1171 11BF"), - (0xB4BD, "1103 1171 11C0"), - (0xB4BE, "1103 1171 11C1"), - (0xB4BF, "1103 1171 11C2"), - (0xB4C0, "1103 1172"), - (0xB4C1, "1103 1172 11A8"), - (0xB4C2, "1103 1172 11A9"), - (0xB4C3, "1103 1172 11AA"), - (0xB4C4, "1103 1172 11AB"), - (0xB4C5, "1103 1172 11AC"), - (0xB4C6, "1103 1172 11AD"), - (0xB4C7, "1103 1172 11AE"), - (0xB4C8, "1103 1172 11AF"), - (0xB4C9, "1103 1172 11B0"), - (0xB4CA, "1103 1172 11B1"), - (0xB4CB, "1103 1172 11B2"), - (0xB4CC, "1103 1172 11B3"), - (0xB4CD, "1103 1172 11B4"), - (0xB4CE, "1103 1172 11B5"), - (0xB4CF, "1103 1172 11B6"), - (0xB4D0, "1103 1172 11B7"), - (0xB4D1, "1103 1172 11B8"), - (0xB4D2, "1103 1172 11B9"), - (0xB4D3, "1103 1172 11BA"), - (0xB4D4, "1103 1172 11BB"), - (0xB4D5, "1103 1172 11BC"), - (0xB4D6, "1103 1172 11BD"), - (0xB4D7, "1103 1172 11BE"), - (0xB4D8, "1103 1172 11BF"), - (0xB4D9, "1103 1172 11C0"), - (0xB4DA, "1103 1172 11C1"), - (0xB4DB, "1103 1172 11C2"), - (0xB4DC, "1103 1173"), - (0xB4DD, "1103 1173 11A8"), - (0xB4DE, "1103 1173 11A9"), - (0xB4DF, "1103 1173 11AA"), - (0xB4E0, "1103 1173 11AB"), - (0xB4E1, "1103 1173 11AC"), - (0xB4E2, "1103 1173 11AD"), - (0xB4E3, "1103 1173 11AE"), - (0xB4E4, "1103 1173 11AF"), - (0xB4E5, "1103 1173 11B0"), - (0xB4E6, "1103 1173 11B1"), - (0xB4E7, "1103 1173 11B2"), - (0xB4E8, "1103 1173 11B3"), - (0xB4E9, "1103 1173 11B4"), - (0xB4EA, "1103 1173 11B5"), - (0xB4EB, "1103 1173 11B6"), - (0xB4EC, "1103 1173 11B7"), - (0xB4ED, "1103 1173 11B8"), - (0xB4EE, "1103 1173 11B9"), - (0xB4EF, "1103 1173 11BA"), - (0xB4F0, "1103 1173 11BB"), - (0xB4F1, "1103 1173 11BC"), - (0xB4F2, "1103 1173 11BD"), - (0xB4F3, "1103 1173 11BE"), - (0xB4F4, "1103 1173 11BF"), - (0xB4F5, "1103 1173 11C0"), - (0xB4F6, "1103 1173 11C1"), - (0xB4F7, "1103 1173 11C2"), - (0xB4F8, "1103 1174"), - (0xB4F9, "1103 1174 11A8"), - (0xB4FA, "1103 1174 11A9"), - (0xB4FB, "1103 1174 11AA"), - (0xB4FC, "1103 1174 11AB"), - (0xB4FD, "1103 1174 11AC"), - (0xB4FE, "1103 1174 11AD"), - (0xB4FF, "1103 1174 11AE"), - (0xB500, "1103 1174 11AF"), - (0xB501, "1103 1174 11B0"), - (0xB502, "1103 1174 11B1"), - (0xB503, "1103 1174 11B2"), - (0xB504, "1103 1174 11B3"), - (0xB505, "1103 1174 11B4"), - (0xB506, "1103 1174 11B5"), - (0xB507, "1103 1174 11B6"), - (0xB508, "1103 1174 11B7"), - (0xB509, "1103 1174 11B8"), - (0xB50A, "1103 1174 11B9"), - (0xB50B, "1103 1174 11BA"), - (0xB50C, "1103 1174 11BB"), - (0xB50D, "1103 1174 11BC"), - (0xB50E, "1103 1174 11BD"), - (0xB50F, "1103 1174 11BE"), - (0xB510, "1103 1174 11BF"), - (0xB511, "1103 1174 11C0"), - (0xB512, "1103 1174 11C1"), - (0xB513, "1103 1174 11C2"), - (0xB514, "1103 1175"), - (0xB515, "1103 1175 11A8"), - (0xB516, "1103 1175 11A9"), - (0xB517, "1103 1175 11AA"), - (0xB518, "1103 1175 11AB"), - (0xB519, "1103 1175 11AC"), - (0xB51A, "1103 1175 11AD"), - (0xB51B, "1103 1175 11AE"), - (0xB51C, "1103 1175 11AF"), - (0xB51D, "1103 1175 11B0"), - (0xB51E, "1103 1175 11B1"), - (0xB51F, "1103 1175 11B2"), - (0xB520, "1103 1175 11B3"), - (0xB521, "1103 1175 11B4"), - (0xB522, "1103 1175 11B5"), - (0xB523, "1103 1175 11B6"), - (0xB524, "1103 1175 11B7"), - (0xB525, "1103 1175 11B8"), - (0xB526, "1103 1175 11B9"), - (0xB527, "1103 1175 11BA"), - (0xB528, "1103 1175 11BB"), - (0xB529, "1103 1175 11BC"), - (0xB52A, "1103 1175 11BD"), - (0xB52B, "1103 1175 11BE"), - (0xB52C, "1103 1175 11BF"), - (0xB52D, "1103 1175 11C0"), - (0xB52E, "1103 1175 11C1"), - (0xB52F, "1103 1175 11C2"), - (0xB530, "1104 1161"), - (0xB531, "1104 1161 11A8"), - (0xB532, "1104 1161 11A9"), - (0xB533, "1104 1161 11AA"), - (0xB534, "1104 1161 11AB"), - (0xB535, "1104 1161 11AC"), - (0xB536, "1104 1161 11AD"), - (0xB537, "1104 1161 11AE"), - (0xB538, "1104 1161 11AF"), - (0xB539, "1104 1161 11B0"), - (0xB53A, "1104 1161 11B1"), - (0xB53B, "1104 1161 11B2"), - (0xB53C, "1104 1161 11B3"), - (0xB53D, "1104 1161 11B4"), - (0xB53E, "1104 1161 11B5"), - (0xB53F, "1104 1161 11B6"), - (0xB540, "1104 1161 11B7"), - (0xB541, "1104 1161 11B8"), - (0xB542, "1104 1161 11B9"), - (0xB543, "1104 1161 11BA"), - (0xB544, "1104 1161 11BB"), - (0xB545, "1104 1161 11BC"), - (0xB546, "1104 1161 11BD"), - (0xB547, "1104 1161 11BE"), - (0xB548, "1104 1161 11BF"), - (0xB549, "1104 1161 11C0"), - (0xB54A, "1104 1161 11C1"), - (0xB54B, "1104 1161 11C2"), - (0xB54C, "1104 1162"), - (0xB54D, "1104 1162 11A8"), - (0xB54E, "1104 1162 11A9"), - (0xB54F, "1104 1162 11AA"), - (0xB550, "1104 1162 11AB"), - (0xB551, "1104 1162 11AC"), - (0xB552, "1104 1162 11AD"), - (0xB553, "1104 1162 11AE"), - (0xB554, "1104 1162 11AF"), - (0xB555, "1104 1162 11B0"), - (0xB556, "1104 1162 11B1"), - (0xB557, "1104 1162 11B2"), - (0xB558, "1104 1162 11B3"), - (0xB559, "1104 1162 11B4"), - (0xB55A, "1104 1162 11B5"), - (0xB55B, "1104 1162 11B6"), - (0xB55C, "1104 1162 11B7"), - (0xB55D, "1104 1162 11B8"), - (0xB55E, "1104 1162 11B9"), - (0xB55F, "1104 1162 11BA"), - (0xB560, "1104 1162 11BB"), - (0xB561, "1104 1162 11BC"), - (0xB562, "1104 1162 11BD"), - (0xB563, "1104 1162 11BE"), - (0xB564, "1104 1162 11BF"), - (0xB565, "1104 1162 11C0"), - (0xB566, "1104 1162 11C1"), - (0xB567, "1104 1162 11C2"), - (0xB568, "1104 1163"), - (0xB569, "1104 1163 11A8"), - (0xB56A, "1104 1163 11A9"), - (0xB56B, "1104 1163 11AA"), - (0xB56C, "1104 1163 11AB"), - (0xB56D, "1104 1163 11AC"), - (0xB56E, "1104 1163 11AD"), - (0xB56F, "1104 1163 11AE"), - (0xB570, "1104 1163 11AF"), - (0xB571, "1104 1163 11B0"), - (0xB572, "1104 1163 11B1"), - (0xB573, "1104 1163 11B2"), - (0xB574, "1104 1163 11B3"), - (0xB575, "1104 1163 11B4"), - (0xB576, "1104 1163 11B5"), - (0xB577, "1104 1163 11B6"), - (0xB578, "1104 1163 11B7"), - (0xB579, "1104 1163 11B8"), - (0xB57A, "1104 1163 11B9"), - (0xB57B, "1104 1163 11BA"), - (0xB57C, "1104 1163 11BB"), - (0xB57D, "1104 1163 11BC"), - (0xB57E, "1104 1163 11BD"), - (0xB57F, "1104 1163 11BE"), - (0xB580, "1104 1163 11BF"), - (0xB581, "1104 1163 11C0"), - (0xB582, "1104 1163 11C1"), - (0xB583, "1104 1163 11C2"), - (0xB584, "1104 1164"), - (0xB585, "1104 1164 11A8"), - (0xB586, "1104 1164 11A9"), - (0xB587, "1104 1164 11AA"), - (0xB588, "1104 1164 11AB"), - (0xB589, "1104 1164 11AC"), - (0xB58A, "1104 1164 11AD"), - (0xB58B, "1104 1164 11AE"), - (0xB58C, "1104 1164 11AF"), - (0xB58D, "1104 1164 11B0"), - (0xB58E, "1104 1164 11B1"), - (0xB58F, "1104 1164 11B2"), - (0xB590, "1104 1164 11B3"), - (0xB591, "1104 1164 11B4"), - (0xB592, "1104 1164 11B5"), - (0xB593, "1104 1164 11B6"), - (0xB594, "1104 1164 11B7"), - (0xB595, "1104 1164 11B8"), - (0xB596, "1104 1164 11B9"), - (0xB597, "1104 1164 11BA"), - (0xB598, "1104 1164 11BB"), - (0xB599, "1104 1164 11BC"), - (0xB59A, "1104 1164 11BD"), - (0xB59B, "1104 1164 11BE"), - (0xB59C, "1104 1164 11BF"), - (0xB59D, "1104 1164 11C0"), - (0xB59E, "1104 1164 11C1"), - (0xB59F, "1104 1164 11C2"), - (0xB5A0, "1104 1165"), - (0xB5A1, "1104 1165 11A8"), - (0xB5A2, "1104 1165 11A9"), - (0xB5A3, "1104 1165 11AA"), - (0xB5A4, "1104 1165 11AB"), - (0xB5A5, "1104 1165 11AC"), - (0xB5A6, "1104 1165 11AD"), - (0xB5A7, "1104 1165 11AE"), - (0xB5A8, "1104 1165 11AF"), - (0xB5A9, "1104 1165 11B0"), - (0xB5AA, "1104 1165 11B1"), - (0xB5AB, "1104 1165 11B2"), - (0xB5AC, "1104 1165 11B3"), - (0xB5AD, "1104 1165 11B4"), - (0xB5AE, "1104 1165 11B5"), - (0xB5AF, "1104 1165 11B6"), - (0xB5B0, "1104 1165 11B7"), - (0xB5B1, "1104 1165 11B8"), - (0xB5B2, "1104 1165 11B9"), - (0xB5B3, "1104 1165 11BA"), - (0xB5B4, "1104 1165 11BB"), - (0xB5B5, "1104 1165 11BC"), - (0xB5B6, "1104 1165 11BD"), - (0xB5B7, "1104 1165 11BE"), - (0xB5B8, "1104 1165 11BF"), - (0xB5B9, "1104 1165 11C0"), - (0xB5BA, "1104 1165 11C1"), - (0xB5BB, "1104 1165 11C2"), - (0xB5BC, "1104 1166"), - (0xB5BD, "1104 1166 11A8"), - (0xB5BE, "1104 1166 11A9"), - (0xB5BF, "1104 1166 11AA"), - (0xB5C0, "1104 1166 11AB"), - (0xB5C1, "1104 1166 11AC"), - (0xB5C2, "1104 1166 11AD"), - (0xB5C3, "1104 1166 11AE"), - (0xB5C4, "1104 1166 11AF"), - (0xB5C5, "1104 1166 11B0"), - (0xB5C6, "1104 1166 11B1"), - (0xB5C7, "1104 1166 11B2"), - (0xB5C8, "1104 1166 11B3"), - (0xB5C9, "1104 1166 11B4"), - (0xB5CA, "1104 1166 11B5"), - (0xB5CB, "1104 1166 11B6"), - (0xB5CC, "1104 1166 11B7"), - (0xB5CD, "1104 1166 11B8"), - (0xB5CE, "1104 1166 11B9"), - (0xB5CF, "1104 1166 11BA"), - (0xB5D0, "1104 1166 11BB"), - (0xB5D1, "1104 1166 11BC"), - (0xB5D2, "1104 1166 11BD"), - (0xB5D3, "1104 1166 11BE"), - (0xB5D4, "1104 1166 11BF"), - (0xB5D5, "1104 1166 11C0"), - (0xB5D6, "1104 1166 11C1"), - (0xB5D7, "1104 1166 11C2"), - (0xB5D8, "1104 1167"), - (0xB5D9, "1104 1167 11A8"), - (0xB5DA, "1104 1167 11A9"), - (0xB5DB, "1104 1167 11AA"), - (0xB5DC, "1104 1167 11AB"), - (0xB5DD, "1104 1167 11AC"), - (0xB5DE, "1104 1167 11AD"), - (0xB5DF, "1104 1167 11AE"), - (0xB5E0, "1104 1167 11AF"), - (0xB5E1, "1104 1167 11B0"), - (0xB5E2, "1104 1167 11B1"), - (0xB5E3, "1104 1167 11B2"), - (0xB5E4, "1104 1167 11B3"), - (0xB5E5, "1104 1167 11B4"), - (0xB5E6, "1104 1167 11B5"), - (0xB5E7, "1104 1167 11B6"), - (0xB5E8, "1104 1167 11B7"), - (0xB5E9, "1104 1167 11B8"), - (0xB5EA, "1104 1167 11B9"), - (0xB5EB, "1104 1167 11BA"), - (0xB5EC, "1104 1167 11BB"), - (0xB5ED, "1104 1167 11BC"), - (0xB5EE, "1104 1167 11BD"), - (0xB5EF, "1104 1167 11BE"), - (0xB5F0, "1104 1167 11BF"), - (0xB5F1, "1104 1167 11C0"), - (0xB5F2, "1104 1167 11C1"), - (0xB5F3, "1104 1167 11C2"), - (0xB5F4, "1104 1168"), - (0xB5F5, "1104 1168 11A8"), - (0xB5F6, "1104 1168 11A9"), - (0xB5F7, "1104 1168 11AA"), - (0xB5F8, "1104 1168 11AB"), - (0xB5F9, "1104 1168 11AC"), - (0xB5FA, "1104 1168 11AD"), - (0xB5FB, "1104 1168 11AE"), - (0xB5FC, "1104 1168 11AF"), - (0xB5FD, "1104 1168 11B0"), - (0xB5FE, "1104 1168 11B1"), - (0xB5FF, "1104 1168 11B2"), - (0xB600, "1104 1168 11B3"), - (0xB601, "1104 1168 11B4"), - (0xB602, "1104 1168 11B5"), - (0xB603, "1104 1168 11B6"), - (0xB604, "1104 1168 11B7"), - (0xB605, "1104 1168 11B8"), - (0xB606, "1104 1168 11B9"), - (0xB607, "1104 1168 11BA"), - (0xB608, "1104 1168 11BB"), - (0xB609, "1104 1168 11BC"), - (0xB60A, "1104 1168 11BD"), - (0xB60B, "1104 1168 11BE"), - (0xB60C, "1104 1168 11BF"), - (0xB60D, "1104 1168 11C0"), - (0xB60E, "1104 1168 11C1"), - (0xB60F, "1104 1168 11C2"), - (0xB610, "1104 1169"), - (0xB611, "1104 1169 11A8"), - (0xB612, "1104 1169 11A9"), - (0xB613, "1104 1169 11AA"), - (0xB614, "1104 1169 11AB"), - (0xB615, "1104 1169 11AC"), - (0xB616, "1104 1169 11AD"), - (0xB617, "1104 1169 11AE"), - (0xB618, "1104 1169 11AF"), - (0xB619, "1104 1169 11B0"), - (0xB61A, "1104 1169 11B1"), - (0xB61B, "1104 1169 11B2"), - (0xB61C, "1104 1169 11B3"), - (0xB61D, "1104 1169 11B4"), - (0xB61E, "1104 1169 11B5"), - (0xB61F, "1104 1169 11B6"), - (0xB620, "1104 1169 11B7"), - (0xB621, "1104 1169 11B8"), - (0xB622, "1104 1169 11B9"), - (0xB623, "1104 1169 11BA"), - (0xB624, "1104 1169 11BB"), - (0xB625, "1104 1169 11BC"), - (0xB626, "1104 1169 11BD"), - (0xB627, "1104 1169 11BE"), - (0xB628, "1104 1169 11BF"), - (0xB629, "1104 1169 11C0"), - (0xB62A, "1104 1169 11C1"), - (0xB62B, "1104 1169 11C2"), - (0xB62C, "1104 116A"), - (0xB62D, "1104 116A 11A8"), - (0xB62E, "1104 116A 11A9"), - (0xB62F, "1104 116A 11AA"), - (0xB630, "1104 116A 11AB"), - (0xB631, "1104 116A 11AC"), - (0xB632, "1104 116A 11AD"), - (0xB633, "1104 116A 11AE"), - (0xB634, "1104 116A 11AF"), - (0xB635, "1104 116A 11B0"), - (0xB636, "1104 116A 11B1"), - (0xB637, "1104 116A 11B2"), - (0xB638, "1104 116A 11B3"), - (0xB639, "1104 116A 11B4"), - (0xB63A, "1104 116A 11B5"), - (0xB63B, "1104 116A 11B6"), - (0xB63C, "1104 116A 11B7"), - (0xB63D, "1104 116A 11B8"), - (0xB63E, "1104 116A 11B9"), - (0xB63F, "1104 116A 11BA"), - (0xB640, "1104 116A 11BB"), - (0xB641, "1104 116A 11BC"), - (0xB642, "1104 116A 11BD"), - (0xB643, "1104 116A 11BE"), - (0xB644, "1104 116A 11BF"), - (0xB645, "1104 116A 11C0"), - (0xB646, "1104 116A 11C1"), - (0xB647, "1104 116A 11C2"), - (0xB648, "1104 116B"), - (0xB649, "1104 116B 11A8"), - (0xB64A, "1104 116B 11A9"), - (0xB64B, "1104 116B 11AA"), - (0xB64C, "1104 116B 11AB"), - (0xB64D, "1104 116B 11AC"), - (0xB64E, "1104 116B 11AD"), - (0xB64F, "1104 116B 11AE"), - (0xB650, "1104 116B 11AF"), - (0xB651, "1104 116B 11B0"), - (0xB652, "1104 116B 11B1"), - (0xB653, "1104 116B 11B2"), - (0xB654, "1104 116B 11B3"), - (0xB655, "1104 116B 11B4"), - (0xB656, "1104 116B 11B5"), - (0xB657, "1104 116B 11B6"), - (0xB658, "1104 116B 11B7"), - (0xB659, "1104 116B 11B8"), - (0xB65A, "1104 116B 11B9"), - (0xB65B, "1104 116B 11BA"), - (0xB65C, "1104 116B 11BB"), - (0xB65D, "1104 116B 11BC"), - (0xB65E, "1104 116B 11BD"), - (0xB65F, "1104 116B 11BE"), - (0xB660, "1104 116B 11BF"), - (0xB661, "1104 116B 11C0"), - (0xB662, "1104 116B 11C1"), - (0xB663, "1104 116B 11C2"), - (0xB664, "1104 116C"), - (0xB665, "1104 116C 11A8"), - (0xB666, "1104 116C 11A9"), - (0xB667, "1104 116C 11AA"), - (0xB668, "1104 116C 11AB"), - (0xB669, "1104 116C 11AC"), - (0xB66A, "1104 116C 11AD"), - (0xB66B, "1104 116C 11AE"), - (0xB66C, "1104 116C 11AF"), - (0xB66D, "1104 116C 11B0"), - (0xB66E, "1104 116C 11B1"), - (0xB66F, "1104 116C 11B2"), - (0xB670, "1104 116C 11B3"), - (0xB671, "1104 116C 11B4"), - (0xB672, "1104 116C 11B5"), - (0xB673, "1104 116C 11B6"), - (0xB674, "1104 116C 11B7"), - (0xB675, "1104 116C 11B8"), - (0xB676, "1104 116C 11B9"), - (0xB677, "1104 116C 11BA"), - (0xB678, "1104 116C 11BB"), - (0xB679, "1104 116C 11BC"), - (0xB67A, "1104 116C 11BD"), - (0xB67B, "1104 116C 11BE"), - (0xB67C, "1104 116C 11BF"), - (0xB67D, "1104 116C 11C0"), - (0xB67E, "1104 116C 11C1"), - (0xB67F, "1104 116C 11C2"), - (0xB680, "1104 116D"), - (0xB681, "1104 116D 11A8"), - (0xB682, "1104 116D 11A9"), - (0xB683, "1104 116D 11AA"), - (0xB684, "1104 116D 11AB"), - (0xB685, "1104 116D 11AC"), - (0xB686, "1104 116D 11AD"), - (0xB687, "1104 116D 11AE"), - (0xB688, "1104 116D 11AF"), - (0xB689, "1104 116D 11B0"), - (0xB68A, "1104 116D 11B1"), - (0xB68B, "1104 116D 11B2"), - (0xB68C, "1104 116D 11B3"), - (0xB68D, "1104 116D 11B4"), - (0xB68E, "1104 116D 11B5"), - (0xB68F, "1104 116D 11B6"), - (0xB690, "1104 116D 11B7"), - (0xB691, "1104 116D 11B8"), - (0xB692, "1104 116D 11B9"), - (0xB693, "1104 116D 11BA"), - (0xB694, "1104 116D 11BB"), - (0xB695, "1104 116D 11BC"), - (0xB696, "1104 116D 11BD"), - (0xB697, "1104 116D 11BE"), - (0xB698, "1104 116D 11BF"), - (0xB699, "1104 116D 11C0"), - (0xB69A, "1104 116D 11C1"), - (0xB69B, "1104 116D 11C2"), - (0xB69C, "1104 116E"), - (0xB69D, "1104 116E 11A8"), - (0xB69E, "1104 116E 11A9"), - (0xB69F, "1104 116E 11AA"), - (0xB6A0, "1104 116E 11AB"), - (0xB6A1, "1104 116E 11AC"), - (0xB6A2, "1104 116E 11AD"), - (0xB6A3, "1104 116E 11AE"), - (0xB6A4, "1104 116E 11AF"), - (0xB6A5, "1104 116E 11B0"), - (0xB6A6, "1104 116E 11B1"), - (0xB6A7, "1104 116E 11B2"), - (0xB6A8, "1104 116E 11B3"), - (0xB6A9, "1104 116E 11B4"), - (0xB6AA, "1104 116E 11B5"), - (0xB6AB, "1104 116E 11B6"), - (0xB6AC, "1104 116E 11B7"), - (0xB6AD, "1104 116E 11B8"), - (0xB6AE, "1104 116E 11B9"), - (0xB6AF, "1104 116E 11BA"), - (0xB6B0, "1104 116E 11BB"), - (0xB6B1, "1104 116E 11BC"), - (0xB6B2, "1104 116E 11BD"), - (0xB6B3, "1104 116E 11BE"), - (0xB6B4, "1104 116E 11BF"), - (0xB6B5, "1104 116E 11C0"), - (0xB6B6, "1104 116E 11C1"), - (0xB6B7, "1104 116E 11C2"), - (0xB6B8, "1104 116F"), - (0xB6B9, "1104 116F 11A8"), - (0xB6BA, "1104 116F 11A9"), - (0xB6BB, "1104 116F 11AA"), - (0xB6BC, "1104 116F 11AB"), - (0xB6BD, "1104 116F 11AC"), - (0xB6BE, "1104 116F 11AD"), - (0xB6BF, "1104 116F 11AE"), - (0xB6C0, "1104 116F 11AF"), - (0xB6C1, "1104 116F 11B0"), - (0xB6C2, "1104 116F 11B1"), - (0xB6C3, "1104 116F 11B2"), - (0xB6C4, "1104 116F 11B3"), - (0xB6C5, "1104 116F 11B4"), - (0xB6C6, "1104 116F 11B5"), - (0xB6C7, "1104 116F 11B6"), - (0xB6C8, "1104 116F 11B7"), - (0xB6C9, "1104 116F 11B8"), - (0xB6CA, "1104 116F 11B9"), - (0xB6CB, "1104 116F 11BA"), - (0xB6CC, "1104 116F 11BB"), - (0xB6CD, "1104 116F 11BC"), - (0xB6CE, "1104 116F 11BD"), - (0xB6CF, "1104 116F 11BE"), - (0xB6D0, "1104 116F 11BF"), - (0xB6D1, "1104 116F 11C0"), - (0xB6D2, "1104 116F 11C1"), - (0xB6D3, "1104 116F 11C2"), - (0xB6D4, "1104 1170"), - (0xB6D5, "1104 1170 11A8"), - (0xB6D6, "1104 1170 11A9"), - (0xB6D7, "1104 1170 11AA"), - (0xB6D8, "1104 1170 11AB"), - (0xB6D9, "1104 1170 11AC"), - (0xB6DA, "1104 1170 11AD"), - (0xB6DB, "1104 1170 11AE"), - (0xB6DC, "1104 1170 11AF"), - (0xB6DD, "1104 1170 11B0"), - (0xB6DE, "1104 1170 11B1"), - (0xB6DF, "1104 1170 11B2"), - (0xB6E0, "1104 1170 11B3"), - (0xB6E1, "1104 1170 11B4"), - (0xB6E2, "1104 1170 11B5"), - (0xB6E3, "1104 1170 11B6"), - (0xB6E4, "1104 1170 11B7"), - (0xB6E5, "1104 1170 11B8"), - (0xB6E6, "1104 1170 11B9"), - (0xB6E7, "1104 1170 11BA"), - (0xB6E8, "1104 1170 11BB"), - (0xB6E9, "1104 1170 11BC"), - (0xB6EA, "1104 1170 11BD"), - (0xB6EB, "1104 1170 11BE"), - (0xB6EC, "1104 1170 11BF"), - (0xB6ED, "1104 1170 11C0"), - (0xB6EE, "1104 1170 11C1"), - (0xB6EF, "1104 1170 11C2"), - (0xB6F0, "1104 1171"), - (0xB6F1, "1104 1171 11A8"), - (0xB6F2, "1104 1171 11A9"), - (0xB6F3, "1104 1171 11AA"), - (0xB6F4, "1104 1171 11AB"), - (0xB6F5, "1104 1171 11AC"), - (0xB6F6, "1104 1171 11AD"), - (0xB6F7, "1104 1171 11AE"), - (0xB6F8, "1104 1171 11AF"), - (0xB6F9, "1104 1171 11B0"), - (0xB6FA, "1104 1171 11B1"), - (0xB6FB, "1104 1171 11B2"), - (0xB6FC, "1104 1171 11B3"), - (0xB6FD, "1104 1171 11B4"), - (0xB6FE, "1104 1171 11B5"), - (0xB6FF, "1104 1171 11B6"), - (0xB700, "1104 1171 11B7"), - (0xB701, "1104 1171 11B8"), - (0xB702, "1104 1171 11B9"), - (0xB703, "1104 1171 11BA"), - (0xB704, "1104 1171 11BB"), - (0xB705, "1104 1171 11BC"), - (0xB706, "1104 1171 11BD"), - (0xB707, "1104 1171 11BE"), - (0xB708, "1104 1171 11BF"), - (0xB709, "1104 1171 11C0"), - (0xB70A, "1104 1171 11C1"), - (0xB70B, "1104 1171 11C2"), - (0xB70C, "1104 1172"), - (0xB70D, "1104 1172 11A8"), - (0xB70E, "1104 1172 11A9"), - (0xB70F, "1104 1172 11AA"), - (0xB710, "1104 1172 11AB"), - (0xB711, "1104 1172 11AC"), - (0xB712, "1104 1172 11AD"), - (0xB713, "1104 1172 11AE"), - (0xB714, "1104 1172 11AF"), - (0xB715, "1104 1172 11B0"), - (0xB716, "1104 1172 11B1"), - (0xB717, "1104 1172 11B2"), - (0xB718, "1104 1172 11B3"), - (0xB719, "1104 1172 11B4"), - (0xB71A, "1104 1172 11B5"), - (0xB71B, "1104 1172 11B6"), - (0xB71C, "1104 1172 11B7"), - (0xB71D, "1104 1172 11B8"), - (0xB71E, "1104 1172 11B9"), - (0xB71F, "1104 1172 11BA"), - (0xB720, "1104 1172 11BB"), - (0xB721, "1104 1172 11BC"), - (0xB722, "1104 1172 11BD"), - (0xB723, "1104 1172 11BE"), - (0xB724, "1104 1172 11BF"), - (0xB725, "1104 1172 11C0"), - (0xB726, "1104 1172 11C1"), - (0xB727, "1104 1172 11C2"), - (0xB728, "1104 1173"), - (0xB729, "1104 1173 11A8"), - (0xB72A, "1104 1173 11A9"), - (0xB72B, "1104 1173 11AA"), - (0xB72C, "1104 1173 11AB"), - (0xB72D, "1104 1173 11AC"), - (0xB72E, "1104 1173 11AD"), - (0xB72F, "1104 1173 11AE"), - (0xB730, "1104 1173 11AF"), - (0xB731, "1104 1173 11B0"), - (0xB732, "1104 1173 11B1"), - (0xB733, "1104 1173 11B2"), - (0xB734, "1104 1173 11B3"), - (0xB735, "1104 1173 11B4"), - (0xB736, "1104 1173 11B5"), - (0xB737, "1104 1173 11B6"), - (0xB738, "1104 1173 11B7"), - (0xB739, "1104 1173 11B8"), - (0xB73A, "1104 1173 11B9"), - (0xB73B, "1104 1173 11BA"), - (0xB73C, "1104 1173 11BB"), - (0xB73D, "1104 1173 11BC"), - (0xB73E, "1104 1173 11BD"), - (0xB73F, "1104 1173 11BE"), - (0xB740, "1104 1173 11BF"), - (0xB741, "1104 1173 11C0"), - (0xB742, "1104 1173 11C1"), - (0xB743, "1104 1173 11C2"), - (0xB744, "1104 1174"), - (0xB745, "1104 1174 11A8"), - (0xB746, "1104 1174 11A9"), - (0xB747, "1104 1174 11AA"), - (0xB748, "1104 1174 11AB"), - (0xB749, "1104 1174 11AC"), - (0xB74A, "1104 1174 11AD"), - (0xB74B, "1104 1174 11AE"), - (0xB74C, "1104 1174 11AF"), - (0xB74D, "1104 1174 11B0"), - (0xB74E, "1104 1174 11B1"), - (0xB74F, "1104 1174 11B2"), - (0xB750, "1104 1174 11B3"), - (0xB751, "1104 1174 11B4"), - (0xB752, "1104 1174 11B5"), - (0xB753, "1104 1174 11B6"), - (0xB754, "1104 1174 11B7"), - (0xB755, "1104 1174 11B8"), - (0xB756, "1104 1174 11B9"), - (0xB757, "1104 1174 11BA"), - (0xB758, "1104 1174 11BB"), - (0xB759, "1104 1174 11BC"), - (0xB75A, "1104 1174 11BD"), - (0xB75B, "1104 1174 11BE"), - (0xB75C, "1104 1174 11BF"), - (0xB75D, "1104 1174 11C0"), - (0xB75E, "1104 1174 11C1"), - (0xB75F, "1104 1174 11C2"), - (0xB760, "1104 1175"), - (0xB761, "1104 1175 11A8"), - (0xB762, "1104 1175 11A9"), - (0xB763, "1104 1175 11AA"), - (0xB764, "1104 1175 11AB"), - (0xB765, "1104 1175 11AC"), - (0xB766, "1104 1175 11AD"), - (0xB767, "1104 1175 11AE"), - (0xB768, "1104 1175 11AF"), - (0xB769, "1104 1175 11B0"), - (0xB76A, "1104 1175 11B1"), - (0xB76B, "1104 1175 11B2"), - (0xB76C, "1104 1175 11B3"), - (0xB76D, "1104 1175 11B4"), - (0xB76E, "1104 1175 11B5"), - (0xB76F, "1104 1175 11B6"), - (0xB770, "1104 1175 11B7"), - (0xB771, "1104 1175 11B8"), - (0xB772, "1104 1175 11B9"), - (0xB773, "1104 1175 11BA"), - (0xB774, "1104 1175 11BB"), - (0xB775, "1104 1175 11BC"), - (0xB776, "1104 1175 11BD"), - (0xB777, "1104 1175 11BE"), - (0xB778, "1104 1175 11BF"), - (0xB779, "1104 1175 11C0"), - (0xB77A, "1104 1175 11C1"), - (0xB77B, "1104 1175 11C2"), - (0xB77C, "1105 1161"), - (0xB77D, "1105 1161 11A8"), - (0xB77E, "1105 1161 11A9"), - (0xB77F, "1105 1161 11AA"), - (0xB780, "1105 1161 11AB"), - (0xB781, "1105 1161 11AC"), - (0xB782, "1105 1161 11AD"), - (0xB783, "1105 1161 11AE"), - (0xB784, "1105 1161 11AF"), - (0xB785, "1105 1161 11B0"), - (0xB786, "1105 1161 11B1"), - (0xB787, "1105 1161 11B2"), - (0xB788, "1105 1161 11B3"), - (0xB789, "1105 1161 11B4"), - (0xB78A, "1105 1161 11B5"), - (0xB78B, "1105 1161 11B6"), - (0xB78C, "1105 1161 11B7"), - (0xB78D, "1105 1161 11B8"), - (0xB78E, "1105 1161 11B9"), - (0xB78F, "1105 1161 11BA"), - (0xB790, "1105 1161 11BB"), - (0xB791, "1105 1161 11BC"), - (0xB792, "1105 1161 11BD"), - (0xB793, "1105 1161 11BE"), - (0xB794, "1105 1161 11BF"), - (0xB795, "1105 1161 11C0"), - (0xB796, "1105 1161 11C1"), - (0xB797, "1105 1161 11C2"), - (0xB798, "1105 1162"), - (0xB799, "1105 1162 11A8"), - (0xB79A, "1105 1162 11A9"), - (0xB79B, "1105 1162 11AA"), - (0xB79C, "1105 1162 11AB"), - (0xB79D, "1105 1162 11AC"), - (0xB79E, "1105 1162 11AD"), - (0xB79F, "1105 1162 11AE"), - (0xB7A0, "1105 1162 11AF"), - (0xB7A1, "1105 1162 11B0"), - (0xB7A2, "1105 1162 11B1"), - (0xB7A3, "1105 1162 11B2"), - (0xB7A4, "1105 1162 11B3"), - (0xB7A5, "1105 1162 11B4"), - (0xB7A6, "1105 1162 11B5"), - (0xB7A7, "1105 1162 11B6"), - (0xB7A8, "1105 1162 11B7"), - (0xB7A9, "1105 1162 11B8"), - (0xB7AA, "1105 1162 11B9"), - (0xB7AB, "1105 1162 11BA"), - (0xB7AC, "1105 1162 11BB"), - (0xB7AD, "1105 1162 11BC"), - (0xB7AE, "1105 1162 11BD"), - (0xB7AF, "1105 1162 11BE"), - (0xB7B0, "1105 1162 11BF"), - (0xB7B1, "1105 1162 11C0"), - (0xB7B2, "1105 1162 11C1"), - (0xB7B3, "1105 1162 11C2"), - (0xB7B4, "1105 1163"), - (0xB7B5, "1105 1163 11A8"), - (0xB7B6, "1105 1163 11A9"), - (0xB7B7, "1105 1163 11AA"), - (0xB7B8, "1105 1163 11AB"), - (0xB7B9, "1105 1163 11AC"), - (0xB7BA, "1105 1163 11AD"), - (0xB7BB, "1105 1163 11AE"), - (0xB7BC, "1105 1163 11AF"), - (0xB7BD, "1105 1163 11B0"), - (0xB7BE, "1105 1163 11B1"), - (0xB7BF, "1105 1163 11B2"), - (0xB7C0, "1105 1163 11B3"), - (0xB7C1, "1105 1163 11B4"), - (0xB7C2, "1105 1163 11B5"), - (0xB7C3, "1105 1163 11B6"), - (0xB7C4, "1105 1163 11B7"), - (0xB7C5, "1105 1163 11B8"), - (0xB7C6, "1105 1163 11B9"), - (0xB7C7, "1105 1163 11BA"), - (0xB7C8, "1105 1163 11BB"), - (0xB7C9, "1105 1163 11BC"), - (0xB7CA, "1105 1163 11BD"), - (0xB7CB, "1105 1163 11BE"), - (0xB7CC, "1105 1163 11BF"), - (0xB7CD, "1105 1163 11C0"), - (0xB7CE, "1105 1163 11C1"), - (0xB7CF, "1105 1163 11C2"), - (0xB7D0, "1105 1164"), - (0xB7D1, "1105 1164 11A8"), - (0xB7D2, "1105 1164 11A9"), - (0xB7D3, "1105 1164 11AA"), - (0xB7D4, "1105 1164 11AB"), - (0xB7D5, "1105 1164 11AC"), - (0xB7D6, "1105 1164 11AD"), - (0xB7D7, "1105 1164 11AE"), - (0xB7D8, "1105 1164 11AF"), - (0xB7D9, "1105 1164 11B0"), - (0xB7DA, "1105 1164 11B1"), - (0xB7DB, "1105 1164 11B2"), - (0xB7DC, "1105 1164 11B3"), - (0xB7DD, "1105 1164 11B4"), - (0xB7DE, "1105 1164 11B5"), - (0xB7DF, "1105 1164 11B6"), - (0xB7E0, "1105 1164 11B7"), - (0xB7E1, "1105 1164 11B8"), - (0xB7E2, "1105 1164 11B9"), - (0xB7E3, "1105 1164 11BA"), - (0xB7E4, "1105 1164 11BB"), - (0xB7E5, "1105 1164 11BC"), - (0xB7E6, "1105 1164 11BD"), - (0xB7E7, "1105 1164 11BE"), - (0xB7E8, "1105 1164 11BF"), - (0xB7E9, "1105 1164 11C0"), - (0xB7EA, "1105 1164 11C1"), - (0xB7EB, "1105 1164 11C2"), - (0xB7EC, "1105 1165"), - (0xB7ED, "1105 1165 11A8"), - (0xB7EE, "1105 1165 11A9"), - (0xB7EF, "1105 1165 11AA"), - (0xB7F0, "1105 1165 11AB"), - (0xB7F1, "1105 1165 11AC"), - (0xB7F2, "1105 1165 11AD"), - (0xB7F3, "1105 1165 11AE"), - (0xB7F4, "1105 1165 11AF"), - (0xB7F5, "1105 1165 11B0"), - (0xB7F6, "1105 1165 11B1"), - (0xB7F7, "1105 1165 11B2"), - (0xB7F8, "1105 1165 11B3"), - (0xB7F9, "1105 1165 11B4"), - (0xB7FA, "1105 1165 11B5"), - (0xB7FB, "1105 1165 11B6"), - (0xB7FC, "1105 1165 11B7"), - (0xB7FD, "1105 1165 11B8"), - (0xB7FE, "1105 1165 11B9"), - (0xB7FF, "1105 1165 11BA"), - (0xB800, "1105 1165 11BB"), - (0xB801, "1105 1165 11BC"), - (0xB802, "1105 1165 11BD"), - (0xB803, "1105 1165 11BE"), - (0xB804, "1105 1165 11BF"), - (0xB805, "1105 1165 11C0"), - (0xB806, "1105 1165 11C1"), - (0xB807, "1105 1165 11C2"), - (0xB808, "1105 1166"), - (0xB809, "1105 1166 11A8"), - (0xB80A, "1105 1166 11A9"), - (0xB80B, "1105 1166 11AA"), - (0xB80C, "1105 1166 11AB"), - (0xB80D, "1105 1166 11AC"), - (0xB80E, "1105 1166 11AD"), - (0xB80F, "1105 1166 11AE"), - (0xB810, "1105 1166 11AF"), - (0xB811, "1105 1166 11B0"), - (0xB812, "1105 1166 11B1"), - (0xB813, "1105 1166 11B2"), - (0xB814, "1105 1166 11B3"), - (0xB815, "1105 1166 11B4"), - (0xB816, "1105 1166 11B5"), - (0xB817, "1105 1166 11B6"), - (0xB818, "1105 1166 11B7"), - (0xB819, "1105 1166 11B8"), - (0xB81A, "1105 1166 11B9"), - (0xB81B, "1105 1166 11BA"), - (0xB81C, "1105 1166 11BB"), - (0xB81D, "1105 1166 11BC"), - (0xB81E, "1105 1166 11BD"), - (0xB81F, "1105 1166 11BE"), - (0xB820, "1105 1166 11BF"), - (0xB821, "1105 1166 11C0"), - (0xB822, "1105 1166 11C1"), - (0xB823, "1105 1166 11C2"), - (0xB824, "1105 1167"), - (0xB825, "1105 1167 11A8"), - (0xB826, "1105 1167 11A9"), - (0xB827, "1105 1167 11AA"), - (0xB828, "1105 1167 11AB"), - (0xB829, "1105 1167 11AC"), - (0xB82A, "1105 1167 11AD"), - (0xB82B, "1105 1167 11AE"), - (0xB82C, "1105 1167 11AF"), - (0xB82D, "1105 1167 11B0"), - (0xB82E, "1105 1167 11B1"), - (0xB82F, "1105 1167 11B2"), - (0xB830, "1105 1167 11B3"), - (0xB831, "1105 1167 11B4"), - (0xB832, "1105 1167 11B5"), - (0xB833, "1105 1167 11B6"), - (0xB834, "1105 1167 11B7"), - (0xB835, "1105 1167 11B8"), - (0xB836, "1105 1167 11B9"), - (0xB837, "1105 1167 11BA"), - (0xB838, "1105 1167 11BB"), - (0xB839, "1105 1167 11BC"), - (0xB83A, "1105 1167 11BD"), - (0xB83B, "1105 1167 11BE"), - (0xB83C, "1105 1167 11BF"), - (0xB83D, "1105 1167 11C0"), - (0xB83E, "1105 1167 11C1"), - (0xB83F, "1105 1167 11C2"), - (0xB840, "1105 1168"), - (0xB841, "1105 1168 11A8"), - (0xB842, "1105 1168 11A9"), - (0xB843, "1105 1168 11AA"), - (0xB844, "1105 1168 11AB"), - (0xB845, "1105 1168 11AC"), - (0xB846, "1105 1168 11AD"), - (0xB847, "1105 1168 11AE"), - (0xB848, "1105 1168 11AF"), - (0xB849, "1105 1168 11B0"), - (0xB84A, "1105 1168 11B1"), - (0xB84B, "1105 1168 11B2"), - (0xB84C, "1105 1168 11B3"), - (0xB84D, "1105 1168 11B4"), - (0xB84E, "1105 1168 11B5"), - (0xB84F, "1105 1168 11B6"), - (0xB850, "1105 1168 11B7"), - (0xB851, "1105 1168 11B8"), - (0xB852, "1105 1168 11B9"), - (0xB853, "1105 1168 11BA"), - (0xB854, "1105 1168 11BB"), - (0xB855, "1105 1168 11BC"), - (0xB856, "1105 1168 11BD"), - (0xB857, "1105 1168 11BE"), - (0xB858, "1105 1168 11BF"), - (0xB859, "1105 1168 11C0"), - (0xB85A, "1105 1168 11C1"), - (0xB85B, "1105 1168 11C2"), - (0xB85C, "1105 1169"), - (0xB85D, "1105 1169 11A8"), - (0xB85E, "1105 1169 11A9"), - (0xB85F, "1105 1169 11AA"), - (0xB860, "1105 1169 11AB"), - (0xB861, "1105 1169 11AC"), - (0xB862, "1105 1169 11AD"), - (0xB863, "1105 1169 11AE"), - (0xB864, "1105 1169 11AF"), - (0xB865, "1105 1169 11B0"), - (0xB866, "1105 1169 11B1"), - (0xB867, "1105 1169 11B2"), - (0xB868, "1105 1169 11B3"), - (0xB869, "1105 1169 11B4"), - (0xB86A, "1105 1169 11B5"), - (0xB86B, "1105 1169 11B6"), - (0xB86C, "1105 1169 11B7"), - (0xB86D, "1105 1169 11B8"), - (0xB86E, "1105 1169 11B9"), - (0xB86F, "1105 1169 11BA"), - (0xB870, "1105 1169 11BB"), - (0xB871, "1105 1169 11BC"), - (0xB872, "1105 1169 11BD"), - (0xB873, "1105 1169 11BE"), - (0xB874, "1105 1169 11BF"), - (0xB875, "1105 1169 11C0"), - (0xB876, "1105 1169 11C1"), - (0xB877, "1105 1169 11C2"), - (0xB878, "1105 116A"), - (0xB879, "1105 116A 11A8"), - (0xB87A, "1105 116A 11A9"), - (0xB87B, "1105 116A 11AA"), - (0xB87C, "1105 116A 11AB"), - (0xB87D, "1105 116A 11AC"), - (0xB87E, "1105 116A 11AD"), - (0xB87F, "1105 116A 11AE"), - (0xB880, "1105 116A 11AF"), - (0xB881, "1105 116A 11B0"), - (0xB882, "1105 116A 11B1"), - (0xB883, "1105 116A 11B2"), - (0xB884, "1105 116A 11B3"), - (0xB885, "1105 116A 11B4"), - (0xB886, "1105 116A 11B5"), - (0xB887, "1105 116A 11B6"), - (0xB888, "1105 116A 11B7"), - (0xB889, "1105 116A 11B8"), - (0xB88A, "1105 116A 11B9"), - (0xB88B, "1105 116A 11BA"), - (0xB88C, "1105 116A 11BB"), - (0xB88D, "1105 116A 11BC"), - (0xB88E, "1105 116A 11BD"), - (0xB88F, "1105 116A 11BE"), - (0xB890, "1105 116A 11BF"), - (0xB891, "1105 116A 11C0"), - (0xB892, "1105 116A 11C1"), - (0xB893, "1105 116A 11C2"), - (0xB894, "1105 116B"), - (0xB895, "1105 116B 11A8"), - (0xB896, "1105 116B 11A9"), - (0xB897, "1105 116B 11AA"), - (0xB898, "1105 116B 11AB"), - (0xB899, "1105 116B 11AC"), - (0xB89A, "1105 116B 11AD"), - (0xB89B, "1105 116B 11AE"), - (0xB89C, "1105 116B 11AF"), - (0xB89D, "1105 116B 11B0"), - (0xB89E, "1105 116B 11B1"), - (0xB89F, "1105 116B 11B2"), - (0xB8A0, "1105 116B 11B3"), - (0xB8A1, "1105 116B 11B4"), - (0xB8A2, "1105 116B 11B5"), - (0xB8A3, "1105 116B 11B6"), - (0xB8A4, "1105 116B 11B7"), - (0xB8A5, "1105 116B 11B8"), - (0xB8A6, "1105 116B 11B9"), - (0xB8A7, "1105 116B 11BA"), - (0xB8A8, "1105 116B 11BB"), - (0xB8A9, "1105 116B 11BC"), - (0xB8AA, "1105 116B 11BD"), - (0xB8AB, "1105 116B 11BE"), - (0xB8AC, "1105 116B 11BF"), - (0xB8AD, "1105 116B 11C0"), - (0xB8AE, "1105 116B 11C1"), - (0xB8AF, "1105 116B 11C2"), - (0xB8B0, "1105 116C"), - (0xB8B1, "1105 116C 11A8"), - (0xB8B2, "1105 116C 11A9"), - (0xB8B3, "1105 116C 11AA"), - (0xB8B4, "1105 116C 11AB"), - (0xB8B5, "1105 116C 11AC"), - (0xB8B6, "1105 116C 11AD"), - (0xB8B7, "1105 116C 11AE"), - (0xB8B8, "1105 116C 11AF"), - (0xB8B9, "1105 116C 11B0"), - (0xB8BA, "1105 116C 11B1"), - (0xB8BB, "1105 116C 11B2"), - (0xB8BC, "1105 116C 11B3"), - (0xB8BD, "1105 116C 11B4"), - (0xB8BE, "1105 116C 11B5"), - (0xB8BF, "1105 116C 11B6"), - (0xB8C0, "1105 116C 11B7"), - (0xB8C1, "1105 116C 11B8"), - (0xB8C2, "1105 116C 11B9"), - (0xB8C3, "1105 116C 11BA"), - (0xB8C4, "1105 116C 11BB"), - (0xB8C5, "1105 116C 11BC"), - (0xB8C6, "1105 116C 11BD"), - (0xB8C7, "1105 116C 11BE"), - (0xB8C8, "1105 116C 11BF"), - (0xB8C9, "1105 116C 11C0"), - (0xB8CA, "1105 116C 11C1"), - (0xB8CB, "1105 116C 11C2"), - (0xB8CC, "1105 116D"), - (0xB8CD, "1105 116D 11A8"), - (0xB8CE, "1105 116D 11A9"), - (0xB8CF, "1105 116D 11AA"), - (0xB8D0, "1105 116D 11AB"), - (0xB8D1, "1105 116D 11AC"), - (0xB8D2, "1105 116D 11AD"), - (0xB8D3, "1105 116D 11AE"), - (0xB8D4, "1105 116D 11AF"), - (0xB8D5, "1105 116D 11B0"), - (0xB8D6, "1105 116D 11B1"), - (0xB8D7, "1105 116D 11B2"), - (0xB8D8, "1105 116D 11B3"), - (0xB8D9, "1105 116D 11B4"), - (0xB8DA, "1105 116D 11B5"), - (0xB8DB, "1105 116D 11B6"), - (0xB8DC, "1105 116D 11B7"), - (0xB8DD, "1105 116D 11B8"), - (0xB8DE, "1105 116D 11B9"), - (0xB8DF, "1105 116D 11BA"), - (0xB8E0, "1105 116D 11BB"), - (0xB8E1, "1105 116D 11BC"), - (0xB8E2, "1105 116D 11BD"), - (0xB8E3, "1105 116D 11BE"), - (0xB8E4, "1105 116D 11BF"), - (0xB8E5, "1105 116D 11C0"), - (0xB8E6, "1105 116D 11C1"), - (0xB8E7, "1105 116D 11C2"), - (0xB8E8, "1105 116E"), - (0xB8E9, "1105 116E 11A8"), - (0xB8EA, "1105 116E 11A9"), - (0xB8EB, "1105 116E 11AA"), - (0xB8EC, "1105 116E 11AB"), - (0xB8ED, "1105 116E 11AC"), - (0xB8EE, "1105 116E 11AD"), - (0xB8EF, "1105 116E 11AE"), - (0xB8F0, "1105 116E 11AF"), - (0xB8F1, "1105 116E 11B0"), - (0xB8F2, "1105 116E 11B1"), - (0xB8F3, "1105 116E 11B2"), - (0xB8F4, "1105 116E 11B3"), - (0xB8F5, "1105 116E 11B4"), - (0xB8F6, "1105 116E 11B5"), - (0xB8F7, "1105 116E 11B6"), - (0xB8F8, "1105 116E 11B7"), - (0xB8F9, "1105 116E 11B8"), - (0xB8FA, "1105 116E 11B9"), - (0xB8FB, "1105 116E 11BA"), - (0xB8FC, "1105 116E 11BB"), - (0xB8FD, "1105 116E 11BC"), - (0xB8FE, "1105 116E 11BD"), - (0xB8FF, "1105 116E 11BE"), - (0xB900, "1105 116E 11BF"), - (0xB901, "1105 116E 11C0"), - (0xB902, "1105 116E 11C1"), - (0xB903, "1105 116E 11C2"), - (0xB904, "1105 116F"), - (0xB905, "1105 116F 11A8"), - (0xB906, "1105 116F 11A9"), - (0xB907, "1105 116F 11AA"), - (0xB908, "1105 116F 11AB"), - (0xB909, "1105 116F 11AC"), - (0xB90A, "1105 116F 11AD"), - (0xB90B, "1105 116F 11AE"), - (0xB90C, "1105 116F 11AF"), - (0xB90D, "1105 116F 11B0"), - (0xB90E, "1105 116F 11B1"), - (0xB90F, "1105 116F 11B2"), - (0xB910, "1105 116F 11B3"), - (0xB911, "1105 116F 11B4"), - (0xB912, "1105 116F 11B5"), - (0xB913, "1105 116F 11B6"), - (0xB914, "1105 116F 11B7"), - (0xB915, "1105 116F 11B8"), - (0xB916, "1105 116F 11B9"), - (0xB917, "1105 116F 11BA"), - (0xB918, "1105 116F 11BB"), - (0xB919, "1105 116F 11BC"), - (0xB91A, "1105 116F 11BD"), - (0xB91B, "1105 116F 11BE"), - (0xB91C, "1105 116F 11BF"), - (0xB91D, "1105 116F 11C0"), - (0xB91E, "1105 116F 11C1"), - (0xB91F, "1105 116F 11C2"), - (0xB920, "1105 1170"), - (0xB921, "1105 1170 11A8"), - (0xB922, "1105 1170 11A9"), - (0xB923, "1105 1170 11AA"), - (0xB924, "1105 1170 11AB"), - (0xB925, "1105 1170 11AC"), - (0xB926, "1105 1170 11AD"), - (0xB927, "1105 1170 11AE"), - (0xB928, "1105 1170 11AF"), - (0xB929, "1105 1170 11B0"), - (0xB92A, "1105 1170 11B1"), - (0xB92B, "1105 1170 11B2"), - (0xB92C, "1105 1170 11B3"), - (0xB92D, "1105 1170 11B4"), - (0xB92E, "1105 1170 11B5"), - (0xB92F, "1105 1170 11B6"), - (0xB930, "1105 1170 11B7"), - (0xB931, "1105 1170 11B8"), - (0xB932, "1105 1170 11B9"), - (0xB933, "1105 1170 11BA"), - (0xB934, "1105 1170 11BB"), - (0xB935, "1105 1170 11BC"), - (0xB936, "1105 1170 11BD"), - (0xB937, "1105 1170 11BE"), - (0xB938, "1105 1170 11BF"), - (0xB939, "1105 1170 11C0"), - (0xB93A, "1105 1170 11C1"), - (0xB93B, "1105 1170 11C2"), - (0xB93C, "1105 1171"), - (0xB93D, "1105 1171 11A8"), - (0xB93E, "1105 1171 11A9"), - (0xB93F, "1105 1171 11AA"), - (0xB940, "1105 1171 11AB"), - (0xB941, "1105 1171 11AC"), - (0xB942, "1105 1171 11AD"), - (0xB943, "1105 1171 11AE"), - (0xB944, "1105 1171 11AF"), - (0xB945, "1105 1171 11B0"), - (0xB946, "1105 1171 11B1"), - (0xB947, "1105 1171 11B2"), - (0xB948, "1105 1171 11B3"), - (0xB949, "1105 1171 11B4"), - (0xB94A, "1105 1171 11B5"), - (0xB94B, "1105 1171 11B6"), - (0xB94C, "1105 1171 11B7"), - (0xB94D, "1105 1171 11B8"), - (0xB94E, "1105 1171 11B9"), - (0xB94F, "1105 1171 11BA"), - (0xB950, "1105 1171 11BB"), - (0xB951, "1105 1171 11BC"), - (0xB952, "1105 1171 11BD"), - (0xB953, "1105 1171 11BE"), - (0xB954, "1105 1171 11BF"), - (0xB955, "1105 1171 11C0"), - (0xB956, "1105 1171 11C1"), - (0xB957, "1105 1171 11C2"), - (0xB958, "1105 1172"), - (0xB959, "1105 1172 11A8"), - (0xB95A, "1105 1172 11A9"), - (0xB95B, "1105 1172 11AA"), - (0xB95C, "1105 1172 11AB"), - (0xB95D, "1105 1172 11AC"), - (0xB95E, "1105 1172 11AD"), - (0xB95F, "1105 1172 11AE"), - (0xB960, "1105 1172 11AF"), - (0xB961, "1105 1172 11B0"), - (0xB962, "1105 1172 11B1"), - (0xB963, "1105 1172 11B2"), - (0xB964, "1105 1172 11B3"), - (0xB965, "1105 1172 11B4"), - (0xB966, "1105 1172 11B5"), - (0xB967, "1105 1172 11B6"), - (0xB968, "1105 1172 11B7"), - (0xB969, "1105 1172 11B8"), - (0xB96A, "1105 1172 11B9"), - (0xB96B, "1105 1172 11BA"), - (0xB96C, "1105 1172 11BB"), - (0xB96D, "1105 1172 11BC"), - (0xB96E, "1105 1172 11BD"), - (0xB96F, "1105 1172 11BE"), - (0xB970, "1105 1172 11BF"), - (0xB971, "1105 1172 11C0"), - (0xB972, "1105 1172 11C1"), - (0xB973, "1105 1172 11C2"), - (0xB974, "1105 1173"), - (0xB975, "1105 1173 11A8"), - (0xB976, "1105 1173 11A9"), - (0xB977, "1105 1173 11AA"), - (0xB978, "1105 1173 11AB"), - (0xB979, "1105 1173 11AC"), - (0xB97A, "1105 1173 11AD"), - (0xB97B, "1105 1173 11AE"), - (0xB97C, "1105 1173 11AF"), - (0xB97D, "1105 1173 11B0"), - (0xB97E, "1105 1173 11B1"), - (0xB97F, "1105 1173 11B2"), - (0xB980, "1105 1173 11B3"), - (0xB981, "1105 1173 11B4"), - (0xB982, "1105 1173 11B5"), - (0xB983, "1105 1173 11B6"), - (0xB984, "1105 1173 11B7"), - (0xB985, "1105 1173 11B8"), - (0xB986, "1105 1173 11B9"), - (0xB987, "1105 1173 11BA"), - (0xB988, "1105 1173 11BB"), - (0xB989, "1105 1173 11BC"), - (0xB98A, "1105 1173 11BD"), - (0xB98B, "1105 1173 11BE"), - (0xB98C, "1105 1173 11BF"), - (0xB98D, "1105 1173 11C0"), - (0xB98E, "1105 1173 11C1"), - (0xB98F, "1105 1173 11C2"), - (0xB990, "1105 1174"), - (0xB991, "1105 1174 11A8"), - (0xB992, "1105 1174 11A9"), - (0xB993, "1105 1174 11AA"), - (0xB994, "1105 1174 11AB"), - (0xB995, "1105 1174 11AC"), - (0xB996, "1105 1174 11AD"), - (0xB997, "1105 1174 11AE"), - (0xB998, "1105 1174 11AF"), - (0xB999, "1105 1174 11B0"), - (0xB99A, "1105 1174 11B1"), - (0xB99B, "1105 1174 11B2"), - (0xB99C, "1105 1174 11B3"), - (0xB99D, "1105 1174 11B4"), - (0xB99E, "1105 1174 11B5"), - (0xB99F, "1105 1174 11B6"), - (0xB9A0, "1105 1174 11B7"), - (0xB9A1, "1105 1174 11B8"), - (0xB9A2, "1105 1174 11B9"), - (0xB9A3, "1105 1174 11BA"), - (0xB9A4, "1105 1174 11BB"), - (0xB9A5, "1105 1174 11BC"), - (0xB9A6, "1105 1174 11BD"), - (0xB9A7, "1105 1174 11BE"), - (0xB9A8, "1105 1174 11BF"), - (0xB9A9, "1105 1174 11C0"), - (0xB9AA, "1105 1174 11C1"), - (0xB9AB, "1105 1174 11C2"), - (0xB9AC, "1105 1175"), - (0xB9AD, "1105 1175 11A8"), - (0xB9AE, "1105 1175 11A9"), - (0xB9AF, "1105 1175 11AA"), - (0xB9B0, "1105 1175 11AB"), - (0xB9B1, "1105 1175 11AC"), - (0xB9B2, "1105 1175 11AD"), - (0xB9B3, "1105 1175 11AE"), - (0xB9B4, "1105 1175 11AF"), - (0xB9B5, "1105 1175 11B0"), - (0xB9B6, "1105 1175 11B1"), - (0xB9B7, "1105 1175 11B2"), - (0xB9B8, "1105 1175 11B3"), - (0xB9B9, "1105 1175 11B4"), - (0xB9BA, "1105 1175 11B5"), - (0xB9BB, "1105 1175 11B6"), - (0xB9BC, "1105 1175 11B7"), - (0xB9BD, "1105 1175 11B8"), - (0xB9BE, "1105 1175 11B9"), - (0xB9BF, "1105 1175 11BA"), - (0xB9C0, "1105 1175 11BB"), - (0xB9C1, "1105 1175 11BC"), - (0xB9C2, "1105 1175 11BD"), - (0xB9C3, "1105 1175 11BE"), - (0xB9C4, "1105 1175 11BF"), - (0xB9C5, "1105 1175 11C0"), - (0xB9C6, "1105 1175 11C1"), - (0xB9C7, "1105 1175 11C2"), - (0xB9C8, "1106 1161"), - (0xB9C9, "1106 1161 11A8"), - (0xB9CA, "1106 1161 11A9"), - (0xB9CB, "1106 1161 11AA"), - (0xB9CC, "1106 1161 11AB"), - (0xB9CD, "1106 1161 11AC"), - (0xB9CE, "1106 1161 11AD"), - (0xB9CF, "1106 1161 11AE"), - (0xB9D0, "1106 1161 11AF"), - (0xB9D1, "1106 1161 11B0"), - (0xB9D2, "1106 1161 11B1"), - (0xB9D3, "1106 1161 11B2"), - (0xB9D4, "1106 1161 11B3"), - (0xB9D5, "1106 1161 11B4"), - (0xB9D6, "1106 1161 11B5"), - (0xB9D7, "1106 1161 11B6"), - (0xB9D8, "1106 1161 11B7"), - (0xB9D9, "1106 1161 11B8"), - (0xB9DA, "1106 1161 11B9"), - (0xB9DB, "1106 1161 11BA"), - (0xB9DC, "1106 1161 11BB"), - (0xB9DD, "1106 1161 11BC"), - (0xB9DE, "1106 1161 11BD"), - (0xB9DF, "1106 1161 11BE"), - (0xB9E0, "1106 1161 11BF"), - (0xB9E1, "1106 1161 11C0"), - (0xB9E2, "1106 1161 11C1"), - (0xB9E3, "1106 1161 11C2"), - (0xB9E4, "1106 1162"), - (0xB9E5, "1106 1162 11A8"), - (0xB9E6, "1106 1162 11A9"), - (0xB9E7, "1106 1162 11AA"), - (0xB9E8, "1106 1162 11AB"), - (0xB9E9, "1106 1162 11AC"), - (0xB9EA, "1106 1162 11AD"), - (0xB9EB, "1106 1162 11AE"), - (0xB9EC, "1106 1162 11AF"), - (0xB9ED, "1106 1162 11B0"), - (0xB9EE, "1106 1162 11B1"), - (0xB9EF, "1106 1162 11B2"), - (0xB9F0, "1106 1162 11B3"), - (0xB9F1, "1106 1162 11B4"), - (0xB9F2, "1106 1162 11B5"), - (0xB9F3, "1106 1162 11B6"), - (0xB9F4, "1106 1162 11B7"), - (0xB9F5, "1106 1162 11B8"), - (0xB9F6, "1106 1162 11B9"), - (0xB9F7, "1106 1162 11BA"), - (0xB9F8, "1106 1162 11BB"), - (0xB9F9, "1106 1162 11BC"), - (0xB9FA, "1106 1162 11BD"), - (0xB9FB, "1106 1162 11BE"), - (0xB9FC, "1106 1162 11BF"), - (0xB9FD, "1106 1162 11C0"), - (0xB9FE, "1106 1162 11C1"), - (0xB9FF, "1106 1162 11C2"), - (0xBA00, "1106 1163"), - (0xBA01, "1106 1163 11A8"), - (0xBA02, "1106 1163 11A9"), - (0xBA03, "1106 1163 11AA"), - (0xBA04, "1106 1163 11AB"), - (0xBA05, "1106 1163 11AC"), - (0xBA06, "1106 1163 11AD"), - (0xBA07, "1106 1163 11AE"), - (0xBA08, "1106 1163 11AF"), - (0xBA09, "1106 1163 11B0"), - (0xBA0A, "1106 1163 11B1"), - (0xBA0B, "1106 1163 11B2"), - (0xBA0C, "1106 1163 11B3"), - (0xBA0D, "1106 1163 11B4"), - (0xBA0E, "1106 1163 11B5"), - (0xBA0F, "1106 1163 11B6"), - (0xBA10, "1106 1163 11B7"), - (0xBA11, "1106 1163 11B8"), - (0xBA12, "1106 1163 11B9"), - (0xBA13, "1106 1163 11BA"), - (0xBA14, "1106 1163 11BB"), - (0xBA15, "1106 1163 11BC"), - (0xBA16, "1106 1163 11BD"), - (0xBA17, "1106 1163 11BE"), - (0xBA18, "1106 1163 11BF"), - (0xBA19, "1106 1163 11C0"), - (0xBA1A, "1106 1163 11C1"), - (0xBA1B, "1106 1163 11C2"), - (0xBA1C, "1106 1164"), - (0xBA1D, "1106 1164 11A8"), - (0xBA1E, "1106 1164 11A9"), - (0xBA1F, "1106 1164 11AA"), - (0xBA20, "1106 1164 11AB"), - (0xBA21, "1106 1164 11AC"), - (0xBA22, "1106 1164 11AD"), - (0xBA23, "1106 1164 11AE"), - (0xBA24, "1106 1164 11AF"), - (0xBA25, "1106 1164 11B0"), - (0xBA26, "1106 1164 11B1"), - (0xBA27, "1106 1164 11B2"), - (0xBA28, "1106 1164 11B3"), - (0xBA29, "1106 1164 11B4"), - (0xBA2A, "1106 1164 11B5"), - (0xBA2B, "1106 1164 11B6"), - (0xBA2C, "1106 1164 11B7"), - (0xBA2D, "1106 1164 11B8"), - (0xBA2E, "1106 1164 11B9"), - (0xBA2F, "1106 1164 11BA"), - (0xBA30, "1106 1164 11BB"), - (0xBA31, "1106 1164 11BC"), - (0xBA32, "1106 1164 11BD"), - (0xBA33, "1106 1164 11BE"), - (0xBA34, "1106 1164 11BF"), - (0xBA35, "1106 1164 11C0"), - (0xBA36, "1106 1164 11C1"), - (0xBA37, "1106 1164 11C2"), - (0xBA38, "1106 1165"), - (0xBA39, "1106 1165 11A8"), - (0xBA3A, "1106 1165 11A9"), - (0xBA3B, "1106 1165 11AA"), - (0xBA3C, "1106 1165 11AB"), - (0xBA3D, "1106 1165 11AC"), - (0xBA3E, "1106 1165 11AD"), - (0xBA3F, "1106 1165 11AE"), - (0xBA40, "1106 1165 11AF"), - (0xBA41, "1106 1165 11B0"), - (0xBA42, "1106 1165 11B1"), - (0xBA43, "1106 1165 11B2"), - (0xBA44, "1106 1165 11B3"), - (0xBA45, "1106 1165 11B4"), - (0xBA46, "1106 1165 11B5"), - (0xBA47, "1106 1165 11B6"), - (0xBA48, "1106 1165 11B7"), - (0xBA49, "1106 1165 11B8"), - (0xBA4A, "1106 1165 11B9"), - (0xBA4B, "1106 1165 11BA"), - (0xBA4C, "1106 1165 11BB"), - (0xBA4D, "1106 1165 11BC"), - (0xBA4E, "1106 1165 11BD"), - (0xBA4F, "1106 1165 11BE"), - (0xBA50, "1106 1165 11BF"), - (0xBA51, "1106 1165 11C0"), - (0xBA52, "1106 1165 11C1"), - (0xBA53, "1106 1165 11C2"), - (0xBA54, "1106 1166"), - (0xBA55, "1106 1166 11A8"), - (0xBA56, "1106 1166 11A9"), - (0xBA57, "1106 1166 11AA"), - (0xBA58, "1106 1166 11AB"), - (0xBA59, "1106 1166 11AC"), - (0xBA5A, "1106 1166 11AD"), - (0xBA5B, "1106 1166 11AE"), - (0xBA5C, "1106 1166 11AF"), - (0xBA5D, "1106 1166 11B0"), - (0xBA5E, "1106 1166 11B1"), - (0xBA5F, "1106 1166 11B2"), - (0xBA60, "1106 1166 11B3"), - (0xBA61, "1106 1166 11B4"), - (0xBA62, "1106 1166 11B5"), - (0xBA63, "1106 1166 11B6"), - (0xBA64, "1106 1166 11B7"), - (0xBA65, "1106 1166 11B8"), - (0xBA66, "1106 1166 11B9"), - (0xBA67, "1106 1166 11BA"), - (0xBA68, "1106 1166 11BB"), - (0xBA69, "1106 1166 11BC"), - (0xBA6A, "1106 1166 11BD"), - (0xBA6B, "1106 1166 11BE"), - (0xBA6C, "1106 1166 11BF"), - (0xBA6D, "1106 1166 11C0"), - (0xBA6E, "1106 1166 11C1"), - (0xBA6F, "1106 1166 11C2"), - (0xBA70, "1106 1167"), - (0xBA71, "1106 1167 11A8"), - (0xBA72, "1106 1167 11A9"), - (0xBA73, "1106 1167 11AA"), - (0xBA74, "1106 1167 11AB"), - (0xBA75, "1106 1167 11AC"), - (0xBA76, "1106 1167 11AD"), - (0xBA77, "1106 1167 11AE"), - (0xBA78, "1106 1167 11AF"), - (0xBA79, "1106 1167 11B0"), - (0xBA7A, "1106 1167 11B1"), - (0xBA7B, "1106 1167 11B2"), - (0xBA7C, "1106 1167 11B3"), - (0xBA7D, "1106 1167 11B4"), - (0xBA7E, "1106 1167 11B5"), - (0xBA7F, "1106 1167 11B6"), - (0xBA80, "1106 1167 11B7"), - (0xBA81, "1106 1167 11B8"), - (0xBA82, "1106 1167 11B9"), - (0xBA83, "1106 1167 11BA"), - (0xBA84, "1106 1167 11BB"), - (0xBA85, "1106 1167 11BC"), - (0xBA86, "1106 1167 11BD"), - (0xBA87, "1106 1167 11BE"), - (0xBA88, "1106 1167 11BF"), - (0xBA89, "1106 1167 11C0"), - (0xBA8A, "1106 1167 11C1"), - (0xBA8B, "1106 1167 11C2"), - (0xBA8C, "1106 1168"), - (0xBA8D, "1106 1168 11A8"), - (0xBA8E, "1106 1168 11A9"), - (0xBA8F, "1106 1168 11AA"), - (0xBA90, "1106 1168 11AB"), - (0xBA91, "1106 1168 11AC"), - (0xBA92, "1106 1168 11AD"), - (0xBA93, "1106 1168 11AE"), - (0xBA94, "1106 1168 11AF"), - (0xBA95, "1106 1168 11B0"), - (0xBA96, "1106 1168 11B1"), - (0xBA97, "1106 1168 11B2"), - (0xBA98, "1106 1168 11B3"), - (0xBA99, "1106 1168 11B4"), - (0xBA9A, "1106 1168 11B5"), - (0xBA9B, "1106 1168 11B6"), - (0xBA9C, "1106 1168 11B7"), - (0xBA9D, "1106 1168 11B8"), - (0xBA9E, "1106 1168 11B9"), - (0xBA9F, "1106 1168 11BA"), - (0xBAA0, "1106 1168 11BB"), - (0xBAA1, "1106 1168 11BC"), - (0xBAA2, "1106 1168 11BD"), - (0xBAA3, "1106 1168 11BE"), - (0xBAA4, "1106 1168 11BF"), - (0xBAA5, "1106 1168 11C0"), - (0xBAA6, "1106 1168 11C1"), - (0xBAA7, "1106 1168 11C2"), - (0xBAA8, "1106 1169"), - (0xBAA9, "1106 1169 11A8"), - (0xBAAA, "1106 1169 11A9"), - (0xBAAB, "1106 1169 11AA"), - (0xBAAC, "1106 1169 11AB"), - (0xBAAD, "1106 1169 11AC"), - (0xBAAE, "1106 1169 11AD"), - (0xBAAF, "1106 1169 11AE"), - (0xBAB0, "1106 1169 11AF"), - (0xBAB1, "1106 1169 11B0"), - (0xBAB2, "1106 1169 11B1"), - (0xBAB3, "1106 1169 11B2"), - (0xBAB4, "1106 1169 11B3"), - (0xBAB5, "1106 1169 11B4"), - (0xBAB6, "1106 1169 11B5"), - (0xBAB7, "1106 1169 11B6"), - (0xBAB8, "1106 1169 11B7"), - (0xBAB9, "1106 1169 11B8"), - (0xBABA, "1106 1169 11B9"), - (0xBABB, "1106 1169 11BA"), - (0xBABC, "1106 1169 11BB"), - (0xBABD, "1106 1169 11BC"), - (0xBABE, "1106 1169 11BD"), - (0xBABF, "1106 1169 11BE"), - (0xBAC0, "1106 1169 11BF"), - (0xBAC1, "1106 1169 11C0"), - (0xBAC2, "1106 1169 11C1"), - (0xBAC3, "1106 1169 11C2"), - (0xBAC4, "1106 116A"), - (0xBAC5, "1106 116A 11A8"), - (0xBAC6, "1106 116A 11A9"), - (0xBAC7, "1106 116A 11AA"), - (0xBAC8, "1106 116A 11AB"), - (0xBAC9, "1106 116A 11AC"), - (0xBACA, "1106 116A 11AD"), - (0xBACB, "1106 116A 11AE"), - (0xBACC, "1106 116A 11AF"), - (0xBACD, "1106 116A 11B0"), - (0xBACE, "1106 116A 11B1"), - (0xBACF, "1106 116A 11B2"), - (0xBAD0, "1106 116A 11B3"), - (0xBAD1, "1106 116A 11B4"), - (0xBAD2, "1106 116A 11B5"), - (0xBAD3, "1106 116A 11B6"), - (0xBAD4, "1106 116A 11B7"), - (0xBAD5, "1106 116A 11B8"), - (0xBAD6, "1106 116A 11B9"), - (0xBAD7, "1106 116A 11BA"), - (0xBAD8, "1106 116A 11BB"), - (0xBAD9, "1106 116A 11BC"), - (0xBADA, "1106 116A 11BD"), - (0xBADB, "1106 116A 11BE"), - (0xBADC, "1106 116A 11BF"), - (0xBADD, "1106 116A 11C0"), - (0xBADE, "1106 116A 11C1"), - (0xBADF, "1106 116A 11C2"), - (0xBAE0, "1106 116B"), - (0xBAE1, "1106 116B 11A8"), - (0xBAE2, "1106 116B 11A9"), - (0xBAE3, "1106 116B 11AA"), - (0xBAE4, "1106 116B 11AB"), - (0xBAE5, "1106 116B 11AC"), - (0xBAE6, "1106 116B 11AD"), - (0xBAE7, "1106 116B 11AE"), - (0xBAE8, "1106 116B 11AF"), - (0xBAE9, "1106 116B 11B0"), - (0xBAEA, "1106 116B 11B1"), - (0xBAEB, "1106 116B 11B2"), - (0xBAEC, "1106 116B 11B3"), - (0xBAED, "1106 116B 11B4"), - (0xBAEE, "1106 116B 11B5"), - (0xBAEF, "1106 116B 11B6"), - (0xBAF0, "1106 116B 11B7"), - (0xBAF1, "1106 116B 11B8"), - (0xBAF2, "1106 116B 11B9"), - (0xBAF3, "1106 116B 11BA"), - (0xBAF4, "1106 116B 11BB"), - (0xBAF5, "1106 116B 11BC"), - (0xBAF6, "1106 116B 11BD"), - (0xBAF7, "1106 116B 11BE"), - (0xBAF8, "1106 116B 11BF"), - (0xBAF9, "1106 116B 11C0"), - (0xBAFA, "1106 116B 11C1"), - (0xBAFB, "1106 116B 11C2"), - (0xBAFC, "1106 116C"), - (0xBAFD, "1106 116C 11A8"), - (0xBAFE, "1106 116C 11A9"), - (0xBAFF, "1106 116C 11AA"), - (0xBB00, "1106 116C 11AB"), - (0xBB01, "1106 116C 11AC"), - (0xBB02, "1106 116C 11AD"), - (0xBB03, "1106 116C 11AE"), - (0xBB04, "1106 116C 11AF"), - (0xBB05, "1106 116C 11B0"), - (0xBB06, "1106 116C 11B1"), - (0xBB07, "1106 116C 11B2"), - (0xBB08, "1106 116C 11B3"), - (0xBB09, "1106 116C 11B4"), - (0xBB0A, "1106 116C 11B5"), - (0xBB0B, "1106 116C 11B6"), - (0xBB0C, "1106 116C 11B7"), - (0xBB0D, "1106 116C 11B8"), - (0xBB0E, "1106 116C 11B9"), - (0xBB0F, "1106 116C 11BA"), - (0xBB10, "1106 116C 11BB"), - (0xBB11, "1106 116C 11BC"), - (0xBB12, "1106 116C 11BD"), - (0xBB13, "1106 116C 11BE"), - (0xBB14, "1106 116C 11BF"), - (0xBB15, "1106 116C 11C0"), - (0xBB16, "1106 116C 11C1"), - (0xBB17, "1106 116C 11C2"), - (0xBB18, "1106 116D"), - (0xBB19, "1106 116D 11A8"), - (0xBB1A, "1106 116D 11A9"), - (0xBB1B, "1106 116D 11AA"), - (0xBB1C, "1106 116D 11AB"), - (0xBB1D, "1106 116D 11AC"), - (0xBB1E, "1106 116D 11AD"), - (0xBB1F, "1106 116D 11AE"), - (0xBB20, "1106 116D 11AF"), - (0xBB21, "1106 116D 11B0"), - (0xBB22, "1106 116D 11B1"), - (0xBB23, "1106 116D 11B2"), - (0xBB24, "1106 116D 11B3"), - (0xBB25, "1106 116D 11B4"), - (0xBB26, "1106 116D 11B5"), - (0xBB27, "1106 116D 11B6"), - (0xBB28, "1106 116D 11B7"), - (0xBB29, "1106 116D 11B8"), - (0xBB2A, "1106 116D 11B9"), - (0xBB2B, "1106 116D 11BA"), - (0xBB2C, "1106 116D 11BB"), - (0xBB2D, "1106 116D 11BC"), - (0xBB2E, "1106 116D 11BD"), - (0xBB2F, "1106 116D 11BE"), - (0xBB30, "1106 116D 11BF"), - (0xBB31, "1106 116D 11C0"), - (0xBB32, "1106 116D 11C1"), - (0xBB33, "1106 116D 11C2"), - (0xBB34, "1106 116E"), - (0xBB35, "1106 116E 11A8"), - (0xBB36, "1106 116E 11A9"), - (0xBB37, "1106 116E 11AA"), - (0xBB38, "1106 116E 11AB"), - (0xBB39, "1106 116E 11AC"), - (0xBB3A, "1106 116E 11AD"), - (0xBB3B, "1106 116E 11AE"), - (0xBB3C, "1106 116E 11AF"), - (0xBB3D, "1106 116E 11B0"), - (0xBB3E, "1106 116E 11B1"), - (0xBB3F, "1106 116E 11B2"), - (0xBB40, "1106 116E 11B3"), - (0xBB41, "1106 116E 11B4"), - (0xBB42, "1106 116E 11B5"), - (0xBB43, "1106 116E 11B6"), - (0xBB44, "1106 116E 11B7"), - (0xBB45, "1106 116E 11B8"), - (0xBB46, "1106 116E 11B9"), - (0xBB47, "1106 116E 11BA"), - (0xBB48, "1106 116E 11BB"), - (0xBB49, "1106 116E 11BC"), - (0xBB4A, "1106 116E 11BD"), - (0xBB4B, "1106 116E 11BE"), - (0xBB4C, "1106 116E 11BF"), - (0xBB4D, "1106 116E 11C0"), - (0xBB4E, "1106 116E 11C1"), - (0xBB4F, "1106 116E 11C2"), - (0xBB50, "1106 116F"), - (0xBB51, "1106 116F 11A8"), - (0xBB52, "1106 116F 11A9"), - (0xBB53, "1106 116F 11AA"), - (0xBB54, "1106 116F 11AB"), - (0xBB55, "1106 116F 11AC"), - (0xBB56, "1106 116F 11AD"), - (0xBB57, "1106 116F 11AE"), - (0xBB58, "1106 116F 11AF"), - (0xBB59, "1106 116F 11B0"), - (0xBB5A, "1106 116F 11B1"), - (0xBB5B, "1106 116F 11B2"), - (0xBB5C, "1106 116F 11B3"), - (0xBB5D, "1106 116F 11B4"), - (0xBB5E, "1106 116F 11B5"), - (0xBB5F, "1106 116F 11B6"), - (0xBB60, "1106 116F 11B7"), - (0xBB61, "1106 116F 11B8"), - (0xBB62, "1106 116F 11B9"), - (0xBB63, "1106 116F 11BA"), - (0xBB64, "1106 116F 11BB"), - (0xBB65, "1106 116F 11BC"), - (0xBB66, "1106 116F 11BD"), - (0xBB67, "1106 116F 11BE"), - (0xBB68, "1106 116F 11BF"), - (0xBB69, "1106 116F 11C0"), - (0xBB6A, "1106 116F 11C1"), - (0xBB6B, "1106 116F 11C2"), - (0xBB6C, "1106 1170"), - (0xBB6D, "1106 1170 11A8"), - (0xBB6E, "1106 1170 11A9"), - (0xBB6F, "1106 1170 11AA"), - (0xBB70, "1106 1170 11AB"), - (0xBB71, "1106 1170 11AC"), - (0xBB72, "1106 1170 11AD"), - (0xBB73, "1106 1170 11AE"), - (0xBB74, "1106 1170 11AF"), - (0xBB75, "1106 1170 11B0"), - (0xBB76, "1106 1170 11B1"), - (0xBB77, "1106 1170 11B2"), - (0xBB78, "1106 1170 11B3"), - (0xBB79, "1106 1170 11B4"), - (0xBB7A, "1106 1170 11B5"), - (0xBB7B, "1106 1170 11B6"), - (0xBB7C, "1106 1170 11B7"), - (0xBB7D, "1106 1170 11B8"), - (0xBB7E, "1106 1170 11B9"), - (0xBB7F, "1106 1170 11BA"), - (0xBB80, "1106 1170 11BB"), - (0xBB81, "1106 1170 11BC"), - (0xBB82, "1106 1170 11BD"), - (0xBB83, "1106 1170 11BE"), - (0xBB84, "1106 1170 11BF"), - (0xBB85, "1106 1170 11C0"), - (0xBB86, "1106 1170 11C1"), - (0xBB87, "1106 1170 11C2"), - (0xBB88, "1106 1171"), - (0xBB89, "1106 1171 11A8"), - (0xBB8A, "1106 1171 11A9"), - (0xBB8B, "1106 1171 11AA"), - (0xBB8C, "1106 1171 11AB"), - (0xBB8D, "1106 1171 11AC"), - (0xBB8E, "1106 1171 11AD"), - (0xBB8F, "1106 1171 11AE"), - (0xBB90, "1106 1171 11AF"), - (0xBB91, "1106 1171 11B0"), - (0xBB92, "1106 1171 11B1"), - (0xBB93, "1106 1171 11B2"), - (0xBB94, "1106 1171 11B3"), - (0xBB95, "1106 1171 11B4"), - (0xBB96, "1106 1171 11B5"), - (0xBB97, "1106 1171 11B6"), - (0xBB98, "1106 1171 11B7"), - (0xBB99, "1106 1171 11B8"), - (0xBB9A, "1106 1171 11B9"), - (0xBB9B, "1106 1171 11BA"), - (0xBB9C, "1106 1171 11BB"), - (0xBB9D, "1106 1171 11BC"), - (0xBB9E, "1106 1171 11BD"), - (0xBB9F, "1106 1171 11BE"), - (0xBBA0, "1106 1171 11BF"), - (0xBBA1, "1106 1171 11C0"), - (0xBBA2, "1106 1171 11C1"), - (0xBBA3, "1106 1171 11C2"), - (0xBBA4, "1106 1172"), - (0xBBA5, "1106 1172 11A8"), - (0xBBA6, "1106 1172 11A9"), - (0xBBA7, "1106 1172 11AA"), - (0xBBA8, "1106 1172 11AB"), - (0xBBA9, "1106 1172 11AC"), - (0xBBAA, "1106 1172 11AD"), - (0xBBAB, "1106 1172 11AE"), - (0xBBAC, "1106 1172 11AF"), - (0xBBAD, "1106 1172 11B0"), - (0xBBAE, "1106 1172 11B1"), - (0xBBAF, "1106 1172 11B2"), - (0xBBB0, "1106 1172 11B3"), - (0xBBB1, "1106 1172 11B4"), - (0xBBB2, "1106 1172 11B5"), - (0xBBB3, "1106 1172 11B6"), - (0xBBB4, "1106 1172 11B7"), - (0xBBB5, "1106 1172 11B8"), - (0xBBB6, "1106 1172 11B9"), - (0xBBB7, "1106 1172 11BA"), - (0xBBB8, "1106 1172 11BB"), - (0xBBB9, "1106 1172 11BC"), - (0xBBBA, "1106 1172 11BD"), - (0xBBBB, "1106 1172 11BE"), - (0xBBBC, "1106 1172 11BF"), - (0xBBBD, "1106 1172 11C0"), - (0xBBBE, "1106 1172 11C1"), - (0xBBBF, "1106 1172 11C2"), - (0xBBC0, "1106 1173"), - (0xBBC1, "1106 1173 11A8"), - (0xBBC2, "1106 1173 11A9"), - (0xBBC3, "1106 1173 11AA"), - (0xBBC4, "1106 1173 11AB"), - (0xBBC5, "1106 1173 11AC"), - (0xBBC6, "1106 1173 11AD"), - (0xBBC7, "1106 1173 11AE"), - (0xBBC8, "1106 1173 11AF"), - (0xBBC9, "1106 1173 11B0"), - (0xBBCA, "1106 1173 11B1"), - (0xBBCB, "1106 1173 11B2"), - (0xBBCC, "1106 1173 11B3"), - (0xBBCD, "1106 1173 11B4"), - (0xBBCE, "1106 1173 11B5"), - (0xBBCF, "1106 1173 11B6"), - (0xBBD0, "1106 1173 11B7"), - (0xBBD1, "1106 1173 11B8"), - (0xBBD2, "1106 1173 11B9"), - (0xBBD3, "1106 1173 11BA"), - (0xBBD4, "1106 1173 11BB"), - (0xBBD5, "1106 1173 11BC"), - (0xBBD6, "1106 1173 11BD"), - (0xBBD7, "1106 1173 11BE"), - (0xBBD8, "1106 1173 11BF"), - (0xBBD9, "1106 1173 11C0"), - (0xBBDA, "1106 1173 11C1"), - (0xBBDB, "1106 1173 11C2"), - (0xBBDC, "1106 1174"), - (0xBBDD, "1106 1174 11A8"), - (0xBBDE, "1106 1174 11A9"), - (0xBBDF, "1106 1174 11AA"), - (0xBBE0, "1106 1174 11AB"), - (0xBBE1, "1106 1174 11AC"), - (0xBBE2, "1106 1174 11AD"), - (0xBBE3, "1106 1174 11AE"), - (0xBBE4, "1106 1174 11AF"), - (0xBBE5, "1106 1174 11B0"), - (0xBBE6, "1106 1174 11B1"), - (0xBBE7, "1106 1174 11B2"), - (0xBBE8, "1106 1174 11B3"), - (0xBBE9, "1106 1174 11B4"), - (0xBBEA, "1106 1174 11B5"), - (0xBBEB, "1106 1174 11B6"), - (0xBBEC, "1106 1174 11B7"), - (0xBBED, "1106 1174 11B8"), - (0xBBEE, "1106 1174 11B9"), - (0xBBEF, "1106 1174 11BA"), - (0xBBF0, "1106 1174 11BB"), - (0xBBF1, "1106 1174 11BC"), - (0xBBF2, "1106 1174 11BD"), - (0xBBF3, "1106 1174 11BE"), - (0xBBF4, "1106 1174 11BF"), - (0xBBF5, "1106 1174 11C0"), - (0xBBF6, "1106 1174 11C1"), - (0xBBF7, "1106 1174 11C2"), - (0xBBF8, "1106 1175"), - (0xBBF9, "1106 1175 11A8"), - (0xBBFA, "1106 1175 11A9"), - (0xBBFB, "1106 1175 11AA"), - (0xBBFC, "1106 1175 11AB"), - (0xBBFD, "1106 1175 11AC"), - (0xBBFE, "1106 1175 11AD"), - (0xBBFF, "1106 1175 11AE"), - (0xBC00, "1106 1175 11AF"), - (0xBC01, "1106 1175 11B0"), - (0xBC02, "1106 1175 11B1"), - (0xBC03, "1106 1175 11B2"), - (0xBC04, "1106 1175 11B3"), - (0xBC05, "1106 1175 11B4"), - (0xBC06, "1106 1175 11B5"), - (0xBC07, "1106 1175 11B6"), - (0xBC08, "1106 1175 11B7"), - (0xBC09, "1106 1175 11B8"), - (0xBC0A, "1106 1175 11B9"), - (0xBC0B, "1106 1175 11BA"), - (0xBC0C, "1106 1175 11BB"), - (0xBC0D, "1106 1175 11BC"), - (0xBC0E, "1106 1175 11BD"), - (0xBC0F, "1106 1175 11BE"), - (0xBC10, "1106 1175 11BF"), - (0xBC11, "1106 1175 11C0"), - (0xBC12, "1106 1175 11C1"), - (0xBC13, "1106 1175 11C2"), - (0xBC14, "1107 1161"), - (0xBC15, "1107 1161 11A8"), - (0xBC16, "1107 1161 11A9"), - (0xBC17, "1107 1161 11AA"), - (0xBC18, "1107 1161 11AB"), - (0xBC19, "1107 1161 11AC"), - (0xBC1A, "1107 1161 11AD"), - (0xBC1B, "1107 1161 11AE"), - (0xBC1C, "1107 1161 11AF"), - (0xBC1D, "1107 1161 11B0"), - (0xBC1E, "1107 1161 11B1"), - (0xBC1F, "1107 1161 11B2"), - (0xBC20, "1107 1161 11B3"), - (0xBC21, "1107 1161 11B4"), - (0xBC22, "1107 1161 11B5"), - (0xBC23, "1107 1161 11B6"), - (0xBC24, "1107 1161 11B7"), - (0xBC25, "1107 1161 11B8"), - (0xBC26, "1107 1161 11B9"), - (0xBC27, "1107 1161 11BA"), - (0xBC28, "1107 1161 11BB"), - (0xBC29, "1107 1161 11BC"), - (0xBC2A, "1107 1161 11BD"), - (0xBC2B, "1107 1161 11BE"), - (0xBC2C, "1107 1161 11BF"), - (0xBC2D, "1107 1161 11C0"), - (0xBC2E, "1107 1161 11C1"), - (0xBC2F, "1107 1161 11C2"), - (0xBC30, "1107 1162"), - (0xBC31, "1107 1162 11A8"), - (0xBC32, "1107 1162 11A9"), - (0xBC33, "1107 1162 11AA"), - (0xBC34, "1107 1162 11AB"), - (0xBC35, "1107 1162 11AC"), - (0xBC36, "1107 1162 11AD"), - (0xBC37, "1107 1162 11AE"), - (0xBC38, "1107 1162 11AF"), - (0xBC39, "1107 1162 11B0"), - (0xBC3A, "1107 1162 11B1"), - (0xBC3B, "1107 1162 11B2"), - (0xBC3C, "1107 1162 11B3"), - (0xBC3D, "1107 1162 11B4"), - (0xBC3E, "1107 1162 11B5"), - (0xBC3F, "1107 1162 11B6"), - (0xBC40, "1107 1162 11B7"), - (0xBC41, "1107 1162 11B8"), - (0xBC42, "1107 1162 11B9"), - (0xBC43, "1107 1162 11BA"), - (0xBC44, "1107 1162 11BB"), - (0xBC45, "1107 1162 11BC"), - (0xBC46, "1107 1162 11BD"), - (0xBC47, "1107 1162 11BE"), - (0xBC48, "1107 1162 11BF"), - (0xBC49, "1107 1162 11C0"), - (0xBC4A, "1107 1162 11C1"), - (0xBC4B, "1107 1162 11C2"), - (0xBC4C, "1107 1163"), - (0xBC4D, "1107 1163 11A8"), - (0xBC4E, "1107 1163 11A9"), - (0xBC4F, "1107 1163 11AA"), - (0xBC50, "1107 1163 11AB"), - (0xBC51, "1107 1163 11AC"), - (0xBC52, "1107 1163 11AD"), - (0xBC53, "1107 1163 11AE"), - (0xBC54, "1107 1163 11AF"), - (0xBC55, "1107 1163 11B0"), - (0xBC56, "1107 1163 11B1"), - (0xBC57, "1107 1163 11B2"), - (0xBC58, "1107 1163 11B3"), - (0xBC59, "1107 1163 11B4"), - (0xBC5A, "1107 1163 11B5"), - (0xBC5B, "1107 1163 11B6"), - (0xBC5C, "1107 1163 11B7"), - (0xBC5D, "1107 1163 11B8"), - (0xBC5E, "1107 1163 11B9"), - (0xBC5F, "1107 1163 11BA"), - (0xBC60, "1107 1163 11BB"), - (0xBC61, "1107 1163 11BC"), - (0xBC62, "1107 1163 11BD"), - (0xBC63, "1107 1163 11BE"), - (0xBC64, "1107 1163 11BF"), - (0xBC65, "1107 1163 11C0"), - (0xBC66, "1107 1163 11C1"), - (0xBC67, "1107 1163 11C2"), - (0xBC68, "1107 1164"), - (0xBC69, "1107 1164 11A8"), - (0xBC6A, "1107 1164 11A9"), - (0xBC6B, "1107 1164 11AA"), - (0xBC6C, "1107 1164 11AB"), - (0xBC6D, "1107 1164 11AC"), - (0xBC6E, "1107 1164 11AD"), - (0xBC6F, "1107 1164 11AE"), - (0xBC70, "1107 1164 11AF"), - (0xBC71, "1107 1164 11B0"), - (0xBC72, "1107 1164 11B1"), - (0xBC73, "1107 1164 11B2"), - (0xBC74, "1107 1164 11B3"), - (0xBC75, "1107 1164 11B4"), - (0xBC76, "1107 1164 11B5"), - (0xBC77, "1107 1164 11B6"), - (0xBC78, "1107 1164 11B7"), - (0xBC79, "1107 1164 11B8"), - (0xBC7A, "1107 1164 11B9"), - (0xBC7B, "1107 1164 11BA"), - (0xBC7C, "1107 1164 11BB"), - (0xBC7D, "1107 1164 11BC"), - (0xBC7E, "1107 1164 11BD"), - (0xBC7F, "1107 1164 11BE"), - (0xBC80, "1107 1164 11BF"), - (0xBC81, "1107 1164 11C0"), - (0xBC82, "1107 1164 11C1"), - (0xBC83, "1107 1164 11C2"), - (0xBC84, "1107 1165"), - (0xBC85, "1107 1165 11A8"), - (0xBC86, "1107 1165 11A9"), - (0xBC87, "1107 1165 11AA"), - (0xBC88, "1107 1165 11AB"), - (0xBC89, "1107 1165 11AC"), - (0xBC8A, "1107 1165 11AD"), - (0xBC8B, "1107 1165 11AE"), - (0xBC8C, "1107 1165 11AF"), - (0xBC8D, "1107 1165 11B0"), - (0xBC8E, "1107 1165 11B1"), - (0xBC8F, "1107 1165 11B2"), - (0xBC90, "1107 1165 11B3"), - (0xBC91, "1107 1165 11B4"), - (0xBC92, "1107 1165 11B5"), - (0xBC93, "1107 1165 11B6"), - (0xBC94, "1107 1165 11B7"), - (0xBC95, "1107 1165 11B8"), - (0xBC96, "1107 1165 11B9"), - (0xBC97, "1107 1165 11BA"), - (0xBC98, "1107 1165 11BB"), - (0xBC99, "1107 1165 11BC"), - (0xBC9A, "1107 1165 11BD"), - (0xBC9B, "1107 1165 11BE"), - (0xBC9C, "1107 1165 11BF"), - (0xBC9D, "1107 1165 11C0"), - (0xBC9E, "1107 1165 11C1"), - (0xBC9F, "1107 1165 11C2"), - (0xBCA0, "1107 1166"), - (0xBCA1, "1107 1166 11A8"), - (0xBCA2, "1107 1166 11A9"), - (0xBCA3, "1107 1166 11AA"), - (0xBCA4, "1107 1166 11AB"), - (0xBCA5, "1107 1166 11AC"), - (0xBCA6, "1107 1166 11AD"), - (0xBCA7, "1107 1166 11AE"), - (0xBCA8, "1107 1166 11AF"), - (0xBCA9, "1107 1166 11B0"), - (0xBCAA, "1107 1166 11B1"), - (0xBCAB, "1107 1166 11B2"), - (0xBCAC, "1107 1166 11B3"), - (0xBCAD, "1107 1166 11B4"), - (0xBCAE, "1107 1166 11B5"), - (0xBCAF, "1107 1166 11B6"), - (0xBCB0, "1107 1166 11B7"), - (0xBCB1, "1107 1166 11B8"), - (0xBCB2, "1107 1166 11B9"), - (0xBCB3, "1107 1166 11BA"), - (0xBCB4, "1107 1166 11BB"), - (0xBCB5, "1107 1166 11BC"), - (0xBCB6, "1107 1166 11BD"), - (0xBCB7, "1107 1166 11BE"), - (0xBCB8, "1107 1166 11BF"), - (0xBCB9, "1107 1166 11C0"), - (0xBCBA, "1107 1166 11C1"), - (0xBCBB, "1107 1166 11C2"), - (0xBCBC, "1107 1167"), - (0xBCBD, "1107 1167 11A8"), - (0xBCBE, "1107 1167 11A9"), - (0xBCBF, "1107 1167 11AA"), - (0xBCC0, "1107 1167 11AB"), - (0xBCC1, "1107 1167 11AC"), - (0xBCC2, "1107 1167 11AD"), - (0xBCC3, "1107 1167 11AE"), - (0xBCC4, "1107 1167 11AF"), - (0xBCC5, "1107 1167 11B0"), - (0xBCC6, "1107 1167 11B1"), - (0xBCC7, "1107 1167 11B2"), - (0xBCC8, "1107 1167 11B3"), - (0xBCC9, "1107 1167 11B4"), - (0xBCCA, "1107 1167 11B5"), - (0xBCCB, "1107 1167 11B6"), - (0xBCCC, "1107 1167 11B7"), - (0xBCCD, "1107 1167 11B8"), - (0xBCCE, "1107 1167 11B9"), - (0xBCCF, "1107 1167 11BA"), - (0xBCD0, "1107 1167 11BB"), - (0xBCD1, "1107 1167 11BC"), - (0xBCD2, "1107 1167 11BD"), - (0xBCD3, "1107 1167 11BE"), - (0xBCD4, "1107 1167 11BF"), - (0xBCD5, "1107 1167 11C0"), - (0xBCD6, "1107 1167 11C1"), - (0xBCD7, "1107 1167 11C2"), - (0xBCD8, "1107 1168"), - (0xBCD9, "1107 1168 11A8"), - (0xBCDA, "1107 1168 11A9"), - (0xBCDB, "1107 1168 11AA"), - (0xBCDC, "1107 1168 11AB"), - (0xBCDD, "1107 1168 11AC"), - (0xBCDE, "1107 1168 11AD"), - (0xBCDF, "1107 1168 11AE"), - (0xBCE0, "1107 1168 11AF"), - (0xBCE1, "1107 1168 11B0"), - (0xBCE2, "1107 1168 11B1"), - (0xBCE3, "1107 1168 11B2"), - (0xBCE4, "1107 1168 11B3"), - (0xBCE5, "1107 1168 11B4"), - (0xBCE6, "1107 1168 11B5"), - (0xBCE7, "1107 1168 11B6"), - (0xBCE8, "1107 1168 11B7"), - (0xBCE9, "1107 1168 11B8"), - (0xBCEA, "1107 1168 11B9"), - (0xBCEB, "1107 1168 11BA"), - (0xBCEC, "1107 1168 11BB"), - (0xBCED, "1107 1168 11BC"), - (0xBCEE, "1107 1168 11BD"), - (0xBCEF, "1107 1168 11BE"), - (0xBCF0, "1107 1168 11BF"), - (0xBCF1, "1107 1168 11C0"), - (0xBCF2, "1107 1168 11C1"), - (0xBCF3, "1107 1168 11C2"), - (0xBCF4, "1107 1169"), - (0xBCF5, "1107 1169 11A8"), - (0xBCF6, "1107 1169 11A9"), - (0xBCF7, "1107 1169 11AA"), - (0xBCF8, "1107 1169 11AB"), - (0xBCF9, "1107 1169 11AC"), - (0xBCFA, "1107 1169 11AD"), - (0xBCFB, "1107 1169 11AE"), - (0xBCFC, "1107 1169 11AF"), - (0xBCFD, "1107 1169 11B0"), - (0xBCFE, "1107 1169 11B1"), - (0xBCFF, "1107 1169 11B2"), - (0xBD00, "1107 1169 11B3"), - (0xBD01, "1107 1169 11B4"), - (0xBD02, "1107 1169 11B5"), - (0xBD03, "1107 1169 11B6"), - (0xBD04, "1107 1169 11B7"), - (0xBD05, "1107 1169 11B8"), - (0xBD06, "1107 1169 11B9"), - (0xBD07, "1107 1169 11BA"), - (0xBD08, "1107 1169 11BB"), - (0xBD09, "1107 1169 11BC"), - (0xBD0A, "1107 1169 11BD"), - (0xBD0B, "1107 1169 11BE"), - (0xBD0C, "1107 1169 11BF"), - (0xBD0D, "1107 1169 11C0"), - (0xBD0E, "1107 1169 11C1"), - (0xBD0F, "1107 1169 11C2"), - (0xBD10, "1107 116A"), - (0xBD11, "1107 116A 11A8"), - (0xBD12, "1107 116A 11A9"), - (0xBD13, "1107 116A 11AA"), - (0xBD14, "1107 116A 11AB"), - (0xBD15, "1107 116A 11AC"), - (0xBD16, "1107 116A 11AD"), - (0xBD17, "1107 116A 11AE"), - (0xBD18, "1107 116A 11AF"), - (0xBD19, "1107 116A 11B0"), - (0xBD1A, "1107 116A 11B1"), - (0xBD1B, "1107 116A 11B2"), - (0xBD1C, "1107 116A 11B3"), - (0xBD1D, "1107 116A 11B4"), - (0xBD1E, "1107 116A 11B5"), - (0xBD1F, "1107 116A 11B6"), - (0xBD20, "1107 116A 11B7"), - (0xBD21, "1107 116A 11B8"), - (0xBD22, "1107 116A 11B9"), - (0xBD23, "1107 116A 11BA"), - (0xBD24, "1107 116A 11BB"), - (0xBD25, "1107 116A 11BC"), - (0xBD26, "1107 116A 11BD"), - (0xBD27, "1107 116A 11BE"), - (0xBD28, "1107 116A 11BF"), - (0xBD29, "1107 116A 11C0"), - (0xBD2A, "1107 116A 11C1"), - (0xBD2B, "1107 116A 11C2"), - (0xBD2C, "1107 116B"), - (0xBD2D, "1107 116B 11A8"), - (0xBD2E, "1107 116B 11A9"), - (0xBD2F, "1107 116B 11AA"), - (0xBD30, "1107 116B 11AB"), - (0xBD31, "1107 116B 11AC"), - (0xBD32, "1107 116B 11AD"), - (0xBD33, "1107 116B 11AE"), - (0xBD34, "1107 116B 11AF"), - (0xBD35, "1107 116B 11B0"), - (0xBD36, "1107 116B 11B1"), - (0xBD37, "1107 116B 11B2"), - (0xBD38, "1107 116B 11B3"), - (0xBD39, "1107 116B 11B4"), - (0xBD3A, "1107 116B 11B5"), - (0xBD3B, "1107 116B 11B6"), - (0xBD3C, "1107 116B 11B7"), - (0xBD3D, "1107 116B 11B8"), - (0xBD3E, "1107 116B 11B9"), - (0xBD3F, "1107 116B 11BA"), - (0xBD40, "1107 116B 11BB"), - (0xBD41, "1107 116B 11BC"), - (0xBD42, "1107 116B 11BD"), - (0xBD43, "1107 116B 11BE"), - (0xBD44, "1107 116B 11BF"), - (0xBD45, "1107 116B 11C0"), - (0xBD46, "1107 116B 11C1"), - (0xBD47, "1107 116B 11C2"), - (0xBD48, "1107 116C"), - (0xBD49, "1107 116C 11A8"), - (0xBD4A, "1107 116C 11A9"), - (0xBD4B, "1107 116C 11AA"), - (0xBD4C, "1107 116C 11AB"), - (0xBD4D, "1107 116C 11AC"), - (0xBD4E, "1107 116C 11AD"), - (0xBD4F, "1107 116C 11AE"), - (0xBD50, "1107 116C 11AF"), - (0xBD51, "1107 116C 11B0"), - (0xBD52, "1107 116C 11B1"), - (0xBD53, "1107 116C 11B2"), - (0xBD54, "1107 116C 11B3"), - (0xBD55, "1107 116C 11B4"), - (0xBD56, "1107 116C 11B5"), - (0xBD57, "1107 116C 11B6"), - (0xBD58, "1107 116C 11B7"), - (0xBD59, "1107 116C 11B8"), - (0xBD5A, "1107 116C 11B9"), - (0xBD5B, "1107 116C 11BA"), - (0xBD5C, "1107 116C 11BB"), - (0xBD5D, "1107 116C 11BC"), - (0xBD5E, "1107 116C 11BD"), - (0xBD5F, "1107 116C 11BE"), - (0xBD60, "1107 116C 11BF"), - (0xBD61, "1107 116C 11C0"), - (0xBD62, "1107 116C 11C1"), - (0xBD63, "1107 116C 11C2"), - (0xBD64, "1107 116D"), - (0xBD65, "1107 116D 11A8"), - (0xBD66, "1107 116D 11A9"), - (0xBD67, "1107 116D 11AA"), - (0xBD68, "1107 116D 11AB"), - (0xBD69, "1107 116D 11AC"), - (0xBD6A, "1107 116D 11AD"), - (0xBD6B, "1107 116D 11AE"), - (0xBD6C, "1107 116D 11AF"), - (0xBD6D, "1107 116D 11B0"), - (0xBD6E, "1107 116D 11B1"), - (0xBD6F, "1107 116D 11B2"), - (0xBD70, "1107 116D 11B3"), - (0xBD71, "1107 116D 11B4"), - (0xBD72, "1107 116D 11B5"), - (0xBD73, "1107 116D 11B6"), - (0xBD74, "1107 116D 11B7"), - (0xBD75, "1107 116D 11B8"), - (0xBD76, "1107 116D 11B9"), - (0xBD77, "1107 116D 11BA"), - (0xBD78, "1107 116D 11BB"), - (0xBD79, "1107 116D 11BC"), - (0xBD7A, "1107 116D 11BD"), - (0xBD7B, "1107 116D 11BE"), - (0xBD7C, "1107 116D 11BF"), - (0xBD7D, "1107 116D 11C0"), - (0xBD7E, "1107 116D 11C1"), - (0xBD7F, "1107 116D 11C2"), - (0xBD80, "1107 116E"), - (0xBD81, "1107 116E 11A8"), - (0xBD82, "1107 116E 11A9"), - (0xBD83, "1107 116E 11AA"), - (0xBD84, "1107 116E 11AB"), - (0xBD85, "1107 116E 11AC"), - (0xBD86, "1107 116E 11AD"), - (0xBD87, "1107 116E 11AE"), - (0xBD88, "1107 116E 11AF"), - (0xBD89, "1107 116E 11B0"), - (0xBD8A, "1107 116E 11B1"), - (0xBD8B, "1107 116E 11B2"), - (0xBD8C, "1107 116E 11B3"), - (0xBD8D, "1107 116E 11B4"), - (0xBD8E, "1107 116E 11B5"), - (0xBD8F, "1107 116E 11B6"), - (0xBD90, "1107 116E 11B7"), - (0xBD91, "1107 116E 11B8"), - (0xBD92, "1107 116E 11B9"), - (0xBD93, "1107 116E 11BA"), - (0xBD94, "1107 116E 11BB"), - (0xBD95, "1107 116E 11BC"), - (0xBD96, "1107 116E 11BD"), - (0xBD97, "1107 116E 11BE"), - (0xBD98, "1107 116E 11BF"), - (0xBD99, "1107 116E 11C0"), - (0xBD9A, "1107 116E 11C1"), - (0xBD9B, "1107 116E 11C2"), - (0xBD9C, "1107 116F"), - (0xBD9D, "1107 116F 11A8"), - (0xBD9E, "1107 116F 11A9"), - (0xBD9F, "1107 116F 11AA"), - (0xBDA0, "1107 116F 11AB"), - (0xBDA1, "1107 116F 11AC"), - (0xBDA2, "1107 116F 11AD"), - (0xBDA3, "1107 116F 11AE"), - (0xBDA4, "1107 116F 11AF"), - (0xBDA5, "1107 116F 11B0"), - (0xBDA6, "1107 116F 11B1"), - (0xBDA7, "1107 116F 11B2"), - (0xBDA8, "1107 116F 11B3"), - (0xBDA9, "1107 116F 11B4"), - (0xBDAA, "1107 116F 11B5"), - (0xBDAB, "1107 116F 11B6"), - (0xBDAC, "1107 116F 11B7"), - (0xBDAD, "1107 116F 11B8"), - (0xBDAE, "1107 116F 11B9"), - (0xBDAF, "1107 116F 11BA"), - (0xBDB0, "1107 116F 11BB"), - (0xBDB1, "1107 116F 11BC"), - (0xBDB2, "1107 116F 11BD"), - (0xBDB3, "1107 116F 11BE"), - (0xBDB4, "1107 116F 11BF"), - (0xBDB5, "1107 116F 11C0"), - (0xBDB6, "1107 116F 11C1"), - (0xBDB7, "1107 116F 11C2"), - (0xBDB8, "1107 1170"), - (0xBDB9, "1107 1170 11A8"), - (0xBDBA, "1107 1170 11A9"), - (0xBDBB, "1107 1170 11AA"), - (0xBDBC, "1107 1170 11AB"), - (0xBDBD, "1107 1170 11AC"), - (0xBDBE, "1107 1170 11AD"), - (0xBDBF, "1107 1170 11AE"), - (0xBDC0, "1107 1170 11AF"), - (0xBDC1, "1107 1170 11B0"), - (0xBDC2, "1107 1170 11B1"), - (0xBDC3, "1107 1170 11B2"), - (0xBDC4, "1107 1170 11B3"), - (0xBDC5, "1107 1170 11B4"), - (0xBDC6, "1107 1170 11B5"), - (0xBDC7, "1107 1170 11B6"), - (0xBDC8, "1107 1170 11B7"), - (0xBDC9, "1107 1170 11B8"), - (0xBDCA, "1107 1170 11B9"), - (0xBDCB, "1107 1170 11BA"), - (0xBDCC, "1107 1170 11BB"), - (0xBDCD, "1107 1170 11BC"), - (0xBDCE, "1107 1170 11BD"), - (0xBDCF, "1107 1170 11BE"), - (0xBDD0, "1107 1170 11BF"), - (0xBDD1, "1107 1170 11C0"), - (0xBDD2, "1107 1170 11C1"), - (0xBDD3, "1107 1170 11C2"), - (0xBDD4, "1107 1171"), - (0xBDD5, "1107 1171 11A8"), - (0xBDD6, "1107 1171 11A9"), - (0xBDD7, "1107 1171 11AA"), - (0xBDD8, "1107 1171 11AB"), - (0xBDD9, "1107 1171 11AC"), - (0xBDDA, "1107 1171 11AD"), - (0xBDDB, "1107 1171 11AE"), - (0xBDDC, "1107 1171 11AF"), - (0xBDDD, "1107 1171 11B0"), - (0xBDDE, "1107 1171 11B1"), - (0xBDDF, "1107 1171 11B2"), - (0xBDE0, "1107 1171 11B3"), - (0xBDE1, "1107 1171 11B4"), - (0xBDE2, "1107 1171 11B5"), - (0xBDE3, "1107 1171 11B6"), - (0xBDE4, "1107 1171 11B7"), - (0xBDE5, "1107 1171 11B8"), - (0xBDE6, "1107 1171 11B9"), - (0xBDE7, "1107 1171 11BA"), - (0xBDE8, "1107 1171 11BB"), - (0xBDE9, "1107 1171 11BC"), - (0xBDEA, "1107 1171 11BD"), - (0xBDEB, "1107 1171 11BE"), - (0xBDEC, "1107 1171 11BF"), - (0xBDED, "1107 1171 11C0"), - (0xBDEE, "1107 1171 11C1"), - (0xBDEF, "1107 1171 11C2"), - (0xBDF0, "1107 1172"), - (0xBDF1, "1107 1172 11A8"), - (0xBDF2, "1107 1172 11A9"), - (0xBDF3, "1107 1172 11AA"), - (0xBDF4, "1107 1172 11AB"), - (0xBDF5, "1107 1172 11AC"), - (0xBDF6, "1107 1172 11AD"), - (0xBDF7, "1107 1172 11AE"), - (0xBDF8, "1107 1172 11AF"), - (0xBDF9, "1107 1172 11B0"), - (0xBDFA, "1107 1172 11B1"), - (0xBDFB, "1107 1172 11B2"), - (0xBDFC, "1107 1172 11B3"), - (0xBDFD, "1107 1172 11B4"), - (0xBDFE, "1107 1172 11B5"), - (0xBDFF, "1107 1172 11B6"), - (0xBE00, "1107 1172 11B7"), - (0xBE01, "1107 1172 11B8"), - (0xBE02, "1107 1172 11B9"), - (0xBE03, "1107 1172 11BA"), - (0xBE04, "1107 1172 11BB"), - (0xBE05, "1107 1172 11BC"), - (0xBE06, "1107 1172 11BD"), - (0xBE07, "1107 1172 11BE"), - (0xBE08, "1107 1172 11BF"), - (0xBE09, "1107 1172 11C0"), - (0xBE0A, "1107 1172 11C1"), - (0xBE0B, "1107 1172 11C2"), - (0xBE0C, "1107 1173"), - (0xBE0D, "1107 1173 11A8"), - (0xBE0E, "1107 1173 11A9"), - (0xBE0F, "1107 1173 11AA"), - (0xBE10, "1107 1173 11AB"), - (0xBE11, "1107 1173 11AC"), - (0xBE12, "1107 1173 11AD"), - (0xBE13, "1107 1173 11AE"), - (0xBE14, "1107 1173 11AF"), - (0xBE15, "1107 1173 11B0"), - (0xBE16, "1107 1173 11B1"), - (0xBE17, "1107 1173 11B2"), - (0xBE18, "1107 1173 11B3"), - (0xBE19, "1107 1173 11B4"), - (0xBE1A, "1107 1173 11B5"), - (0xBE1B, "1107 1173 11B6"), - (0xBE1C, "1107 1173 11B7"), - (0xBE1D, "1107 1173 11B8"), - (0xBE1E, "1107 1173 11B9"), - (0xBE1F, "1107 1173 11BA"), - (0xBE20, "1107 1173 11BB"), - (0xBE21, "1107 1173 11BC"), - (0xBE22, "1107 1173 11BD"), - (0xBE23, "1107 1173 11BE"), - (0xBE24, "1107 1173 11BF"), - (0xBE25, "1107 1173 11C0"), - (0xBE26, "1107 1173 11C1"), - (0xBE27, "1107 1173 11C2"), - (0xBE28, "1107 1174"), - (0xBE29, "1107 1174 11A8"), - (0xBE2A, "1107 1174 11A9"), - (0xBE2B, "1107 1174 11AA"), - (0xBE2C, "1107 1174 11AB"), - (0xBE2D, "1107 1174 11AC"), - (0xBE2E, "1107 1174 11AD"), - (0xBE2F, "1107 1174 11AE"), - (0xBE30, "1107 1174 11AF"), - (0xBE31, "1107 1174 11B0"), - (0xBE32, "1107 1174 11B1"), - (0xBE33, "1107 1174 11B2"), - (0xBE34, "1107 1174 11B3"), - (0xBE35, "1107 1174 11B4"), - (0xBE36, "1107 1174 11B5"), - (0xBE37, "1107 1174 11B6"), - (0xBE38, "1107 1174 11B7"), - (0xBE39, "1107 1174 11B8"), - (0xBE3A, "1107 1174 11B9"), - (0xBE3B, "1107 1174 11BA"), - (0xBE3C, "1107 1174 11BB"), - (0xBE3D, "1107 1174 11BC"), - (0xBE3E, "1107 1174 11BD"), - (0xBE3F, "1107 1174 11BE"), - (0xBE40, "1107 1174 11BF"), - (0xBE41, "1107 1174 11C0"), - (0xBE42, "1107 1174 11C1"), - (0xBE43, "1107 1174 11C2"), - (0xBE44, "1107 1175"), - (0xBE45, "1107 1175 11A8"), - (0xBE46, "1107 1175 11A9"), - (0xBE47, "1107 1175 11AA"), - (0xBE48, "1107 1175 11AB"), - (0xBE49, "1107 1175 11AC"), - (0xBE4A, "1107 1175 11AD"), - (0xBE4B, "1107 1175 11AE"), - (0xBE4C, "1107 1175 11AF"), - (0xBE4D, "1107 1175 11B0"), - (0xBE4E, "1107 1175 11B1"), - (0xBE4F, "1107 1175 11B2"), - (0xBE50, "1107 1175 11B3"), - (0xBE51, "1107 1175 11B4"), - (0xBE52, "1107 1175 11B5"), - (0xBE53, "1107 1175 11B6"), - (0xBE54, "1107 1175 11B7"), - (0xBE55, "1107 1175 11B8"), - (0xBE56, "1107 1175 11B9"), - (0xBE57, "1107 1175 11BA"), - (0xBE58, "1107 1175 11BB"), - (0xBE59, "1107 1175 11BC"), - (0xBE5A, "1107 1175 11BD"), - (0xBE5B, "1107 1175 11BE"), - (0xBE5C, "1107 1175 11BF"), - (0xBE5D, "1107 1175 11C0"), - (0xBE5E, "1107 1175 11C1"), - (0xBE5F, "1107 1175 11C2"), - (0xBE60, "1108 1161"), - (0xBE61, "1108 1161 11A8"), - (0xBE62, "1108 1161 11A9"), - (0xBE63, "1108 1161 11AA"), - (0xBE64, "1108 1161 11AB"), - (0xBE65, "1108 1161 11AC"), - (0xBE66, "1108 1161 11AD"), - (0xBE67, "1108 1161 11AE"), - (0xBE68, "1108 1161 11AF"), - (0xBE69, "1108 1161 11B0"), - (0xBE6A, "1108 1161 11B1"), - (0xBE6B, "1108 1161 11B2"), - (0xBE6C, "1108 1161 11B3"), - (0xBE6D, "1108 1161 11B4"), - (0xBE6E, "1108 1161 11B5"), - (0xBE6F, "1108 1161 11B6"), - (0xBE70, "1108 1161 11B7"), - (0xBE71, "1108 1161 11B8"), - (0xBE72, "1108 1161 11B9"), - (0xBE73, "1108 1161 11BA"), - (0xBE74, "1108 1161 11BB"), - (0xBE75, "1108 1161 11BC"), - (0xBE76, "1108 1161 11BD"), - (0xBE77, "1108 1161 11BE"), - (0xBE78, "1108 1161 11BF"), - (0xBE79, "1108 1161 11C0"), - (0xBE7A, "1108 1161 11C1"), - (0xBE7B, "1108 1161 11C2"), - (0xBE7C, "1108 1162"), - (0xBE7D, "1108 1162 11A8"), - (0xBE7E, "1108 1162 11A9"), - (0xBE7F, "1108 1162 11AA"), - (0xBE80, "1108 1162 11AB"), - (0xBE81, "1108 1162 11AC"), - (0xBE82, "1108 1162 11AD"), - (0xBE83, "1108 1162 11AE"), - (0xBE84, "1108 1162 11AF"), - (0xBE85, "1108 1162 11B0"), - (0xBE86, "1108 1162 11B1"), - (0xBE87, "1108 1162 11B2"), - (0xBE88, "1108 1162 11B3"), - (0xBE89, "1108 1162 11B4"), - (0xBE8A, "1108 1162 11B5"), - (0xBE8B, "1108 1162 11B6"), - (0xBE8C, "1108 1162 11B7"), - (0xBE8D, "1108 1162 11B8"), - (0xBE8E, "1108 1162 11B9"), - (0xBE8F, "1108 1162 11BA"), - (0xBE90, "1108 1162 11BB"), - (0xBE91, "1108 1162 11BC"), - (0xBE92, "1108 1162 11BD"), - (0xBE93, "1108 1162 11BE"), - (0xBE94, "1108 1162 11BF"), - (0xBE95, "1108 1162 11C0"), - (0xBE96, "1108 1162 11C1"), - (0xBE97, "1108 1162 11C2"), - (0xBE98, "1108 1163"), - (0xBE99, "1108 1163 11A8"), - (0xBE9A, "1108 1163 11A9"), - (0xBE9B, "1108 1163 11AA"), - (0xBE9C, "1108 1163 11AB"), - (0xBE9D, "1108 1163 11AC"), - (0xBE9E, "1108 1163 11AD"), - (0xBE9F, "1108 1163 11AE"), - (0xBEA0, "1108 1163 11AF"), - (0xBEA1, "1108 1163 11B0"), - (0xBEA2, "1108 1163 11B1"), - (0xBEA3, "1108 1163 11B2"), - (0xBEA4, "1108 1163 11B3"), - (0xBEA5, "1108 1163 11B4"), - (0xBEA6, "1108 1163 11B5"), - (0xBEA7, "1108 1163 11B6"), - (0xBEA8, "1108 1163 11B7"), - (0xBEA9, "1108 1163 11B8"), - (0xBEAA, "1108 1163 11B9"), - (0xBEAB, "1108 1163 11BA"), - (0xBEAC, "1108 1163 11BB"), - (0xBEAD, "1108 1163 11BC"), - (0xBEAE, "1108 1163 11BD"), - (0xBEAF, "1108 1163 11BE"), - (0xBEB0, "1108 1163 11BF"), - (0xBEB1, "1108 1163 11C0"), - (0xBEB2, "1108 1163 11C1"), - (0xBEB3, "1108 1163 11C2"), - (0xBEB4, "1108 1164"), - (0xBEB5, "1108 1164 11A8"), - (0xBEB6, "1108 1164 11A9"), - (0xBEB7, "1108 1164 11AA"), - (0xBEB8, "1108 1164 11AB"), - (0xBEB9, "1108 1164 11AC"), - (0xBEBA, "1108 1164 11AD"), - (0xBEBB, "1108 1164 11AE"), - (0xBEBC, "1108 1164 11AF"), - (0xBEBD, "1108 1164 11B0"), - (0xBEBE, "1108 1164 11B1"), - (0xBEBF, "1108 1164 11B2"), - (0xBEC0, "1108 1164 11B3"), - (0xBEC1, "1108 1164 11B4"), - (0xBEC2, "1108 1164 11B5"), - (0xBEC3, "1108 1164 11B6"), - (0xBEC4, "1108 1164 11B7"), - (0xBEC5, "1108 1164 11B8"), - (0xBEC6, "1108 1164 11B9"), - (0xBEC7, "1108 1164 11BA"), - (0xBEC8, "1108 1164 11BB"), - (0xBEC9, "1108 1164 11BC"), - (0xBECA, "1108 1164 11BD"), - (0xBECB, "1108 1164 11BE"), - (0xBECC, "1108 1164 11BF"), - (0xBECD, "1108 1164 11C0"), - (0xBECE, "1108 1164 11C1"), - (0xBECF, "1108 1164 11C2"), - (0xBED0, "1108 1165"), - (0xBED1, "1108 1165 11A8"), - (0xBED2, "1108 1165 11A9"), - (0xBED3, "1108 1165 11AA"), - (0xBED4, "1108 1165 11AB"), - (0xBED5, "1108 1165 11AC"), - (0xBED6, "1108 1165 11AD"), - (0xBED7, "1108 1165 11AE"), - (0xBED8, "1108 1165 11AF"), - (0xBED9, "1108 1165 11B0"), - (0xBEDA, "1108 1165 11B1"), - (0xBEDB, "1108 1165 11B2"), - (0xBEDC, "1108 1165 11B3"), - (0xBEDD, "1108 1165 11B4"), - (0xBEDE, "1108 1165 11B5"), - (0xBEDF, "1108 1165 11B6"), - (0xBEE0, "1108 1165 11B7"), - (0xBEE1, "1108 1165 11B8"), - (0xBEE2, "1108 1165 11B9"), - (0xBEE3, "1108 1165 11BA"), - (0xBEE4, "1108 1165 11BB"), - (0xBEE5, "1108 1165 11BC"), - (0xBEE6, "1108 1165 11BD"), - (0xBEE7, "1108 1165 11BE"), - (0xBEE8, "1108 1165 11BF"), - (0xBEE9, "1108 1165 11C0"), - (0xBEEA, "1108 1165 11C1"), - (0xBEEB, "1108 1165 11C2"), - (0xBEEC, "1108 1166"), - (0xBEED, "1108 1166 11A8"), - (0xBEEE, "1108 1166 11A9"), - (0xBEEF, "1108 1166 11AA"), - (0xBEF0, "1108 1166 11AB"), - (0xBEF1, "1108 1166 11AC"), - (0xBEF2, "1108 1166 11AD"), - (0xBEF3, "1108 1166 11AE"), - (0xBEF4, "1108 1166 11AF"), - (0xBEF5, "1108 1166 11B0"), - (0xBEF6, "1108 1166 11B1"), - (0xBEF7, "1108 1166 11B2"), - (0xBEF8, "1108 1166 11B3"), - (0xBEF9, "1108 1166 11B4"), - (0xBEFA, "1108 1166 11B5"), - (0xBEFB, "1108 1166 11B6"), - (0xBEFC, "1108 1166 11B7"), - (0xBEFD, "1108 1166 11B8"), - (0xBEFE, "1108 1166 11B9"), - (0xBEFF, "1108 1166 11BA"), - (0xBF00, "1108 1166 11BB"), - (0xBF01, "1108 1166 11BC"), - (0xBF02, "1108 1166 11BD"), - (0xBF03, "1108 1166 11BE"), - (0xBF04, "1108 1166 11BF"), - (0xBF05, "1108 1166 11C0"), - (0xBF06, "1108 1166 11C1"), - (0xBF07, "1108 1166 11C2"), - (0xBF08, "1108 1167"), - (0xBF09, "1108 1167 11A8"), - (0xBF0A, "1108 1167 11A9"), - (0xBF0B, "1108 1167 11AA"), - (0xBF0C, "1108 1167 11AB"), - (0xBF0D, "1108 1167 11AC"), - (0xBF0E, "1108 1167 11AD"), - (0xBF0F, "1108 1167 11AE"), - (0xBF10, "1108 1167 11AF"), - (0xBF11, "1108 1167 11B0"), - (0xBF12, "1108 1167 11B1"), - (0xBF13, "1108 1167 11B2"), - (0xBF14, "1108 1167 11B3"), - (0xBF15, "1108 1167 11B4"), - (0xBF16, "1108 1167 11B5"), - (0xBF17, "1108 1167 11B6"), - (0xBF18, "1108 1167 11B7"), - (0xBF19, "1108 1167 11B8"), - (0xBF1A, "1108 1167 11B9"), - (0xBF1B, "1108 1167 11BA"), - (0xBF1C, "1108 1167 11BB"), - (0xBF1D, "1108 1167 11BC"), - (0xBF1E, "1108 1167 11BD"), - (0xBF1F, "1108 1167 11BE"), - (0xBF20, "1108 1167 11BF"), - (0xBF21, "1108 1167 11C0"), - (0xBF22, "1108 1167 11C1"), - (0xBF23, "1108 1167 11C2"), - (0xBF24, "1108 1168"), - (0xBF25, "1108 1168 11A8"), - (0xBF26, "1108 1168 11A9"), - (0xBF27, "1108 1168 11AA"), - (0xBF28, "1108 1168 11AB"), - (0xBF29, "1108 1168 11AC"), - (0xBF2A, "1108 1168 11AD"), - (0xBF2B, "1108 1168 11AE"), - (0xBF2C, "1108 1168 11AF"), - (0xBF2D, "1108 1168 11B0"), - (0xBF2E, "1108 1168 11B1"), - (0xBF2F, "1108 1168 11B2"), - (0xBF30, "1108 1168 11B3"), - (0xBF31, "1108 1168 11B4"), - (0xBF32, "1108 1168 11B5"), - (0xBF33, "1108 1168 11B6"), - (0xBF34, "1108 1168 11B7"), - (0xBF35, "1108 1168 11B8"), - (0xBF36, "1108 1168 11B9"), - (0xBF37, "1108 1168 11BA"), - (0xBF38, "1108 1168 11BB"), - (0xBF39, "1108 1168 11BC"), - (0xBF3A, "1108 1168 11BD"), - (0xBF3B, "1108 1168 11BE"), - (0xBF3C, "1108 1168 11BF"), - (0xBF3D, "1108 1168 11C0"), - (0xBF3E, "1108 1168 11C1"), - (0xBF3F, "1108 1168 11C2"), - (0xBF40, "1108 1169"), - (0xBF41, "1108 1169 11A8"), - (0xBF42, "1108 1169 11A9"), - (0xBF43, "1108 1169 11AA"), - (0xBF44, "1108 1169 11AB"), - (0xBF45, "1108 1169 11AC"), - (0xBF46, "1108 1169 11AD"), - (0xBF47, "1108 1169 11AE"), - (0xBF48, "1108 1169 11AF"), - (0xBF49, "1108 1169 11B0"), - (0xBF4A, "1108 1169 11B1"), - (0xBF4B, "1108 1169 11B2"), - (0xBF4C, "1108 1169 11B3"), - (0xBF4D, "1108 1169 11B4"), - (0xBF4E, "1108 1169 11B5"), - (0xBF4F, "1108 1169 11B6"), - (0xBF50, "1108 1169 11B7"), - (0xBF51, "1108 1169 11B8"), - (0xBF52, "1108 1169 11B9"), - (0xBF53, "1108 1169 11BA"), - (0xBF54, "1108 1169 11BB"), - (0xBF55, "1108 1169 11BC"), - (0xBF56, "1108 1169 11BD"), - (0xBF57, "1108 1169 11BE"), - (0xBF58, "1108 1169 11BF"), - (0xBF59, "1108 1169 11C0"), - (0xBF5A, "1108 1169 11C1"), - (0xBF5B, "1108 1169 11C2"), - (0xBF5C, "1108 116A"), - (0xBF5D, "1108 116A 11A8"), - (0xBF5E, "1108 116A 11A9"), - (0xBF5F, "1108 116A 11AA"), - (0xBF60, "1108 116A 11AB"), - (0xBF61, "1108 116A 11AC"), - (0xBF62, "1108 116A 11AD"), - (0xBF63, "1108 116A 11AE"), - (0xBF64, "1108 116A 11AF"), - (0xBF65, "1108 116A 11B0"), - (0xBF66, "1108 116A 11B1"), - (0xBF67, "1108 116A 11B2"), - (0xBF68, "1108 116A 11B3"), - (0xBF69, "1108 116A 11B4"), - (0xBF6A, "1108 116A 11B5"), - (0xBF6B, "1108 116A 11B6"), - (0xBF6C, "1108 116A 11B7"), - (0xBF6D, "1108 116A 11B8"), - (0xBF6E, "1108 116A 11B9"), - (0xBF6F, "1108 116A 11BA"), - (0xBF70, "1108 116A 11BB"), - (0xBF71, "1108 116A 11BC"), - (0xBF72, "1108 116A 11BD"), - (0xBF73, "1108 116A 11BE"), - (0xBF74, "1108 116A 11BF"), - (0xBF75, "1108 116A 11C0"), - (0xBF76, "1108 116A 11C1"), - (0xBF77, "1108 116A 11C2"), - (0xBF78, "1108 116B"), - (0xBF79, "1108 116B 11A8"), - (0xBF7A, "1108 116B 11A9"), - (0xBF7B, "1108 116B 11AA"), - (0xBF7C, "1108 116B 11AB"), - (0xBF7D, "1108 116B 11AC"), - (0xBF7E, "1108 116B 11AD"), - (0xBF7F, "1108 116B 11AE"), - (0xBF80, "1108 116B 11AF"), - (0xBF81, "1108 116B 11B0"), - (0xBF82, "1108 116B 11B1"), - (0xBF83, "1108 116B 11B2"), - (0xBF84, "1108 116B 11B3"), - (0xBF85, "1108 116B 11B4"), - (0xBF86, "1108 116B 11B5"), - (0xBF87, "1108 116B 11B6"), - (0xBF88, "1108 116B 11B7"), - (0xBF89, "1108 116B 11B8"), - (0xBF8A, "1108 116B 11B9"), - (0xBF8B, "1108 116B 11BA"), - (0xBF8C, "1108 116B 11BB"), - (0xBF8D, "1108 116B 11BC"), - (0xBF8E, "1108 116B 11BD"), - (0xBF8F, "1108 116B 11BE"), - (0xBF90, "1108 116B 11BF"), - (0xBF91, "1108 116B 11C0"), - (0xBF92, "1108 116B 11C1"), - (0xBF93, "1108 116B 11C2"), - (0xBF94, "1108 116C"), - (0xBF95, "1108 116C 11A8"), - (0xBF96, "1108 116C 11A9"), - (0xBF97, "1108 116C 11AA"), - (0xBF98, "1108 116C 11AB"), - (0xBF99, "1108 116C 11AC"), - (0xBF9A, "1108 116C 11AD"), - (0xBF9B, "1108 116C 11AE"), - (0xBF9C, "1108 116C 11AF"), - (0xBF9D, "1108 116C 11B0"), - (0xBF9E, "1108 116C 11B1"), - (0xBF9F, "1108 116C 11B2"), - (0xBFA0, "1108 116C 11B3"), - (0xBFA1, "1108 116C 11B4"), - (0xBFA2, "1108 116C 11B5"), - (0xBFA3, "1108 116C 11B6"), - (0xBFA4, "1108 116C 11B7"), - (0xBFA5, "1108 116C 11B8"), - (0xBFA6, "1108 116C 11B9"), - (0xBFA7, "1108 116C 11BA"), - (0xBFA8, "1108 116C 11BB"), - (0xBFA9, "1108 116C 11BC"), - (0xBFAA, "1108 116C 11BD"), - (0xBFAB, "1108 116C 11BE"), - (0xBFAC, "1108 116C 11BF"), - (0xBFAD, "1108 116C 11C0"), - (0xBFAE, "1108 116C 11C1"), - (0xBFAF, "1108 116C 11C2"), - (0xBFB0, "1108 116D"), - (0xBFB1, "1108 116D 11A8"), - (0xBFB2, "1108 116D 11A9"), - (0xBFB3, "1108 116D 11AA"), - (0xBFB4, "1108 116D 11AB"), - (0xBFB5, "1108 116D 11AC"), - (0xBFB6, "1108 116D 11AD"), - (0xBFB7, "1108 116D 11AE"), - (0xBFB8, "1108 116D 11AF"), - (0xBFB9, "1108 116D 11B0"), - (0xBFBA, "1108 116D 11B1"), - (0xBFBB, "1108 116D 11B2"), - (0xBFBC, "1108 116D 11B3"), - (0xBFBD, "1108 116D 11B4"), - (0xBFBE, "1108 116D 11B5"), - (0xBFBF, "1108 116D 11B6"), - (0xBFC0, "1108 116D 11B7"), - (0xBFC1, "1108 116D 11B8"), - (0xBFC2, "1108 116D 11B9"), - (0xBFC3, "1108 116D 11BA"), - (0xBFC4, "1108 116D 11BB"), - (0xBFC5, "1108 116D 11BC"), - (0xBFC6, "1108 116D 11BD"), - (0xBFC7, "1108 116D 11BE"), - (0xBFC8, "1108 116D 11BF"), - (0xBFC9, "1108 116D 11C0"), - (0xBFCA, "1108 116D 11C1"), - (0xBFCB, "1108 116D 11C2"), - (0xBFCC, "1108 116E"), - (0xBFCD, "1108 116E 11A8"), - (0xBFCE, "1108 116E 11A9"), - (0xBFCF, "1108 116E 11AA"), - (0xBFD0, "1108 116E 11AB"), - (0xBFD1, "1108 116E 11AC"), - (0xBFD2, "1108 116E 11AD"), - (0xBFD3, "1108 116E 11AE"), - (0xBFD4, "1108 116E 11AF"), - (0xBFD5, "1108 116E 11B0"), - (0xBFD6, "1108 116E 11B1"), - (0xBFD7, "1108 116E 11B2"), - (0xBFD8, "1108 116E 11B3"), - (0xBFD9, "1108 116E 11B4"), - (0xBFDA, "1108 116E 11B5"), - (0xBFDB, "1108 116E 11B6"), - (0xBFDC, "1108 116E 11B7"), - (0xBFDD, "1108 116E 11B8"), - (0xBFDE, "1108 116E 11B9"), - (0xBFDF, "1108 116E 11BA"), - (0xBFE0, "1108 116E 11BB"), - (0xBFE1, "1108 116E 11BC"), - (0xBFE2, "1108 116E 11BD"), - (0xBFE3, "1108 116E 11BE"), - (0xBFE4, "1108 116E 11BF"), - (0xBFE5, "1108 116E 11C0"), - (0xBFE6, "1108 116E 11C1"), - (0xBFE7, "1108 116E 11C2"), - (0xBFE8, "1108 116F"), - (0xBFE9, "1108 116F 11A8"), - (0xBFEA, "1108 116F 11A9"), - (0xBFEB, "1108 116F 11AA"), - (0xBFEC, "1108 116F 11AB"), - (0xBFED, "1108 116F 11AC"), - (0xBFEE, "1108 116F 11AD"), - (0xBFEF, "1108 116F 11AE"), - (0xBFF0, "1108 116F 11AF"), - (0xBFF1, "1108 116F 11B0"), - (0xBFF2, "1108 116F 11B1"), - (0xBFF3, "1108 116F 11B2"), - (0xBFF4, "1108 116F 11B3"), - (0xBFF5, "1108 116F 11B4"), - (0xBFF6, "1108 116F 11B5"), - (0xBFF7, "1108 116F 11B6"), - (0xBFF8, "1108 116F 11B7"), - (0xBFF9, "1108 116F 11B8"), - (0xBFFA, "1108 116F 11B9"), - (0xBFFB, "1108 116F 11BA"), - (0xBFFC, "1108 116F 11BB"), - (0xBFFD, "1108 116F 11BC"), - (0xBFFE, "1108 116F 11BD"), - (0xBFFF, "1108 116F 11BE"), - (0xC000, "1108 116F 11BF"), - (0xC001, "1108 116F 11C0"), - (0xC002, "1108 116F 11C1"), - (0xC003, "1108 116F 11C2"), - (0xC004, "1108 1170"), - (0xC005, "1108 1170 11A8"), - (0xC006, "1108 1170 11A9"), - (0xC007, "1108 1170 11AA"), - (0xC008, "1108 1170 11AB"), - (0xC009, "1108 1170 11AC"), - (0xC00A, "1108 1170 11AD"), - (0xC00B, "1108 1170 11AE"), - (0xC00C, "1108 1170 11AF"), - (0xC00D, "1108 1170 11B0"), - (0xC00E, "1108 1170 11B1"), - (0xC00F, "1108 1170 11B2"), - (0xC010, "1108 1170 11B3"), - (0xC011, "1108 1170 11B4"), - (0xC012, "1108 1170 11B5"), - (0xC013, "1108 1170 11B6"), - (0xC014, "1108 1170 11B7"), - (0xC015, "1108 1170 11B8"), - (0xC016, "1108 1170 11B9"), - (0xC017, "1108 1170 11BA"), - (0xC018, "1108 1170 11BB"), - (0xC019, "1108 1170 11BC"), - (0xC01A, "1108 1170 11BD"), - (0xC01B, "1108 1170 11BE"), - (0xC01C, "1108 1170 11BF"), - (0xC01D, "1108 1170 11C0"), - (0xC01E, "1108 1170 11C1"), - (0xC01F, "1108 1170 11C2"), - (0xC020, "1108 1171"), - (0xC021, "1108 1171 11A8"), - (0xC022, "1108 1171 11A9"), - (0xC023, "1108 1171 11AA"), - (0xC024, "1108 1171 11AB"), - (0xC025, "1108 1171 11AC"), - (0xC026, "1108 1171 11AD"), - (0xC027, "1108 1171 11AE"), - (0xC028, "1108 1171 11AF"), - (0xC029, "1108 1171 11B0"), - (0xC02A, "1108 1171 11B1"), - (0xC02B, "1108 1171 11B2"), - (0xC02C, "1108 1171 11B3"), - (0xC02D, "1108 1171 11B4"), - (0xC02E, "1108 1171 11B5"), - (0xC02F, "1108 1171 11B6"), - (0xC030, "1108 1171 11B7"), - (0xC031, "1108 1171 11B8"), - (0xC032, "1108 1171 11B9"), - (0xC033, "1108 1171 11BA"), - (0xC034, "1108 1171 11BB"), - (0xC035, "1108 1171 11BC"), - (0xC036, "1108 1171 11BD"), - (0xC037, "1108 1171 11BE"), - (0xC038, "1108 1171 11BF"), - (0xC039, "1108 1171 11C0"), - (0xC03A, "1108 1171 11C1"), - (0xC03B, "1108 1171 11C2"), - (0xC03C, "1108 1172"), - (0xC03D, "1108 1172 11A8"), - (0xC03E, "1108 1172 11A9"), - (0xC03F, "1108 1172 11AA"), - (0xC040, "1108 1172 11AB"), - (0xC041, "1108 1172 11AC"), - (0xC042, "1108 1172 11AD"), - (0xC043, "1108 1172 11AE"), - (0xC044, "1108 1172 11AF"), - (0xC045, "1108 1172 11B0"), - (0xC046, "1108 1172 11B1"), - (0xC047, "1108 1172 11B2"), - (0xC048, "1108 1172 11B3"), - (0xC049, "1108 1172 11B4"), - (0xC04A, "1108 1172 11B5"), - (0xC04B, "1108 1172 11B6"), - (0xC04C, "1108 1172 11B7"), - (0xC04D, "1108 1172 11B8"), - (0xC04E, "1108 1172 11B9"), - (0xC04F, "1108 1172 11BA"), - (0xC050, "1108 1172 11BB"), - (0xC051, "1108 1172 11BC"), - (0xC052, "1108 1172 11BD"), - (0xC053, "1108 1172 11BE"), - (0xC054, "1108 1172 11BF"), - (0xC055, "1108 1172 11C0"), - (0xC056, "1108 1172 11C1"), - (0xC057, "1108 1172 11C2"), - (0xC058, "1108 1173"), - (0xC059, "1108 1173 11A8"), - (0xC05A, "1108 1173 11A9"), - (0xC05B, "1108 1173 11AA"), - (0xC05C, "1108 1173 11AB"), - (0xC05D, "1108 1173 11AC"), - (0xC05E, "1108 1173 11AD"), - (0xC05F, "1108 1173 11AE"), - (0xC060, "1108 1173 11AF"), - (0xC061, "1108 1173 11B0"), - (0xC062, "1108 1173 11B1"), - (0xC063, "1108 1173 11B2"), - (0xC064, "1108 1173 11B3"), - (0xC065, "1108 1173 11B4"), - (0xC066, "1108 1173 11B5"), - (0xC067, "1108 1173 11B6"), - (0xC068, "1108 1173 11B7"), - (0xC069, "1108 1173 11B8"), - (0xC06A, "1108 1173 11B9"), - (0xC06B, "1108 1173 11BA"), - (0xC06C, "1108 1173 11BB"), - (0xC06D, "1108 1173 11BC"), - (0xC06E, "1108 1173 11BD"), - (0xC06F, "1108 1173 11BE"), - (0xC070, "1108 1173 11BF"), - (0xC071, "1108 1173 11C0"), - (0xC072, "1108 1173 11C1"), - (0xC073, "1108 1173 11C2"), - (0xC074, "1108 1174"), - (0xC075, "1108 1174 11A8"), - (0xC076, "1108 1174 11A9"), - (0xC077, "1108 1174 11AA"), - (0xC078, "1108 1174 11AB"), - (0xC079, "1108 1174 11AC"), - (0xC07A, "1108 1174 11AD"), - (0xC07B, "1108 1174 11AE"), - (0xC07C, "1108 1174 11AF"), - (0xC07D, "1108 1174 11B0"), - (0xC07E, "1108 1174 11B1"), - (0xC07F, "1108 1174 11B2"), - (0xC080, "1108 1174 11B3"), - (0xC081, "1108 1174 11B4"), - (0xC082, "1108 1174 11B5"), - (0xC083, "1108 1174 11B6"), - (0xC084, "1108 1174 11B7"), - (0xC085, "1108 1174 11B8"), - (0xC086, "1108 1174 11B9"), - (0xC087, "1108 1174 11BA"), - (0xC088, "1108 1174 11BB"), - (0xC089, "1108 1174 11BC"), - (0xC08A, "1108 1174 11BD"), - (0xC08B, "1108 1174 11BE"), - (0xC08C, "1108 1174 11BF"), - (0xC08D, "1108 1174 11C0"), - (0xC08E, "1108 1174 11C1"), - (0xC08F, "1108 1174 11C2"), - (0xC090, "1108 1175"), - (0xC091, "1108 1175 11A8"), - (0xC092, "1108 1175 11A9"), - (0xC093, "1108 1175 11AA"), - (0xC094, "1108 1175 11AB"), - (0xC095, "1108 1175 11AC"), - (0xC096, "1108 1175 11AD"), - (0xC097, "1108 1175 11AE"), - (0xC098, "1108 1175 11AF"), - (0xC099, "1108 1175 11B0"), - (0xC09A, "1108 1175 11B1"), - (0xC09B, "1108 1175 11B2"), - (0xC09C, "1108 1175 11B3"), - (0xC09D, "1108 1175 11B4"), - (0xC09E, "1108 1175 11B5"), - (0xC09F, "1108 1175 11B6"), - (0xC0A0, "1108 1175 11B7"), - (0xC0A1, "1108 1175 11B8"), - (0xC0A2, "1108 1175 11B9"), - (0xC0A3, "1108 1175 11BA"), - (0xC0A4, "1108 1175 11BB"), - (0xC0A5, "1108 1175 11BC"), - (0xC0A6, "1108 1175 11BD"), - (0xC0A7, "1108 1175 11BE"), - (0xC0A8, "1108 1175 11BF"), - (0xC0A9, "1108 1175 11C0"), - (0xC0AA, "1108 1175 11C1"), - (0xC0AB, "1108 1175 11C2"), - (0xC0AC, "1109 1161"), - (0xC0AD, "1109 1161 11A8"), - (0xC0AE, "1109 1161 11A9"), - (0xC0AF, "1109 1161 11AA"), - (0xC0B0, "1109 1161 11AB"), - (0xC0B1, "1109 1161 11AC"), - (0xC0B2, "1109 1161 11AD"), - (0xC0B3, "1109 1161 11AE"), - (0xC0B4, "1109 1161 11AF"), - (0xC0B5, "1109 1161 11B0"), - (0xC0B6, "1109 1161 11B1"), - (0xC0B7, "1109 1161 11B2"), - (0xC0B8, "1109 1161 11B3"), - (0xC0B9, "1109 1161 11B4"), - (0xC0BA, "1109 1161 11B5"), - (0xC0BB, "1109 1161 11B6"), - (0xC0BC, "1109 1161 11B7"), - (0xC0BD, "1109 1161 11B8"), - (0xC0BE, "1109 1161 11B9"), - (0xC0BF, "1109 1161 11BA"), - (0xC0C0, "1109 1161 11BB"), - (0xC0C1, "1109 1161 11BC"), - (0xC0C2, "1109 1161 11BD"), - (0xC0C3, "1109 1161 11BE"), - (0xC0C4, "1109 1161 11BF"), - (0xC0C5, "1109 1161 11C0"), - (0xC0C6, "1109 1161 11C1"), - (0xC0C7, "1109 1161 11C2"), - (0xC0C8, "1109 1162"), - (0xC0C9, "1109 1162 11A8"), - (0xC0CA, "1109 1162 11A9"), - (0xC0CB, "1109 1162 11AA"), - (0xC0CC, "1109 1162 11AB"), - (0xC0CD, "1109 1162 11AC"), - (0xC0CE, "1109 1162 11AD"), - (0xC0CF, "1109 1162 11AE"), - (0xC0D0, "1109 1162 11AF"), - (0xC0D1, "1109 1162 11B0"), - (0xC0D2, "1109 1162 11B1"), - (0xC0D3, "1109 1162 11B2"), - (0xC0D4, "1109 1162 11B3"), - (0xC0D5, "1109 1162 11B4"), - (0xC0D6, "1109 1162 11B5"), - (0xC0D7, "1109 1162 11B6"), - (0xC0D8, "1109 1162 11B7"), - (0xC0D9, "1109 1162 11B8"), - (0xC0DA, "1109 1162 11B9"), - (0xC0DB, "1109 1162 11BA"), - (0xC0DC, "1109 1162 11BB"), - (0xC0DD, "1109 1162 11BC"), - (0xC0DE, "1109 1162 11BD"), - (0xC0DF, "1109 1162 11BE"), - (0xC0E0, "1109 1162 11BF"), - (0xC0E1, "1109 1162 11C0"), - (0xC0E2, "1109 1162 11C1"), - (0xC0E3, "1109 1162 11C2"), - (0xC0E4, "1109 1163"), - (0xC0E5, "1109 1163 11A8"), - (0xC0E6, "1109 1163 11A9"), - (0xC0E7, "1109 1163 11AA"), - (0xC0E8, "1109 1163 11AB"), - (0xC0E9, "1109 1163 11AC"), - (0xC0EA, "1109 1163 11AD"), - (0xC0EB, "1109 1163 11AE"), - (0xC0EC, "1109 1163 11AF"), - (0xC0ED, "1109 1163 11B0"), - (0xC0EE, "1109 1163 11B1"), - (0xC0EF, "1109 1163 11B2"), - (0xC0F0, "1109 1163 11B3"), - (0xC0F1, "1109 1163 11B4"), - (0xC0F2, "1109 1163 11B5"), - (0xC0F3, "1109 1163 11B6"), - (0xC0F4, "1109 1163 11B7"), - (0xC0F5, "1109 1163 11B8"), - (0xC0F6, "1109 1163 11B9"), - (0xC0F7, "1109 1163 11BA"), - (0xC0F8, "1109 1163 11BB"), - (0xC0F9, "1109 1163 11BC"), - (0xC0FA, "1109 1163 11BD"), - (0xC0FB, "1109 1163 11BE"), - (0xC0FC, "1109 1163 11BF"), - (0xC0FD, "1109 1163 11C0"), - (0xC0FE, "1109 1163 11C1"), - (0xC0FF, "1109 1163 11C2"), - (0xC100, "1109 1164"), - (0xC101, "1109 1164 11A8"), - (0xC102, "1109 1164 11A9"), - (0xC103, "1109 1164 11AA"), - (0xC104, "1109 1164 11AB"), - (0xC105, "1109 1164 11AC"), - (0xC106, "1109 1164 11AD"), - (0xC107, "1109 1164 11AE"), - (0xC108, "1109 1164 11AF"), - (0xC109, "1109 1164 11B0"), - (0xC10A, "1109 1164 11B1"), - (0xC10B, "1109 1164 11B2"), - (0xC10C, "1109 1164 11B3"), - (0xC10D, "1109 1164 11B4"), - (0xC10E, "1109 1164 11B5"), - (0xC10F, "1109 1164 11B6"), - (0xC110, "1109 1164 11B7"), - (0xC111, "1109 1164 11B8"), - (0xC112, "1109 1164 11B9"), - (0xC113, "1109 1164 11BA"), - (0xC114, "1109 1164 11BB"), - (0xC115, "1109 1164 11BC"), - (0xC116, "1109 1164 11BD"), - (0xC117, "1109 1164 11BE"), - (0xC118, "1109 1164 11BF"), - (0xC119, "1109 1164 11C0"), - (0xC11A, "1109 1164 11C1"), - (0xC11B, "1109 1164 11C2"), - (0xC11C, "1109 1165"), - (0xC11D, "1109 1165 11A8"), - (0xC11E, "1109 1165 11A9"), - (0xC11F, "1109 1165 11AA"), - (0xC120, "1109 1165 11AB"), - (0xC121, "1109 1165 11AC"), - (0xC122, "1109 1165 11AD"), - (0xC123, "1109 1165 11AE"), - (0xC124, "1109 1165 11AF"), - (0xC125, "1109 1165 11B0"), - (0xC126, "1109 1165 11B1"), - (0xC127, "1109 1165 11B2"), - (0xC128, "1109 1165 11B3"), - (0xC129, "1109 1165 11B4"), - (0xC12A, "1109 1165 11B5"), - (0xC12B, "1109 1165 11B6"), - (0xC12C, "1109 1165 11B7"), - (0xC12D, "1109 1165 11B8"), - (0xC12E, "1109 1165 11B9"), - (0xC12F, "1109 1165 11BA"), - (0xC130, "1109 1165 11BB"), - (0xC131, "1109 1165 11BC"), - (0xC132, "1109 1165 11BD"), - (0xC133, "1109 1165 11BE"), - (0xC134, "1109 1165 11BF"), - (0xC135, "1109 1165 11C0"), - (0xC136, "1109 1165 11C1"), - (0xC137, "1109 1165 11C2"), - (0xC138, "1109 1166"), - (0xC139, "1109 1166 11A8"), - (0xC13A, "1109 1166 11A9"), - (0xC13B, "1109 1166 11AA"), - (0xC13C, "1109 1166 11AB"), - (0xC13D, "1109 1166 11AC"), - (0xC13E, "1109 1166 11AD"), - (0xC13F, "1109 1166 11AE"), - (0xC140, "1109 1166 11AF"), - (0xC141, "1109 1166 11B0"), - (0xC142, "1109 1166 11B1"), - (0xC143, "1109 1166 11B2"), - (0xC144, "1109 1166 11B3"), - (0xC145, "1109 1166 11B4"), - (0xC146, "1109 1166 11B5"), - (0xC147, "1109 1166 11B6"), - (0xC148, "1109 1166 11B7"), - (0xC149, "1109 1166 11B8"), - (0xC14A, "1109 1166 11B9"), - (0xC14B, "1109 1166 11BA"), - (0xC14C, "1109 1166 11BB"), - (0xC14D, "1109 1166 11BC"), - (0xC14E, "1109 1166 11BD"), - (0xC14F, "1109 1166 11BE"), - (0xC150, "1109 1166 11BF"), - (0xC151, "1109 1166 11C0"), - (0xC152, "1109 1166 11C1"), - (0xC153, "1109 1166 11C2"), - (0xC154, "1109 1167"), - (0xC155, "1109 1167 11A8"), - (0xC156, "1109 1167 11A9"), - (0xC157, "1109 1167 11AA"), - (0xC158, "1109 1167 11AB"), - (0xC159, "1109 1167 11AC"), - (0xC15A, "1109 1167 11AD"), - (0xC15B, "1109 1167 11AE"), - (0xC15C, "1109 1167 11AF"), - (0xC15D, "1109 1167 11B0"), - (0xC15E, "1109 1167 11B1"), - (0xC15F, "1109 1167 11B2"), - (0xC160, "1109 1167 11B3"), - (0xC161, "1109 1167 11B4"), - (0xC162, "1109 1167 11B5"), - (0xC163, "1109 1167 11B6"), - (0xC164, "1109 1167 11B7"), - (0xC165, "1109 1167 11B8"), - (0xC166, "1109 1167 11B9"), - (0xC167, "1109 1167 11BA"), - (0xC168, "1109 1167 11BB"), - (0xC169, "1109 1167 11BC"), - (0xC16A, "1109 1167 11BD"), - (0xC16B, "1109 1167 11BE"), - (0xC16C, "1109 1167 11BF"), - (0xC16D, "1109 1167 11C0"), - (0xC16E, "1109 1167 11C1"), - (0xC16F, "1109 1167 11C2"), - (0xC170, "1109 1168"), - (0xC171, "1109 1168 11A8"), - (0xC172, "1109 1168 11A9"), - (0xC173, "1109 1168 11AA"), - (0xC174, "1109 1168 11AB"), - (0xC175, "1109 1168 11AC"), - (0xC176, "1109 1168 11AD"), - (0xC177, "1109 1168 11AE"), - (0xC178, "1109 1168 11AF"), - (0xC179, "1109 1168 11B0"), - (0xC17A, "1109 1168 11B1"), - (0xC17B, "1109 1168 11B2"), - (0xC17C, "1109 1168 11B3"), - (0xC17D, "1109 1168 11B4"), - (0xC17E, "1109 1168 11B5"), - (0xC17F, "1109 1168 11B6"), - (0xC180, "1109 1168 11B7"), - (0xC181, "1109 1168 11B8"), - (0xC182, "1109 1168 11B9"), - (0xC183, "1109 1168 11BA"), - (0xC184, "1109 1168 11BB"), - (0xC185, "1109 1168 11BC"), - (0xC186, "1109 1168 11BD"), - (0xC187, "1109 1168 11BE"), - (0xC188, "1109 1168 11BF"), - (0xC189, "1109 1168 11C0"), - (0xC18A, "1109 1168 11C1"), - (0xC18B, "1109 1168 11C2"), - (0xC18C, "1109 1169"), - (0xC18D, "1109 1169 11A8"), - (0xC18E, "1109 1169 11A9"), - (0xC18F, "1109 1169 11AA"), - (0xC190, "1109 1169 11AB"), - (0xC191, "1109 1169 11AC"), - (0xC192, "1109 1169 11AD"), - (0xC193, "1109 1169 11AE"), - (0xC194, "1109 1169 11AF"), - (0xC195, "1109 1169 11B0"), - (0xC196, "1109 1169 11B1"), - (0xC197, "1109 1169 11B2"), - (0xC198, "1109 1169 11B3"), - (0xC199, "1109 1169 11B4"), - (0xC19A, "1109 1169 11B5"), - (0xC19B, "1109 1169 11B6"), - (0xC19C, "1109 1169 11B7"), - (0xC19D, "1109 1169 11B8"), - (0xC19E, "1109 1169 11B9"), - (0xC19F, "1109 1169 11BA"), - (0xC1A0, "1109 1169 11BB"), - (0xC1A1, "1109 1169 11BC"), - (0xC1A2, "1109 1169 11BD"), - (0xC1A3, "1109 1169 11BE"), - (0xC1A4, "1109 1169 11BF"), - (0xC1A5, "1109 1169 11C0"), - (0xC1A6, "1109 1169 11C1"), - (0xC1A7, "1109 1169 11C2"), - (0xC1A8, "1109 116A"), - (0xC1A9, "1109 116A 11A8"), - (0xC1AA, "1109 116A 11A9"), - (0xC1AB, "1109 116A 11AA"), - (0xC1AC, "1109 116A 11AB"), - (0xC1AD, "1109 116A 11AC"), - (0xC1AE, "1109 116A 11AD"), - (0xC1AF, "1109 116A 11AE"), - (0xC1B0, "1109 116A 11AF"), - (0xC1B1, "1109 116A 11B0"), - (0xC1B2, "1109 116A 11B1"), - (0xC1B3, "1109 116A 11B2"), - (0xC1B4, "1109 116A 11B3"), - (0xC1B5, "1109 116A 11B4"), - (0xC1B6, "1109 116A 11B5"), - (0xC1B7, "1109 116A 11B6"), - (0xC1B8, "1109 116A 11B7"), - (0xC1B9, "1109 116A 11B8"), - (0xC1BA, "1109 116A 11B9"), - (0xC1BB, "1109 116A 11BA"), - (0xC1BC, "1109 116A 11BB"), - (0xC1BD, "1109 116A 11BC"), - (0xC1BE, "1109 116A 11BD"), - (0xC1BF, "1109 116A 11BE"), - (0xC1C0, "1109 116A 11BF"), - (0xC1C1, "1109 116A 11C0"), - (0xC1C2, "1109 116A 11C1"), - (0xC1C3, "1109 116A 11C2"), - (0xC1C4, "1109 116B"), - (0xC1C5, "1109 116B 11A8"), - (0xC1C6, "1109 116B 11A9"), - (0xC1C7, "1109 116B 11AA"), - (0xC1C8, "1109 116B 11AB"), - (0xC1C9, "1109 116B 11AC"), - (0xC1CA, "1109 116B 11AD"), - (0xC1CB, "1109 116B 11AE"), - (0xC1CC, "1109 116B 11AF"), - (0xC1CD, "1109 116B 11B0"), - (0xC1CE, "1109 116B 11B1"), - (0xC1CF, "1109 116B 11B2"), - (0xC1D0, "1109 116B 11B3"), - (0xC1D1, "1109 116B 11B4"), - (0xC1D2, "1109 116B 11B5"), - (0xC1D3, "1109 116B 11B6"), - (0xC1D4, "1109 116B 11B7"), - (0xC1D5, "1109 116B 11B8"), - (0xC1D6, "1109 116B 11B9"), - (0xC1D7, "1109 116B 11BA"), - (0xC1D8, "1109 116B 11BB"), - (0xC1D9, "1109 116B 11BC"), - (0xC1DA, "1109 116B 11BD"), - (0xC1DB, "1109 116B 11BE"), - (0xC1DC, "1109 116B 11BF"), - (0xC1DD, "1109 116B 11C0"), - (0xC1DE, "1109 116B 11C1"), - (0xC1DF, "1109 116B 11C2"), - (0xC1E0, "1109 116C"), - (0xC1E1, "1109 116C 11A8"), - (0xC1E2, "1109 116C 11A9"), - (0xC1E3, "1109 116C 11AA"), - (0xC1E4, "1109 116C 11AB"), - (0xC1E5, "1109 116C 11AC"), - (0xC1E6, "1109 116C 11AD"), - (0xC1E7, "1109 116C 11AE"), - (0xC1E8, "1109 116C 11AF"), - (0xC1E9, "1109 116C 11B0"), - (0xC1EA, "1109 116C 11B1"), - (0xC1EB, "1109 116C 11B2"), - (0xC1EC, "1109 116C 11B3"), - (0xC1ED, "1109 116C 11B4"), - (0xC1EE, "1109 116C 11B5"), - (0xC1EF, "1109 116C 11B6"), - (0xC1F0, "1109 116C 11B7"), - (0xC1F1, "1109 116C 11B8"), - (0xC1F2, "1109 116C 11B9"), - (0xC1F3, "1109 116C 11BA"), - (0xC1F4, "1109 116C 11BB"), - (0xC1F5, "1109 116C 11BC"), - (0xC1F6, "1109 116C 11BD"), - (0xC1F7, "1109 116C 11BE"), - (0xC1F8, "1109 116C 11BF"), - (0xC1F9, "1109 116C 11C0"), - (0xC1FA, "1109 116C 11C1"), - (0xC1FB, "1109 116C 11C2"), - (0xC1FC, "1109 116D"), - (0xC1FD, "1109 116D 11A8"), - (0xC1FE, "1109 116D 11A9"), - (0xC1FF, "1109 116D 11AA"), - (0xC200, "1109 116D 11AB"), - (0xC201, "1109 116D 11AC"), - (0xC202, "1109 116D 11AD"), - (0xC203, "1109 116D 11AE"), - (0xC204, "1109 116D 11AF"), - (0xC205, "1109 116D 11B0"), - (0xC206, "1109 116D 11B1"), - (0xC207, "1109 116D 11B2"), - (0xC208, "1109 116D 11B3"), - (0xC209, "1109 116D 11B4"), - (0xC20A, "1109 116D 11B5"), - (0xC20B, "1109 116D 11B6"), - (0xC20C, "1109 116D 11B7"), - (0xC20D, "1109 116D 11B8"), - (0xC20E, "1109 116D 11B9"), - (0xC20F, "1109 116D 11BA"), - (0xC210, "1109 116D 11BB"), - (0xC211, "1109 116D 11BC"), - (0xC212, "1109 116D 11BD"), - (0xC213, "1109 116D 11BE"), - (0xC214, "1109 116D 11BF"), - (0xC215, "1109 116D 11C0"), - (0xC216, "1109 116D 11C1"), - (0xC217, "1109 116D 11C2"), - (0xC218, "1109 116E"), - (0xC219, "1109 116E 11A8"), - (0xC21A, "1109 116E 11A9"), - (0xC21B, "1109 116E 11AA"), - (0xC21C, "1109 116E 11AB"), - (0xC21D, "1109 116E 11AC"), - (0xC21E, "1109 116E 11AD"), - (0xC21F, "1109 116E 11AE"), - (0xC220, "1109 116E 11AF"), - (0xC221, "1109 116E 11B0"), - (0xC222, "1109 116E 11B1"), - (0xC223, "1109 116E 11B2"), - (0xC224, "1109 116E 11B3"), - (0xC225, "1109 116E 11B4"), - (0xC226, "1109 116E 11B5"), - (0xC227, "1109 116E 11B6"), - (0xC228, "1109 116E 11B7"), - (0xC229, "1109 116E 11B8"), - (0xC22A, "1109 116E 11B9"), - (0xC22B, "1109 116E 11BA"), - (0xC22C, "1109 116E 11BB"), - (0xC22D, "1109 116E 11BC"), - (0xC22E, "1109 116E 11BD"), - (0xC22F, "1109 116E 11BE"), - (0xC230, "1109 116E 11BF"), - (0xC231, "1109 116E 11C0"), - (0xC232, "1109 116E 11C1"), - (0xC233, "1109 116E 11C2"), - (0xC234, "1109 116F"), - (0xC235, "1109 116F 11A8"), - (0xC236, "1109 116F 11A9"), - (0xC237, "1109 116F 11AA"), - (0xC238, "1109 116F 11AB"), - (0xC239, "1109 116F 11AC"), - (0xC23A, "1109 116F 11AD"), - (0xC23B, "1109 116F 11AE"), - (0xC23C, "1109 116F 11AF"), - (0xC23D, "1109 116F 11B0"), - (0xC23E, "1109 116F 11B1"), - (0xC23F, "1109 116F 11B2"), - (0xC240, "1109 116F 11B3"), - (0xC241, "1109 116F 11B4"), - (0xC242, "1109 116F 11B5"), - (0xC243, "1109 116F 11B6"), - (0xC244, "1109 116F 11B7"), - (0xC245, "1109 116F 11B8"), - (0xC246, "1109 116F 11B9"), - (0xC247, "1109 116F 11BA"), - (0xC248, "1109 116F 11BB"), - (0xC249, "1109 116F 11BC"), - (0xC24A, "1109 116F 11BD"), - (0xC24B, "1109 116F 11BE"), - (0xC24C, "1109 116F 11BF"), - (0xC24D, "1109 116F 11C0"), - (0xC24E, "1109 116F 11C1"), - (0xC24F, "1109 116F 11C2"), - (0xC250, "1109 1170"), - (0xC251, "1109 1170 11A8"), - (0xC252, "1109 1170 11A9"), - (0xC253, "1109 1170 11AA"), - (0xC254, "1109 1170 11AB"), - (0xC255, "1109 1170 11AC"), - (0xC256, "1109 1170 11AD"), - (0xC257, "1109 1170 11AE"), - (0xC258, "1109 1170 11AF"), - (0xC259, "1109 1170 11B0"), - (0xC25A, "1109 1170 11B1"), - (0xC25B, "1109 1170 11B2"), - (0xC25C, "1109 1170 11B3"), - (0xC25D, "1109 1170 11B4"), - (0xC25E, "1109 1170 11B5"), - (0xC25F, "1109 1170 11B6"), - (0xC260, "1109 1170 11B7"), - (0xC261, "1109 1170 11B8"), - (0xC262, "1109 1170 11B9"), - (0xC263, "1109 1170 11BA"), - (0xC264, "1109 1170 11BB"), - (0xC265, "1109 1170 11BC"), - (0xC266, "1109 1170 11BD"), - (0xC267, "1109 1170 11BE"), - (0xC268, "1109 1170 11BF"), - (0xC269, "1109 1170 11C0"), - (0xC26A, "1109 1170 11C1"), - (0xC26B, "1109 1170 11C2"), - (0xC26C, "1109 1171"), - (0xC26D, "1109 1171 11A8"), - (0xC26E, "1109 1171 11A9"), - (0xC26F, "1109 1171 11AA"), - (0xC270, "1109 1171 11AB"), - (0xC271, "1109 1171 11AC"), - (0xC272, "1109 1171 11AD"), - (0xC273, "1109 1171 11AE"), - (0xC274, "1109 1171 11AF"), - (0xC275, "1109 1171 11B0"), - (0xC276, "1109 1171 11B1"), - (0xC277, "1109 1171 11B2"), - (0xC278, "1109 1171 11B3"), - (0xC279, "1109 1171 11B4"), - (0xC27A, "1109 1171 11B5"), - (0xC27B, "1109 1171 11B6"), - (0xC27C, "1109 1171 11B7"), - (0xC27D, "1109 1171 11B8"), - (0xC27E, "1109 1171 11B9"), - (0xC27F, "1109 1171 11BA"), - (0xC280, "1109 1171 11BB"), - (0xC281, "1109 1171 11BC"), - (0xC282, "1109 1171 11BD"), - (0xC283, "1109 1171 11BE"), - (0xC284, "1109 1171 11BF"), - (0xC285, "1109 1171 11C0"), - (0xC286, "1109 1171 11C1"), - (0xC287, "1109 1171 11C2"), - (0xC288, "1109 1172"), - (0xC289, "1109 1172 11A8"), - (0xC28A, "1109 1172 11A9"), - (0xC28B, "1109 1172 11AA"), - (0xC28C, "1109 1172 11AB"), - (0xC28D, "1109 1172 11AC"), - (0xC28E, "1109 1172 11AD"), - (0xC28F, "1109 1172 11AE"), - (0xC290, "1109 1172 11AF"), - (0xC291, "1109 1172 11B0"), - (0xC292, "1109 1172 11B1"), - (0xC293, "1109 1172 11B2"), - (0xC294, "1109 1172 11B3"), - (0xC295, "1109 1172 11B4"), - (0xC296, "1109 1172 11B5"), - (0xC297, "1109 1172 11B6"), - (0xC298, "1109 1172 11B7"), - (0xC299, "1109 1172 11B8"), - (0xC29A, "1109 1172 11B9"), - (0xC29B, "1109 1172 11BA"), - (0xC29C, "1109 1172 11BB"), - (0xC29D, "1109 1172 11BC"), - (0xC29E, "1109 1172 11BD"), - (0xC29F, "1109 1172 11BE"), - (0xC2A0, "1109 1172 11BF"), - (0xC2A1, "1109 1172 11C0"), - (0xC2A2, "1109 1172 11C1"), - (0xC2A3, "1109 1172 11C2"), - (0xC2A4, "1109 1173"), - (0xC2A5, "1109 1173 11A8"), - (0xC2A6, "1109 1173 11A9"), - (0xC2A7, "1109 1173 11AA"), - (0xC2A8, "1109 1173 11AB"), - (0xC2A9, "1109 1173 11AC"), - (0xC2AA, "1109 1173 11AD"), - (0xC2AB, "1109 1173 11AE"), - (0xC2AC, "1109 1173 11AF"), - (0xC2AD, "1109 1173 11B0"), - (0xC2AE, "1109 1173 11B1"), - (0xC2AF, "1109 1173 11B2"), - (0xC2B0, "1109 1173 11B3"), - (0xC2B1, "1109 1173 11B4"), - (0xC2B2, "1109 1173 11B5"), - (0xC2B3, "1109 1173 11B6"), - (0xC2B4, "1109 1173 11B7"), - (0xC2B5, "1109 1173 11B8"), - (0xC2B6, "1109 1173 11B9"), - (0xC2B7, "1109 1173 11BA"), - (0xC2B8, "1109 1173 11BB"), - (0xC2B9, "1109 1173 11BC"), - (0xC2BA, "1109 1173 11BD"), - (0xC2BB, "1109 1173 11BE"), - (0xC2BC, "1109 1173 11BF"), - (0xC2BD, "1109 1173 11C0"), - (0xC2BE, "1109 1173 11C1"), - (0xC2BF, "1109 1173 11C2"), - (0xC2C0, "1109 1174"), - (0xC2C1, "1109 1174 11A8"), - (0xC2C2, "1109 1174 11A9"), - (0xC2C3, "1109 1174 11AA"), - (0xC2C4, "1109 1174 11AB"), - (0xC2C5, "1109 1174 11AC"), - (0xC2C6, "1109 1174 11AD"), - (0xC2C7, "1109 1174 11AE"), - (0xC2C8, "1109 1174 11AF"), - (0xC2C9, "1109 1174 11B0"), - (0xC2CA, "1109 1174 11B1"), - (0xC2CB, "1109 1174 11B2"), - (0xC2CC, "1109 1174 11B3"), - (0xC2CD, "1109 1174 11B4"), - (0xC2CE, "1109 1174 11B5"), - (0xC2CF, "1109 1174 11B6"), - (0xC2D0, "1109 1174 11B7"), - (0xC2D1, "1109 1174 11B8"), - (0xC2D2, "1109 1174 11B9"), - (0xC2D3, "1109 1174 11BA"), - (0xC2D4, "1109 1174 11BB"), - (0xC2D5, "1109 1174 11BC"), - (0xC2D6, "1109 1174 11BD"), - (0xC2D7, "1109 1174 11BE"), - (0xC2D8, "1109 1174 11BF"), - (0xC2D9, "1109 1174 11C0"), - (0xC2DA, "1109 1174 11C1"), - (0xC2DB, "1109 1174 11C2"), - (0xC2DC, "1109 1175"), - (0xC2DD, "1109 1175 11A8"), - (0xC2DE, "1109 1175 11A9"), - (0xC2DF, "1109 1175 11AA"), - (0xC2E0, "1109 1175 11AB"), - (0xC2E1, "1109 1175 11AC"), - (0xC2E2, "1109 1175 11AD"), - (0xC2E3, "1109 1175 11AE"), - (0xC2E4, "1109 1175 11AF"), - (0xC2E5, "1109 1175 11B0"), - (0xC2E6, "1109 1175 11B1"), - (0xC2E7, "1109 1175 11B2"), - (0xC2E8, "1109 1175 11B3"), - (0xC2E9, "1109 1175 11B4"), - (0xC2EA, "1109 1175 11B5"), - (0xC2EB, "1109 1175 11B6"), - (0xC2EC, "1109 1175 11B7"), - (0xC2ED, "1109 1175 11B8"), - (0xC2EE, "1109 1175 11B9"), - (0xC2EF, "1109 1175 11BA"), - (0xC2F0, "1109 1175 11BB"), - (0xC2F1, "1109 1175 11BC"), - (0xC2F2, "1109 1175 11BD"), - (0xC2F3, "1109 1175 11BE"), - (0xC2F4, "1109 1175 11BF"), - (0xC2F5, "1109 1175 11C0"), - (0xC2F6, "1109 1175 11C1"), - (0xC2F7, "1109 1175 11C2"), - (0xC2F8, "110A 1161"), - (0xC2F9, "110A 1161 11A8"), - (0xC2FA, "110A 1161 11A9"), - (0xC2FB, "110A 1161 11AA"), - (0xC2FC, "110A 1161 11AB"), - (0xC2FD, "110A 1161 11AC"), - (0xC2FE, "110A 1161 11AD"), - (0xC2FF, "110A 1161 11AE"), - (0xC300, "110A 1161 11AF"), - (0xC301, "110A 1161 11B0"), - (0xC302, "110A 1161 11B1"), - (0xC303, "110A 1161 11B2"), - (0xC304, "110A 1161 11B3"), - (0xC305, "110A 1161 11B4"), - (0xC306, "110A 1161 11B5"), - (0xC307, "110A 1161 11B6"), - (0xC308, "110A 1161 11B7"), - (0xC309, "110A 1161 11B8"), - (0xC30A, "110A 1161 11B9"), - (0xC30B, "110A 1161 11BA"), - (0xC30C, "110A 1161 11BB"), - (0xC30D, "110A 1161 11BC"), - (0xC30E, "110A 1161 11BD"), - (0xC30F, "110A 1161 11BE"), - (0xC310, "110A 1161 11BF"), - (0xC311, "110A 1161 11C0"), - (0xC312, "110A 1161 11C1"), - (0xC313, "110A 1161 11C2"), - (0xC314, "110A 1162"), - (0xC315, "110A 1162 11A8"), - (0xC316, "110A 1162 11A9"), - (0xC317, "110A 1162 11AA"), - (0xC318, "110A 1162 11AB"), - (0xC319, "110A 1162 11AC"), - (0xC31A, "110A 1162 11AD"), - (0xC31B, "110A 1162 11AE"), - (0xC31C, "110A 1162 11AF"), - (0xC31D, "110A 1162 11B0"), - (0xC31E, "110A 1162 11B1"), - (0xC31F, "110A 1162 11B2"), - (0xC320, "110A 1162 11B3"), - (0xC321, "110A 1162 11B4"), - (0xC322, "110A 1162 11B5"), - (0xC323, "110A 1162 11B6"), - (0xC324, "110A 1162 11B7"), - (0xC325, "110A 1162 11B8"), - (0xC326, "110A 1162 11B9"), - (0xC327, "110A 1162 11BA"), - (0xC328, "110A 1162 11BB"), - (0xC329, "110A 1162 11BC"), - (0xC32A, "110A 1162 11BD"), - (0xC32B, "110A 1162 11BE"), - (0xC32C, "110A 1162 11BF"), - (0xC32D, "110A 1162 11C0"), - (0xC32E, "110A 1162 11C1"), - (0xC32F, "110A 1162 11C2"), - (0xC330, "110A 1163"), - (0xC331, "110A 1163 11A8"), - (0xC332, "110A 1163 11A9"), - (0xC333, "110A 1163 11AA"), - (0xC334, "110A 1163 11AB"), - (0xC335, "110A 1163 11AC"), - (0xC336, "110A 1163 11AD"), - (0xC337, "110A 1163 11AE"), - (0xC338, "110A 1163 11AF"), - (0xC339, "110A 1163 11B0"), - (0xC33A, "110A 1163 11B1"), - (0xC33B, "110A 1163 11B2"), - (0xC33C, "110A 1163 11B3"), - (0xC33D, "110A 1163 11B4"), - (0xC33E, "110A 1163 11B5"), - (0xC33F, "110A 1163 11B6"), - (0xC340, "110A 1163 11B7"), - (0xC341, "110A 1163 11B8"), - (0xC342, "110A 1163 11B9"), - (0xC343, "110A 1163 11BA"), - (0xC344, "110A 1163 11BB"), - (0xC345, "110A 1163 11BC"), - (0xC346, "110A 1163 11BD"), - (0xC347, "110A 1163 11BE"), - (0xC348, "110A 1163 11BF"), - (0xC349, "110A 1163 11C0"), - (0xC34A, "110A 1163 11C1"), - (0xC34B, "110A 1163 11C2"), - (0xC34C, "110A 1164"), - (0xC34D, "110A 1164 11A8"), - (0xC34E, "110A 1164 11A9"), - (0xC34F, "110A 1164 11AA"), - (0xC350, "110A 1164 11AB"), - (0xC351, "110A 1164 11AC"), - (0xC352, "110A 1164 11AD"), - (0xC353, "110A 1164 11AE"), - (0xC354, "110A 1164 11AF"), - (0xC355, "110A 1164 11B0"), - (0xC356, "110A 1164 11B1"), - (0xC357, "110A 1164 11B2"), - (0xC358, "110A 1164 11B3"), - (0xC359, "110A 1164 11B4"), - (0xC35A, "110A 1164 11B5"), - (0xC35B, "110A 1164 11B6"), - (0xC35C, "110A 1164 11B7"), - (0xC35D, "110A 1164 11B8"), - (0xC35E, "110A 1164 11B9"), - (0xC35F, "110A 1164 11BA"), - (0xC360, "110A 1164 11BB"), - (0xC361, "110A 1164 11BC"), - (0xC362, "110A 1164 11BD"), - (0xC363, "110A 1164 11BE"), - (0xC364, "110A 1164 11BF"), - (0xC365, "110A 1164 11C0"), - (0xC366, "110A 1164 11C1"), - (0xC367, "110A 1164 11C2"), - (0xC368, "110A 1165"), - (0xC369, "110A 1165 11A8"), - (0xC36A, "110A 1165 11A9"), - (0xC36B, "110A 1165 11AA"), - (0xC36C, "110A 1165 11AB"), - (0xC36D, "110A 1165 11AC"), - (0xC36E, "110A 1165 11AD"), - (0xC36F, "110A 1165 11AE"), - (0xC370, "110A 1165 11AF"), - (0xC371, "110A 1165 11B0"), - (0xC372, "110A 1165 11B1"), - (0xC373, "110A 1165 11B2"), - (0xC374, "110A 1165 11B3"), - (0xC375, "110A 1165 11B4"), - (0xC376, "110A 1165 11B5"), - (0xC377, "110A 1165 11B6"), - (0xC378, "110A 1165 11B7"), - (0xC379, "110A 1165 11B8"), - (0xC37A, "110A 1165 11B9"), - (0xC37B, "110A 1165 11BA"), - (0xC37C, "110A 1165 11BB"), - (0xC37D, "110A 1165 11BC"), - (0xC37E, "110A 1165 11BD"), - (0xC37F, "110A 1165 11BE"), - (0xC380, "110A 1165 11BF"), - (0xC381, "110A 1165 11C0"), - (0xC382, "110A 1165 11C1"), - (0xC383, "110A 1165 11C2"), - (0xC384, "110A 1166"), - (0xC385, "110A 1166 11A8"), - (0xC386, "110A 1166 11A9"), - (0xC387, "110A 1166 11AA"), - (0xC388, "110A 1166 11AB"), - (0xC389, "110A 1166 11AC"), - (0xC38A, "110A 1166 11AD"), - (0xC38B, "110A 1166 11AE"), - (0xC38C, "110A 1166 11AF"), - (0xC38D, "110A 1166 11B0"), - (0xC38E, "110A 1166 11B1"), - (0xC38F, "110A 1166 11B2"), - (0xC390, "110A 1166 11B3"), - (0xC391, "110A 1166 11B4"), - (0xC392, "110A 1166 11B5"), - (0xC393, "110A 1166 11B6"), - (0xC394, "110A 1166 11B7"), - (0xC395, "110A 1166 11B8"), - (0xC396, "110A 1166 11B9"), - (0xC397, "110A 1166 11BA"), - (0xC398, "110A 1166 11BB"), - (0xC399, "110A 1166 11BC"), - (0xC39A, "110A 1166 11BD"), - (0xC39B, "110A 1166 11BE"), - (0xC39C, "110A 1166 11BF"), - (0xC39D, "110A 1166 11C0"), - (0xC39E, "110A 1166 11C1"), - (0xC39F, "110A 1166 11C2"), - (0xC3A0, "110A 1167"), - (0xC3A1, "110A 1167 11A8"), - (0xC3A2, "110A 1167 11A9"), - (0xC3A3, "110A 1167 11AA"), - (0xC3A4, "110A 1167 11AB"), - (0xC3A5, "110A 1167 11AC"), - (0xC3A6, "110A 1167 11AD"), - (0xC3A7, "110A 1167 11AE"), - (0xC3A8, "110A 1167 11AF"), - (0xC3A9, "110A 1167 11B0"), - (0xC3AA, "110A 1167 11B1"), - (0xC3AB, "110A 1167 11B2"), - (0xC3AC, "110A 1167 11B3"), - (0xC3AD, "110A 1167 11B4"), - (0xC3AE, "110A 1167 11B5"), - (0xC3AF, "110A 1167 11B6"), - (0xC3B0, "110A 1167 11B7"), - (0xC3B1, "110A 1167 11B8"), - (0xC3B2, "110A 1167 11B9"), - (0xC3B3, "110A 1167 11BA"), - (0xC3B4, "110A 1167 11BB"), - (0xC3B5, "110A 1167 11BC"), - (0xC3B6, "110A 1167 11BD"), - (0xC3B7, "110A 1167 11BE"), - (0xC3B8, "110A 1167 11BF"), - (0xC3B9, "110A 1167 11C0"), - (0xC3BA, "110A 1167 11C1"), - (0xC3BB, "110A 1167 11C2"), - (0xC3BC, "110A 1168"), - (0xC3BD, "110A 1168 11A8"), - (0xC3BE, "110A 1168 11A9"), - (0xC3BF, "110A 1168 11AA"), - (0xC3C0, "110A 1168 11AB"), - (0xC3C1, "110A 1168 11AC"), - (0xC3C2, "110A 1168 11AD"), - (0xC3C3, "110A 1168 11AE"), - (0xC3C4, "110A 1168 11AF"), - (0xC3C5, "110A 1168 11B0"), - (0xC3C6, "110A 1168 11B1"), - (0xC3C7, "110A 1168 11B2"), - (0xC3C8, "110A 1168 11B3"), - (0xC3C9, "110A 1168 11B4"), - (0xC3CA, "110A 1168 11B5"), - (0xC3CB, "110A 1168 11B6"), - (0xC3CC, "110A 1168 11B7"), - (0xC3CD, "110A 1168 11B8"), - (0xC3CE, "110A 1168 11B9"), - (0xC3CF, "110A 1168 11BA"), - (0xC3D0, "110A 1168 11BB"), - (0xC3D1, "110A 1168 11BC"), - (0xC3D2, "110A 1168 11BD"), - (0xC3D3, "110A 1168 11BE"), - (0xC3D4, "110A 1168 11BF"), - (0xC3D5, "110A 1168 11C0"), - (0xC3D6, "110A 1168 11C1"), - (0xC3D7, "110A 1168 11C2"), - (0xC3D8, "110A 1169"), - (0xC3D9, "110A 1169 11A8"), - (0xC3DA, "110A 1169 11A9"), - (0xC3DB, "110A 1169 11AA"), - (0xC3DC, "110A 1169 11AB"), - (0xC3DD, "110A 1169 11AC"), - (0xC3DE, "110A 1169 11AD"), - (0xC3DF, "110A 1169 11AE"), - (0xC3E0, "110A 1169 11AF"), - (0xC3E1, "110A 1169 11B0"), - (0xC3E2, "110A 1169 11B1"), - (0xC3E3, "110A 1169 11B2"), - (0xC3E4, "110A 1169 11B3"), - (0xC3E5, "110A 1169 11B4"), - (0xC3E6, "110A 1169 11B5"), - (0xC3E7, "110A 1169 11B6"), - (0xC3E8, "110A 1169 11B7"), - (0xC3E9, "110A 1169 11B8"), - (0xC3EA, "110A 1169 11B9"), - (0xC3EB, "110A 1169 11BA"), - (0xC3EC, "110A 1169 11BB"), - (0xC3ED, "110A 1169 11BC"), - (0xC3EE, "110A 1169 11BD"), - (0xC3EF, "110A 1169 11BE"), - (0xC3F0, "110A 1169 11BF"), - (0xC3F1, "110A 1169 11C0"), - (0xC3F2, "110A 1169 11C1"), - (0xC3F3, "110A 1169 11C2"), - (0xC3F4, "110A 116A"), - (0xC3F5, "110A 116A 11A8"), - (0xC3F6, "110A 116A 11A9"), - (0xC3F7, "110A 116A 11AA"), - (0xC3F8, "110A 116A 11AB"), - (0xC3F9, "110A 116A 11AC"), - (0xC3FA, "110A 116A 11AD"), - (0xC3FB, "110A 116A 11AE"), - (0xC3FC, "110A 116A 11AF"), - (0xC3FD, "110A 116A 11B0"), - (0xC3FE, "110A 116A 11B1"), - (0xC3FF, "110A 116A 11B2"), - (0xC400, "110A 116A 11B3"), - (0xC401, "110A 116A 11B4"), - (0xC402, "110A 116A 11B5"), - (0xC403, "110A 116A 11B6"), - (0xC404, "110A 116A 11B7"), - (0xC405, "110A 116A 11B8"), - (0xC406, "110A 116A 11B9"), - (0xC407, "110A 116A 11BA"), - (0xC408, "110A 116A 11BB"), - (0xC409, "110A 116A 11BC"), - (0xC40A, "110A 116A 11BD"), - (0xC40B, "110A 116A 11BE"), - (0xC40C, "110A 116A 11BF"), - (0xC40D, "110A 116A 11C0"), - (0xC40E, "110A 116A 11C1"), - (0xC40F, "110A 116A 11C2"), - (0xC410, "110A 116B"), - (0xC411, "110A 116B 11A8"), - (0xC412, "110A 116B 11A9"), - (0xC413, "110A 116B 11AA"), - (0xC414, "110A 116B 11AB"), - (0xC415, "110A 116B 11AC"), - (0xC416, "110A 116B 11AD"), - (0xC417, "110A 116B 11AE"), - (0xC418, "110A 116B 11AF"), - (0xC419, "110A 116B 11B0"), - (0xC41A, "110A 116B 11B1"), - (0xC41B, "110A 116B 11B2"), - (0xC41C, "110A 116B 11B3"), - (0xC41D, "110A 116B 11B4"), - (0xC41E, "110A 116B 11B5"), - (0xC41F, "110A 116B 11B6"), - (0xC420, "110A 116B 11B7"), - (0xC421, "110A 116B 11B8"), - (0xC422, "110A 116B 11B9"), - (0xC423, "110A 116B 11BA"), - (0xC424, "110A 116B 11BB"), - (0xC425, "110A 116B 11BC"), - (0xC426, "110A 116B 11BD"), - (0xC427, "110A 116B 11BE"), - (0xC428, "110A 116B 11BF"), - (0xC429, "110A 116B 11C0"), - (0xC42A, "110A 116B 11C1"), - (0xC42B, "110A 116B 11C2"), - (0xC42C, "110A 116C"), - (0xC42D, "110A 116C 11A8"), - (0xC42E, "110A 116C 11A9"), - (0xC42F, "110A 116C 11AA"), - (0xC430, "110A 116C 11AB"), - (0xC431, "110A 116C 11AC"), - (0xC432, "110A 116C 11AD"), - (0xC433, "110A 116C 11AE"), - (0xC434, "110A 116C 11AF"), - (0xC435, "110A 116C 11B0"), - (0xC436, "110A 116C 11B1"), - (0xC437, "110A 116C 11B2"), - (0xC438, "110A 116C 11B3"), - (0xC439, "110A 116C 11B4"), - (0xC43A, "110A 116C 11B5"), - (0xC43B, "110A 116C 11B6"), - (0xC43C, "110A 116C 11B7"), - (0xC43D, "110A 116C 11B8"), - (0xC43E, "110A 116C 11B9"), - (0xC43F, "110A 116C 11BA"), - (0xC440, "110A 116C 11BB"), - (0xC441, "110A 116C 11BC"), - (0xC442, "110A 116C 11BD"), - (0xC443, "110A 116C 11BE"), - (0xC444, "110A 116C 11BF"), - (0xC445, "110A 116C 11C0"), - (0xC446, "110A 116C 11C1"), - (0xC447, "110A 116C 11C2"), - (0xC448, "110A 116D"), - (0xC449, "110A 116D 11A8"), - (0xC44A, "110A 116D 11A9"), - (0xC44B, "110A 116D 11AA"), - (0xC44C, "110A 116D 11AB"), - (0xC44D, "110A 116D 11AC"), - (0xC44E, "110A 116D 11AD"), - (0xC44F, "110A 116D 11AE"), - (0xC450, "110A 116D 11AF"), - (0xC451, "110A 116D 11B0"), - (0xC452, "110A 116D 11B1"), - (0xC453, "110A 116D 11B2"), - (0xC454, "110A 116D 11B3"), - (0xC455, "110A 116D 11B4"), - (0xC456, "110A 116D 11B5"), - (0xC457, "110A 116D 11B6"), - (0xC458, "110A 116D 11B7"), - (0xC459, "110A 116D 11B8"), - (0xC45A, "110A 116D 11B9"), - (0xC45B, "110A 116D 11BA"), - (0xC45C, "110A 116D 11BB"), - (0xC45D, "110A 116D 11BC"), - (0xC45E, "110A 116D 11BD"), - (0xC45F, "110A 116D 11BE"), - (0xC460, "110A 116D 11BF"), - (0xC461, "110A 116D 11C0"), - (0xC462, "110A 116D 11C1"), - (0xC463, "110A 116D 11C2"), - (0xC464, "110A 116E"), - (0xC465, "110A 116E 11A8"), - (0xC466, "110A 116E 11A9"), - (0xC467, "110A 116E 11AA"), - (0xC468, "110A 116E 11AB"), - (0xC469, "110A 116E 11AC"), - (0xC46A, "110A 116E 11AD"), - (0xC46B, "110A 116E 11AE"), - (0xC46C, "110A 116E 11AF"), - (0xC46D, "110A 116E 11B0"), - (0xC46E, "110A 116E 11B1"), - (0xC46F, "110A 116E 11B2"), - (0xC470, "110A 116E 11B3"), - (0xC471, "110A 116E 11B4"), - (0xC472, "110A 116E 11B5"), - (0xC473, "110A 116E 11B6"), - (0xC474, "110A 116E 11B7"), - (0xC475, "110A 116E 11B8"), - (0xC476, "110A 116E 11B9"), - (0xC477, "110A 116E 11BA"), - (0xC478, "110A 116E 11BB"), - (0xC479, "110A 116E 11BC"), - (0xC47A, "110A 116E 11BD"), - (0xC47B, "110A 116E 11BE"), - (0xC47C, "110A 116E 11BF"), - (0xC47D, "110A 116E 11C0"), - (0xC47E, "110A 116E 11C1"), - (0xC47F, "110A 116E 11C2"), - (0xC480, "110A 116F"), - (0xC481, "110A 116F 11A8"), - (0xC482, "110A 116F 11A9"), - (0xC483, "110A 116F 11AA"), - (0xC484, "110A 116F 11AB"), - (0xC485, "110A 116F 11AC"), - (0xC486, "110A 116F 11AD"), - (0xC487, "110A 116F 11AE"), - (0xC488, "110A 116F 11AF"), - (0xC489, "110A 116F 11B0"), - (0xC48A, "110A 116F 11B1"), - (0xC48B, "110A 116F 11B2"), - (0xC48C, "110A 116F 11B3"), - (0xC48D, "110A 116F 11B4"), - (0xC48E, "110A 116F 11B5"), - (0xC48F, "110A 116F 11B6"), - (0xC490, "110A 116F 11B7"), - (0xC491, "110A 116F 11B8"), - (0xC492, "110A 116F 11B9"), - (0xC493, "110A 116F 11BA"), - (0xC494, "110A 116F 11BB"), - (0xC495, "110A 116F 11BC"), - (0xC496, "110A 116F 11BD"), - (0xC497, "110A 116F 11BE"), - (0xC498, "110A 116F 11BF"), - (0xC499, "110A 116F 11C0"), - (0xC49A, "110A 116F 11C1"), - (0xC49B, "110A 116F 11C2"), - (0xC49C, "110A 1170"), - (0xC49D, "110A 1170 11A8"), - (0xC49E, "110A 1170 11A9"), - (0xC49F, "110A 1170 11AA"), - (0xC4A0, "110A 1170 11AB"), - (0xC4A1, "110A 1170 11AC"), - (0xC4A2, "110A 1170 11AD"), - (0xC4A3, "110A 1170 11AE"), - (0xC4A4, "110A 1170 11AF"), - (0xC4A5, "110A 1170 11B0"), - (0xC4A6, "110A 1170 11B1"), - (0xC4A7, "110A 1170 11B2"), - (0xC4A8, "110A 1170 11B3"), - (0xC4A9, "110A 1170 11B4"), - (0xC4AA, "110A 1170 11B5"), - (0xC4AB, "110A 1170 11B6"), - (0xC4AC, "110A 1170 11B7"), - (0xC4AD, "110A 1170 11B8"), - (0xC4AE, "110A 1170 11B9"), - (0xC4AF, "110A 1170 11BA"), - (0xC4B0, "110A 1170 11BB"), - (0xC4B1, "110A 1170 11BC"), - (0xC4B2, "110A 1170 11BD"), - (0xC4B3, "110A 1170 11BE"), - (0xC4B4, "110A 1170 11BF"), - (0xC4B5, "110A 1170 11C0"), - (0xC4B6, "110A 1170 11C1"), - (0xC4B7, "110A 1170 11C2"), - (0xC4B8, "110A 1171"), - (0xC4B9, "110A 1171 11A8"), - (0xC4BA, "110A 1171 11A9"), - (0xC4BB, "110A 1171 11AA"), - (0xC4BC, "110A 1171 11AB"), - (0xC4BD, "110A 1171 11AC"), - (0xC4BE, "110A 1171 11AD"), - (0xC4BF, "110A 1171 11AE"), - (0xC4C0, "110A 1171 11AF"), - (0xC4C1, "110A 1171 11B0"), - (0xC4C2, "110A 1171 11B1"), - (0xC4C3, "110A 1171 11B2"), - (0xC4C4, "110A 1171 11B3"), - (0xC4C5, "110A 1171 11B4"), - (0xC4C6, "110A 1171 11B5"), - (0xC4C7, "110A 1171 11B6"), - (0xC4C8, "110A 1171 11B7"), - (0xC4C9, "110A 1171 11B8"), - (0xC4CA, "110A 1171 11B9"), - (0xC4CB, "110A 1171 11BA"), - (0xC4CC, "110A 1171 11BB"), - (0xC4CD, "110A 1171 11BC"), - (0xC4CE, "110A 1171 11BD"), - (0xC4CF, "110A 1171 11BE"), - (0xC4D0, "110A 1171 11BF"), - (0xC4D1, "110A 1171 11C0"), - (0xC4D2, "110A 1171 11C1"), - (0xC4D3, "110A 1171 11C2"), - (0xC4D4, "110A 1172"), - (0xC4D5, "110A 1172 11A8"), - (0xC4D6, "110A 1172 11A9"), - (0xC4D7, "110A 1172 11AA"), - (0xC4D8, "110A 1172 11AB"), - (0xC4D9, "110A 1172 11AC"), - (0xC4DA, "110A 1172 11AD"), - (0xC4DB, "110A 1172 11AE"), - (0xC4DC, "110A 1172 11AF"), - (0xC4DD, "110A 1172 11B0"), - (0xC4DE, "110A 1172 11B1"), - (0xC4DF, "110A 1172 11B2"), - (0xC4E0, "110A 1172 11B3"), - (0xC4E1, "110A 1172 11B4"), - (0xC4E2, "110A 1172 11B5"), - (0xC4E3, "110A 1172 11B6"), - (0xC4E4, "110A 1172 11B7"), - (0xC4E5, "110A 1172 11B8"), - (0xC4E6, "110A 1172 11B9"), - (0xC4E7, "110A 1172 11BA"), - (0xC4E8, "110A 1172 11BB"), - (0xC4E9, "110A 1172 11BC"), - (0xC4EA, "110A 1172 11BD"), - (0xC4EB, "110A 1172 11BE"), - (0xC4EC, "110A 1172 11BF"), - (0xC4ED, "110A 1172 11C0"), - (0xC4EE, "110A 1172 11C1"), - (0xC4EF, "110A 1172 11C2"), - (0xC4F0, "110A 1173"), - (0xC4F1, "110A 1173 11A8"), - (0xC4F2, "110A 1173 11A9"), - (0xC4F3, "110A 1173 11AA"), - (0xC4F4, "110A 1173 11AB"), - (0xC4F5, "110A 1173 11AC"), - (0xC4F6, "110A 1173 11AD"), - (0xC4F7, "110A 1173 11AE"), - (0xC4F8, "110A 1173 11AF"), - (0xC4F9, "110A 1173 11B0"), - (0xC4FA, "110A 1173 11B1"), - (0xC4FB, "110A 1173 11B2"), - (0xC4FC, "110A 1173 11B3"), - (0xC4FD, "110A 1173 11B4"), - (0xC4FE, "110A 1173 11B5"), - (0xC4FF, "110A 1173 11B6"), - (0xC500, "110A 1173 11B7"), - (0xC501, "110A 1173 11B8"), - (0xC502, "110A 1173 11B9"), - (0xC503, "110A 1173 11BA"), - (0xC504, "110A 1173 11BB"), - (0xC505, "110A 1173 11BC"), - (0xC506, "110A 1173 11BD"), - (0xC507, "110A 1173 11BE"), - (0xC508, "110A 1173 11BF"), - (0xC509, "110A 1173 11C0"), - (0xC50A, "110A 1173 11C1"), - (0xC50B, "110A 1173 11C2"), - (0xC50C, "110A 1174"), - (0xC50D, "110A 1174 11A8"), - (0xC50E, "110A 1174 11A9"), - (0xC50F, "110A 1174 11AA"), - (0xC510, "110A 1174 11AB"), - (0xC511, "110A 1174 11AC"), - (0xC512, "110A 1174 11AD"), - (0xC513, "110A 1174 11AE"), - (0xC514, "110A 1174 11AF"), - (0xC515, "110A 1174 11B0"), - (0xC516, "110A 1174 11B1"), - (0xC517, "110A 1174 11B2"), - (0xC518, "110A 1174 11B3"), - (0xC519, "110A 1174 11B4"), - (0xC51A, "110A 1174 11B5"), - (0xC51B, "110A 1174 11B6"), - (0xC51C, "110A 1174 11B7"), - (0xC51D, "110A 1174 11B8"), - (0xC51E, "110A 1174 11B9"), - (0xC51F, "110A 1174 11BA"), - (0xC520, "110A 1174 11BB"), - (0xC521, "110A 1174 11BC"), - (0xC522, "110A 1174 11BD"), - (0xC523, "110A 1174 11BE"), - (0xC524, "110A 1174 11BF"), - (0xC525, "110A 1174 11C0"), - (0xC526, "110A 1174 11C1"), - (0xC527, "110A 1174 11C2"), - (0xC528, "110A 1175"), - (0xC529, "110A 1175 11A8"), - (0xC52A, "110A 1175 11A9"), - (0xC52B, "110A 1175 11AA"), - (0xC52C, "110A 1175 11AB"), - (0xC52D, "110A 1175 11AC"), - (0xC52E, "110A 1175 11AD"), - (0xC52F, "110A 1175 11AE"), - (0xC530, "110A 1175 11AF"), - (0xC531, "110A 1175 11B0"), - (0xC532, "110A 1175 11B1"), - (0xC533, "110A 1175 11B2"), - (0xC534, "110A 1175 11B3"), - (0xC535, "110A 1175 11B4"), - (0xC536, "110A 1175 11B5"), - (0xC537, "110A 1175 11B6"), - (0xC538, "110A 1175 11B7"), - (0xC539, "110A 1175 11B8"), - (0xC53A, "110A 1175 11B9"), - (0xC53B, "110A 1175 11BA"), - (0xC53C, "110A 1175 11BB"), - (0xC53D, "110A 1175 11BC"), - (0xC53E, "110A 1175 11BD"), - (0xC53F, "110A 1175 11BE"), - (0xC540, "110A 1175 11BF"), - (0xC541, "110A 1175 11C0"), - (0xC542, "110A 1175 11C1"), - (0xC543, "110A 1175 11C2"), - (0xC544, "110B 1161"), - (0xC545, "110B 1161 11A8"), - (0xC546, "110B 1161 11A9"), - (0xC547, "110B 1161 11AA"), - (0xC548, "110B 1161 11AB"), - (0xC549, "110B 1161 11AC"), - (0xC54A, "110B 1161 11AD"), - (0xC54B, "110B 1161 11AE"), - (0xC54C, "110B 1161 11AF"), - (0xC54D, "110B 1161 11B0"), - (0xC54E, "110B 1161 11B1"), - (0xC54F, "110B 1161 11B2"), - (0xC550, "110B 1161 11B3"), - (0xC551, "110B 1161 11B4"), - (0xC552, "110B 1161 11B5"), - (0xC553, "110B 1161 11B6"), - (0xC554, "110B 1161 11B7"), - (0xC555, "110B 1161 11B8"), - (0xC556, "110B 1161 11B9"), - (0xC557, "110B 1161 11BA"), - (0xC558, "110B 1161 11BB"), - (0xC559, "110B 1161 11BC"), - (0xC55A, "110B 1161 11BD"), - (0xC55B, "110B 1161 11BE"), - (0xC55C, "110B 1161 11BF"), - (0xC55D, "110B 1161 11C0"), - (0xC55E, "110B 1161 11C1"), - (0xC55F, "110B 1161 11C2"), - (0xC560, "110B 1162"), - (0xC561, "110B 1162 11A8"), - (0xC562, "110B 1162 11A9"), - (0xC563, "110B 1162 11AA"), - (0xC564, "110B 1162 11AB"), - (0xC565, "110B 1162 11AC"), - (0xC566, "110B 1162 11AD"), - (0xC567, "110B 1162 11AE"), - (0xC568, "110B 1162 11AF"), - (0xC569, "110B 1162 11B0"), - (0xC56A, "110B 1162 11B1"), - (0xC56B, "110B 1162 11B2"), - (0xC56C, "110B 1162 11B3"), - (0xC56D, "110B 1162 11B4"), - (0xC56E, "110B 1162 11B5"), - (0xC56F, "110B 1162 11B6"), - (0xC570, "110B 1162 11B7"), - (0xC571, "110B 1162 11B8"), - (0xC572, "110B 1162 11B9"), - (0xC573, "110B 1162 11BA"), - (0xC574, "110B 1162 11BB"), - (0xC575, "110B 1162 11BC"), - (0xC576, "110B 1162 11BD"), - (0xC577, "110B 1162 11BE"), - (0xC578, "110B 1162 11BF"), - (0xC579, "110B 1162 11C0"), - (0xC57A, "110B 1162 11C1"), - (0xC57B, "110B 1162 11C2"), - (0xC57C, "110B 1163"), - (0xC57D, "110B 1163 11A8"), - (0xC57E, "110B 1163 11A9"), - (0xC57F, "110B 1163 11AA"), - (0xC580, "110B 1163 11AB"), - (0xC581, "110B 1163 11AC"), - (0xC582, "110B 1163 11AD"), - (0xC583, "110B 1163 11AE"), - (0xC584, "110B 1163 11AF"), - (0xC585, "110B 1163 11B0"), - (0xC586, "110B 1163 11B1"), - (0xC587, "110B 1163 11B2"), - (0xC588, "110B 1163 11B3"), - (0xC589, "110B 1163 11B4"), - (0xC58A, "110B 1163 11B5"), - (0xC58B, "110B 1163 11B6"), - (0xC58C, "110B 1163 11B7"), - (0xC58D, "110B 1163 11B8"), - (0xC58E, "110B 1163 11B9"), - (0xC58F, "110B 1163 11BA"), - (0xC590, "110B 1163 11BB"), - (0xC591, "110B 1163 11BC"), - (0xC592, "110B 1163 11BD"), - (0xC593, "110B 1163 11BE"), - (0xC594, "110B 1163 11BF"), - (0xC595, "110B 1163 11C0"), - (0xC596, "110B 1163 11C1"), - (0xC597, "110B 1163 11C2"), - (0xC598, "110B 1164"), - (0xC599, "110B 1164 11A8"), - (0xC59A, "110B 1164 11A9"), - (0xC59B, "110B 1164 11AA"), - (0xC59C, "110B 1164 11AB"), - (0xC59D, "110B 1164 11AC"), - (0xC59E, "110B 1164 11AD"), - (0xC59F, "110B 1164 11AE"), - (0xC5A0, "110B 1164 11AF"), - (0xC5A1, "110B 1164 11B0"), - (0xC5A2, "110B 1164 11B1"), - (0xC5A3, "110B 1164 11B2"), - (0xC5A4, "110B 1164 11B3"), - (0xC5A5, "110B 1164 11B4"), - (0xC5A6, "110B 1164 11B5"), - (0xC5A7, "110B 1164 11B6"), - (0xC5A8, "110B 1164 11B7"), - (0xC5A9, "110B 1164 11B8"), - (0xC5AA, "110B 1164 11B9"), - (0xC5AB, "110B 1164 11BA"), - (0xC5AC, "110B 1164 11BB"), - (0xC5AD, "110B 1164 11BC"), - (0xC5AE, "110B 1164 11BD"), - (0xC5AF, "110B 1164 11BE"), - (0xC5B0, "110B 1164 11BF"), - (0xC5B1, "110B 1164 11C0"), - (0xC5B2, "110B 1164 11C1"), - (0xC5B3, "110B 1164 11C2"), - (0xC5B4, "110B 1165"), - (0xC5B5, "110B 1165 11A8"), - (0xC5B6, "110B 1165 11A9"), - (0xC5B7, "110B 1165 11AA"), - (0xC5B8, "110B 1165 11AB"), - (0xC5B9, "110B 1165 11AC"), - (0xC5BA, "110B 1165 11AD"), - (0xC5BB, "110B 1165 11AE"), - (0xC5BC, "110B 1165 11AF"), - (0xC5BD, "110B 1165 11B0"), - (0xC5BE, "110B 1165 11B1"), - (0xC5BF, "110B 1165 11B2"), - (0xC5C0, "110B 1165 11B3"), - (0xC5C1, "110B 1165 11B4"), - (0xC5C2, "110B 1165 11B5"), - (0xC5C3, "110B 1165 11B6"), - (0xC5C4, "110B 1165 11B7"), - (0xC5C5, "110B 1165 11B8"), - (0xC5C6, "110B 1165 11B9"), - (0xC5C7, "110B 1165 11BA"), - (0xC5C8, "110B 1165 11BB"), - (0xC5C9, "110B 1165 11BC"), - (0xC5CA, "110B 1165 11BD"), - (0xC5CB, "110B 1165 11BE"), - (0xC5CC, "110B 1165 11BF"), - (0xC5CD, "110B 1165 11C0"), - (0xC5CE, "110B 1165 11C1"), - (0xC5CF, "110B 1165 11C2"), - (0xC5D0, "110B 1166"), - (0xC5D1, "110B 1166 11A8"), - (0xC5D2, "110B 1166 11A9"), - (0xC5D3, "110B 1166 11AA"), - (0xC5D4, "110B 1166 11AB"), - (0xC5D5, "110B 1166 11AC"), - (0xC5D6, "110B 1166 11AD"), - (0xC5D7, "110B 1166 11AE"), - (0xC5D8, "110B 1166 11AF"), - (0xC5D9, "110B 1166 11B0"), - (0xC5DA, "110B 1166 11B1"), - (0xC5DB, "110B 1166 11B2"), - (0xC5DC, "110B 1166 11B3"), - (0xC5DD, "110B 1166 11B4"), - (0xC5DE, "110B 1166 11B5"), - (0xC5DF, "110B 1166 11B6"), - (0xC5E0, "110B 1166 11B7"), - (0xC5E1, "110B 1166 11B8"), - (0xC5E2, "110B 1166 11B9"), - (0xC5E3, "110B 1166 11BA"), - (0xC5E4, "110B 1166 11BB"), - (0xC5E5, "110B 1166 11BC"), - (0xC5E6, "110B 1166 11BD"), - (0xC5E7, "110B 1166 11BE"), - (0xC5E8, "110B 1166 11BF"), - (0xC5E9, "110B 1166 11C0"), - (0xC5EA, "110B 1166 11C1"), - (0xC5EB, "110B 1166 11C2"), - (0xC5EC, "110B 1167"), - (0xC5ED, "110B 1167 11A8"), - (0xC5EE, "110B 1167 11A9"), - (0xC5EF, "110B 1167 11AA"), - (0xC5F0, "110B 1167 11AB"), - (0xC5F1, "110B 1167 11AC"), - (0xC5F2, "110B 1167 11AD"), - (0xC5F3, "110B 1167 11AE"), - (0xC5F4, "110B 1167 11AF"), - (0xC5F5, "110B 1167 11B0"), - (0xC5F6, "110B 1167 11B1"), - (0xC5F7, "110B 1167 11B2"), - (0xC5F8, "110B 1167 11B3"), - (0xC5F9, "110B 1167 11B4"), - (0xC5FA, "110B 1167 11B5"), - (0xC5FB, "110B 1167 11B6"), - (0xC5FC, "110B 1167 11B7"), - (0xC5FD, "110B 1167 11B8"), - (0xC5FE, "110B 1167 11B9"), - (0xC5FF, "110B 1167 11BA"), - (0xC600, "110B 1167 11BB"), - (0xC601, "110B 1167 11BC"), - (0xC602, "110B 1167 11BD"), - (0xC603, "110B 1167 11BE"), - (0xC604, "110B 1167 11BF"), - (0xC605, "110B 1167 11C0"), - (0xC606, "110B 1167 11C1"), - (0xC607, "110B 1167 11C2"), - (0xC608, "110B 1168"), - (0xC609, "110B 1168 11A8"), - (0xC60A, "110B 1168 11A9"), - (0xC60B, "110B 1168 11AA"), - (0xC60C, "110B 1168 11AB"), - (0xC60D, "110B 1168 11AC"), - (0xC60E, "110B 1168 11AD"), - (0xC60F, "110B 1168 11AE"), - (0xC610, "110B 1168 11AF"), - (0xC611, "110B 1168 11B0"), - (0xC612, "110B 1168 11B1"), - (0xC613, "110B 1168 11B2"), - (0xC614, "110B 1168 11B3"), - (0xC615, "110B 1168 11B4"), - (0xC616, "110B 1168 11B5"), - (0xC617, "110B 1168 11B6"), - (0xC618, "110B 1168 11B7"), - (0xC619, "110B 1168 11B8"), - (0xC61A, "110B 1168 11B9"), - (0xC61B, "110B 1168 11BA"), - (0xC61C, "110B 1168 11BB"), - (0xC61D, "110B 1168 11BC"), - (0xC61E, "110B 1168 11BD"), - (0xC61F, "110B 1168 11BE"), - (0xC620, "110B 1168 11BF"), - (0xC621, "110B 1168 11C0"), - (0xC622, "110B 1168 11C1"), - (0xC623, "110B 1168 11C2"), - (0xC624, "110B 1169"), - (0xC625, "110B 1169 11A8"), - (0xC626, "110B 1169 11A9"), - (0xC627, "110B 1169 11AA"), - (0xC628, "110B 1169 11AB"), - (0xC629, "110B 1169 11AC"), - (0xC62A, "110B 1169 11AD"), - (0xC62B, "110B 1169 11AE"), - (0xC62C, "110B 1169 11AF"), - (0xC62D, "110B 1169 11B0"), - (0xC62E, "110B 1169 11B1"), - (0xC62F, "110B 1169 11B2"), - (0xC630, "110B 1169 11B3"), - (0xC631, "110B 1169 11B4"), - (0xC632, "110B 1169 11B5"), - (0xC633, "110B 1169 11B6"), - (0xC634, "110B 1169 11B7"), - (0xC635, "110B 1169 11B8"), - (0xC636, "110B 1169 11B9"), - (0xC637, "110B 1169 11BA"), - (0xC638, "110B 1169 11BB"), - (0xC639, "110B 1169 11BC"), - (0xC63A, "110B 1169 11BD"), - (0xC63B, "110B 1169 11BE"), - (0xC63C, "110B 1169 11BF"), - (0xC63D, "110B 1169 11C0"), - (0xC63E, "110B 1169 11C1"), - (0xC63F, "110B 1169 11C2"), - (0xC640, "110B 116A"), - (0xC641, "110B 116A 11A8"), - (0xC642, "110B 116A 11A9"), - (0xC643, "110B 116A 11AA"), - (0xC644, "110B 116A 11AB"), - (0xC645, "110B 116A 11AC"), - (0xC646, "110B 116A 11AD"), - (0xC647, "110B 116A 11AE"), - (0xC648, "110B 116A 11AF"), - (0xC649, "110B 116A 11B0"), - (0xC64A, "110B 116A 11B1"), - (0xC64B, "110B 116A 11B2"), - (0xC64C, "110B 116A 11B3"), - (0xC64D, "110B 116A 11B4"), - (0xC64E, "110B 116A 11B5"), - (0xC64F, "110B 116A 11B6"), - (0xC650, "110B 116A 11B7"), - (0xC651, "110B 116A 11B8"), - (0xC652, "110B 116A 11B9"), - (0xC653, "110B 116A 11BA"), - (0xC654, "110B 116A 11BB"), - (0xC655, "110B 116A 11BC"), - (0xC656, "110B 116A 11BD"), - (0xC657, "110B 116A 11BE"), - (0xC658, "110B 116A 11BF"), - (0xC659, "110B 116A 11C0"), - (0xC65A, "110B 116A 11C1"), - (0xC65B, "110B 116A 11C2"), - (0xC65C, "110B 116B"), - (0xC65D, "110B 116B 11A8"), - (0xC65E, "110B 116B 11A9"), - (0xC65F, "110B 116B 11AA"), - (0xC660, "110B 116B 11AB"), - (0xC661, "110B 116B 11AC"), - (0xC662, "110B 116B 11AD"), - (0xC663, "110B 116B 11AE"), - (0xC664, "110B 116B 11AF"), - (0xC665, "110B 116B 11B0"), - (0xC666, "110B 116B 11B1"), - (0xC667, "110B 116B 11B2"), - (0xC668, "110B 116B 11B3"), - (0xC669, "110B 116B 11B4"), - (0xC66A, "110B 116B 11B5"), - (0xC66B, "110B 116B 11B6"), - (0xC66C, "110B 116B 11B7"), - (0xC66D, "110B 116B 11B8"), - (0xC66E, "110B 116B 11B9"), - (0xC66F, "110B 116B 11BA"), - (0xC670, "110B 116B 11BB"), - (0xC671, "110B 116B 11BC"), - (0xC672, "110B 116B 11BD"), - (0xC673, "110B 116B 11BE"), - (0xC674, "110B 116B 11BF"), - (0xC675, "110B 116B 11C0"), - (0xC676, "110B 116B 11C1"), - (0xC677, "110B 116B 11C2"), - (0xC678, "110B 116C"), - (0xC679, "110B 116C 11A8"), - (0xC67A, "110B 116C 11A9"), - (0xC67B, "110B 116C 11AA"), - (0xC67C, "110B 116C 11AB"), - (0xC67D, "110B 116C 11AC"), - (0xC67E, "110B 116C 11AD"), - (0xC67F, "110B 116C 11AE"), - (0xC680, "110B 116C 11AF"), - (0xC681, "110B 116C 11B0"), - (0xC682, "110B 116C 11B1"), - (0xC683, "110B 116C 11B2"), - (0xC684, "110B 116C 11B3"), - (0xC685, "110B 116C 11B4"), - (0xC686, "110B 116C 11B5"), - (0xC687, "110B 116C 11B6"), - (0xC688, "110B 116C 11B7"), - (0xC689, "110B 116C 11B8"), - (0xC68A, "110B 116C 11B9"), - (0xC68B, "110B 116C 11BA"), - (0xC68C, "110B 116C 11BB"), - (0xC68D, "110B 116C 11BC"), - (0xC68E, "110B 116C 11BD"), - (0xC68F, "110B 116C 11BE"), - (0xC690, "110B 116C 11BF"), - (0xC691, "110B 116C 11C0"), - (0xC692, "110B 116C 11C1"), - (0xC693, "110B 116C 11C2"), - (0xC694, "110B 116D"), - (0xC695, "110B 116D 11A8"), - (0xC696, "110B 116D 11A9"), - (0xC697, "110B 116D 11AA"), - (0xC698, "110B 116D 11AB"), - (0xC699, "110B 116D 11AC"), - (0xC69A, "110B 116D 11AD"), - (0xC69B, "110B 116D 11AE"), - (0xC69C, "110B 116D 11AF"), - (0xC69D, "110B 116D 11B0"), - (0xC69E, "110B 116D 11B1"), - (0xC69F, "110B 116D 11B2"), - (0xC6A0, "110B 116D 11B3"), - (0xC6A1, "110B 116D 11B4"), - (0xC6A2, "110B 116D 11B5"), - (0xC6A3, "110B 116D 11B6"), - (0xC6A4, "110B 116D 11B7"), - (0xC6A5, "110B 116D 11B8"), - (0xC6A6, "110B 116D 11B9"), - (0xC6A7, "110B 116D 11BA"), - (0xC6A8, "110B 116D 11BB"), - (0xC6A9, "110B 116D 11BC"), - (0xC6AA, "110B 116D 11BD"), - (0xC6AB, "110B 116D 11BE"), - (0xC6AC, "110B 116D 11BF"), - (0xC6AD, "110B 116D 11C0"), - (0xC6AE, "110B 116D 11C1"), - (0xC6AF, "110B 116D 11C2"), - (0xC6B0, "110B 116E"), - (0xC6B1, "110B 116E 11A8"), - (0xC6B2, "110B 116E 11A9"), - (0xC6B3, "110B 116E 11AA"), - (0xC6B4, "110B 116E 11AB"), - (0xC6B5, "110B 116E 11AC"), - (0xC6B6, "110B 116E 11AD"), - (0xC6B7, "110B 116E 11AE"), - (0xC6B8, "110B 116E 11AF"), - (0xC6B9, "110B 116E 11B0"), - (0xC6BA, "110B 116E 11B1"), - (0xC6BB, "110B 116E 11B2"), - (0xC6BC, "110B 116E 11B3"), - (0xC6BD, "110B 116E 11B4"), - (0xC6BE, "110B 116E 11B5"), - (0xC6BF, "110B 116E 11B6"), - (0xC6C0, "110B 116E 11B7"), - (0xC6C1, "110B 116E 11B8"), - (0xC6C2, "110B 116E 11B9"), - (0xC6C3, "110B 116E 11BA"), - (0xC6C4, "110B 116E 11BB"), - (0xC6C5, "110B 116E 11BC"), - (0xC6C6, "110B 116E 11BD"), - (0xC6C7, "110B 116E 11BE"), - (0xC6C8, "110B 116E 11BF"), - (0xC6C9, "110B 116E 11C0"), - (0xC6CA, "110B 116E 11C1"), - (0xC6CB, "110B 116E 11C2"), - (0xC6CC, "110B 116F"), - (0xC6CD, "110B 116F 11A8"), - (0xC6CE, "110B 116F 11A9"), - (0xC6CF, "110B 116F 11AA"), - (0xC6D0, "110B 116F 11AB"), - (0xC6D1, "110B 116F 11AC"), - (0xC6D2, "110B 116F 11AD"), - (0xC6D3, "110B 116F 11AE"), - (0xC6D4, "110B 116F 11AF"), - (0xC6D5, "110B 116F 11B0"), - (0xC6D6, "110B 116F 11B1"), - (0xC6D7, "110B 116F 11B2"), - (0xC6D8, "110B 116F 11B3"), - (0xC6D9, "110B 116F 11B4"), - (0xC6DA, "110B 116F 11B5"), - (0xC6DB, "110B 116F 11B6"), - (0xC6DC, "110B 116F 11B7"), - (0xC6DD, "110B 116F 11B8"), - (0xC6DE, "110B 116F 11B9"), - (0xC6DF, "110B 116F 11BA"), - (0xC6E0, "110B 116F 11BB"), - (0xC6E1, "110B 116F 11BC"), - (0xC6E2, "110B 116F 11BD"), - (0xC6E3, "110B 116F 11BE"), - (0xC6E4, "110B 116F 11BF"), - (0xC6E5, "110B 116F 11C0"), - (0xC6E6, "110B 116F 11C1"), - (0xC6E7, "110B 116F 11C2"), - (0xC6E8, "110B 1170"), - (0xC6E9, "110B 1170 11A8"), - (0xC6EA, "110B 1170 11A9"), - (0xC6EB, "110B 1170 11AA"), - (0xC6EC, "110B 1170 11AB"), - (0xC6ED, "110B 1170 11AC"), - (0xC6EE, "110B 1170 11AD"), - (0xC6EF, "110B 1170 11AE"), - (0xC6F0, "110B 1170 11AF"), - (0xC6F1, "110B 1170 11B0"), - (0xC6F2, "110B 1170 11B1"), - (0xC6F3, "110B 1170 11B2"), - (0xC6F4, "110B 1170 11B3"), - (0xC6F5, "110B 1170 11B4"), - (0xC6F6, "110B 1170 11B5"), - (0xC6F7, "110B 1170 11B6"), - (0xC6F8, "110B 1170 11B7"), - (0xC6F9, "110B 1170 11B8"), - (0xC6FA, "110B 1170 11B9"), - (0xC6FB, "110B 1170 11BA"), - (0xC6FC, "110B 1170 11BB"), - (0xC6FD, "110B 1170 11BC"), - (0xC6FE, "110B 1170 11BD"), - (0xC6FF, "110B 1170 11BE"), - (0xC700, "110B 1170 11BF"), - (0xC701, "110B 1170 11C0"), - (0xC702, "110B 1170 11C1"), - (0xC703, "110B 1170 11C2"), - (0xC704, "110B 1171"), - (0xC705, "110B 1171 11A8"), - (0xC706, "110B 1171 11A9"), - (0xC707, "110B 1171 11AA"), - (0xC708, "110B 1171 11AB"), - (0xC709, "110B 1171 11AC"), - (0xC70A, "110B 1171 11AD"), - (0xC70B, "110B 1171 11AE"), - (0xC70C, "110B 1171 11AF"), - (0xC70D, "110B 1171 11B0"), - (0xC70E, "110B 1171 11B1"), - (0xC70F, "110B 1171 11B2"), - (0xC710, "110B 1171 11B3"), - (0xC711, "110B 1171 11B4"), - (0xC712, "110B 1171 11B5"), - (0xC713, "110B 1171 11B6"), - (0xC714, "110B 1171 11B7"), - (0xC715, "110B 1171 11B8"), - (0xC716, "110B 1171 11B9"), - (0xC717, "110B 1171 11BA"), - (0xC718, "110B 1171 11BB"), - (0xC719, "110B 1171 11BC"), - (0xC71A, "110B 1171 11BD"), - (0xC71B, "110B 1171 11BE"), - (0xC71C, "110B 1171 11BF"), - (0xC71D, "110B 1171 11C0"), - (0xC71E, "110B 1171 11C1"), - (0xC71F, "110B 1171 11C2"), - (0xC720, "110B 1172"), - (0xC721, "110B 1172 11A8"), - (0xC722, "110B 1172 11A9"), - (0xC723, "110B 1172 11AA"), - (0xC724, "110B 1172 11AB"), - (0xC725, "110B 1172 11AC"), - (0xC726, "110B 1172 11AD"), - (0xC727, "110B 1172 11AE"), - (0xC728, "110B 1172 11AF"), - (0xC729, "110B 1172 11B0"), - (0xC72A, "110B 1172 11B1"), - (0xC72B, "110B 1172 11B2"), - (0xC72C, "110B 1172 11B3"), - (0xC72D, "110B 1172 11B4"), - (0xC72E, "110B 1172 11B5"), - (0xC72F, "110B 1172 11B6"), - (0xC730, "110B 1172 11B7"), - (0xC731, "110B 1172 11B8"), - (0xC732, "110B 1172 11B9"), - (0xC733, "110B 1172 11BA"), - (0xC734, "110B 1172 11BB"), - (0xC735, "110B 1172 11BC"), - (0xC736, "110B 1172 11BD"), - (0xC737, "110B 1172 11BE"), - (0xC738, "110B 1172 11BF"), - (0xC739, "110B 1172 11C0"), - (0xC73A, "110B 1172 11C1"), - (0xC73B, "110B 1172 11C2"), - (0xC73C, "110B 1173"), - (0xC73D, "110B 1173 11A8"), - (0xC73E, "110B 1173 11A9"), - (0xC73F, "110B 1173 11AA"), - (0xC740, "110B 1173 11AB"), - (0xC741, "110B 1173 11AC"), - (0xC742, "110B 1173 11AD"), - (0xC743, "110B 1173 11AE"), - (0xC744, "110B 1173 11AF"), - (0xC745, "110B 1173 11B0"), - (0xC746, "110B 1173 11B1"), - (0xC747, "110B 1173 11B2"), - (0xC748, "110B 1173 11B3"), - (0xC749, "110B 1173 11B4"), - (0xC74A, "110B 1173 11B5"), - (0xC74B, "110B 1173 11B6"), - (0xC74C, "110B 1173 11B7"), - (0xC74D, "110B 1173 11B8"), - (0xC74E, "110B 1173 11B9"), - (0xC74F, "110B 1173 11BA"), - (0xC750, "110B 1173 11BB"), - (0xC751, "110B 1173 11BC"), - (0xC752, "110B 1173 11BD"), - (0xC753, "110B 1173 11BE"), - (0xC754, "110B 1173 11BF"), - (0xC755, "110B 1173 11C0"), - (0xC756, "110B 1173 11C1"), - (0xC757, "110B 1173 11C2"), - (0xC758, "110B 1174"), - (0xC759, "110B 1174 11A8"), - (0xC75A, "110B 1174 11A9"), - (0xC75B, "110B 1174 11AA"), - (0xC75C, "110B 1174 11AB"), - (0xC75D, "110B 1174 11AC"), - (0xC75E, "110B 1174 11AD"), - (0xC75F, "110B 1174 11AE"), - (0xC760, "110B 1174 11AF"), - (0xC761, "110B 1174 11B0"), - (0xC762, "110B 1174 11B1"), - (0xC763, "110B 1174 11B2"), - (0xC764, "110B 1174 11B3"), - (0xC765, "110B 1174 11B4"), - (0xC766, "110B 1174 11B5"), - (0xC767, "110B 1174 11B6"), - (0xC768, "110B 1174 11B7"), - (0xC769, "110B 1174 11B8"), - (0xC76A, "110B 1174 11B9"), - (0xC76B, "110B 1174 11BA"), - (0xC76C, "110B 1174 11BB"), - (0xC76D, "110B 1174 11BC"), - (0xC76E, "110B 1174 11BD"), - (0xC76F, "110B 1174 11BE"), - (0xC770, "110B 1174 11BF"), - (0xC771, "110B 1174 11C0"), - (0xC772, "110B 1174 11C1"), - (0xC773, "110B 1174 11C2"), - (0xC774, "110B 1175"), - (0xC775, "110B 1175 11A8"), - (0xC776, "110B 1175 11A9"), - (0xC777, "110B 1175 11AA"), - (0xC778, "110B 1175 11AB"), - (0xC779, "110B 1175 11AC"), - (0xC77A, "110B 1175 11AD"), - (0xC77B, "110B 1175 11AE"), - (0xC77C, "110B 1175 11AF"), - (0xC77D, "110B 1175 11B0"), - (0xC77E, "110B 1175 11B1"), - (0xC77F, "110B 1175 11B2"), - (0xC780, "110B 1175 11B3"), - (0xC781, "110B 1175 11B4"), - (0xC782, "110B 1175 11B5"), - (0xC783, "110B 1175 11B6"), - (0xC784, "110B 1175 11B7"), - (0xC785, "110B 1175 11B8"), - (0xC786, "110B 1175 11B9"), - (0xC787, "110B 1175 11BA"), - (0xC788, "110B 1175 11BB"), - (0xC789, "110B 1175 11BC"), - (0xC78A, "110B 1175 11BD"), - (0xC78B, "110B 1175 11BE"), - (0xC78C, "110B 1175 11BF"), - (0xC78D, "110B 1175 11C0"), - (0xC78E, "110B 1175 11C1"), - (0xC78F, "110B 1175 11C2"), - (0xC790, "110C 1161"), - (0xC791, "110C 1161 11A8"), - (0xC792, "110C 1161 11A9"), - (0xC793, "110C 1161 11AA"), - (0xC794, "110C 1161 11AB"), - (0xC795, "110C 1161 11AC"), - (0xC796, "110C 1161 11AD"), - (0xC797, "110C 1161 11AE"), - (0xC798, "110C 1161 11AF"), - (0xC799, "110C 1161 11B0"), - (0xC79A, "110C 1161 11B1"), - (0xC79B, "110C 1161 11B2"), - (0xC79C, "110C 1161 11B3"), - (0xC79D, "110C 1161 11B4"), - (0xC79E, "110C 1161 11B5"), - (0xC79F, "110C 1161 11B6"), - (0xC7A0, "110C 1161 11B7"), - (0xC7A1, "110C 1161 11B8"), - (0xC7A2, "110C 1161 11B9"), - (0xC7A3, "110C 1161 11BA"), - (0xC7A4, "110C 1161 11BB"), - (0xC7A5, "110C 1161 11BC"), - (0xC7A6, "110C 1161 11BD"), - (0xC7A7, "110C 1161 11BE"), - (0xC7A8, "110C 1161 11BF"), - (0xC7A9, "110C 1161 11C0"), - (0xC7AA, "110C 1161 11C1"), - (0xC7AB, "110C 1161 11C2"), - (0xC7AC, "110C 1162"), - (0xC7AD, "110C 1162 11A8"), - (0xC7AE, "110C 1162 11A9"), - (0xC7AF, "110C 1162 11AA"), - (0xC7B0, "110C 1162 11AB"), - (0xC7B1, "110C 1162 11AC"), - (0xC7B2, "110C 1162 11AD"), - (0xC7B3, "110C 1162 11AE"), - (0xC7B4, "110C 1162 11AF"), - (0xC7B5, "110C 1162 11B0"), - (0xC7B6, "110C 1162 11B1"), - (0xC7B7, "110C 1162 11B2"), - (0xC7B8, "110C 1162 11B3"), - (0xC7B9, "110C 1162 11B4"), - (0xC7BA, "110C 1162 11B5"), - (0xC7BB, "110C 1162 11B6"), - (0xC7BC, "110C 1162 11B7"), - (0xC7BD, "110C 1162 11B8"), - (0xC7BE, "110C 1162 11B9"), - (0xC7BF, "110C 1162 11BA"), - (0xC7C0, "110C 1162 11BB"), - (0xC7C1, "110C 1162 11BC"), - (0xC7C2, "110C 1162 11BD"), - (0xC7C3, "110C 1162 11BE"), - (0xC7C4, "110C 1162 11BF"), - (0xC7C5, "110C 1162 11C0"), - (0xC7C6, "110C 1162 11C1"), - (0xC7C7, "110C 1162 11C2"), - (0xC7C8, "110C 1163"), - (0xC7C9, "110C 1163 11A8"), - (0xC7CA, "110C 1163 11A9"), - (0xC7CB, "110C 1163 11AA"), - (0xC7CC, "110C 1163 11AB"), - (0xC7CD, "110C 1163 11AC"), - (0xC7CE, "110C 1163 11AD"), - (0xC7CF, "110C 1163 11AE"), - (0xC7D0, "110C 1163 11AF"), - (0xC7D1, "110C 1163 11B0"), - (0xC7D2, "110C 1163 11B1"), - (0xC7D3, "110C 1163 11B2"), - (0xC7D4, "110C 1163 11B3"), - (0xC7D5, "110C 1163 11B4"), - (0xC7D6, "110C 1163 11B5"), - (0xC7D7, "110C 1163 11B6"), - (0xC7D8, "110C 1163 11B7"), - (0xC7D9, "110C 1163 11B8"), - (0xC7DA, "110C 1163 11B9"), - (0xC7DB, "110C 1163 11BA"), - (0xC7DC, "110C 1163 11BB"), - (0xC7DD, "110C 1163 11BC"), - (0xC7DE, "110C 1163 11BD"), - (0xC7DF, "110C 1163 11BE"), - (0xC7E0, "110C 1163 11BF"), - (0xC7E1, "110C 1163 11C0"), - (0xC7E2, "110C 1163 11C1"), - (0xC7E3, "110C 1163 11C2"), - (0xC7E4, "110C 1164"), - (0xC7E5, "110C 1164 11A8"), - (0xC7E6, "110C 1164 11A9"), - (0xC7E7, "110C 1164 11AA"), - (0xC7E8, "110C 1164 11AB"), - (0xC7E9, "110C 1164 11AC"), - (0xC7EA, "110C 1164 11AD"), - (0xC7EB, "110C 1164 11AE"), - (0xC7EC, "110C 1164 11AF"), - (0xC7ED, "110C 1164 11B0"), - (0xC7EE, "110C 1164 11B1"), - (0xC7EF, "110C 1164 11B2"), - (0xC7F0, "110C 1164 11B3"), - (0xC7F1, "110C 1164 11B4"), - (0xC7F2, "110C 1164 11B5"), - (0xC7F3, "110C 1164 11B6"), - (0xC7F4, "110C 1164 11B7"), - (0xC7F5, "110C 1164 11B8"), - (0xC7F6, "110C 1164 11B9"), - (0xC7F7, "110C 1164 11BA"), - (0xC7F8, "110C 1164 11BB"), - (0xC7F9, "110C 1164 11BC"), - (0xC7FA, "110C 1164 11BD"), - (0xC7FB, "110C 1164 11BE"), - (0xC7FC, "110C 1164 11BF"), - (0xC7FD, "110C 1164 11C0"), - (0xC7FE, "110C 1164 11C1"), - (0xC7FF, "110C 1164 11C2"), - (0xC800, "110C 1165"), - (0xC801, "110C 1165 11A8"), - (0xC802, "110C 1165 11A9"), - (0xC803, "110C 1165 11AA"), - (0xC804, "110C 1165 11AB"), - (0xC805, "110C 1165 11AC"), - (0xC806, "110C 1165 11AD"), - (0xC807, "110C 1165 11AE"), - (0xC808, "110C 1165 11AF"), - (0xC809, "110C 1165 11B0"), - (0xC80A, "110C 1165 11B1"), - (0xC80B, "110C 1165 11B2"), - (0xC80C, "110C 1165 11B3"), - (0xC80D, "110C 1165 11B4"), - (0xC80E, "110C 1165 11B5"), - (0xC80F, "110C 1165 11B6"), - (0xC810, "110C 1165 11B7"), - (0xC811, "110C 1165 11B8"), - (0xC812, "110C 1165 11B9"), - (0xC813, "110C 1165 11BA"), - (0xC814, "110C 1165 11BB"), - (0xC815, "110C 1165 11BC"), - (0xC816, "110C 1165 11BD"), - (0xC817, "110C 1165 11BE"), - (0xC818, "110C 1165 11BF"), - (0xC819, "110C 1165 11C0"), - (0xC81A, "110C 1165 11C1"), - (0xC81B, "110C 1165 11C2"), - (0xC81C, "110C 1166"), - (0xC81D, "110C 1166 11A8"), - (0xC81E, "110C 1166 11A9"), - (0xC81F, "110C 1166 11AA"), - (0xC820, "110C 1166 11AB"), - (0xC821, "110C 1166 11AC"), - (0xC822, "110C 1166 11AD"), - (0xC823, "110C 1166 11AE"), - (0xC824, "110C 1166 11AF"), - (0xC825, "110C 1166 11B0"), - (0xC826, "110C 1166 11B1"), - (0xC827, "110C 1166 11B2"), - (0xC828, "110C 1166 11B3"), - (0xC829, "110C 1166 11B4"), - (0xC82A, "110C 1166 11B5"), - (0xC82B, "110C 1166 11B6"), - (0xC82C, "110C 1166 11B7"), - (0xC82D, "110C 1166 11B8"), - (0xC82E, "110C 1166 11B9"), - (0xC82F, "110C 1166 11BA"), - (0xC830, "110C 1166 11BB"), - (0xC831, "110C 1166 11BC"), - (0xC832, "110C 1166 11BD"), - (0xC833, "110C 1166 11BE"), - (0xC834, "110C 1166 11BF"), - (0xC835, "110C 1166 11C0"), - (0xC836, "110C 1166 11C1"), - (0xC837, "110C 1166 11C2"), - (0xC838, "110C 1167"), - (0xC839, "110C 1167 11A8"), - (0xC83A, "110C 1167 11A9"), - (0xC83B, "110C 1167 11AA"), - (0xC83C, "110C 1167 11AB"), - (0xC83D, "110C 1167 11AC"), - (0xC83E, "110C 1167 11AD"), - (0xC83F, "110C 1167 11AE"), - (0xC840, "110C 1167 11AF"), - (0xC841, "110C 1167 11B0"), - (0xC842, "110C 1167 11B1"), - (0xC843, "110C 1167 11B2"), - (0xC844, "110C 1167 11B3"), - (0xC845, "110C 1167 11B4"), - (0xC846, "110C 1167 11B5"), - (0xC847, "110C 1167 11B6"), - (0xC848, "110C 1167 11B7"), - (0xC849, "110C 1167 11B8"), - (0xC84A, "110C 1167 11B9"), - (0xC84B, "110C 1167 11BA"), - (0xC84C, "110C 1167 11BB"), - (0xC84D, "110C 1167 11BC"), - (0xC84E, "110C 1167 11BD"), - (0xC84F, "110C 1167 11BE"), - (0xC850, "110C 1167 11BF"), - (0xC851, "110C 1167 11C0"), - (0xC852, "110C 1167 11C1"), - (0xC853, "110C 1167 11C2"), - (0xC854, "110C 1168"), - (0xC855, "110C 1168 11A8"), - (0xC856, "110C 1168 11A9"), - (0xC857, "110C 1168 11AA"), - (0xC858, "110C 1168 11AB"), - (0xC859, "110C 1168 11AC"), - (0xC85A, "110C 1168 11AD"), - (0xC85B, "110C 1168 11AE"), - (0xC85C, "110C 1168 11AF"), - (0xC85D, "110C 1168 11B0"), - (0xC85E, "110C 1168 11B1"), - (0xC85F, "110C 1168 11B2"), - (0xC860, "110C 1168 11B3"), - (0xC861, "110C 1168 11B4"), - (0xC862, "110C 1168 11B5"), - (0xC863, "110C 1168 11B6"), - (0xC864, "110C 1168 11B7"), - (0xC865, "110C 1168 11B8"), - (0xC866, "110C 1168 11B9"), - (0xC867, "110C 1168 11BA"), - (0xC868, "110C 1168 11BB"), - (0xC869, "110C 1168 11BC"), - (0xC86A, "110C 1168 11BD"), - (0xC86B, "110C 1168 11BE"), - (0xC86C, "110C 1168 11BF"), - (0xC86D, "110C 1168 11C0"), - (0xC86E, "110C 1168 11C1"), - (0xC86F, "110C 1168 11C2"), - (0xC870, "110C 1169"), - (0xC871, "110C 1169 11A8"), - (0xC872, "110C 1169 11A9"), - (0xC873, "110C 1169 11AA"), - (0xC874, "110C 1169 11AB"), - (0xC875, "110C 1169 11AC"), - (0xC876, "110C 1169 11AD"), - (0xC877, "110C 1169 11AE"), - (0xC878, "110C 1169 11AF"), - (0xC879, "110C 1169 11B0"), - (0xC87A, "110C 1169 11B1"), - (0xC87B, "110C 1169 11B2"), - (0xC87C, "110C 1169 11B3"), - (0xC87D, "110C 1169 11B4"), - (0xC87E, "110C 1169 11B5"), - (0xC87F, "110C 1169 11B6"), - (0xC880, "110C 1169 11B7"), - (0xC881, "110C 1169 11B8"), - (0xC882, "110C 1169 11B9"), - (0xC883, "110C 1169 11BA"), - (0xC884, "110C 1169 11BB"), - (0xC885, "110C 1169 11BC"), - (0xC886, "110C 1169 11BD"), - (0xC887, "110C 1169 11BE"), - (0xC888, "110C 1169 11BF"), - (0xC889, "110C 1169 11C0"), - (0xC88A, "110C 1169 11C1"), - (0xC88B, "110C 1169 11C2"), - (0xC88C, "110C 116A"), - (0xC88D, "110C 116A 11A8"), - (0xC88E, "110C 116A 11A9"), - (0xC88F, "110C 116A 11AA"), - (0xC890, "110C 116A 11AB"), - (0xC891, "110C 116A 11AC"), - (0xC892, "110C 116A 11AD"), - (0xC893, "110C 116A 11AE"), - (0xC894, "110C 116A 11AF"), - (0xC895, "110C 116A 11B0"), - (0xC896, "110C 116A 11B1"), - (0xC897, "110C 116A 11B2"), - (0xC898, "110C 116A 11B3"), - (0xC899, "110C 116A 11B4"), - (0xC89A, "110C 116A 11B5"), - (0xC89B, "110C 116A 11B6"), - (0xC89C, "110C 116A 11B7"), - (0xC89D, "110C 116A 11B8"), - (0xC89E, "110C 116A 11B9"), - (0xC89F, "110C 116A 11BA"), - (0xC8A0, "110C 116A 11BB"), - (0xC8A1, "110C 116A 11BC"), - (0xC8A2, "110C 116A 11BD"), - (0xC8A3, "110C 116A 11BE"), - (0xC8A4, "110C 116A 11BF"), - (0xC8A5, "110C 116A 11C0"), - (0xC8A6, "110C 116A 11C1"), - (0xC8A7, "110C 116A 11C2"), - (0xC8A8, "110C 116B"), - (0xC8A9, "110C 116B 11A8"), - (0xC8AA, "110C 116B 11A9"), - (0xC8AB, "110C 116B 11AA"), - (0xC8AC, "110C 116B 11AB"), - (0xC8AD, "110C 116B 11AC"), - (0xC8AE, "110C 116B 11AD"), - (0xC8AF, "110C 116B 11AE"), - (0xC8B0, "110C 116B 11AF"), - (0xC8B1, "110C 116B 11B0"), - (0xC8B2, "110C 116B 11B1"), - (0xC8B3, "110C 116B 11B2"), - (0xC8B4, "110C 116B 11B3"), - (0xC8B5, "110C 116B 11B4"), - (0xC8B6, "110C 116B 11B5"), - (0xC8B7, "110C 116B 11B6"), - (0xC8B8, "110C 116B 11B7"), - (0xC8B9, "110C 116B 11B8"), - (0xC8BA, "110C 116B 11B9"), - (0xC8BB, "110C 116B 11BA"), - (0xC8BC, "110C 116B 11BB"), - (0xC8BD, "110C 116B 11BC"), - (0xC8BE, "110C 116B 11BD"), - (0xC8BF, "110C 116B 11BE"), - (0xC8C0, "110C 116B 11BF"), - (0xC8C1, "110C 116B 11C0"), - (0xC8C2, "110C 116B 11C1"), - (0xC8C3, "110C 116B 11C2"), - (0xC8C4, "110C 116C"), - (0xC8C5, "110C 116C 11A8"), - (0xC8C6, "110C 116C 11A9"), - (0xC8C7, "110C 116C 11AA"), - (0xC8C8, "110C 116C 11AB"), - (0xC8C9, "110C 116C 11AC"), - (0xC8CA, "110C 116C 11AD"), - (0xC8CB, "110C 116C 11AE"), - (0xC8CC, "110C 116C 11AF"), - (0xC8CD, "110C 116C 11B0"), - (0xC8CE, "110C 116C 11B1"), - (0xC8CF, "110C 116C 11B2"), - (0xC8D0, "110C 116C 11B3"), - (0xC8D1, "110C 116C 11B4"), - (0xC8D2, "110C 116C 11B5"), - (0xC8D3, "110C 116C 11B6"), - (0xC8D4, "110C 116C 11B7"), - (0xC8D5, "110C 116C 11B8"), - (0xC8D6, "110C 116C 11B9"), - (0xC8D7, "110C 116C 11BA"), - (0xC8D8, "110C 116C 11BB"), - (0xC8D9, "110C 116C 11BC"), - (0xC8DA, "110C 116C 11BD"), - (0xC8DB, "110C 116C 11BE"), - (0xC8DC, "110C 116C 11BF"), - (0xC8DD, "110C 116C 11C0"), - (0xC8DE, "110C 116C 11C1"), - (0xC8DF, "110C 116C 11C2"), - (0xC8E0, "110C 116D"), - (0xC8E1, "110C 116D 11A8"), - (0xC8E2, "110C 116D 11A9"), - (0xC8E3, "110C 116D 11AA"), - (0xC8E4, "110C 116D 11AB"), - (0xC8E5, "110C 116D 11AC"), - (0xC8E6, "110C 116D 11AD"), - (0xC8E7, "110C 116D 11AE"), - (0xC8E8, "110C 116D 11AF"), - (0xC8E9, "110C 116D 11B0"), - (0xC8EA, "110C 116D 11B1"), - (0xC8EB, "110C 116D 11B2"), - (0xC8EC, "110C 116D 11B3"), - (0xC8ED, "110C 116D 11B4"), - (0xC8EE, "110C 116D 11B5"), - (0xC8EF, "110C 116D 11B6"), - (0xC8F0, "110C 116D 11B7"), - (0xC8F1, "110C 116D 11B8"), - (0xC8F2, "110C 116D 11B9"), - (0xC8F3, "110C 116D 11BA"), - (0xC8F4, "110C 116D 11BB"), - (0xC8F5, "110C 116D 11BC"), - (0xC8F6, "110C 116D 11BD"), - (0xC8F7, "110C 116D 11BE"), - (0xC8F8, "110C 116D 11BF"), - (0xC8F9, "110C 116D 11C0"), - (0xC8FA, "110C 116D 11C1"), - (0xC8FB, "110C 116D 11C2"), - (0xC8FC, "110C 116E"), - (0xC8FD, "110C 116E 11A8"), - (0xC8FE, "110C 116E 11A9"), - (0xC8FF, "110C 116E 11AA"), - (0xC900, "110C 116E 11AB"), - (0xC901, "110C 116E 11AC"), - (0xC902, "110C 116E 11AD"), - (0xC903, "110C 116E 11AE"), - (0xC904, "110C 116E 11AF"), - (0xC905, "110C 116E 11B0"), - (0xC906, "110C 116E 11B1"), - (0xC907, "110C 116E 11B2"), - (0xC908, "110C 116E 11B3"), - (0xC909, "110C 116E 11B4"), - (0xC90A, "110C 116E 11B5"), - (0xC90B, "110C 116E 11B6"), - (0xC90C, "110C 116E 11B7"), - (0xC90D, "110C 116E 11B8"), - (0xC90E, "110C 116E 11B9"), - (0xC90F, "110C 116E 11BA"), - (0xC910, "110C 116E 11BB"), - (0xC911, "110C 116E 11BC"), - (0xC912, "110C 116E 11BD"), - (0xC913, "110C 116E 11BE"), - (0xC914, "110C 116E 11BF"), - (0xC915, "110C 116E 11C0"), - (0xC916, "110C 116E 11C1"), - (0xC917, "110C 116E 11C2"), - (0xC918, "110C 116F"), - (0xC919, "110C 116F 11A8"), - (0xC91A, "110C 116F 11A9"), - (0xC91B, "110C 116F 11AA"), - (0xC91C, "110C 116F 11AB"), - (0xC91D, "110C 116F 11AC"), - (0xC91E, "110C 116F 11AD"), - (0xC91F, "110C 116F 11AE"), - (0xC920, "110C 116F 11AF"), - (0xC921, "110C 116F 11B0"), - (0xC922, "110C 116F 11B1"), - (0xC923, "110C 116F 11B2"), - (0xC924, "110C 116F 11B3"), - (0xC925, "110C 116F 11B4"), - (0xC926, "110C 116F 11B5"), - (0xC927, "110C 116F 11B6"), - (0xC928, "110C 116F 11B7"), - (0xC929, "110C 116F 11B8"), - (0xC92A, "110C 116F 11B9"), - (0xC92B, "110C 116F 11BA"), - (0xC92C, "110C 116F 11BB"), - (0xC92D, "110C 116F 11BC"), - (0xC92E, "110C 116F 11BD"), - (0xC92F, "110C 116F 11BE"), - (0xC930, "110C 116F 11BF"), - (0xC931, "110C 116F 11C0"), - (0xC932, "110C 116F 11C1"), - (0xC933, "110C 116F 11C2"), - (0xC934, "110C 1170"), - (0xC935, "110C 1170 11A8"), - (0xC936, "110C 1170 11A9"), - (0xC937, "110C 1170 11AA"), - (0xC938, "110C 1170 11AB"), - (0xC939, "110C 1170 11AC"), - (0xC93A, "110C 1170 11AD"), - (0xC93B, "110C 1170 11AE"), - (0xC93C, "110C 1170 11AF"), - (0xC93D, "110C 1170 11B0"), - (0xC93E, "110C 1170 11B1"), - (0xC93F, "110C 1170 11B2"), - (0xC940, "110C 1170 11B3"), - (0xC941, "110C 1170 11B4"), - (0xC942, "110C 1170 11B5"), - (0xC943, "110C 1170 11B6"), - (0xC944, "110C 1170 11B7"), - (0xC945, "110C 1170 11B8"), - (0xC946, "110C 1170 11B9"), - (0xC947, "110C 1170 11BA"), - (0xC948, "110C 1170 11BB"), - (0xC949, "110C 1170 11BC"), - (0xC94A, "110C 1170 11BD"), - (0xC94B, "110C 1170 11BE"), - (0xC94C, "110C 1170 11BF"), - (0xC94D, "110C 1170 11C0"), - (0xC94E, "110C 1170 11C1"), - (0xC94F, "110C 1170 11C2"), - (0xC950, "110C 1171"), - (0xC951, "110C 1171 11A8"), - (0xC952, "110C 1171 11A9"), - (0xC953, "110C 1171 11AA"), - (0xC954, "110C 1171 11AB"), - (0xC955, "110C 1171 11AC"), - (0xC956, "110C 1171 11AD"), - (0xC957, "110C 1171 11AE"), - (0xC958, "110C 1171 11AF"), - (0xC959, "110C 1171 11B0"), - (0xC95A, "110C 1171 11B1"), - (0xC95B, "110C 1171 11B2"), - (0xC95C, "110C 1171 11B3"), - (0xC95D, "110C 1171 11B4"), - (0xC95E, "110C 1171 11B5"), - (0xC95F, "110C 1171 11B6"), - (0xC960, "110C 1171 11B7"), - (0xC961, "110C 1171 11B8"), - (0xC962, "110C 1171 11B9"), - (0xC963, "110C 1171 11BA"), - (0xC964, "110C 1171 11BB"), - (0xC965, "110C 1171 11BC"), - (0xC966, "110C 1171 11BD"), - (0xC967, "110C 1171 11BE"), - (0xC968, "110C 1171 11BF"), - (0xC969, "110C 1171 11C0"), - (0xC96A, "110C 1171 11C1"), - (0xC96B, "110C 1171 11C2"), - (0xC96C, "110C 1172"), - (0xC96D, "110C 1172 11A8"), - (0xC96E, "110C 1172 11A9"), - (0xC96F, "110C 1172 11AA"), - (0xC970, "110C 1172 11AB"), - (0xC971, "110C 1172 11AC"), - (0xC972, "110C 1172 11AD"), - (0xC973, "110C 1172 11AE"), - (0xC974, "110C 1172 11AF"), - (0xC975, "110C 1172 11B0"), - (0xC976, "110C 1172 11B1"), - (0xC977, "110C 1172 11B2"), - (0xC978, "110C 1172 11B3"), - (0xC979, "110C 1172 11B4"), - (0xC97A, "110C 1172 11B5"), - (0xC97B, "110C 1172 11B6"), - (0xC97C, "110C 1172 11B7"), - (0xC97D, "110C 1172 11B8"), - (0xC97E, "110C 1172 11B9"), - (0xC97F, "110C 1172 11BA"), - (0xC980, "110C 1172 11BB"), - (0xC981, "110C 1172 11BC"), - (0xC982, "110C 1172 11BD"), - (0xC983, "110C 1172 11BE"), - (0xC984, "110C 1172 11BF"), - (0xC985, "110C 1172 11C0"), - (0xC986, "110C 1172 11C1"), - (0xC987, "110C 1172 11C2"), - (0xC988, "110C 1173"), - (0xC989, "110C 1173 11A8"), - (0xC98A, "110C 1173 11A9"), - (0xC98B, "110C 1173 11AA"), - (0xC98C, "110C 1173 11AB"), - (0xC98D, "110C 1173 11AC"), - (0xC98E, "110C 1173 11AD"), - (0xC98F, "110C 1173 11AE"), - (0xC990, "110C 1173 11AF"), - (0xC991, "110C 1173 11B0"), - (0xC992, "110C 1173 11B1"), - (0xC993, "110C 1173 11B2"), - (0xC994, "110C 1173 11B3"), - (0xC995, "110C 1173 11B4"), - (0xC996, "110C 1173 11B5"), - (0xC997, "110C 1173 11B6"), - (0xC998, "110C 1173 11B7"), - (0xC999, "110C 1173 11B8"), - (0xC99A, "110C 1173 11B9"), - (0xC99B, "110C 1173 11BA"), - (0xC99C, "110C 1173 11BB"), - (0xC99D, "110C 1173 11BC"), - (0xC99E, "110C 1173 11BD"), - (0xC99F, "110C 1173 11BE"), - (0xC9A0, "110C 1173 11BF"), - (0xC9A1, "110C 1173 11C0"), - (0xC9A2, "110C 1173 11C1"), - (0xC9A3, "110C 1173 11C2"), - (0xC9A4, "110C 1174"), - (0xC9A5, "110C 1174 11A8"), - (0xC9A6, "110C 1174 11A9"), - (0xC9A7, "110C 1174 11AA"), - (0xC9A8, "110C 1174 11AB"), - (0xC9A9, "110C 1174 11AC"), - (0xC9AA, "110C 1174 11AD"), - (0xC9AB, "110C 1174 11AE"), - (0xC9AC, "110C 1174 11AF"), - (0xC9AD, "110C 1174 11B0"), - (0xC9AE, "110C 1174 11B1"), - (0xC9AF, "110C 1174 11B2"), - (0xC9B0, "110C 1174 11B3"), - (0xC9B1, "110C 1174 11B4"), - (0xC9B2, "110C 1174 11B5"), - (0xC9B3, "110C 1174 11B6"), - (0xC9B4, "110C 1174 11B7"), - (0xC9B5, "110C 1174 11B8"), - (0xC9B6, "110C 1174 11B9"), - (0xC9B7, "110C 1174 11BA"), - (0xC9B8, "110C 1174 11BB"), - (0xC9B9, "110C 1174 11BC"), - (0xC9BA, "110C 1174 11BD"), - (0xC9BB, "110C 1174 11BE"), - (0xC9BC, "110C 1174 11BF"), - (0xC9BD, "110C 1174 11C0"), - (0xC9BE, "110C 1174 11C1"), - (0xC9BF, "110C 1174 11C2"), - (0xC9C0, "110C 1175"), - (0xC9C1, "110C 1175 11A8"), - (0xC9C2, "110C 1175 11A9"), - (0xC9C3, "110C 1175 11AA"), - (0xC9C4, "110C 1175 11AB"), - (0xC9C5, "110C 1175 11AC"), - (0xC9C6, "110C 1175 11AD"), - (0xC9C7, "110C 1175 11AE"), - (0xC9C8, "110C 1175 11AF"), - (0xC9C9, "110C 1175 11B0"), - (0xC9CA, "110C 1175 11B1"), - (0xC9CB, "110C 1175 11B2"), - (0xC9CC, "110C 1175 11B3"), - (0xC9CD, "110C 1175 11B4"), - (0xC9CE, "110C 1175 11B5"), - (0xC9CF, "110C 1175 11B6"), - (0xC9D0, "110C 1175 11B7"), - (0xC9D1, "110C 1175 11B8"), - (0xC9D2, "110C 1175 11B9"), - (0xC9D3, "110C 1175 11BA"), - (0xC9D4, "110C 1175 11BB"), - (0xC9D5, "110C 1175 11BC"), - (0xC9D6, "110C 1175 11BD"), - (0xC9D7, "110C 1175 11BE"), - (0xC9D8, "110C 1175 11BF"), - (0xC9D9, "110C 1175 11C0"), - (0xC9DA, "110C 1175 11C1"), - (0xC9DB, "110C 1175 11C2"), - (0xC9DC, "110D 1161"), - (0xC9DD, "110D 1161 11A8"), - (0xC9DE, "110D 1161 11A9"), - (0xC9DF, "110D 1161 11AA"), - (0xC9E0, "110D 1161 11AB"), - (0xC9E1, "110D 1161 11AC"), - (0xC9E2, "110D 1161 11AD"), - (0xC9E3, "110D 1161 11AE"), - (0xC9E4, "110D 1161 11AF"), - (0xC9E5, "110D 1161 11B0"), - (0xC9E6, "110D 1161 11B1"), - (0xC9E7, "110D 1161 11B2"), - (0xC9E8, "110D 1161 11B3"), - (0xC9E9, "110D 1161 11B4"), - (0xC9EA, "110D 1161 11B5"), - (0xC9EB, "110D 1161 11B6"), - (0xC9EC, "110D 1161 11B7"), - (0xC9ED, "110D 1161 11B8"), - (0xC9EE, "110D 1161 11B9"), - (0xC9EF, "110D 1161 11BA"), - (0xC9F0, "110D 1161 11BB"), - (0xC9F1, "110D 1161 11BC"), - (0xC9F2, "110D 1161 11BD"), - (0xC9F3, "110D 1161 11BE"), - (0xC9F4, "110D 1161 11BF"), - (0xC9F5, "110D 1161 11C0"), - (0xC9F6, "110D 1161 11C1"), - (0xC9F7, "110D 1161 11C2"), - (0xC9F8, "110D 1162"), - (0xC9F9, "110D 1162 11A8"), - (0xC9FA, "110D 1162 11A9"), - (0xC9FB, "110D 1162 11AA"), - (0xC9FC, "110D 1162 11AB"), - (0xC9FD, "110D 1162 11AC"), - (0xC9FE, "110D 1162 11AD"), - (0xC9FF, "110D 1162 11AE"), - (0xCA00, "110D 1162 11AF"), - (0xCA01, "110D 1162 11B0"), - (0xCA02, "110D 1162 11B1"), - (0xCA03, "110D 1162 11B2"), - (0xCA04, "110D 1162 11B3"), - (0xCA05, "110D 1162 11B4"), - (0xCA06, "110D 1162 11B5"), - (0xCA07, "110D 1162 11B6"), - (0xCA08, "110D 1162 11B7"), - (0xCA09, "110D 1162 11B8"), - (0xCA0A, "110D 1162 11B9"), - (0xCA0B, "110D 1162 11BA"), - (0xCA0C, "110D 1162 11BB"), - (0xCA0D, "110D 1162 11BC"), - (0xCA0E, "110D 1162 11BD"), - (0xCA0F, "110D 1162 11BE"), - (0xCA10, "110D 1162 11BF"), - (0xCA11, "110D 1162 11C0"), - (0xCA12, "110D 1162 11C1"), - (0xCA13, "110D 1162 11C2"), - (0xCA14, "110D 1163"), - (0xCA15, "110D 1163 11A8"), - (0xCA16, "110D 1163 11A9"), - (0xCA17, "110D 1163 11AA"), - (0xCA18, "110D 1163 11AB"), - (0xCA19, "110D 1163 11AC"), - (0xCA1A, "110D 1163 11AD"), - (0xCA1B, "110D 1163 11AE"), - (0xCA1C, "110D 1163 11AF"), - (0xCA1D, "110D 1163 11B0"), - (0xCA1E, "110D 1163 11B1"), - (0xCA1F, "110D 1163 11B2"), - (0xCA20, "110D 1163 11B3"), - (0xCA21, "110D 1163 11B4"), - (0xCA22, "110D 1163 11B5"), - (0xCA23, "110D 1163 11B6"), - (0xCA24, "110D 1163 11B7"), - (0xCA25, "110D 1163 11B8"), - (0xCA26, "110D 1163 11B9"), - (0xCA27, "110D 1163 11BA"), - (0xCA28, "110D 1163 11BB"), - (0xCA29, "110D 1163 11BC"), - (0xCA2A, "110D 1163 11BD"), - (0xCA2B, "110D 1163 11BE"), - (0xCA2C, "110D 1163 11BF"), - (0xCA2D, "110D 1163 11C0"), - (0xCA2E, "110D 1163 11C1"), - (0xCA2F, "110D 1163 11C2"), - (0xCA30, "110D 1164"), - (0xCA31, "110D 1164 11A8"), - (0xCA32, "110D 1164 11A9"), - (0xCA33, "110D 1164 11AA"), - (0xCA34, "110D 1164 11AB"), - (0xCA35, "110D 1164 11AC"), - (0xCA36, "110D 1164 11AD"), - (0xCA37, "110D 1164 11AE"), - (0xCA38, "110D 1164 11AF"), - (0xCA39, "110D 1164 11B0"), - (0xCA3A, "110D 1164 11B1"), - (0xCA3B, "110D 1164 11B2"), - (0xCA3C, "110D 1164 11B3"), - (0xCA3D, "110D 1164 11B4"), - (0xCA3E, "110D 1164 11B5"), - (0xCA3F, "110D 1164 11B6"), - (0xCA40, "110D 1164 11B7"), - (0xCA41, "110D 1164 11B8"), - (0xCA42, "110D 1164 11B9"), - (0xCA43, "110D 1164 11BA"), - (0xCA44, "110D 1164 11BB"), - (0xCA45, "110D 1164 11BC"), - (0xCA46, "110D 1164 11BD"), - (0xCA47, "110D 1164 11BE"), - (0xCA48, "110D 1164 11BF"), - (0xCA49, "110D 1164 11C0"), - (0xCA4A, "110D 1164 11C1"), - (0xCA4B, "110D 1164 11C2"), - (0xCA4C, "110D 1165"), - (0xCA4D, "110D 1165 11A8"), - (0xCA4E, "110D 1165 11A9"), - (0xCA4F, "110D 1165 11AA"), - (0xCA50, "110D 1165 11AB"), - (0xCA51, "110D 1165 11AC"), - (0xCA52, "110D 1165 11AD"), - (0xCA53, "110D 1165 11AE"), - (0xCA54, "110D 1165 11AF"), - (0xCA55, "110D 1165 11B0"), - (0xCA56, "110D 1165 11B1"), - (0xCA57, "110D 1165 11B2"), - (0xCA58, "110D 1165 11B3"), - (0xCA59, "110D 1165 11B4"), - (0xCA5A, "110D 1165 11B5"), - (0xCA5B, "110D 1165 11B6"), - (0xCA5C, "110D 1165 11B7"), - (0xCA5D, "110D 1165 11B8"), - (0xCA5E, "110D 1165 11B9"), - (0xCA5F, "110D 1165 11BA"), - (0xCA60, "110D 1165 11BB"), - (0xCA61, "110D 1165 11BC"), - (0xCA62, "110D 1165 11BD"), - (0xCA63, "110D 1165 11BE"), - (0xCA64, "110D 1165 11BF"), - (0xCA65, "110D 1165 11C0"), - (0xCA66, "110D 1165 11C1"), - (0xCA67, "110D 1165 11C2"), - (0xCA68, "110D 1166"), - (0xCA69, "110D 1166 11A8"), - (0xCA6A, "110D 1166 11A9"), - (0xCA6B, "110D 1166 11AA"), - (0xCA6C, "110D 1166 11AB"), - (0xCA6D, "110D 1166 11AC"), - (0xCA6E, "110D 1166 11AD"), - (0xCA6F, "110D 1166 11AE"), - (0xCA70, "110D 1166 11AF"), - (0xCA71, "110D 1166 11B0"), - (0xCA72, "110D 1166 11B1"), - (0xCA73, "110D 1166 11B2"), - (0xCA74, "110D 1166 11B3"), - (0xCA75, "110D 1166 11B4"), - (0xCA76, "110D 1166 11B5"), - (0xCA77, "110D 1166 11B6"), - (0xCA78, "110D 1166 11B7"), - (0xCA79, "110D 1166 11B8"), - (0xCA7A, "110D 1166 11B9"), - (0xCA7B, "110D 1166 11BA"), - (0xCA7C, "110D 1166 11BB"), - (0xCA7D, "110D 1166 11BC"), - (0xCA7E, "110D 1166 11BD"), - (0xCA7F, "110D 1166 11BE"), - (0xCA80, "110D 1166 11BF"), - (0xCA81, "110D 1166 11C0"), - (0xCA82, "110D 1166 11C1"), - (0xCA83, "110D 1166 11C2"), - (0xCA84, "110D 1167"), - (0xCA85, "110D 1167 11A8"), - (0xCA86, "110D 1167 11A9"), - (0xCA87, "110D 1167 11AA"), - (0xCA88, "110D 1167 11AB"), - (0xCA89, "110D 1167 11AC"), - (0xCA8A, "110D 1167 11AD"), - (0xCA8B, "110D 1167 11AE"), - (0xCA8C, "110D 1167 11AF"), - (0xCA8D, "110D 1167 11B0"), - (0xCA8E, "110D 1167 11B1"), - (0xCA8F, "110D 1167 11B2"), - (0xCA90, "110D 1167 11B3"), - (0xCA91, "110D 1167 11B4"), - (0xCA92, "110D 1167 11B5"), - (0xCA93, "110D 1167 11B6"), - (0xCA94, "110D 1167 11B7"), - (0xCA95, "110D 1167 11B8"), - (0xCA96, "110D 1167 11B9"), - (0xCA97, "110D 1167 11BA"), - (0xCA98, "110D 1167 11BB"), - (0xCA99, "110D 1167 11BC"), - (0xCA9A, "110D 1167 11BD"), - (0xCA9B, "110D 1167 11BE"), - (0xCA9C, "110D 1167 11BF"), - (0xCA9D, "110D 1167 11C0"), - (0xCA9E, "110D 1167 11C1"), - (0xCA9F, "110D 1167 11C2"), - (0xCAA0, "110D 1168"), - (0xCAA1, "110D 1168 11A8"), - (0xCAA2, "110D 1168 11A9"), - (0xCAA3, "110D 1168 11AA"), - (0xCAA4, "110D 1168 11AB"), - (0xCAA5, "110D 1168 11AC"), - (0xCAA6, "110D 1168 11AD"), - (0xCAA7, "110D 1168 11AE"), - (0xCAA8, "110D 1168 11AF"), - (0xCAA9, "110D 1168 11B0"), - (0xCAAA, "110D 1168 11B1"), - (0xCAAB, "110D 1168 11B2"), - (0xCAAC, "110D 1168 11B3"), - (0xCAAD, "110D 1168 11B4"), - (0xCAAE, "110D 1168 11B5"), - (0xCAAF, "110D 1168 11B6"), - (0xCAB0, "110D 1168 11B7"), - (0xCAB1, "110D 1168 11B8"), - (0xCAB2, "110D 1168 11B9"), - (0xCAB3, "110D 1168 11BA"), - (0xCAB4, "110D 1168 11BB"), - (0xCAB5, "110D 1168 11BC"), - (0xCAB6, "110D 1168 11BD"), - (0xCAB7, "110D 1168 11BE"), - (0xCAB8, "110D 1168 11BF"), - (0xCAB9, "110D 1168 11C0"), - (0xCABA, "110D 1168 11C1"), - (0xCABB, "110D 1168 11C2"), - (0xCABC, "110D 1169"), - (0xCABD, "110D 1169 11A8"), - (0xCABE, "110D 1169 11A9"), - (0xCABF, "110D 1169 11AA"), - (0xCAC0, "110D 1169 11AB"), - (0xCAC1, "110D 1169 11AC"), - (0xCAC2, "110D 1169 11AD"), - (0xCAC3, "110D 1169 11AE"), - (0xCAC4, "110D 1169 11AF"), - (0xCAC5, "110D 1169 11B0"), - (0xCAC6, "110D 1169 11B1"), - (0xCAC7, "110D 1169 11B2"), - (0xCAC8, "110D 1169 11B3"), - (0xCAC9, "110D 1169 11B4"), - (0xCACA, "110D 1169 11B5"), - (0xCACB, "110D 1169 11B6"), - (0xCACC, "110D 1169 11B7"), - (0xCACD, "110D 1169 11B8"), - (0xCACE, "110D 1169 11B9"), - (0xCACF, "110D 1169 11BA"), - (0xCAD0, "110D 1169 11BB"), - (0xCAD1, "110D 1169 11BC"), - (0xCAD2, "110D 1169 11BD"), - (0xCAD3, "110D 1169 11BE"), - (0xCAD4, "110D 1169 11BF"), - (0xCAD5, "110D 1169 11C0"), - (0xCAD6, "110D 1169 11C1"), - (0xCAD7, "110D 1169 11C2"), - (0xCAD8, "110D 116A"), - (0xCAD9, "110D 116A 11A8"), - (0xCADA, "110D 116A 11A9"), - (0xCADB, "110D 116A 11AA"), - (0xCADC, "110D 116A 11AB"), - (0xCADD, "110D 116A 11AC"), - (0xCADE, "110D 116A 11AD"), - (0xCADF, "110D 116A 11AE"), - (0xCAE0, "110D 116A 11AF"), - (0xCAE1, "110D 116A 11B0"), - (0xCAE2, "110D 116A 11B1"), - (0xCAE3, "110D 116A 11B2"), - (0xCAE4, "110D 116A 11B3"), - (0xCAE5, "110D 116A 11B4"), - (0xCAE6, "110D 116A 11B5"), - (0xCAE7, "110D 116A 11B6"), - (0xCAE8, "110D 116A 11B7"), - (0xCAE9, "110D 116A 11B8"), - (0xCAEA, "110D 116A 11B9"), - (0xCAEB, "110D 116A 11BA"), - (0xCAEC, "110D 116A 11BB"), - (0xCAED, "110D 116A 11BC"), - (0xCAEE, "110D 116A 11BD"), - (0xCAEF, "110D 116A 11BE"), - (0xCAF0, "110D 116A 11BF"), - (0xCAF1, "110D 116A 11C0"), - (0xCAF2, "110D 116A 11C1"), - (0xCAF3, "110D 116A 11C2"), - (0xCAF4, "110D 116B"), - (0xCAF5, "110D 116B 11A8"), - (0xCAF6, "110D 116B 11A9"), - (0xCAF7, "110D 116B 11AA"), - (0xCAF8, "110D 116B 11AB"), - (0xCAF9, "110D 116B 11AC"), - (0xCAFA, "110D 116B 11AD"), - (0xCAFB, "110D 116B 11AE"), - (0xCAFC, "110D 116B 11AF"), - (0xCAFD, "110D 116B 11B0"), - (0xCAFE, "110D 116B 11B1"), - (0xCAFF, "110D 116B 11B2"), - (0xCB00, "110D 116B 11B3"), - (0xCB01, "110D 116B 11B4"), - (0xCB02, "110D 116B 11B5"), - (0xCB03, "110D 116B 11B6"), - (0xCB04, "110D 116B 11B7"), - (0xCB05, "110D 116B 11B8"), - (0xCB06, "110D 116B 11B9"), - (0xCB07, "110D 116B 11BA"), - (0xCB08, "110D 116B 11BB"), - (0xCB09, "110D 116B 11BC"), - (0xCB0A, "110D 116B 11BD"), - (0xCB0B, "110D 116B 11BE"), - (0xCB0C, "110D 116B 11BF"), - (0xCB0D, "110D 116B 11C0"), - (0xCB0E, "110D 116B 11C1"), - (0xCB0F, "110D 116B 11C2"), - (0xCB10, "110D 116C"), - (0xCB11, "110D 116C 11A8"), - (0xCB12, "110D 116C 11A9"), - (0xCB13, "110D 116C 11AA"), - (0xCB14, "110D 116C 11AB"), - (0xCB15, "110D 116C 11AC"), - (0xCB16, "110D 116C 11AD"), - (0xCB17, "110D 116C 11AE"), - (0xCB18, "110D 116C 11AF"), - (0xCB19, "110D 116C 11B0"), - (0xCB1A, "110D 116C 11B1"), - (0xCB1B, "110D 116C 11B2"), - (0xCB1C, "110D 116C 11B3"), - (0xCB1D, "110D 116C 11B4"), - (0xCB1E, "110D 116C 11B5"), - (0xCB1F, "110D 116C 11B6"), - (0xCB20, "110D 116C 11B7"), - (0xCB21, "110D 116C 11B8"), - (0xCB22, "110D 116C 11B9"), - (0xCB23, "110D 116C 11BA"), - (0xCB24, "110D 116C 11BB"), - (0xCB25, "110D 116C 11BC"), - (0xCB26, "110D 116C 11BD"), - (0xCB27, "110D 116C 11BE"), - (0xCB28, "110D 116C 11BF"), - (0xCB29, "110D 116C 11C0"), - (0xCB2A, "110D 116C 11C1"), - (0xCB2B, "110D 116C 11C2"), - (0xCB2C, "110D 116D"), - (0xCB2D, "110D 116D 11A8"), - (0xCB2E, "110D 116D 11A9"), - (0xCB2F, "110D 116D 11AA"), - (0xCB30, "110D 116D 11AB"), - (0xCB31, "110D 116D 11AC"), - (0xCB32, "110D 116D 11AD"), - (0xCB33, "110D 116D 11AE"), - (0xCB34, "110D 116D 11AF"), - (0xCB35, "110D 116D 11B0"), - (0xCB36, "110D 116D 11B1"), - (0xCB37, "110D 116D 11B2"), - (0xCB38, "110D 116D 11B3"), - (0xCB39, "110D 116D 11B4"), - (0xCB3A, "110D 116D 11B5"), - (0xCB3B, "110D 116D 11B6"), - (0xCB3C, "110D 116D 11B7"), - (0xCB3D, "110D 116D 11B8"), - (0xCB3E, "110D 116D 11B9"), - (0xCB3F, "110D 116D 11BA"), - (0xCB40, "110D 116D 11BB"), - (0xCB41, "110D 116D 11BC"), - (0xCB42, "110D 116D 11BD"), - (0xCB43, "110D 116D 11BE"), - (0xCB44, "110D 116D 11BF"), - (0xCB45, "110D 116D 11C0"), - (0xCB46, "110D 116D 11C1"), - (0xCB47, "110D 116D 11C2"), - (0xCB48, "110D 116E"), - (0xCB49, "110D 116E 11A8"), - (0xCB4A, "110D 116E 11A9"), - (0xCB4B, "110D 116E 11AA"), - (0xCB4C, "110D 116E 11AB"), - (0xCB4D, "110D 116E 11AC"), - (0xCB4E, "110D 116E 11AD"), - (0xCB4F, "110D 116E 11AE"), - (0xCB50, "110D 116E 11AF"), - (0xCB51, "110D 116E 11B0"), - (0xCB52, "110D 116E 11B1"), - (0xCB53, "110D 116E 11B2"), - (0xCB54, "110D 116E 11B3"), - (0xCB55, "110D 116E 11B4"), - (0xCB56, "110D 116E 11B5"), - (0xCB57, "110D 116E 11B6"), - (0xCB58, "110D 116E 11B7"), - (0xCB59, "110D 116E 11B8"), - (0xCB5A, "110D 116E 11B9"), - (0xCB5B, "110D 116E 11BA"), - (0xCB5C, "110D 116E 11BB"), - (0xCB5D, "110D 116E 11BC"), - (0xCB5E, "110D 116E 11BD"), - (0xCB5F, "110D 116E 11BE"), - (0xCB60, "110D 116E 11BF"), - (0xCB61, "110D 116E 11C0"), - (0xCB62, "110D 116E 11C1"), - (0xCB63, "110D 116E 11C2"), - (0xCB64, "110D 116F"), - (0xCB65, "110D 116F 11A8"), - (0xCB66, "110D 116F 11A9"), - (0xCB67, "110D 116F 11AA"), - (0xCB68, "110D 116F 11AB"), - (0xCB69, "110D 116F 11AC"), - (0xCB6A, "110D 116F 11AD"), - (0xCB6B, "110D 116F 11AE"), - (0xCB6C, "110D 116F 11AF"), - (0xCB6D, "110D 116F 11B0"), - (0xCB6E, "110D 116F 11B1"), - (0xCB6F, "110D 116F 11B2"), - (0xCB70, "110D 116F 11B3"), - (0xCB71, "110D 116F 11B4"), - (0xCB72, "110D 116F 11B5"), - (0xCB73, "110D 116F 11B6"), - (0xCB74, "110D 116F 11B7"), - (0xCB75, "110D 116F 11B8"), - (0xCB76, "110D 116F 11B9"), - (0xCB77, "110D 116F 11BA"), - (0xCB78, "110D 116F 11BB"), - (0xCB79, "110D 116F 11BC"), - (0xCB7A, "110D 116F 11BD"), - (0xCB7B, "110D 116F 11BE"), - (0xCB7C, "110D 116F 11BF"), - (0xCB7D, "110D 116F 11C0"), - (0xCB7E, "110D 116F 11C1"), - (0xCB7F, "110D 116F 11C2"), - (0xCB80, "110D 1170"), - (0xCB81, "110D 1170 11A8"), - (0xCB82, "110D 1170 11A9"), - (0xCB83, "110D 1170 11AA"), - (0xCB84, "110D 1170 11AB"), - (0xCB85, "110D 1170 11AC"), - (0xCB86, "110D 1170 11AD"), - (0xCB87, "110D 1170 11AE"), - (0xCB88, "110D 1170 11AF"), - (0xCB89, "110D 1170 11B0"), - (0xCB8A, "110D 1170 11B1"), - (0xCB8B, "110D 1170 11B2"), - (0xCB8C, "110D 1170 11B3"), - (0xCB8D, "110D 1170 11B4"), - (0xCB8E, "110D 1170 11B5"), - (0xCB8F, "110D 1170 11B6"), - (0xCB90, "110D 1170 11B7"), - (0xCB91, "110D 1170 11B8"), - (0xCB92, "110D 1170 11B9"), - (0xCB93, "110D 1170 11BA"), - (0xCB94, "110D 1170 11BB"), - (0xCB95, "110D 1170 11BC"), - (0xCB96, "110D 1170 11BD"), - (0xCB97, "110D 1170 11BE"), - (0xCB98, "110D 1170 11BF"), - (0xCB99, "110D 1170 11C0"), - (0xCB9A, "110D 1170 11C1"), - (0xCB9B, "110D 1170 11C2"), - (0xCB9C, "110D 1171"), - (0xCB9D, "110D 1171 11A8"), - (0xCB9E, "110D 1171 11A9"), - (0xCB9F, "110D 1171 11AA"), - (0xCBA0, "110D 1171 11AB"), - (0xCBA1, "110D 1171 11AC"), - (0xCBA2, "110D 1171 11AD"), - (0xCBA3, "110D 1171 11AE"), - (0xCBA4, "110D 1171 11AF"), - (0xCBA5, "110D 1171 11B0"), - (0xCBA6, "110D 1171 11B1"), - (0xCBA7, "110D 1171 11B2"), - (0xCBA8, "110D 1171 11B3"), - (0xCBA9, "110D 1171 11B4"), - (0xCBAA, "110D 1171 11B5"), - (0xCBAB, "110D 1171 11B6"), - (0xCBAC, "110D 1171 11B7"), - (0xCBAD, "110D 1171 11B8"), - (0xCBAE, "110D 1171 11B9"), - (0xCBAF, "110D 1171 11BA"), - (0xCBB0, "110D 1171 11BB"), - (0xCBB1, "110D 1171 11BC"), - (0xCBB2, "110D 1171 11BD"), - (0xCBB3, "110D 1171 11BE"), - (0xCBB4, "110D 1171 11BF"), - (0xCBB5, "110D 1171 11C0"), - (0xCBB6, "110D 1171 11C1"), - (0xCBB7, "110D 1171 11C2"), - (0xCBB8, "110D 1172"), - (0xCBB9, "110D 1172 11A8"), - (0xCBBA, "110D 1172 11A9"), - (0xCBBB, "110D 1172 11AA"), - (0xCBBC, "110D 1172 11AB"), - (0xCBBD, "110D 1172 11AC"), - (0xCBBE, "110D 1172 11AD"), - (0xCBBF, "110D 1172 11AE"), - (0xCBC0, "110D 1172 11AF"), - (0xCBC1, "110D 1172 11B0"), - (0xCBC2, "110D 1172 11B1"), - (0xCBC3, "110D 1172 11B2"), - (0xCBC4, "110D 1172 11B3"), - (0xCBC5, "110D 1172 11B4"), - (0xCBC6, "110D 1172 11B5"), - (0xCBC7, "110D 1172 11B6"), - (0xCBC8, "110D 1172 11B7"), - (0xCBC9, "110D 1172 11B8"), - (0xCBCA, "110D 1172 11B9"), - (0xCBCB, "110D 1172 11BA"), - (0xCBCC, "110D 1172 11BB"), - (0xCBCD, "110D 1172 11BC"), - (0xCBCE, "110D 1172 11BD"), - (0xCBCF, "110D 1172 11BE"), - (0xCBD0, "110D 1172 11BF"), - (0xCBD1, "110D 1172 11C0"), - (0xCBD2, "110D 1172 11C1"), - (0xCBD3, "110D 1172 11C2"), - (0xCBD4, "110D 1173"), - (0xCBD5, "110D 1173 11A8"), - (0xCBD6, "110D 1173 11A9"), - (0xCBD7, "110D 1173 11AA"), - (0xCBD8, "110D 1173 11AB"), - (0xCBD9, "110D 1173 11AC"), - (0xCBDA, "110D 1173 11AD"), - (0xCBDB, "110D 1173 11AE"), - (0xCBDC, "110D 1173 11AF"), - (0xCBDD, "110D 1173 11B0"), - (0xCBDE, "110D 1173 11B1"), - (0xCBDF, "110D 1173 11B2"), - (0xCBE0, "110D 1173 11B3"), - (0xCBE1, "110D 1173 11B4"), - (0xCBE2, "110D 1173 11B5"), - (0xCBE3, "110D 1173 11B6"), - (0xCBE4, "110D 1173 11B7"), - (0xCBE5, "110D 1173 11B8"), - (0xCBE6, "110D 1173 11B9"), - (0xCBE7, "110D 1173 11BA"), - (0xCBE8, "110D 1173 11BB"), - (0xCBE9, "110D 1173 11BC"), - (0xCBEA, "110D 1173 11BD"), - (0xCBEB, "110D 1173 11BE"), - (0xCBEC, "110D 1173 11BF"), - (0xCBED, "110D 1173 11C0"), - (0xCBEE, "110D 1173 11C1"), - (0xCBEF, "110D 1173 11C2"), - (0xCBF0, "110D 1174"), - (0xCBF1, "110D 1174 11A8"), - (0xCBF2, "110D 1174 11A9"), - (0xCBF3, "110D 1174 11AA"), - (0xCBF4, "110D 1174 11AB"), - (0xCBF5, "110D 1174 11AC"), - (0xCBF6, "110D 1174 11AD"), - (0xCBF7, "110D 1174 11AE"), - (0xCBF8, "110D 1174 11AF"), - (0xCBF9, "110D 1174 11B0"), - (0xCBFA, "110D 1174 11B1"), - (0xCBFB, "110D 1174 11B2"), - (0xCBFC, "110D 1174 11B3"), - (0xCBFD, "110D 1174 11B4"), - (0xCBFE, "110D 1174 11B5"), - (0xCBFF, "110D 1174 11B6"), - (0xCC00, "110D 1174 11B7"), - (0xCC01, "110D 1174 11B8"), - (0xCC02, "110D 1174 11B9"), - (0xCC03, "110D 1174 11BA"), - (0xCC04, "110D 1174 11BB"), - (0xCC05, "110D 1174 11BC"), - (0xCC06, "110D 1174 11BD"), - (0xCC07, "110D 1174 11BE"), - (0xCC08, "110D 1174 11BF"), - (0xCC09, "110D 1174 11C0"), - (0xCC0A, "110D 1174 11C1"), - (0xCC0B, "110D 1174 11C2"), - (0xCC0C, "110D 1175"), - (0xCC0D, "110D 1175 11A8"), - (0xCC0E, "110D 1175 11A9"), - (0xCC0F, "110D 1175 11AA"), - (0xCC10, "110D 1175 11AB"), - (0xCC11, "110D 1175 11AC"), - (0xCC12, "110D 1175 11AD"), - (0xCC13, "110D 1175 11AE"), - (0xCC14, "110D 1175 11AF"), - (0xCC15, "110D 1175 11B0"), - (0xCC16, "110D 1175 11B1"), - (0xCC17, "110D 1175 11B2"), - (0xCC18, "110D 1175 11B3"), - (0xCC19, "110D 1175 11B4"), - (0xCC1A, "110D 1175 11B5"), - (0xCC1B, "110D 1175 11B6"), - (0xCC1C, "110D 1175 11B7"), - (0xCC1D, "110D 1175 11B8"), - (0xCC1E, "110D 1175 11B9"), - (0xCC1F, "110D 1175 11BA"), - (0xCC20, "110D 1175 11BB"), - (0xCC21, "110D 1175 11BC"), - (0xCC22, "110D 1175 11BD"), - (0xCC23, "110D 1175 11BE"), - (0xCC24, "110D 1175 11BF"), - (0xCC25, "110D 1175 11C0"), - (0xCC26, "110D 1175 11C1"), - (0xCC27, "110D 1175 11C2"), - (0xCC28, "110E 1161"), - (0xCC29, "110E 1161 11A8"), - (0xCC2A, "110E 1161 11A9"), - (0xCC2B, "110E 1161 11AA"), - (0xCC2C, "110E 1161 11AB"), - (0xCC2D, "110E 1161 11AC"), - (0xCC2E, "110E 1161 11AD"), - (0xCC2F, "110E 1161 11AE"), - (0xCC30, "110E 1161 11AF"), - (0xCC31, "110E 1161 11B0"), - (0xCC32, "110E 1161 11B1"), - (0xCC33, "110E 1161 11B2"), - (0xCC34, "110E 1161 11B3"), - (0xCC35, "110E 1161 11B4"), - (0xCC36, "110E 1161 11B5"), - (0xCC37, "110E 1161 11B6"), - (0xCC38, "110E 1161 11B7"), - (0xCC39, "110E 1161 11B8"), - (0xCC3A, "110E 1161 11B9"), - (0xCC3B, "110E 1161 11BA"), - (0xCC3C, "110E 1161 11BB"), - (0xCC3D, "110E 1161 11BC"), - (0xCC3E, "110E 1161 11BD"), - (0xCC3F, "110E 1161 11BE"), - (0xCC40, "110E 1161 11BF"), - (0xCC41, "110E 1161 11C0"), - (0xCC42, "110E 1161 11C1"), - (0xCC43, "110E 1161 11C2"), - (0xCC44, "110E 1162"), - (0xCC45, "110E 1162 11A8"), - (0xCC46, "110E 1162 11A9"), - (0xCC47, "110E 1162 11AA"), - (0xCC48, "110E 1162 11AB"), - (0xCC49, "110E 1162 11AC"), - (0xCC4A, "110E 1162 11AD"), - (0xCC4B, "110E 1162 11AE"), - (0xCC4C, "110E 1162 11AF"), - (0xCC4D, "110E 1162 11B0"), - (0xCC4E, "110E 1162 11B1"), - (0xCC4F, "110E 1162 11B2"), - (0xCC50, "110E 1162 11B3"), - (0xCC51, "110E 1162 11B4"), - (0xCC52, "110E 1162 11B5"), - (0xCC53, "110E 1162 11B6"), - (0xCC54, "110E 1162 11B7"), - (0xCC55, "110E 1162 11B8"), - (0xCC56, "110E 1162 11B9"), - (0xCC57, "110E 1162 11BA"), - (0xCC58, "110E 1162 11BB"), - (0xCC59, "110E 1162 11BC"), - (0xCC5A, "110E 1162 11BD"), - (0xCC5B, "110E 1162 11BE"), - (0xCC5C, "110E 1162 11BF"), - (0xCC5D, "110E 1162 11C0"), - (0xCC5E, "110E 1162 11C1"), - (0xCC5F, "110E 1162 11C2"), - (0xCC60, "110E 1163"), - (0xCC61, "110E 1163 11A8"), - (0xCC62, "110E 1163 11A9"), - (0xCC63, "110E 1163 11AA"), - (0xCC64, "110E 1163 11AB"), - (0xCC65, "110E 1163 11AC"), - (0xCC66, "110E 1163 11AD"), - (0xCC67, "110E 1163 11AE"), - (0xCC68, "110E 1163 11AF"), - (0xCC69, "110E 1163 11B0"), - (0xCC6A, "110E 1163 11B1"), - (0xCC6B, "110E 1163 11B2"), - (0xCC6C, "110E 1163 11B3"), - (0xCC6D, "110E 1163 11B4"), - (0xCC6E, "110E 1163 11B5"), - (0xCC6F, "110E 1163 11B6"), - (0xCC70, "110E 1163 11B7"), - (0xCC71, "110E 1163 11B8"), - (0xCC72, "110E 1163 11B9"), - (0xCC73, "110E 1163 11BA"), - (0xCC74, "110E 1163 11BB"), - (0xCC75, "110E 1163 11BC"), - (0xCC76, "110E 1163 11BD"), - (0xCC77, "110E 1163 11BE"), - (0xCC78, "110E 1163 11BF"), - (0xCC79, "110E 1163 11C0"), - (0xCC7A, "110E 1163 11C1"), - (0xCC7B, "110E 1163 11C2"), - (0xCC7C, "110E 1164"), - (0xCC7D, "110E 1164 11A8"), - (0xCC7E, "110E 1164 11A9"), - (0xCC7F, "110E 1164 11AA"), - (0xCC80, "110E 1164 11AB"), - (0xCC81, "110E 1164 11AC"), - (0xCC82, "110E 1164 11AD"), - (0xCC83, "110E 1164 11AE"), - (0xCC84, "110E 1164 11AF"), - (0xCC85, "110E 1164 11B0"), - (0xCC86, "110E 1164 11B1"), - (0xCC87, "110E 1164 11B2"), - (0xCC88, "110E 1164 11B3"), - (0xCC89, "110E 1164 11B4"), - (0xCC8A, "110E 1164 11B5"), - (0xCC8B, "110E 1164 11B6"), - (0xCC8C, "110E 1164 11B7"), - (0xCC8D, "110E 1164 11B8"), - (0xCC8E, "110E 1164 11B9"), - (0xCC8F, "110E 1164 11BA"), - (0xCC90, "110E 1164 11BB"), - (0xCC91, "110E 1164 11BC"), - (0xCC92, "110E 1164 11BD"), - (0xCC93, "110E 1164 11BE"), - (0xCC94, "110E 1164 11BF"), - (0xCC95, "110E 1164 11C0"), - (0xCC96, "110E 1164 11C1"), - (0xCC97, "110E 1164 11C2"), - (0xCC98, "110E 1165"), - (0xCC99, "110E 1165 11A8"), - (0xCC9A, "110E 1165 11A9"), - (0xCC9B, "110E 1165 11AA"), - (0xCC9C, "110E 1165 11AB"), - (0xCC9D, "110E 1165 11AC"), - (0xCC9E, "110E 1165 11AD"), - (0xCC9F, "110E 1165 11AE"), - (0xCCA0, "110E 1165 11AF"), - (0xCCA1, "110E 1165 11B0"), - (0xCCA2, "110E 1165 11B1"), - (0xCCA3, "110E 1165 11B2"), - (0xCCA4, "110E 1165 11B3"), - (0xCCA5, "110E 1165 11B4"), - (0xCCA6, "110E 1165 11B5"), - (0xCCA7, "110E 1165 11B6"), - (0xCCA8, "110E 1165 11B7"), - (0xCCA9, "110E 1165 11B8"), - (0xCCAA, "110E 1165 11B9"), - (0xCCAB, "110E 1165 11BA"), - (0xCCAC, "110E 1165 11BB"), - (0xCCAD, "110E 1165 11BC"), - (0xCCAE, "110E 1165 11BD"), - (0xCCAF, "110E 1165 11BE"), - (0xCCB0, "110E 1165 11BF"), - (0xCCB1, "110E 1165 11C0"), - (0xCCB2, "110E 1165 11C1"), - (0xCCB3, "110E 1165 11C2"), - (0xCCB4, "110E 1166"), - (0xCCB5, "110E 1166 11A8"), - (0xCCB6, "110E 1166 11A9"), - (0xCCB7, "110E 1166 11AA"), - (0xCCB8, "110E 1166 11AB"), - (0xCCB9, "110E 1166 11AC"), - (0xCCBA, "110E 1166 11AD"), - (0xCCBB, "110E 1166 11AE"), - (0xCCBC, "110E 1166 11AF"), - (0xCCBD, "110E 1166 11B0"), - (0xCCBE, "110E 1166 11B1"), - (0xCCBF, "110E 1166 11B2"), - (0xCCC0, "110E 1166 11B3"), - (0xCCC1, "110E 1166 11B4"), - (0xCCC2, "110E 1166 11B5"), - (0xCCC3, "110E 1166 11B6"), - (0xCCC4, "110E 1166 11B7"), - (0xCCC5, "110E 1166 11B8"), - (0xCCC6, "110E 1166 11B9"), - (0xCCC7, "110E 1166 11BA"), - (0xCCC8, "110E 1166 11BB"), - (0xCCC9, "110E 1166 11BC"), - (0xCCCA, "110E 1166 11BD"), - (0xCCCB, "110E 1166 11BE"), - (0xCCCC, "110E 1166 11BF"), - (0xCCCD, "110E 1166 11C0"), - (0xCCCE, "110E 1166 11C1"), - (0xCCCF, "110E 1166 11C2"), - (0xCCD0, "110E 1167"), - (0xCCD1, "110E 1167 11A8"), - (0xCCD2, "110E 1167 11A9"), - (0xCCD3, "110E 1167 11AA"), - (0xCCD4, "110E 1167 11AB"), - (0xCCD5, "110E 1167 11AC"), - (0xCCD6, "110E 1167 11AD"), - (0xCCD7, "110E 1167 11AE"), - (0xCCD8, "110E 1167 11AF"), - (0xCCD9, "110E 1167 11B0"), - (0xCCDA, "110E 1167 11B1"), - (0xCCDB, "110E 1167 11B2"), - (0xCCDC, "110E 1167 11B3"), - (0xCCDD, "110E 1167 11B4"), - (0xCCDE, "110E 1167 11B5"), - (0xCCDF, "110E 1167 11B6"), - (0xCCE0, "110E 1167 11B7"), - (0xCCE1, "110E 1167 11B8"), - (0xCCE2, "110E 1167 11B9"), - (0xCCE3, "110E 1167 11BA"), - (0xCCE4, "110E 1167 11BB"), - (0xCCE5, "110E 1167 11BC"), - (0xCCE6, "110E 1167 11BD"), - (0xCCE7, "110E 1167 11BE"), - (0xCCE8, "110E 1167 11BF"), - (0xCCE9, "110E 1167 11C0"), - (0xCCEA, "110E 1167 11C1"), - (0xCCEB, "110E 1167 11C2"), - (0xCCEC, "110E 1168"), - (0xCCED, "110E 1168 11A8"), - (0xCCEE, "110E 1168 11A9"), - (0xCCEF, "110E 1168 11AA"), - (0xCCF0, "110E 1168 11AB"), - (0xCCF1, "110E 1168 11AC"), - (0xCCF2, "110E 1168 11AD"), - (0xCCF3, "110E 1168 11AE"), - (0xCCF4, "110E 1168 11AF"), - (0xCCF5, "110E 1168 11B0"), - (0xCCF6, "110E 1168 11B1"), - (0xCCF7, "110E 1168 11B2"), - (0xCCF8, "110E 1168 11B3"), - (0xCCF9, "110E 1168 11B4"), - (0xCCFA, "110E 1168 11B5"), - (0xCCFB, "110E 1168 11B6"), - (0xCCFC, "110E 1168 11B7"), - (0xCCFD, "110E 1168 11B8"), - (0xCCFE, "110E 1168 11B9"), - (0xCCFF, "110E 1168 11BA"), - (0xCD00, "110E 1168 11BB"), - (0xCD01, "110E 1168 11BC"), - (0xCD02, "110E 1168 11BD"), - (0xCD03, "110E 1168 11BE"), - (0xCD04, "110E 1168 11BF"), - (0xCD05, "110E 1168 11C0"), - (0xCD06, "110E 1168 11C1"), - (0xCD07, "110E 1168 11C2"), - (0xCD08, "110E 1169"), - (0xCD09, "110E 1169 11A8"), - (0xCD0A, "110E 1169 11A9"), - (0xCD0B, "110E 1169 11AA"), - (0xCD0C, "110E 1169 11AB"), - (0xCD0D, "110E 1169 11AC"), - (0xCD0E, "110E 1169 11AD"), - (0xCD0F, "110E 1169 11AE"), - (0xCD10, "110E 1169 11AF"), - (0xCD11, "110E 1169 11B0"), - (0xCD12, "110E 1169 11B1"), - (0xCD13, "110E 1169 11B2"), - (0xCD14, "110E 1169 11B3"), - (0xCD15, "110E 1169 11B4"), - (0xCD16, "110E 1169 11B5"), - (0xCD17, "110E 1169 11B6"), - (0xCD18, "110E 1169 11B7"), - (0xCD19, "110E 1169 11B8"), - (0xCD1A, "110E 1169 11B9"), - (0xCD1B, "110E 1169 11BA"), - (0xCD1C, "110E 1169 11BB"), - (0xCD1D, "110E 1169 11BC"), - (0xCD1E, "110E 1169 11BD"), - (0xCD1F, "110E 1169 11BE"), - (0xCD20, "110E 1169 11BF"), - (0xCD21, "110E 1169 11C0"), - (0xCD22, "110E 1169 11C1"), - (0xCD23, "110E 1169 11C2"), - (0xCD24, "110E 116A"), - (0xCD25, "110E 116A 11A8"), - (0xCD26, "110E 116A 11A9"), - (0xCD27, "110E 116A 11AA"), - (0xCD28, "110E 116A 11AB"), - (0xCD29, "110E 116A 11AC"), - (0xCD2A, "110E 116A 11AD"), - (0xCD2B, "110E 116A 11AE"), - (0xCD2C, "110E 116A 11AF"), - (0xCD2D, "110E 116A 11B0"), - (0xCD2E, "110E 116A 11B1"), - (0xCD2F, "110E 116A 11B2"), - (0xCD30, "110E 116A 11B3"), - (0xCD31, "110E 116A 11B4"), - (0xCD32, "110E 116A 11B5"), - (0xCD33, "110E 116A 11B6"), - (0xCD34, "110E 116A 11B7"), - (0xCD35, "110E 116A 11B8"), - (0xCD36, "110E 116A 11B9"), - (0xCD37, "110E 116A 11BA"), - (0xCD38, "110E 116A 11BB"), - (0xCD39, "110E 116A 11BC"), - (0xCD3A, "110E 116A 11BD"), - (0xCD3B, "110E 116A 11BE"), - (0xCD3C, "110E 116A 11BF"), - (0xCD3D, "110E 116A 11C0"), - (0xCD3E, "110E 116A 11C1"), - (0xCD3F, "110E 116A 11C2"), - (0xCD40, "110E 116B"), - (0xCD41, "110E 116B 11A8"), - (0xCD42, "110E 116B 11A9"), - (0xCD43, "110E 116B 11AA"), - (0xCD44, "110E 116B 11AB"), - (0xCD45, "110E 116B 11AC"), - (0xCD46, "110E 116B 11AD"), - (0xCD47, "110E 116B 11AE"), - (0xCD48, "110E 116B 11AF"), - (0xCD49, "110E 116B 11B0"), - (0xCD4A, "110E 116B 11B1"), - (0xCD4B, "110E 116B 11B2"), - (0xCD4C, "110E 116B 11B3"), - (0xCD4D, "110E 116B 11B4"), - (0xCD4E, "110E 116B 11B5"), - (0xCD4F, "110E 116B 11B6"), - (0xCD50, "110E 116B 11B7"), - (0xCD51, "110E 116B 11B8"), - (0xCD52, "110E 116B 11B9"), - (0xCD53, "110E 116B 11BA"), - (0xCD54, "110E 116B 11BB"), - (0xCD55, "110E 116B 11BC"), - (0xCD56, "110E 116B 11BD"), - (0xCD57, "110E 116B 11BE"), - (0xCD58, "110E 116B 11BF"), - (0xCD59, "110E 116B 11C0"), - (0xCD5A, "110E 116B 11C1"), - (0xCD5B, "110E 116B 11C2"), - (0xCD5C, "110E 116C"), - (0xCD5D, "110E 116C 11A8"), - (0xCD5E, "110E 116C 11A9"), - (0xCD5F, "110E 116C 11AA"), - (0xCD60, "110E 116C 11AB"), - (0xCD61, "110E 116C 11AC"), - (0xCD62, "110E 116C 11AD"), - (0xCD63, "110E 116C 11AE"), - (0xCD64, "110E 116C 11AF"), - (0xCD65, "110E 116C 11B0"), - (0xCD66, "110E 116C 11B1"), - (0xCD67, "110E 116C 11B2"), - (0xCD68, "110E 116C 11B3"), - (0xCD69, "110E 116C 11B4"), - (0xCD6A, "110E 116C 11B5"), - (0xCD6B, "110E 116C 11B6"), - (0xCD6C, "110E 116C 11B7"), - (0xCD6D, "110E 116C 11B8"), - (0xCD6E, "110E 116C 11B9"), - (0xCD6F, "110E 116C 11BA"), - (0xCD70, "110E 116C 11BB"), - (0xCD71, "110E 116C 11BC"), - (0xCD72, "110E 116C 11BD"), - (0xCD73, "110E 116C 11BE"), - (0xCD74, "110E 116C 11BF"), - (0xCD75, "110E 116C 11C0"), - (0xCD76, "110E 116C 11C1"), - (0xCD77, "110E 116C 11C2"), - (0xCD78, "110E 116D"), - (0xCD79, "110E 116D 11A8"), - (0xCD7A, "110E 116D 11A9"), - (0xCD7B, "110E 116D 11AA"), - (0xCD7C, "110E 116D 11AB"), - (0xCD7D, "110E 116D 11AC"), - (0xCD7E, "110E 116D 11AD"), - (0xCD7F, "110E 116D 11AE"), - (0xCD80, "110E 116D 11AF"), - (0xCD81, "110E 116D 11B0"), - (0xCD82, "110E 116D 11B1"), - (0xCD83, "110E 116D 11B2"), - (0xCD84, "110E 116D 11B3"), - (0xCD85, "110E 116D 11B4"), - (0xCD86, "110E 116D 11B5"), - (0xCD87, "110E 116D 11B6"), - (0xCD88, "110E 116D 11B7"), - (0xCD89, "110E 116D 11B8"), - (0xCD8A, "110E 116D 11B9"), - (0xCD8B, "110E 116D 11BA"), - (0xCD8C, "110E 116D 11BB"), - (0xCD8D, "110E 116D 11BC"), - (0xCD8E, "110E 116D 11BD"), - (0xCD8F, "110E 116D 11BE"), - (0xCD90, "110E 116D 11BF"), - (0xCD91, "110E 116D 11C0"), - (0xCD92, "110E 116D 11C1"), - (0xCD93, "110E 116D 11C2"), - (0xCD94, "110E 116E"), - (0xCD95, "110E 116E 11A8"), - (0xCD96, "110E 116E 11A9"), - (0xCD97, "110E 116E 11AA"), - (0xCD98, "110E 116E 11AB"), - (0xCD99, "110E 116E 11AC"), - (0xCD9A, "110E 116E 11AD"), - (0xCD9B, "110E 116E 11AE"), - (0xCD9C, "110E 116E 11AF"), - (0xCD9D, "110E 116E 11B0"), - (0xCD9E, "110E 116E 11B1"), - (0xCD9F, "110E 116E 11B2"), - (0xCDA0, "110E 116E 11B3"), - (0xCDA1, "110E 116E 11B4"), - (0xCDA2, "110E 116E 11B5"), - (0xCDA3, "110E 116E 11B6"), - (0xCDA4, "110E 116E 11B7"), - (0xCDA5, "110E 116E 11B8"), - (0xCDA6, "110E 116E 11B9"), - (0xCDA7, "110E 116E 11BA"), - (0xCDA8, "110E 116E 11BB"), - (0xCDA9, "110E 116E 11BC"), - (0xCDAA, "110E 116E 11BD"), - (0xCDAB, "110E 116E 11BE"), - (0xCDAC, "110E 116E 11BF"), - (0xCDAD, "110E 116E 11C0"), - (0xCDAE, "110E 116E 11C1"), - (0xCDAF, "110E 116E 11C2"), - (0xCDB0, "110E 116F"), - (0xCDB1, "110E 116F 11A8"), - (0xCDB2, "110E 116F 11A9"), - (0xCDB3, "110E 116F 11AA"), - (0xCDB4, "110E 116F 11AB"), - (0xCDB5, "110E 116F 11AC"), - (0xCDB6, "110E 116F 11AD"), - (0xCDB7, "110E 116F 11AE"), - (0xCDB8, "110E 116F 11AF"), - (0xCDB9, "110E 116F 11B0"), - (0xCDBA, "110E 116F 11B1"), - (0xCDBB, "110E 116F 11B2"), - (0xCDBC, "110E 116F 11B3"), - (0xCDBD, "110E 116F 11B4"), - (0xCDBE, "110E 116F 11B5"), - (0xCDBF, "110E 116F 11B6"), - (0xCDC0, "110E 116F 11B7"), - (0xCDC1, "110E 116F 11B8"), - (0xCDC2, "110E 116F 11B9"), - (0xCDC3, "110E 116F 11BA"), - (0xCDC4, "110E 116F 11BB"), - (0xCDC5, "110E 116F 11BC"), - (0xCDC6, "110E 116F 11BD"), - (0xCDC7, "110E 116F 11BE"), - (0xCDC8, "110E 116F 11BF"), - (0xCDC9, "110E 116F 11C0"), - (0xCDCA, "110E 116F 11C1"), - (0xCDCB, "110E 116F 11C2"), - (0xCDCC, "110E 1170"), - (0xCDCD, "110E 1170 11A8"), - (0xCDCE, "110E 1170 11A9"), - (0xCDCF, "110E 1170 11AA"), - (0xCDD0, "110E 1170 11AB"), - (0xCDD1, "110E 1170 11AC"), - (0xCDD2, "110E 1170 11AD"), - (0xCDD3, "110E 1170 11AE"), - (0xCDD4, "110E 1170 11AF"), - (0xCDD5, "110E 1170 11B0"), - (0xCDD6, "110E 1170 11B1"), - (0xCDD7, "110E 1170 11B2"), - (0xCDD8, "110E 1170 11B3"), - (0xCDD9, "110E 1170 11B4"), - (0xCDDA, "110E 1170 11B5"), - (0xCDDB, "110E 1170 11B6"), - (0xCDDC, "110E 1170 11B7"), - (0xCDDD, "110E 1170 11B8"), - (0xCDDE, "110E 1170 11B9"), - (0xCDDF, "110E 1170 11BA"), - (0xCDE0, "110E 1170 11BB"), - (0xCDE1, "110E 1170 11BC"), - (0xCDE2, "110E 1170 11BD"), - (0xCDE3, "110E 1170 11BE"), - (0xCDE4, "110E 1170 11BF"), - (0xCDE5, "110E 1170 11C0"), - (0xCDE6, "110E 1170 11C1"), - (0xCDE7, "110E 1170 11C2"), - (0xCDE8, "110E 1171"), - (0xCDE9, "110E 1171 11A8"), - (0xCDEA, "110E 1171 11A9"), - (0xCDEB, "110E 1171 11AA"), - (0xCDEC, "110E 1171 11AB"), - (0xCDED, "110E 1171 11AC"), - (0xCDEE, "110E 1171 11AD"), - (0xCDEF, "110E 1171 11AE"), - (0xCDF0, "110E 1171 11AF"), - (0xCDF1, "110E 1171 11B0"), - (0xCDF2, "110E 1171 11B1"), - (0xCDF3, "110E 1171 11B2"), - (0xCDF4, "110E 1171 11B3"), - (0xCDF5, "110E 1171 11B4"), - (0xCDF6, "110E 1171 11B5"), - (0xCDF7, "110E 1171 11B6"), - (0xCDF8, "110E 1171 11B7"), - (0xCDF9, "110E 1171 11B8"), - (0xCDFA, "110E 1171 11B9"), - (0xCDFB, "110E 1171 11BA"), - (0xCDFC, "110E 1171 11BB"), - (0xCDFD, "110E 1171 11BC"), - (0xCDFE, "110E 1171 11BD"), - (0xCDFF, "110E 1171 11BE"), - (0xCE00, "110E 1171 11BF"), - (0xCE01, "110E 1171 11C0"), - (0xCE02, "110E 1171 11C1"), - (0xCE03, "110E 1171 11C2"), - (0xCE04, "110E 1172"), - (0xCE05, "110E 1172 11A8"), - (0xCE06, "110E 1172 11A9"), - (0xCE07, "110E 1172 11AA"), - (0xCE08, "110E 1172 11AB"), - (0xCE09, "110E 1172 11AC"), - (0xCE0A, "110E 1172 11AD"), - (0xCE0B, "110E 1172 11AE"), - (0xCE0C, "110E 1172 11AF"), - (0xCE0D, "110E 1172 11B0"), - (0xCE0E, "110E 1172 11B1"), - (0xCE0F, "110E 1172 11B2"), - (0xCE10, "110E 1172 11B3"), - (0xCE11, "110E 1172 11B4"), - (0xCE12, "110E 1172 11B5"), - (0xCE13, "110E 1172 11B6"), - (0xCE14, "110E 1172 11B7"), - (0xCE15, "110E 1172 11B8"), - (0xCE16, "110E 1172 11B9"), - (0xCE17, "110E 1172 11BA"), - (0xCE18, "110E 1172 11BB"), - (0xCE19, "110E 1172 11BC"), - (0xCE1A, "110E 1172 11BD"), - (0xCE1B, "110E 1172 11BE"), - (0xCE1C, "110E 1172 11BF"), - (0xCE1D, "110E 1172 11C0"), - (0xCE1E, "110E 1172 11C1"), - (0xCE1F, "110E 1172 11C2"), - (0xCE20, "110E 1173"), - (0xCE21, "110E 1173 11A8"), - (0xCE22, "110E 1173 11A9"), - (0xCE23, "110E 1173 11AA"), - (0xCE24, "110E 1173 11AB"), - (0xCE25, "110E 1173 11AC"), - (0xCE26, "110E 1173 11AD"), - (0xCE27, "110E 1173 11AE"), - (0xCE28, "110E 1173 11AF"), - (0xCE29, "110E 1173 11B0"), - (0xCE2A, "110E 1173 11B1"), - (0xCE2B, "110E 1173 11B2"), - (0xCE2C, "110E 1173 11B3"), - (0xCE2D, "110E 1173 11B4"), - (0xCE2E, "110E 1173 11B5"), - (0xCE2F, "110E 1173 11B6"), - (0xCE30, "110E 1173 11B7"), - (0xCE31, "110E 1173 11B8"), - (0xCE32, "110E 1173 11B9"), - (0xCE33, "110E 1173 11BA"), - (0xCE34, "110E 1173 11BB"), - (0xCE35, "110E 1173 11BC"), - (0xCE36, "110E 1173 11BD"), - (0xCE37, "110E 1173 11BE"), - (0xCE38, "110E 1173 11BF"), - (0xCE39, "110E 1173 11C0"), - (0xCE3A, "110E 1173 11C1"), - (0xCE3B, "110E 1173 11C2"), - (0xCE3C, "110E 1174"), - (0xCE3D, "110E 1174 11A8"), - (0xCE3E, "110E 1174 11A9"), - (0xCE3F, "110E 1174 11AA"), - (0xCE40, "110E 1174 11AB"), - (0xCE41, "110E 1174 11AC"), - (0xCE42, "110E 1174 11AD"), - (0xCE43, "110E 1174 11AE"), - (0xCE44, "110E 1174 11AF"), - (0xCE45, "110E 1174 11B0"), - (0xCE46, "110E 1174 11B1"), - (0xCE47, "110E 1174 11B2"), - (0xCE48, "110E 1174 11B3"), - (0xCE49, "110E 1174 11B4"), - (0xCE4A, "110E 1174 11B5"), - (0xCE4B, "110E 1174 11B6"), - (0xCE4C, "110E 1174 11B7"), - (0xCE4D, "110E 1174 11B8"), - (0xCE4E, "110E 1174 11B9"), - (0xCE4F, "110E 1174 11BA"), - (0xCE50, "110E 1174 11BB"), - (0xCE51, "110E 1174 11BC"), - (0xCE52, "110E 1174 11BD"), - (0xCE53, "110E 1174 11BE"), - (0xCE54, "110E 1174 11BF"), - (0xCE55, "110E 1174 11C0"), - (0xCE56, "110E 1174 11C1"), - (0xCE57, "110E 1174 11C2"), - (0xCE58, "110E 1175"), - (0xCE59, "110E 1175 11A8"), - (0xCE5A, "110E 1175 11A9"), - (0xCE5B, "110E 1175 11AA"), - (0xCE5C, "110E 1175 11AB"), - (0xCE5D, "110E 1175 11AC"), - (0xCE5E, "110E 1175 11AD"), - (0xCE5F, "110E 1175 11AE"), - (0xCE60, "110E 1175 11AF"), - (0xCE61, "110E 1175 11B0"), - (0xCE62, "110E 1175 11B1"), - (0xCE63, "110E 1175 11B2"), - (0xCE64, "110E 1175 11B3"), - (0xCE65, "110E 1175 11B4"), - (0xCE66, "110E 1175 11B5"), - (0xCE67, "110E 1175 11B6"), - (0xCE68, "110E 1175 11B7"), - (0xCE69, "110E 1175 11B8"), - (0xCE6A, "110E 1175 11B9"), - (0xCE6B, "110E 1175 11BA"), - (0xCE6C, "110E 1175 11BB"), - (0xCE6D, "110E 1175 11BC"), - (0xCE6E, "110E 1175 11BD"), - (0xCE6F, "110E 1175 11BE"), - (0xCE70, "110E 1175 11BF"), - (0xCE71, "110E 1175 11C0"), - (0xCE72, "110E 1175 11C1"), - (0xCE73, "110E 1175 11C2"), - (0xCE74, "110F 1161"), - (0xCE75, "110F 1161 11A8"), - (0xCE76, "110F 1161 11A9"), - (0xCE77, "110F 1161 11AA"), - (0xCE78, "110F 1161 11AB"), - (0xCE79, "110F 1161 11AC"), - (0xCE7A, "110F 1161 11AD"), - (0xCE7B, "110F 1161 11AE"), - (0xCE7C, "110F 1161 11AF"), - (0xCE7D, "110F 1161 11B0"), - (0xCE7E, "110F 1161 11B1"), - (0xCE7F, "110F 1161 11B2"), - (0xCE80, "110F 1161 11B3"), - (0xCE81, "110F 1161 11B4"), - (0xCE82, "110F 1161 11B5"), - (0xCE83, "110F 1161 11B6"), - (0xCE84, "110F 1161 11B7"), - (0xCE85, "110F 1161 11B8"), - (0xCE86, "110F 1161 11B9"), - (0xCE87, "110F 1161 11BA"), - (0xCE88, "110F 1161 11BB"), - (0xCE89, "110F 1161 11BC"), - (0xCE8A, "110F 1161 11BD"), - (0xCE8B, "110F 1161 11BE"), - (0xCE8C, "110F 1161 11BF"), - (0xCE8D, "110F 1161 11C0"), - (0xCE8E, "110F 1161 11C1"), - (0xCE8F, "110F 1161 11C2"), - (0xCE90, "110F 1162"), - (0xCE91, "110F 1162 11A8"), - (0xCE92, "110F 1162 11A9"), - (0xCE93, "110F 1162 11AA"), - (0xCE94, "110F 1162 11AB"), - (0xCE95, "110F 1162 11AC"), - (0xCE96, "110F 1162 11AD"), - (0xCE97, "110F 1162 11AE"), - (0xCE98, "110F 1162 11AF"), - (0xCE99, "110F 1162 11B0"), - (0xCE9A, "110F 1162 11B1"), - (0xCE9B, "110F 1162 11B2"), - (0xCE9C, "110F 1162 11B3"), - (0xCE9D, "110F 1162 11B4"), - (0xCE9E, "110F 1162 11B5"), - (0xCE9F, "110F 1162 11B6"), - (0xCEA0, "110F 1162 11B7"), - (0xCEA1, "110F 1162 11B8"), - (0xCEA2, "110F 1162 11B9"), - (0xCEA3, "110F 1162 11BA"), - (0xCEA4, "110F 1162 11BB"), - (0xCEA5, "110F 1162 11BC"), - (0xCEA6, "110F 1162 11BD"), - (0xCEA7, "110F 1162 11BE"), - (0xCEA8, "110F 1162 11BF"), - (0xCEA9, "110F 1162 11C0"), - (0xCEAA, "110F 1162 11C1"), - (0xCEAB, "110F 1162 11C2"), - (0xCEAC, "110F 1163"), - (0xCEAD, "110F 1163 11A8"), - (0xCEAE, "110F 1163 11A9"), - (0xCEAF, "110F 1163 11AA"), - (0xCEB0, "110F 1163 11AB"), - (0xCEB1, "110F 1163 11AC"), - (0xCEB2, "110F 1163 11AD"), - (0xCEB3, "110F 1163 11AE"), - (0xCEB4, "110F 1163 11AF"), - (0xCEB5, "110F 1163 11B0"), - (0xCEB6, "110F 1163 11B1"), - (0xCEB7, "110F 1163 11B2"), - (0xCEB8, "110F 1163 11B3"), - (0xCEB9, "110F 1163 11B4"), - (0xCEBA, "110F 1163 11B5"), - (0xCEBB, "110F 1163 11B6"), - (0xCEBC, "110F 1163 11B7"), - (0xCEBD, "110F 1163 11B8"), - (0xCEBE, "110F 1163 11B9"), - (0xCEBF, "110F 1163 11BA"), - (0xCEC0, "110F 1163 11BB"), - (0xCEC1, "110F 1163 11BC"), - (0xCEC2, "110F 1163 11BD"), - (0xCEC3, "110F 1163 11BE"), - (0xCEC4, "110F 1163 11BF"), - (0xCEC5, "110F 1163 11C0"), - (0xCEC6, "110F 1163 11C1"), - (0xCEC7, "110F 1163 11C2"), - (0xCEC8, "110F 1164"), - (0xCEC9, "110F 1164 11A8"), - (0xCECA, "110F 1164 11A9"), - (0xCECB, "110F 1164 11AA"), - (0xCECC, "110F 1164 11AB"), - (0xCECD, "110F 1164 11AC"), - (0xCECE, "110F 1164 11AD"), - (0xCECF, "110F 1164 11AE"), - (0xCED0, "110F 1164 11AF"), - (0xCED1, "110F 1164 11B0"), - (0xCED2, "110F 1164 11B1"), - (0xCED3, "110F 1164 11B2"), - (0xCED4, "110F 1164 11B3"), - (0xCED5, "110F 1164 11B4"), - (0xCED6, "110F 1164 11B5"), - (0xCED7, "110F 1164 11B6"), - (0xCED8, "110F 1164 11B7"), - (0xCED9, "110F 1164 11B8"), - (0xCEDA, "110F 1164 11B9"), - (0xCEDB, "110F 1164 11BA"), - (0xCEDC, "110F 1164 11BB"), - (0xCEDD, "110F 1164 11BC"), - (0xCEDE, "110F 1164 11BD"), - (0xCEDF, "110F 1164 11BE"), - (0xCEE0, "110F 1164 11BF"), - (0xCEE1, "110F 1164 11C0"), - (0xCEE2, "110F 1164 11C1"), - (0xCEE3, "110F 1164 11C2"), - (0xCEE4, "110F 1165"), - (0xCEE5, "110F 1165 11A8"), - (0xCEE6, "110F 1165 11A9"), - (0xCEE7, "110F 1165 11AA"), - (0xCEE8, "110F 1165 11AB"), - (0xCEE9, "110F 1165 11AC"), - (0xCEEA, "110F 1165 11AD"), - (0xCEEB, "110F 1165 11AE"), - (0xCEEC, "110F 1165 11AF"), - (0xCEED, "110F 1165 11B0"), - (0xCEEE, "110F 1165 11B1"), - (0xCEEF, "110F 1165 11B2"), - (0xCEF0, "110F 1165 11B3"), - (0xCEF1, "110F 1165 11B4"), - (0xCEF2, "110F 1165 11B5"), - (0xCEF3, "110F 1165 11B6"), - (0xCEF4, "110F 1165 11B7"), - (0xCEF5, "110F 1165 11B8"), - (0xCEF6, "110F 1165 11B9"), - (0xCEF7, "110F 1165 11BA"), - (0xCEF8, "110F 1165 11BB"), - (0xCEF9, "110F 1165 11BC"), - (0xCEFA, "110F 1165 11BD"), - (0xCEFB, "110F 1165 11BE"), - (0xCEFC, "110F 1165 11BF"), - (0xCEFD, "110F 1165 11C0"), - (0xCEFE, "110F 1165 11C1"), - (0xCEFF, "110F 1165 11C2"), - (0xCF00, "110F 1166"), - (0xCF01, "110F 1166 11A8"), - (0xCF02, "110F 1166 11A9"), - (0xCF03, "110F 1166 11AA"), - (0xCF04, "110F 1166 11AB"), - (0xCF05, "110F 1166 11AC"), - (0xCF06, "110F 1166 11AD"), - (0xCF07, "110F 1166 11AE"), - (0xCF08, "110F 1166 11AF"), - (0xCF09, "110F 1166 11B0"), - (0xCF0A, "110F 1166 11B1"), - (0xCF0B, "110F 1166 11B2"), - (0xCF0C, "110F 1166 11B3"), - (0xCF0D, "110F 1166 11B4"), - (0xCF0E, "110F 1166 11B5"), - (0xCF0F, "110F 1166 11B6"), - (0xCF10, "110F 1166 11B7"), - (0xCF11, "110F 1166 11B8"), - (0xCF12, "110F 1166 11B9"), - (0xCF13, "110F 1166 11BA"), - (0xCF14, "110F 1166 11BB"), - (0xCF15, "110F 1166 11BC"), - (0xCF16, "110F 1166 11BD"), - (0xCF17, "110F 1166 11BE"), - (0xCF18, "110F 1166 11BF"), - (0xCF19, "110F 1166 11C0"), - (0xCF1A, "110F 1166 11C1"), - (0xCF1B, "110F 1166 11C2"), - (0xCF1C, "110F 1167"), - (0xCF1D, "110F 1167 11A8"), - (0xCF1E, "110F 1167 11A9"), - (0xCF1F, "110F 1167 11AA"), - (0xCF20, "110F 1167 11AB"), - (0xCF21, "110F 1167 11AC"), - (0xCF22, "110F 1167 11AD"), - (0xCF23, "110F 1167 11AE"), - (0xCF24, "110F 1167 11AF"), - (0xCF25, "110F 1167 11B0"), - (0xCF26, "110F 1167 11B1"), - (0xCF27, "110F 1167 11B2"), - (0xCF28, "110F 1167 11B3"), - (0xCF29, "110F 1167 11B4"), - (0xCF2A, "110F 1167 11B5"), - (0xCF2B, "110F 1167 11B6"), - (0xCF2C, "110F 1167 11B7"), - (0xCF2D, "110F 1167 11B8"), - (0xCF2E, "110F 1167 11B9"), - (0xCF2F, "110F 1167 11BA"), - (0xCF30, "110F 1167 11BB"), - (0xCF31, "110F 1167 11BC"), - (0xCF32, "110F 1167 11BD"), - (0xCF33, "110F 1167 11BE"), - (0xCF34, "110F 1167 11BF"), - (0xCF35, "110F 1167 11C0"), - (0xCF36, "110F 1167 11C1"), - (0xCF37, "110F 1167 11C2"), - (0xCF38, "110F 1168"), - (0xCF39, "110F 1168 11A8"), - (0xCF3A, "110F 1168 11A9"), - (0xCF3B, "110F 1168 11AA"), - (0xCF3C, "110F 1168 11AB"), - (0xCF3D, "110F 1168 11AC"), - (0xCF3E, "110F 1168 11AD"), - (0xCF3F, "110F 1168 11AE"), - (0xCF40, "110F 1168 11AF"), - (0xCF41, "110F 1168 11B0"), - (0xCF42, "110F 1168 11B1"), - (0xCF43, "110F 1168 11B2"), - (0xCF44, "110F 1168 11B3"), - (0xCF45, "110F 1168 11B4"), - (0xCF46, "110F 1168 11B5"), - (0xCF47, "110F 1168 11B6"), - (0xCF48, "110F 1168 11B7"), - (0xCF49, "110F 1168 11B8"), - (0xCF4A, "110F 1168 11B9"), - (0xCF4B, "110F 1168 11BA"), - (0xCF4C, "110F 1168 11BB"), - (0xCF4D, "110F 1168 11BC"), - (0xCF4E, "110F 1168 11BD"), - (0xCF4F, "110F 1168 11BE"), - (0xCF50, "110F 1168 11BF"), - (0xCF51, "110F 1168 11C0"), - (0xCF52, "110F 1168 11C1"), - (0xCF53, "110F 1168 11C2"), - (0xCF54, "110F 1169"), - (0xCF55, "110F 1169 11A8"), - (0xCF56, "110F 1169 11A9"), - (0xCF57, "110F 1169 11AA"), - (0xCF58, "110F 1169 11AB"), - (0xCF59, "110F 1169 11AC"), - (0xCF5A, "110F 1169 11AD"), - (0xCF5B, "110F 1169 11AE"), - (0xCF5C, "110F 1169 11AF"), - (0xCF5D, "110F 1169 11B0"), - (0xCF5E, "110F 1169 11B1"), - (0xCF5F, "110F 1169 11B2"), - (0xCF60, "110F 1169 11B3"), - (0xCF61, "110F 1169 11B4"), - (0xCF62, "110F 1169 11B5"), - (0xCF63, "110F 1169 11B6"), - (0xCF64, "110F 1169 11B7"), - (0xCF65, "110F 1169 11B8"), - (0xCF66, "110F 1169 11B9"), - (0xCF67, "110F 1169 11BA"), - (0xCF68, "110F 1169 11BB"), - (0xCF69, "110F 1169 11BC"), - (0xCF6A, "110F 1169 11BD"), - (0xCF6B, "110F 1169 11BE"), - (0xCF6C, "110F 1169 11BF"), - (0xCF6D, "110F 1169 11C0"), - (0xCF6E, "110F 1169 11C1"), - (0xCF6F, "110F 1169 11C2"), - (0xCF70, "110F 116A"), - (0xCF71, "110F 116A 11A8"), - (0xCF72, "110F 116A 11A9"), - (0xCF73, "110F 116A 11AA"), - (0xCF74, "110F 116A 11AB"), - (0xCF75, "110F 116A 11AC"), - (0xCF76, "110F 116A 11AD"), - (0xCF77, "110F 116A 11AE"), - (0xCF78, "110F 116A 11AF"), - (0xCF79, "110F 116A 11B0"), - (0xCF7A, "110F 116A 11B1"), - (0xCF7B, "110F 116A 11B2"), - (0xCF7C, "110F 116A 11B3"), - (0xCF7D, "110F 116A 11B4"), - (0xCF7E, "110F 116A 11B5"), - (0xCF7F, "110F 116A 11B6"), - (0xCF80, "110F 116A 11B7"), - (0xCF81, "110F 116A 11B8"), - (0xCF82, "110F 116A 11B9"), - (0xCF83, "110F 116A 11BA"), - (0xCF84, "110F 116A 11BB"), - (0xCF85, "110F 116A 11BC"), - (0xCF86, "110F 116A 11BD"), - (0xCF87, "110F 116A 11BE"), - (0xCF88, "110F 116A 11BF"), - (0xCF89, "110F 116A 11C0"), - (0xCF8A, "110F 116A 11C1"), - (0xCF8B, "110F 116A 11C2"), - (0xCF8C, "110F 116B"), - (0xCF8D, "110F 116B 11A8"), - (0xCF8E, "110F 116B 11A9"), - (0xCF8F, "110F 116B 11AA"), - (0xCF90, "110F 116B 11AB"), - (0xCF91, "110F 116B 11AC"), - (0xCF92, "110F 116B 11AD"), - (0xCF93, "110F 116B 11AE"), - (0xCF94, "110F 116B 11AF"), - (0xCF95, "110F 116B 11B0"), - (0xCF96, "110F 116B 11B1"), - (0xCF97, "110F 116B 11B2"), - (0xCF98, "110F 116B 11B3"), - (0xCF99, "110F 116B 11B4"), - (0xCF9A, "110F 116B 11B5"), - (0xCF9B, "110F 116B 11B6"), - (0xCF9C, "110F 116B 11B7"), - (0xCF9D, "110F 116B 11B8"), - (0xCF9E, "110F 116B 11B9"), - (0xCF9F, "110F 116B 11BA"), - (0xCFA0, "110F 116B 11BB"), - (0xCFA1, "110F 116B 11BC"), - (0xCFA2, "110F 116B 11BD"), - (0xCFA3, "110F 116B 11BE"), - (0xCFA4, "110F 116B 11BF"), - (0xCFA5, "110F 116B 11C0"), - (0xCFA6, "110F 116B 11C1"), - (0xCFA7, "110F 116B 11C2"), - (0xCFA8, "110F 116C"), - (0xCFA9, "110F 116C 11A8"), - (0xCFAA, "110F 116C 11A9"), - (0xCFAB, "110F 116C 11AA"), - (0xCFAC, "110F 116C 11AB"), - (0xCFAD, "110F 116C 11AC"), - (0xCFAE, "110F 116C 11AD"), - (0xCFAF, "110F 116C 11AE"), - (0xCFB0, "110F 116C 11AF"), - (0xCFB1, "110F 116C 11B0"), - (0xCFB2, "110F 116C 11B1"), - (0xCFB3, "110F 116C 11B2"), - (0xCFB4, "110F 116C 11B3"), - (0xCFB5, "110F 116C 11B4"), - (0xCFB6, "110F 116C 11B5"), - (0xCFB7, "110F 116C 11B6"), - (0xCFB8, "110F 116C 11B7"), - (0xCFB9, "110F 116C 11B8"), - (0xCFBA, "110F 116C 11B9"), - (0xCFBB, "110F 116C 11BA"), - (0xCFBC, "110F 116C 11BB"), - (0xCFBD, "110F 116C 11BC"), - (0xCFBE, "110F 116C 11BD"), - (0xCFBF, "110F 116C 11BE"), - (0xCFC0, "110F 116C 11BF"), - (0xCFC1, "110F 116C 11C0"), - (0xCFC2, "110F 116C 11C1"), - (0xCFC3, "110F 116C 11C2"), - (0xCFC4, "110F 116D"), - (0xCFC5, "110F 116D 11A8"), - (0xCFC6, "110F 116D 11A9"), - (0xCFC7, "110F 116D 11AA"), - (0xCFC8, "110F 116D 11AB"), - (0xCFC9, "110F 116D 11AC"), - (0xCFCA, "110F 116D 11AD"), - (0xCFCB, "110F 116D 11AE"), - (0xCFCC, "110F 116D 11AF"), - (0xCFCD, "110F 116D 11B0"), - (0xCFCE, "110F 116D 11B1"), - (0xCFCF, "110F 116D 11B2"), - (0xCFD0, "110F 116D 11B3"), - (0xCFD1, "110F 116D 11B4"), - (0xCFD2, "110F 116D 11B5"), - (0xCFD3, "110F 116D 11B6"), - (0xCFD4, "110F 116D 11B7"), - (0xCFD5, "110F 116D 11B8"), - (0xCFD6, "110F 116D 11B9"), - (0xCFD7, "110F 116D 11BA"), - (0xCFD8, "110F 116D 11BB"), - (0xCFD9, "110F 116D 11BC"), - (0xCFDA, "110F 116D 11BD"), - (0xCFDB, "110F 116D 11BE"), - (0xCFDC, "110F 116D 11BF"), - (0xCFDD, "110F 116D 11C0"), - (0xCFDE, "110F 116D 11C1"), - (0xCFDF, "110F 116D 11C2"), - (0xCFE0, "110F 116E"), - (0xCFE1, "110F 116E 11A8"), - (0xCFE2, "110F 116E 11A9"), - (0xCFE3, "110F 116E 11AA"), - (0xCFE4, "110F 116E 11AB"), - (0xCFE5, "110F 116E 11AC"), - (0xCFE6, "110F 116E 11AD"), - (0xCFE7, "110F 116E 11AE"), - (0xCFE8, "110F 116E 11AF"), - (0xCFE9, "110F 116E 11B0"), - (0xCFEA, "110F 116E 11B1"), - (0xCFEB, "110F 116E 11B2"), - (0xCFEC, "110F 116E 11B3"), - (0xCFED, "110F 116E 11B4"), - (0xCFEE, "110F 116E 11B5"), - (0xCFEF, "110F 116E 11B6"), - (0xCFF0, "110F 116E 11B7"), - (0xCFF1, "110F 116E 11B8"), - (0xCFF2, "110F 116E 11B9"), - (0xCFF3, "110F 116E 11BA"), - (0xCFF4, "110F 116E 11BB"), - (0xCFF5, "110F 116E 11BC"), - (0xCFF6, "110F 116E 11BD"), - (0xCFF7, "110F 116E 11BE"), - (0xCFF8, "110F 116E 11BF"), - (0xCFF9, "110F 116E 11C0"), - (0xCFFA, "110F 116E 11C1"), - (0xCFFB, "110F 116E 11C2"), - (0xCFFC, "110F 116F"), - (0xCFFD, "110F 116F 11A8"), - (0xCFFE, "110F 116F 11A9"), - (0xCFFF, "110F 116F 11AA"), - (0xD000, "110F 116F 11AB"), - (0xD001, "110F 116F 11AC"), - (0xD002, "110F 116F 11AD"), - (0xD003, "110F 116F 11AE"), - (0xD004, "110F 116F 11AF"), - (0xD005, "110F 116F 11B0"), - (0xD006, "110F 116F 11B1"), - (0xD007, "110F 116F 11B2"), - (0xD008, "110F 116F 11B3"), - (0xD009, "110F 116F 11B4"), - (0xD00A, "110F 116F 11B5"), - (0xD00B, "110F 116F 11B6"), - (0xD00C, "110F 116F 11B7"), - (0xD00D, "110F 116F 11B8"), - (0xD00E, "110F 116F 11B9"), - (0xD00F, "110F 116F 11BA"), - (0xD010, "110F 116F 11BB"), - (0xD011, "110F 116F 11BC"), - (0xD012, "110F 116F 11BD"), - (0xD013, "110F 116F 11BE"), - (0xD014, "110F 116F 11BF"), - (0xD015, "110F 116F 11C0"), - (0xD016, "110F 116F 11C1"), - (0xD017, "110F 116F 11C2"), - (0xD018, "110F 1170"), - (0xD019, "110F 1170 11A8"), - (0xD01A, "110F 1170 11A9"), - (0xD01B, "110F 1170 11AA"), - (0xD01C, "110F 1170 11AB"), - (0xD01D, "110F 1170 11AC"), - (0xD01E, "110F 1170 11AD"), - (0xD01F, "110F 1170 11AE"), - (0xD020, "110F 1170 11AF"), - (0xD021, "110F 1170 11B0"), - (0xD022, "110F 1170 11B1"), - (0xD023, "110F 1170 11B2"), - (0xD024, "110F 1170 11B3"), - (0xD025, "110F 1170 11B4"), - (0xD026, "110F 1170 11B5"), - (0xD027, "110F 1170 11B6"), - (0xD028, "110F 1170 11B7"), - (0xD029, "110F 1170 11B8"), - (0xD02A, "110F 1170 11B9"), - (0xD02B, "110F 1170 11BA"), - (0xD02C, "110F 1170 11BB"), - (0xD02D, "110F 1170 11BC"), - (0xD02E, "110F 1170 11BD"), - (0xD02F, "110F 1170 11BE"), - (0xD030, "110F 1170 11BF"), - (0xD031, "110F 1170 11C0"), - (0xD032, "110F 1170 11C1"), - (0xD033, "110F 1170 11C2"), - (0xD034, "110F 1171"), - (0xD035, "110F 1171 11A8"), - (0xD036, "110F 1171 11A9"), - (0xD037, "110F 1171 11AA"), - (0xD038, "110F 1171 11AB"), - (0xD039, "110F 1171 11AC"), - (0xD03A, "110F 1171 11AD"), - (0xD03B, "110F 1171 11AE"), - (0xD03C, "110F 1171 11AF"), - (0xD03D, "110F 1171 11B0"), - (0xD03E, "110F 1171 11B1"), - (0xD03F, "110F 1171 11B2"), - (0xD040, "110F 1171 11B3"), - (0xD041, "110F 1171 11B4"), - (0xD042, "110F 1171 11B5"), - (0xD043, "110F 1171 11B6"), - (0xD044, "110F 1171 11B7"), - (0xD045, "110F 1171 11B8"), - (0xD046, "110F 1171 11B9"), - (0xD047, "110F 1171 11BA"), - (0xD048, "110F 1171 11BB"), - (0xD049, "110F 1171 11BC"), - (0xD04A, "110F 1171 11BD"), - (0xD04B, "110F 1171 11BE"), - (0xD04C, "110F 1171 11BF"), - (0xD04D, "110F 1171 11C0"), - (0xD04E, "110F 1171 11C1"), - (0xD04F, "110F 1171 11C2"), - (0xD050, "110F 1172"), - (0xD051, "110F 1172 11A8"), - (0xD052, "110F 1172 11A9"), - (0xD053, "110F 1172 11AA"), - (0xD054, "110F 1172 11AB"), - (0xD055, "110F 1172 11AC"), - (0xD056, "110F 1172 11AD"), - (0xD057, "110F 1172 11AE"), - (0xD058, "110F 1172 11AF"), - (0xD059, "110F 1172 11B0"), - (0xD05A, "110F 1172 11B1"), - (0xD05B, "110F 1172 11B2"), - (0xD05C, "110F 1172 11B3"), - (0xD05D, "110F 1172 11B4"), - (0xD05E, "110F 1172 11B5"), - (0xD05F, "110F 1172 11B6"), - (0xD060, "110F 1172 11B7"), - (0xD061, "110F 1172 11B8"), - (0xD062, "110F 1172 11B9"), - (0xD063, "110F 1172 11BA"), - (0xD064, "110F 1172 11BB"), - (0xD065, "110F 1172 11BC"), - (0xD066, "110F 1172 11BD"), - (0xD067, "110F 1172 11BE"), - (0xD068, "110F 1172 11BF"), - (0xD069, "110F 1172 11C0"), - (0xD06A, "110F 1172 11C1"), - (0xD06B, "110F 1172 11C2"), - (0xD06C, "110F 1173"), - (0xD06D, "110F 1173 11A8"), - (0xD06E, "110F 1173 11A9"), - (0xD06F, "110F 1173 11AA"), - (0xD070, "110F 1173 11AB"), - (0xD071, "110F 1173 11AC"), - (0xD072, "110F 1173 11AD"), - (0xD073, "110F 1173 11AE"), - (0xD074, "110F 1173 11AF"), - (0xD075, "110F 1173 11B0"), - (0xD076, "110F 1173 11B1"), - (0xD077, "110F 1173 11B2"), - (0xD078, "110F 1173 11B3"), - (0xD079, "110F 1173 11B4"), - (0xD07A, "110F 1173 11B5"), - (0xD07B, "110F 1173 11B6"), - (0xD07C, "110F 1173 11B7"), - (0xD07D, "110F 1173 11B8"), - (0xD07E, "110F 1173 11B9"), - (0xD07F, "110F 1173 11BA"), - (0xD080, "110F 1173 11BB"), - (0xD081, "110F 1173 11BC"), - (0xD082, "110F 1173 11BD"), - (0xD083, "110F 1173 11BE"), - (0xD084, "110F 1173 11BF"), - (0xD085, "110F 1173 11C0"), - (0xD086, "110F 1173 11C1"), - (0xD087, "110F 1173 11C2"), - (0xD088, "110F 1174"), - (0xD089, "110F 1174 11A8"), - (0xD08A, "110F 1174 11A9"), - (0xD08B, "110F 1174 11AA"), - (0xD08C, "110F 1174 11AB"), - (0xD08D, "110F 1174 11AC"), - (0xD08E, "110F 1174 11AD"), - (0xD08F, "110F 1174 11AE"), - (0xD090, "110F 1174 11AF"), - (0xD091, "110F 1174 11B0"), - (0xD092, "110F 1174 11B1"), - (0xD093, "110F 1174 11B2"), - (0xD094, "110F 1174 11B3"), - (0xD095, "110F 1174 11B4"), - (0xD096, "110F 1174 11B5"), - (0xD097, "110F 1174 11B6"), - (0xD098, "110F 1174 11B7"), - (0xD099, "110F 1174 11B8"), - (0xD09A, "110F 1174 11B9"), - (0xD09B, "110F 1174 11BA"), - (0xD09C, "110F 1174 11BB"), - (0xD09D, "110F 1174 11BC"), - (0xD09E, "110F 1174 11BD"), - (0xD09F, "110F 1174 11BE"), - (0xD0A0, "110F 1174 11BF"), - (0xD0A1, "110F 1174 11C0"), - (0xD0A2, "110F 1174 11C1"), - (0xD0A3, "110F 1174 11C2"), - (0xD0A4, "110F 1175"), - (0xD0A5, "110F 1175 11A8"), - (0xD0A6, "110F 1175 11A9"), - (0xD0A7, "110F 1175 11AA"), - (0xD0A8, "110F 1175 11AB"), - (0xD0A9, "110F 1175 11AC"), - (0xD0AA, "110F 1175 11AD"), - (0xD0AB, "110F 1175 11AE"), - (0xD0AC, "110F 1175 11AF"), - (0xD0AD, "110F 1175 11B0"), - (0xD0AE, "110F 1175 11B1"), - (0xD0AF, "110F 1175 11B2"), - (0xD0B0, "110F 1175 11B3"), - (0xD0B1, "110F 1175 11B4"), - (0xD0B2, "110F 1175 11B5"), - (0xD0B3, "110F 1175 11B6"), - (0xD0B4, "110F 1175 11B7"), - (0xD0B5, "110F 1175 11B8"), - (0xD0B6, "110F 1175 11B9"), - (0xD0B7, "110F 1175 11BA"), - (0xD0B8, "110F 1175 11BB"), - (0xD0B9, "110F 1175 11BC"), - (0xD0BA, "110F 1175 11BD"), - (0xD0BB, "110F 1175 11BE"), - (0xD0BC, "110F 1175 11BF"), - (0xD0BD, "110F 1175 11C0"), - (0xD0BE, "110F 1175 11C1"), - (0xD0BF, "110F 1175 11C2"), - (0xD0C0, "1110 1161"), - (0xD0C1, "1110 1161 11A8"), - (0xD0C2, "1110 1161 11A9"), - (0xD0C3, "1110 1161 11AA"), - (0xD0C4, "1110 1161 11AB"), - (0xD0C5, "1110 1161 11AC"), - (0xD0C6, "1110 1161 11AD"), - (0xD0C7, "1110 1161 11AE"), - (0xD0C8, "1110 1161 11AF"), - (0xD0C9, "1110 1161 11B0"), - (0xD0CA, "1110 1161 11B1"), - (0xD0CB, "1110 1161 11B2"), - (0xD0CC, "1110 1161 11B3"), - (0xD0CD, "1110 1161 11B4"), - (0xD0CE, "1110 1161 11B5"), - (0xD0CF, "1110 1161 11B6"), - (0xD0D0, "1110 1161 11B7"), - (0xD0D1, "1110 1161 11B8"), - (0xD0D2, "1110 1161 11B9"), - (0xD0D3, "1110 1161 11BA"), - (0xD0D4, "1110 1161 11BB"), - (0xD0D5, "1110 1161 11BC"), - (0xD0D6, "1110 1161 11BD"), - (0xD0D7, "1110 1161 11BE"), - (0xD0D8, "1110 1161 11BF"), - (0xD0D9, "1110 1161 11C0"), - (0xD0DA, "1110 1161 11C1"), - (0xD0DB, "1110 1161 11C2"), - (0xD0DC, "1110 1162"), - (0xD0DD, "1110 1162 11A8"), - (0xD0DE, "1110 1162 11A9"), - (0xD0DF, "1110 1162 11AA"), - (0xD0E0, "1110 1162 11AB"), - (0xD0E1, "1110 1162 11AC"), - (0xD0E2, "1110 1162 11AD"), - (0xD0E3, "1110 1162 11AE"), - (0xD0E4, "1110 1162 11AF"), - (0xD0E5, "1110 1162 11B0"), - (0xD0E6, "1110 1162 11B1"), - (0xD0E7, "1110 1162 11B2"), - (0xD0E8, "1110 1162 11B3"), - (0xD0E9, "1110 1162 11B4"), - (0xD0EA, "1110 1162 11B5"), - (0xD0EB, "1110 1162 11B6"), - (0xD0EC, "1110 1162 11B7"), - (0xD0ED, "1110 1162 11B8"), - (0xD0EE, "1110 1162 11B9"), - (0xD0EF, "1110 1162 11BA"), - (0xD0F0, "1110 1162 11BB"), - (0xD0F1, "1110 1162 11BC"), - (0xD0F2, "1110 1162 11BD"), - (0xD0F3, "1110 1162 11BE"), - (0xD0F4, "1110 1162 11BF"), - (0xD0F5, "1110 1162 11C0"), - (0xD0F6, "1110 1162 11C1"), - (0xD0F7, "1110 1162 11C2"), - (0xD0F8, "1110 1163"), - (0xD0F9, "1110 1163 11A8"), - (0xD0FA, "1110 1163 11A9"), - (0xD0FB, "1110 1163 11AA"), - (0xD0FC, "1110 1163 11AB"), - (0xD0FD, "1110 1163 11AC"), - (0xD0FE, "1110 1163 11AD"), - (0xD0FF, "1110 1163 11AE"), - (0xD100, "1110 1163 11AF"), - (0xD101, "1110 1163 11B0"), - (0xD102, "1110 1163 11B1"), - (0xD103, "1110 1163 11B2"), - (0xD104, "1110 1163 11B3"), - (0xD105, "1110 1163 11B4"), - (0xD106, "1110 1163 11B5"), - (0xD107, "1110 1163 11B6"), - (0xD108, "1110 1163 11B7"), - (0xD109, "1110 1163 11B8"), - (0xD10A, "1110 1163 11B9"), - (0xD10B, "1110 1163 11BA"), - (0xD10C, "1110 1163 11BB"), - (0xD10D, "1110 1163 11BC"), - (0xD10E, "1110 1163 11BD"), - (0xD10F, "1110 1163 11BE"), - (0xD110, "1110 1163 11BF"), - (0xD111, "1110 1163 11C0"), - (0xD112, "1110 1163 11C1"), - (0xD113, "1110 1163 11C2"), - (0xD114, "1110 1164"), - (0xD115, "1110 1164 11A8"), - (0xD116, "1110 1164 11A9"), - (0xD117, "1110 1164 11AA"), - (0xD118, "1110 1164 11AB"), - (0xD119, "1110 1164 11AC"), - (0xD11A, "1110 1164 11AD"), - (0xD11B, "1110 1164 11AE"), - (0xD11C, "1110 1164 11AF"), - (0xD11D, "1110 1164 11B0"), - (0xD11E, "1110 1164 11B1"), - (0xD11F, "1110 1164 11B2"), - (0xD120, "1110 1164 11B3"), - (0xD121, "1110 1164 11B4"), - (0xD122, "1110 1164 11B5"), - (0xD123, "1110 1164 11B6"), - (0xD124, "1110 1164 11B7"), - (0xD125, "1110 1164 11B8"), - (0xD126, "1110 1164 11B9"), - (0xD127, "1110 1164 11BA"), - (0xD128, "1110 1164 11BB"), - (0xD129, "1110 1164 11BC"), - (0xD12A, "1110 1164 11BD"), - (0xD12B, "1110 1164 11BE"), - (0xD12C, "1110 1164 11BF"), - (0xD12D, "1110 1164 11C0"), - (0xD12E, "1110 1164 11C1"), - (0xD12F, "1110 1164 11C2"), - (0xD130, "1110 1165"), - (0xD131, "1110 1165 11A8"), - (0xD132, "1110 1165 11A9"), - (0xD133, "1110 1165 11AA"), - (0xD134, "1110 1165 11AB"), - (0xD135, "1110 1165 11AC"), - (0xD136, "1110 1165 11AD"), - (0xD137, "1110 1165 11AE"), - (0xD138, "1110 1165 11AF"), - (0xD139, "1110 1165 11B0"), - (0xD13A, "1110 1165 11B1"), - (0xD13B, "1110 1165 11B2"), - (0xD13C, "1110 1165 11B3"), - (0xD13D, "1110 1165 11B4"), - (0xD13E, "1110 1165 11B5"), - (0xD13F, "1110 1165 11B6"), - (0xD140, "1110 1165 11B7"), - (0xD141, "1110 1165 11B8"), - (0xD142, "1110 1165 11B9"), - (0xD143, "1110 1165 11BA"), - (0xD144, "1110 1165 11BB"), - (0xD145, "1110 1165 11BC"), - (0xD146, "1110 1165 11BD"), - (0xD147, "1110 1165 11BE"), - (0xD148, "1110 1165 11BF"), - (0xD149, "1110 1165 11C0"), - (0xD14A, "1110 1165 11C1"), - (0xD14B, "1110 1165 11C2"), - (0xD14C, "1110 1166"), - (0xD14D, "1110 1166 11A8"), - (0xD14E, "1110 1166 11A9"), - (0xD14F, "1110 1166 11AA"), - (0xD150, "1110 1166 11AB"), - (0xD151, "1110 1166 11AC"), - (0xD152, "1110 1166 11AD"), - (0xD153, "1110 1166 11AE"), - (0xD154, "1110 1166 11AF"), - (0xD155, "1110 1166 11B0"), - (0xD156, "1110 1166 11B1"), - (0xD157, "1110 1166 11B2"), - (0xD158, "1110 1166 11B3"), - (0xD159, "1110 1166 11B4"), - (0xD15A, "1110 1166 11B5"), - (0xD15B, "1110 1166 11B6"), - (0xD15C, "1110 1166 11B7"), - (0xD15D, "1110 1166 11B8"), - (0xD15E, "1110 1166 11B9"), - (0xD15F, "1110 1166 11BA"), - (0xD160, "1110 1166 11BB"), - (0xD161, "1110 1166 11BC"), - (0xD162, "1110 1166 11BD"), - (0xD163, "1110 1166 11BE"), - (0xD164, "1110 1166 11BF"), - (0xD165, "1110 1166 11C0"), - (0xD166, "1110 1166 11C1"), - (0xD167, "1110 1166 11C2"), - (0xD168, "1110 1167"), - (0xD169, "1110 1167 11A8"), - (0xD16A, "1110 1167 11A9"), - (0xD16B, "1110 1167 11AA"), - (0xD16C, "1110 1167 11AB"), - (0xD16D, "1110 1167 11AC"), - (0xD16E, "1110 1167 11AD"), - (0xD16F, "1110 1167 11AE"), - (0xD170, "1110 1167 11AF"), - (0xD171, "1110 1167 11B0"), - (0xD172, "1110 1167 11B1"), - (0xD173, "1110 1167 11B2"), - (0xD174, "1110 1167 11B3"), - (0xD175, "1110 1167 11B4"), - (0xD176, "1110 1167 11B5"), - (0xD177, "1110 1167 11B6"), - (0xD178, "1110 1167 11B7"), - (0xD179, "1110 1167 11B8"), - (0xD17A, "1110 1167 11B9"), - (0xD17B, "1110 1167 11BA"), - (0xD17C, "1110 1167 11BB"), - (0xD17D, "1110 1167 11BC"), - (0xD17E, "1110 1167 11BD"), - (0xD17F, "1110 1167 11BE"), - (0xD180, "1110 1167 11BF"), - (0xD181, "1110 1167 11C0"), - (0xD182, "1110 1167 11C1"), - (0xD183, "1110 1167 11C2"), - (0xD184, "1110 1168"), - (0xD185, "1110 1168 11A8"), - (0xD186, "1110 1168 11A9"), - (0xD187, "1110 1168 11AA"), - (0xD188, "1110 1168 11AB"), - (0xD189, "1110 1168 11AC"), - (0xD18A, "1110 1168 11AD"), - (0xD18B, "1110 1168 11AE"), - (0xD18C, "1110 1168 11AF"), - (0xD18D, "1110 1168 11B0"), - (0xD18E, "1110 1168 11B1"), - (0xD18F, "1110 1168 11B2"), - (0xD190, "1110 1168 11B3"), - (0xD191, "1110 1168 11B4"), - (0xD192, "1110 1168 11B5"), - (0xD193, "1110 1168 11B6"), - (0xD194, "1110 1168 11B7"), - (0xD195, "1110 1168 11B8"), - (0xD196, "1110 1168 11B9"), - (0xD197, "1110 1168 11BA"), - (0xD198, "1110 1168 11BB"), - (0xD199, "1110 1168 11BC"), - (0xD19A, "1110 1168 11BD"), - (0xD19B, "1110 1168 11BE"), - (0xD19C, "1110 1168 11BF"), - (0xD19D, "1110 1168 11C0"), - (0xD19E, "1110 1168 11C1"), - (0xD19F, "1110 1168 11C2"), - (0xD1A0, "1110 1169"), - (0xD1A1, "1110 1169 11A8"), - (0xD1A2, "1110 1169 11A9"), - (0xD1A3, "1110 1169 11AA"), - (0xD1A4, "1110 1169 11AB"), - (0xD1A5, "1110 1169 11AC"), - (0xD1A6, "1110 1169 11AD"), - (0xD1A7, "1110 1169 11AE"), - (0xD1A8, "1110 1169 11AF"), - (0xD1A9, "1110 1169 11B0"), - (0xD1AA, "1110 1169 11B1"), - (0xD1AB, "1110 1169 11B2"), - (0xD1AC, "1110 1169 11B3"), - (0xD1AD, "1110 1169 11B4"), - (0xD1AE, "1110 1169 11B5"), - (0xD1AF, "1110 1169 11B6"), - (0xD1B0, "1110 1169 11B7"), - (0xD1B1, "1110 1169 11B8"), - (0xD1B2, "1110 1169 11B9"), - (0xD1B3, "1110 1169 11BA"), - (0xD1B4, "1110 1169 11BB"), - (0xD1B5, "1110 1169 11BC"), - (0xD1B6, "1110 1169 11BD"), - (0xD1B7, "1110 1169 11BE"), - (0xD1B8, "1110 1169 11BF"), - (0xD1B9, "1110 1169 11C0"), - (0xD1BA, "1110 1169 11C1"), - (0xD1BB, "1110 1169 11C2"), - (0xD1BC, "1110 116A"), - (0xD1BD, "1110 116A 11A8"), - (0xD1BE, "1110 116A 11A9"), - (0xD1BF, "1110 116A 11AA"), - (0xD1C0, "1110 116A 11AB"), - (0xD1C1, "1110 116A 11AC"), - (0xD1C2, "1110 116A 11AD"), - (0xD1C3, "1110 116A 11AE"), - (0xD1C4, "1110 116A 11AF"), - (0xD1C5, "1110 116A 11B0"), - (0xD1C6, "1110 116A 11B1"), - (0xD1C7, "1110 116A 11B2"), - (0xD1C8, "1110 116A 11B3"), - (0xD1C9, "1110 116A 11B4"), - (0xD1CA, "1110 116A 11B5"), - (0xD1CB, "1110 116A 11B6"), - (0xD1CC, "1110 116A 11B7"), - (0xD1CD, "1110 116A 11B8"), - (0xD1CE, "1110 116A 11B9"), - (0xD1CF, "1110 116A 11BA"), - (0xD1D0, "1110 116A 11BB"), - (0xD1D1, "1110 116A 11BC"), - (0xD1D2, "1110 116A 11BD"), - (0xD1D3, "1110 116A 11BE"), - (0xD1D4, "1110 116A 11BF"), - (0xD1D5, "1110 116A 11C0"), - (0xD1D6, "1110 116A 11C1"), - (0xD1D7, "1110 116A 11C2"), - (0xD1D8, "1110 116B"), - (0xD1D9, "1110 116B 11A8"), - (0xD1DA, "1110 116B 11A9"), - (0xD1DB, "1110 116B 11AA"), - (0xD1DC, "1110 116B 11AB"), - (0xD1DD, "1110 116B 11AC"), - (0xD1DE, "1110 116B 11AD"), - (0xD1DF, "1110 116B 11AE"), - (0xD1E0, "1110 116B 11AF"), - (0xD1E1, "1110 116B 11B0"), - (0xD1E2, "1110 116B 11B1"), - (0xD1E3, "1110 116B 11B2"), - (0xD1E4, "1110 116B 11B3"), - (0xD1E5, "1110 116B 11B4"), - (0xD1E6, "1110 116B 11B5"), - (0xD1E7, "1110 116B 11B6"), - (0xD1E8, "1110 116B 11B7"), - (0xD1E9, "1110 116B 11B8"), - (0xD1EA, "1110 116B 11B9"), - (0xD1EB, "1110 116B 11BA"), - (0xD1EC, "1110 116B 11BB"), - (0xD1ED, "1110 116B 11BC"), - (0xD1EE, "1110 116B 11BD"), - (0xD1EF, "1110 116B 11BE"), - (0xD1F0, "1110 116B 11BF"), - (0xD1F1, "1110 116B 11C0"), - (0xD1F2, "1110 116B 11C1"), - (0xD1F3, "1110 116B 11C2"), - (0xD1F4, "1110 116C"), - (0xD1F5, "1110 116C 11A8"), - (0xD1F6, "1110 116C 11A9"), - (0xD1F7, "1110 116C 11AA"), - (0xD1F8, "1110 116C 11AB"), - (0xD1F9, "1110 116C 11AC"), - (0xD1FA, "1110 116C 11AD"), - (0xD1FB, "1110 116C 11AE"), - (0xD1FC, "1110 116C 11AF"), - (0xD1FD, "1110 116C 11B0"), - (0xD1FE, "1110 116C 11B1"), - (0xD1FF, "1110 116C 11B2"), - (0xD200, "1110 116C 11B3"), - (0xD201, "1110 116C 11B4"), - (0xD202, "1110 116C 11B5"), - (0xD203, "1110 116C 11B6"), - (0xD204, "1110 116C 11B7"), - (0xD205, "1110 116C 11B8"), - (0xD206, "1110 116C 11B9"), - (0xD207, "1110 116C 11BA"), - (0xD208, "1110 116C 11BB"), - (0xD209, "1110 116C 11BC"), - (0xD20A, "1110 116C 11BD"), - (0xD20B, "1110 116C 11BE"), - (0xD20C, "1110 116C 11BF"), - (0xD20D, "1110 116C 11C0"), - (0xD20E, "1110 116C 11C1"), - (0xD20F, "1110 116C 11C2"), - (0xD210, "1110 116D"), - (0xD211, "1110 116D 11A8"), - (0xD212, "1110 116D 11A9"), - (0xD213, "1110 116D 11AA"), - (0xD214, "1110 116D 11AB"), - (0xD215, "1110 116D 11AC"), - (0xD216, "1110 116D 11AD"), - (0xD217, "1110 116D 11AE"), - (0xD218, "1110 116D 11AF"), - (0xD219, "1110 116D 11B0"), - (0xD21A, "1110 116D 11B1"), - (0xD21B, "1110 116D 11B2"), - (0xD21C, "1110 116D 11B3"), - (0xD21D, "1110 116D 11B4"), - (0xD21E, "1110 116D 11B5"), - (0xD21F, "1110 116D 11B6"), - (0xD220, "1110 116D 11B7"), - (0xD221, "1110 116D 11B8"), - (0xD222, "1110 116D 11B9"), - (0xD223, "1110 116D 11BA"), - (0xD224, "1110 116D 11BB"), - (0xD225, "1110 116D 11BC"), - (0xD226, "1110 116D 11BD"), - (0xD227, "1110 116D 11BE"), - (0xD228, "1110 116D 11BF"), - (0xD229, "1110 116D 11C0"), - (0xD22A, "1110 116D 11C1"), - (0xD22B, "1110 116D 11C2"), - (0xD22C, "1110 116E"), - (0xD22D, "1110 116E 11A8"), - (0xD22E, "1110 116E 11A9"), - (0xD22F, "1110 116E 11AA"), - (0xD230, "1110 116E 11AB"), - (0xD231, "1110 116E 11AC"), - (0xD232, "1110 116E 11AD"), - (0xD233, "1110 116E 11AE"), - (0xD234, "1110 116E 11AF"), - (0xD235, "1110 116E 11B0"), - (0xD236, "1110 116E 11B1"), - (0xD237, "1110 116E 11B2"), - (0xD238, "1110 116E 11B3"), - (0xD239, "1110 116E 11B4"), - (0xD23A, "1110 116E 11B5"), - (0xD23B, "1110 116E 11B6"), - (0xD23C, "1110 116E 11B7"), - (0xD23D, "1110 116E 11B8"), - (0xD23E, "1110 116E 11B9"), - (0xD23F, "1110 116E 11BA"), - (0xD240, "1110 116E 11BB"), - (0xD241, "1110 116E 11BC"), - (0xD242, "1110 116E 11BD"), - (0xD243, "1110 116E 11BE"), - (0xD244, "1110 116E 11BF"), - (0xD245, "1110 116E 11C0"), - (0xD246, "1110 116E 11C1"), - (0xD247, "1110 116E 11C2"), - (0xD248, "1110 116F"), - (0xD249, "1110 116F 11A8"), - (0xD24A, "1110 116F 11A9"), - (0xD24B, "1110 116F 11AA"), - (0xD24C, "1110 116F 11AB"), - (0xD24D, "1110 116F 11AC"), - (0xD24E, "1110 116F 11AD"), - (0xD24F, "1110 116F 11AE"), - (0xD250, "1110 116F 11AF"), - (0xD251, "1110 116F 11B0"), - (0xD252, "1110 116F 11B1"), - (0xD253, "1110 116F 11B2"), - (0xD254, "1110 116F 11B3"), - (0xD255, "1110 116F 11B4"), - (0xD256, "1110 116F 11B5"), - (0xD257, "1110 116F 11B6"), - (0xD258, "1110 116F 11B7"), - (0xD259, "1110 116F 11B8"), - (0xD25A, "1110 116F 11B9"), - (0xD25B, "1110 116F 11BA"), - (0xD25C, "1110 116F 11BB"), - (0xD25D, "1110 116F 11BC"), - (0xD25E, "1110 116F 11BD"), - (0xD25F, "1110 116F 11BE"), - (0xD260, "1110 116F 11BF"), - (0xD261, "1110 116F 11C0"), - (0xD262, "1110 116F 11C1"), - (0xD263, "1110 116F 11C2"), - (0xD264, "1110 1170"), - (0xD265, "1110 1170 11A8"), - (0xD266, "1110 1170 11A9"), - (0xD267, "1110 1170 11AA"), - (0xD268, "1110 1170 11AB"), - (0xD269, "1110 1170 11AC"), - (0xD26A, "1110 1170 11AD"), - (0xD26B, "1110 1170 11AE"), - (0xD26C, "1110 1170 11AF"), - (0xD26D, "1110 1170 11B0"), - (0xD26E, "1110 1170 11B1"), - (0xD26F, "1110 1170 11B2"), - (0xD270, "1110 1170 11B3"), - (0xD271, "1110 1170 11B4"), - (0xD272, "1110 1170 11B5"), - (0xD273, "1110 1170 11B6"), - (0xD274, "1110 1170 11B7"), - (0xD275, "1110 1170 11B8"), - (0xD276, "1110 1170 11B9"), - (0xD277, "1110 1170 11BA"), - (0xD278, "1110 1170 11BB"), - (0xD279, "1110 1170 11BC"), - (0xD27A, "1110 1170 11BD"), - (0xD27B, "1110 1170 11BE"), - (0xD27C, "1110 1170 11BF"), - (0xD27D, "1110 1170 11C0"), - (0xD27E, "1110 1170 11C1"), - (0xD27F, "1110 1170 11C2"), - (0xD280, "1110 1171"), - (0xD281, "1110 1171 11A8"), - (0xD282, "1110 1171 11A9"), - (0xD283, "1110 1171 11AA"), - (0xD284, "1110 1171 11AB"), - (0xD285, "1110 1171 11AC"), - (0xD286, "1110 1171 11AD"), - (0xD287, "1110 1171 11AE"), - (0xD288, "1110 1171 11AF"), - (0xD289, "1110 1171 11B0"), - (0xD28A, "1110 1171 11B1"), - (0xD28B, "1110 1171 11B2"), - (0xD28C, "1110 1171 11B3"), - (0xD28D, "1110 1171 11B4"), - (0xD28E, "1110 1171 11B5"), - (0xD28F, "1110 1171 11B6"), - (0xD290, "1110 1171 11B7"), - (0xD291, "1110 1171 11B8"), - (0xD292, "1110 1171 11B9"), - (0xD293, "1110 1171 11BA"), - (0xD294, "1110 1171 11BB"), - (0xD295, "1110 1171 11BC"), - (0xD296, "1110 1171 11BD"), - (0xD297, "1110 1171 11BE"), - (0xD298, "1110 1171 11BF"), - (0xD299, "1110 1171 11C0"), - (0xD29A, "1110 1171 11C1"), - (0xD29B, "1110 1171 11C2"), - (0xD29C, "1110 1172"), - (0xD29D, "1110 1172 11A8"), - (0xD29E, "1110 1172 11A9"), - (0xD29F, "1110 1172 11AA"), - (0xD2A0, "1110 1172 11AB"), - (0xD2A1, "1110 1172 11AC"), - (0xD2A2, "1110 1172 11AD"), - (0xD2A3, "1110 1172 11AE"), - (0xD2A4, "1110 1172 11AF"), - (0xD2A5, "1110 1172 11B0"), - (0xD2A6, "1110 1172 11B1"), - (0xD2A7, "1110 1172 11B2"), - (0xD2A8, "1110 1172 11B3"), - (0xD2A9, "1110 1172 11B4"), - (0xD2AA, "1110 1172 11B5"), - (0xD2AB, "1110 1172 11B6"), - (0xD2AC, "1110 1172 11B7"), - (0xD2AD, "1110 1172 11B8"), - (0xD2AE, "1110 1172 11B9"), - (0xD2AF, "1110 1172 11BA"), - (0xD2B0, "1110 1172 11BB"), - (0xD2B1, "1110 1172 11BC"), - (0xD2B2, "1110 1172 11BD"), - (0xD2B3, "1110 1172 11BE"), - (0xD2B4, "1110 1172 11BF"), - (0xD2B5, "1110 1172 11C0"), - (0xD2B6, "1110 1172 11C1"), - (0xD2B7, "1110 1172 11C2"), - (0xD2B8, "1110 1173"), - (0xD2B9, "1110 1173 11A8"), - (0xD2BA, "1110 1173 11A9"), - (0xD2BB, "1110 1173 11AA"), - (0xD2BC, "1110 1173 11AB"), - (0xD2BD, "1110 1173 11AC"), - (0xD2BE, "1110 1173 11AD"), - (0xD2BF, "1110 1173 11AE"), - (0xD2C0, "1110 1173 11AF"), - (0xD2C1, "1110 1173 11B0"), - (0xD2C2, "1110 1173 11B1"), - (0xD2C3, "1110 1173 11B2"), - (0xD2C4, "1110 1173 11B3"), - (0xD2C5, "1110 1173 11B4"), - (0xD2C6, "1110 1173 11B5"), - (0xD2C7, "1110 1173 11B6"), - (0xD2C8, "1110 1173 11B7"), - (0xD2C9, "1110 1173 11B8"), - (0xD2CA, "1110 1173 11B9"), - (0xD2CB, "1110 1173 11BA"), - (0xD2CC, "1110 1173 11BB"), - (0xD2CD, "1110 1173 11BC"), - (0xD2CE, "1110 1173 11BD"), - (0xD2CF, "1110 1173 11BE"), - (0xD2D0, "1110 1173 11BF"), - (0xD2D1, "1110 1173 11C0"), - (0xD2D2, "1110 1173 11C1"), - (0xD2D3, "1110 1173 11C2"), - (0xD2D4, "1110 1174"), - (0xD2D5, "1110 1174 11A8"), - (0xD2D6, "1110 1174 11A9"), - (0xD2D7, "1110 1174 11AA"), - (0xD2D8, "1110 1174 11AB"), - (0xD2D9, "1110 1174 11AC"), - (0xD2DA, "1110 1174 11AD"), - (0xD2DB, "1110 1174 11AE"), - (0xD2DC, "1110 1174 11AF"), - (0xD2DD, "1110 1174 11B0"), - (0xD2DE, "1110 1174 11B1"), - (0xD2DF, "1110 1174 11B2"), - (0xD2E0, "1110 1174 11B3"), - (0xD2E1, "1110 1174 11B4"), - (0xD2E2, "1110 1174 11B5"), - (0xD2E3, "1110 1174 11B6"), - (0xD2E4, "1110 1174 11B7"), - (0xD2E5, "1110 1174 11B8"), - (0xD2E6, "1110 1174 11B9"), - (0xD2E7, "1110 1174 11BA"), - (0xD2E8, "1110 1174 11BB"), - (0xD2E9, "1110 1174 11BC"), - (0xD2EA, "1110 1174 11BD"), - (0xD2EB, "1110 1174 11BE"), - (0xD2EC, "1110 1174 11BF"), - (0xD2ED, "1110 1174 11C0"), - (0xD2EE, "1110 1174 11C1"), - (0xD2EF, "1110 1174 11C2"), - (0xD2F0, "1110 1175"), - (0xD2F1, "1110 1175 11A8"), - (0xD2F2, "1110 1175 11A9"), - (0xD2F3, "1110 1175 11AA"), - (0xD2F4, "1110 1175 11AB"), - (0xD2F5, "1110 1175 11AC"), - (0xD2F6, "1110 1175 11AD"), - (0xD2F7, "1110 1175 11AE"), - (0xD2F8, "1110 1175 11AF"), - (0xD2F9, "1110 1175 11B0"), - (0xD2FA, "1110 1175 11B1"), - (0xD2FB, "1110 1175 11B2"), - (0xD2FC, "1110 1175 11B3"), - (0xD2FD, "1110 1175 11B4"), - (0xD2FE, "1110 1175 11B5"), - (0xD2FF, "1110 1175 11B6"), - (0xD300, "1110 1175 11B7"), - (0xD301, "1110 1175 11B8"), - (0xD302, "1110 1175 11B9"), - (0xD303, "1110 1175 11BA"), - (0xD304, "1110 1175 11BB"), - (0xD305, "1110 1175 11BC"), - (0xD306, "1110 1175 11BD"), - (0xD307, "1110 1175 11BE"), - (0xD308, "1110 1175 11BF"), - (0xD309, "1110 1175 11C0"), - (0xD30A, "1110 1175 11C1"), - (0xD30B, "1110 1175 11C2"), - (0xD30C, "1111 1161"), - (0xD30D, "1111 1161 11A8"), - (0xD30E, "1111 1161 11A9"), - (0xD30F, "1111 1161 11AA"), - (0xD310, "1111 1161 11AB"), - (0xD311, "1111 1161 11AC"), - (0xD312, "1111 1161 11AD"), - (0xD313, "1111 1161 11AE"), - (0xD314, "1111 1161 11AF"), - (0xD315, "1111 1161 11B0"), - (0xD316, "1111 1161 11B1"), - (0xD317, "1111 1161 11B2"), - (0xD318, "1111 1161 11B3"), - (0xD319, "1111 1161 11B4"), - (0xD31A, "1111 1161 11B5"), - (0xD31B, "1111 1161 11B6"), - (0xD31C, "1111 1161 11B7"), - (0xD31D, "1111 1161 11B8"), - (0xD31E, "1111 1161 11B9"), - (0xD31F, "1111 1161 11BA"), - (0xD320, "1111 1161 11BB"), - (0xD321, "1111 1161 11BC"), - (0xD322, "1111 1161 11BD"), - (0xD323, "1111 1161 11BE"), - (0xD324, "1111 1161 11BF"), - (0xD325, "1111 1161 11C0"), - (0xD326, "1111 1161 11C1"), - (0xD327, "1111 1161 11C2"), - (0xD328, "1111 1162"), - (0xD329, "1111 1162 11A8"), - (0xD32A, "1111 1162 11A9"), - (0xD32B, "1111 1162 11AA"), - (0xD32C, "1111 1162 11AB"), - (0xD32D, "1111 1162 11AC"), - (0xD32E, "1111 1162 11AD"), - (0xD32F, "1111 1162 11AE"), - (0xD330, "1111 1162 11AF"), - (0xD331, "1111 1162 11B0"), - (0xD332, "1111 1162 11B1"), - (0xD333, "1111 1162 11B2"), - (0xD334, "1111 1162 11B3"), - (0xD335, "1111 1162 11B4"), - (0xD336, "1111 1162 11B5"), - (0xD337, "1111 1162 11B6"), - (0xD338, "1111 1162 11B7"), - (0xD339, "1111 1162 11B8"), - (0xD33A, "1111 1162 11B9"), - (0xD33B, "1111 1162 11BA"), - (0xD33C, "1111 1162 11BB"), - (0xD33D, "1111 1162 11BC"), - (0xD33E, "1111 1162 11BD"), - (0xD33F, "1111 1162 11BE"), - (0xD340, "1111 1162 11BF"), - (0xD341, "1111 1162 11C0"), - (0xD342, "1111 1162 11C1"), - (0xD343, "1111 1162 11C2"), - (0xD344, "1111 1163"), - (0xD345, "1111 1163 11A8"), - (0xD346, "1111 1163 11A9"), - (0xD347, "1111 1163 11AA"), - (0xD348, "1111 1163 11AB"), - (0xD349, "1111 1163 11AC"), - (0xD34A, "1111 1163 11AD"), - (0xD34B, "1111 1163 11AE"), - (0xD34C, "1111 1163 11AF"), - (0xD34D, "1111 1163 11B0"), - (0xD34E, "1111 1163 11B1"), - (0xD34F, "1111 1163 11B2"), - (0xD350, "1111 1163 11B3"), - (0xD351, "1111 1163 11B4"), - (0xD352, "1111 1163 11B5"), - (0xD353, "1111 1163 11B6"), - (0xD354, "1111 1163 11B7"), - (0xD355, "1111 1163 11B8"), - (0xD356, "1111 1163 11B9"), - (0xD357, "1111 1163 11BA"), - (0xD358, "1111 1163 11BB"), - (0xD359, "1111 1163 11BC"), - (0xD35A, "1111 1163 11BD"), - (0xD35B, "1111 1163 11BE"), - (0xD35C, "1111 1163 11BF"), - (0xD35D, "1111 1163 11C0"), - (0xD35E, "1111 1163 11C1"), - (0xD35F, "1111 1163 11C2"), - (0xD360, "1111 1164"), - (0xD361, "1111 1164 11A8"), - (0xD362, "1111 1164 11A9"), - (0xD363, "1111 1164 11AA"), - (0xD364, "1111 1164 11AB"), - (0xD365, "1111 1164 11AC"), - (0xD366, "1111 1164 11AD"), - (0xD367, "1111 1164 11AE"), - (0xD368, "1111 1164 11AF"), - (0xD369, "1111 1164 11B0"), - (0xD36A, "1111 1164 11B1"), - (0xD36B, "1111 1164 11B2"), - (0xD36C, "1111 1164 11B3"), - (0xD36D, "1111 1164 11B4"), - (0xD36E, "1111 1164 11B5"), - (0xD36F, "1111 1164 11B6"), - (0xD370, "1111 1164 11B7"), - (0xD371, "1111 1164 11B8"), - (0xD372, "1111 1164 11B9"), - (0xD373, "1111 1164 11BA"), - (0xD374, "1111 1164 11BB"), - (0xD375, "1111 1164 11BC"), - (0xD376, "1111 1164 11BD"), - (0xD377, "1111 1164 11BE"), - (0xD378, "1111 1164 11BF"), - (0xD379, "1111 1164 11C0"), - (0xD37A, "1111 1164 11C1"), - (0xD37B, "1111 1164 11C2"), - (0xD37C, "1111 1165"), - (0xD37D, "1111 1165 11A8"), - (0xD37E, "1111 1165 11A9"), - (0xD37F, "1111 1165 11AA"), - (0xD380, "1111 1165 11AB"), - (0xD381, "1111 1165 11AC"), - (0xD382, "1111 1165 11AD"), - (0xD383, "1111 1165 11AE"), - (0xD384, "1111 1165 11AF"), - (0xD385, "1111 1165 11B0"), - (0xD386, "1111 1165 11B1"), - (0xD387, "1111 1165 11B2"), - (0xD388, "1111 1165 11B3"), - (0xD389, "1111 1165 11B4"), - (0xD38A, "1111 1165 11B5"), - (0xD38B, "1111 1165 11B6"), - (0xD38C, "1111 1165 11B7"), - (0xD38D, "1111 1165 11B8"), - (0xD38E, "1111 1165 11B9"), - (0xD38F, "1111 1165 11BA"), - (0xD390, "1111 1165 11BB"), - (0xD391, "1111 1165 11BC"), - (0xD392, "1111 1165 11BD"), - (0xD393, "1111 1165 11BE"), - (0xD394, "1111 1165 11BF"), - (0xD395, "1111 1165 11C0"), - (0xD396, "1111 1165 11C1"), - (0xD397, "1111 1165 11C2"), - (0xD398, "1111 1166"), - (0xD399, "1111 1166 11A8"), - (0xD39A, "1111 1166 11A9"), - (0xD39B, "1111 1166 11AA"), - (0xD39C, "1111 1166 11AB"), - (0xD39D, "1111 1166 11AC"), - (0xD39E, "1111 1166 11AD"), - (0xD39F, "1111 1166 11AE"), - (0xD3A0, "1111 1166 11AF"), - (0xD3A1, "1111 1166 11B0"), - (0xD3A2, "1111 1166 11B1"), - (0xD3A3, "1111 1166 11B2"), - (0xD3A4, "1111 1166 11B3"), - (0xD3A5, "1111 1166 11B4"), - (0xD3A6, "1111 1166 11B5"), - (0xD3A7, "1111 1166 11B6"), - (0xD3A8, "1111 1166 11B7"), - (0xD3A9, "1111 1166 11B8"), - (0xD3AA, "1111 1166 11B9"), - (0xD3AB, "1111 1166 11BA"), - (0xD3AC, "1111 1166 11BB"), - (0xD3AD, "1111 1166 11BC"), - (0xD3AE, "1111 1166 11BD"), - (0xD3AF, "1111 1166 11BE"), - (0xD3B0, "1111 1166 11BF"), - (0xD3B1, "1111 1166 11C0"), - (0xD3B2, "1111 1166 11C1"), - (0xD3B3, "1111 1166 11C2"), - (0xD3B4, "1111 1167"), - (0xD3B5, "1111 1167 11A8"), - (0xD3B6, "1111 1167 11A9"), - (0xD3B7, "1111 1167 11AA"), - (0xD3B8, "1111 1167 11AB"), - (0xD3B9, "1111 1167 11AC"), - (0xD3BA, "1111 1167 11AD"), - (0xD3BB, "1111 1167 11AE"), - (0xD3BC, "1111 1167 11AF"), - (0xD3BD, "1111 1167 11B0"), - (0xD3BE, "1111 1167 11B1"), - (0xD3BF, "1111 1167 11B2"), - (0xD3C0, "1111 1167 11B3"), - (0xD3C1, "1111 1167 11B4"), - (0xD3C2, "1111 1167 11B5"), - (0xD3C3, "1111 1167 11B6"), - (0xD3C4, "1111 1167 11B7"), - (0xD3C5, "1111 1167 11B8"), - (0xD3C6, "1111 1167 11B9"), - (0xD3C7, "1111 1167 11BA"), - (0xD3C8, "1111 1167 11BB"), - (0xD3C9, "1111 1167 11BC"), - (0xD3CA, "1111 1167 11BD"), - (0xD3CB, "1111 1167 11BE"), - (0xD3CC, "1111 1167 11BF"), - (0xD3CD, "1111 1167 11C0"), - (0xD3CE, "1111 1167 11C1"), - (0xD3CF, "1111 1167 11C2"), - (0xD3D0, "1111 1168"), - (0xD3D1, "1111 1168 11A8"), - (0xD3D2, "1111 1168 11A9"), - (0xD3D3, "1111 1168 11AA"), - (0xD3D4, "1111 1168 11AB"), - (0xD3D5, "1111 1168 11AC"), - (0xD3D6, "1111 1168 11AD"), - (0xD3D7, "1111 1168 11AE"), - (0xD3D8, "1111 1168 11AF"), - (0xD3D9, "1111 1168 11B0"), - (0xD3DA, "1111 1168 11B1"), - (0xD3DB, "1111 1168 11B2"), - (0xD3DC, "1111 1168 11B3"), - (0xD3DD, "1111 1168 11B4"), - (0xD3DE, "1111 1168 11B5"), - (0xD3DF, "1111 1168 11B6"), - (0xD3E0, "1111 1168 11B7"), - (0xD3E1, "1111 1168 11B8"), - (0xD3E2, "1111 1168 11B9"), - (0xD3E3, "1111 1168 11BA"), - (0xD3E4, "1111 1168 11BB"), - (0xD3E5, "1111 1168 11BC"), - (0xD3E6, "1111 1168 11BD"), - (0xD3E7, "1111 1168 11BE"), - (0xD3E8, "1111 1168 11BF"), - (0xD3E9, "1111 1168 11C0"), - (0xD3EA, "1111 1168 11C1"), - (0xD3EB, "1111 1168 11C2"), - (0xD3EC, "1111 1169"), - (0xD3ED, "1111 1169 11A8"), - (0xD3EE, "1111 1169 11A9"), - (0xD3EF, "1111 1169 11AA"), - (0xD3F0, "1111 1169 11AB"), - (0xD3F1, "1111 1169 11AC"), - (0xD3F2, "1111 1169 11AD"), - (0xD3F3, "1111 1169 11AE"), - (0xD3F4, "1111 1169 11AF"), - (0xD3F5, "1111 1169 11B0"), - (0xD3F6, "1111 1169 11B1"), - (0xD3F7, "1111 1169 11B2"), - (0xD3F8, "1111 1169 11B3"), - (0xD3F9, "1111 1169 11B4"), - (0xD3FA, "1111 1169 11B5"), - (0xD3FB, "1111 1169 11B6"), - (0xD3FC, "1111 1169 11B7"), - (0xD3FD, "1111 1169 11B8"), - (0xD3FE, "1111 1169 11B9"), - (0xD3FF, "1111 1169 11BA"), - (0xD400, "1111 1169 11BB"), - (0xD401, "1111 1169 11BC"), - (0xD402, "1111 1169 11BD"), - (0xD403, "1111 1169 11BE"), - (0xD404, "1111 1169 11BF"), - (0xD405, "1111 1169 11C0"), - (0xD406, "1111 1169 11C1"), - (0xD407, "1111 1169 11C2"), - (0xD408, "1111 116A"), - (0xD409, "1111 116A 11A8"), - (0xD40A, "1111 116A 11A9"), - (0xD40B, "1111 116A 11AA"), - (0xD40C, "1111 116A 11AB"), - (0xD40D, "1111 116A 11AC"), - (0xD40E, "1111 116A 11AD"), - (0xD40F, "1111 116A 11AE"), - (0xD410, "1111 116A 11AF"), - (0xD411, "1111 116A 11B0"), - (0xD412, "1111 116A 11B1"), - (0xD413, "1111 116A 11B2"), - (0xD414, "1111 116A 11B3"), - (0xD415, "1111 116A 11B4"), - (0xD416, "1111 116A 11B5"), - (0xD417, "1111 116A 11B6"), - (0xD418, "1111 116A 11B7"), - (0xD419, "1111 116A 11B8"), - (0xD41A, "1111 116A 11B9"), - (0xD41B, "1111 116A 11BA"), - (0xD41C, "1111 116A 11BB"), - (0xD41D, "1111 116A 11BC"), - (0xD41E, "1111 116A 11BD"), - (0xD41F, "1111 116A 11BE"), - (0xD420, "1111 116A 11BF"), - (0xD421, "1111 116A 11C0"), - (0xD422, "1111 116A 11C1"), - (0xD423, "1111 116A 11C2"), - (0xD424, "1111 116B"), - (0xD425, "1111 116B 11A8"), - (0xD426, "1111 116B 11A9"), - (0xD427, "1111 116B 11AA"), - (0xD428, "1111 116B 11AB"), - (0xD429, "1111 116B 11AC"), - (0xD42A, "1111 116B 11AD"), - (0xD42B, "1111 116B 11AE"), - (0xD42C, "1111 116B 11AF"), - (0xD42D, "1111 116B 11B0"), - (0xD42E, "1111 116B 11B1"), - (0xD42F, "1111 116B 11B2"), - (0xD430, "1111 116B 11B3"), - (0xD431, "1111 116B 11B4"), - (0xD432, "1111 116B 11B5"), - (0xD433, "1111 116B 11B6"), - (0xD434, "1111 116B 11B7"), - (0xD435, "1111 116B 11B8"), - (0xD436, "1111 116B 11B9"), - (0xD437, "1111 116B 11BA"), - (0xD438, "1111 116B 11BB"), - (0xD439, "1111 116B 11BC"), - (0xD43A, "1111 116B 11BD"), - (0xD43B, "1111 116B 11BE"), - (0xD43C, "1111 116B 11BF"), - (0xD43D, "1111 116B 11C0"), - (0xD43E, "1111 116B 11C1"), - (0xD43F, "1111 116B 11C2"), - (0xD440, "1111 116C"), - (0xD441, "1111 116C 11A8"), - (0xD442, "1111 116C 11A9"), - (0xD443, "1111 116C 11AA"), - (0xD444, "1111 116C 11AB"), - (0xD445, "1111 116C 11AC"), - (0xD446, "1111 116C 11AD"), - (0xD447, "1111 116C 11AE"), - (0xD448, "1111 116C 11AF"), - (0xD449, "1111 116C 11B0"), - (0xD44A, "1111 116C 11B1"), - (0xD44B, "1111 116C 11B2"), - (0xD44C, "1111 116C 11B3"), - (0xD44D, "1111 116C 11B4"), - (0xD44E, "1111 116C 11B5"), - (0xD44F, "1111 116C 11B6"), - (0xD450, "1111 116C 11B7"), - (0xD451, "1111 116C 11B8"), - (0xD452, "1111 116C 11B9"), - (0xD453, "1111 116C 11BA"), - (0xD454, "1111 116C 11BB"), - (0xD455, "1111 116C 11BC"), - (0xD456, "1111 116C 11BD"), - (0xD457, "1111 116C 11BE"), - (0xD458, "1111 116C 11BF"), - (0xD459, "1111 116C 11C0"), - (0xD45A, "1111 116C 11C1"), - (0xD45B, "1111 116C 11C2"), - (0xD45C, "1111 116D"), - (0xD45D, "1111 116D 11A8"), - (0xD45E, "1111 116D 11A9"), - (0xD45F, "1111 116D 11AA"), - (0xD460, "1111 116D 11AB"), - (0xD461, "1111 116D 11AC"), - (0xD462, "1111 116D 11AD"), - (0xD463, "1111 116D 11AE"), - (0xD464, "1111 116D 11AF"), - (0xD465, "1111 116D 11B0"), - (0xD466, "1111 116D 11B1"), - (0xD467, "1111 116D 11B2"), - (0xD468, "1111 116D 11B3"), - (0xD469, "1111 116D 11B4"), - (0xD46A, "1111 116D 11B5"), - (0xD46B, "1111 116D 11B6"), - (0xD46C, "1111 116D 11B7"), - (0xD46D, "1111 116D 11B8"), - (0xD46E, "1111 116D 11B9"), - (0xD46F, "1111 116D 11BA"), - (0xD470, "1111 116D 11BB"), - (0xD471, "1111 116D 11BC"), - (0xD472, "1111 116D 11BD"), - (0xD473, "1111 116D 11BE"), - (0xD474, "1111 116D 11BF"), - (0xD475, "1111 116D 11C0"), - (0xD476, "1111 116D 11C1"), - (0xD477, "1111 116D 11C2"), - (0xD478, "1111 116E"), - (0xD479, "1111 116E 11A8"), - (0xD47A, "1111 116E 11A9"), - (0xD47B, "1111 116E 11AA"), - (0xD47C, "1111 116E 11AB"), - (0xD47D, "1111 116E 11AC"), - (0xD47E, "1111 116E 11AD"), - (0xD47F, "1111 116E 11AE"), - (0xD480, "1111 116E 11AF"), - (0xD481, "1111 116E 11B0"), - (0xD482, "1111 116E 11B1"), - (0xD483, "1111 116E 11B2"), - (0xD484, "1111 116E 11B3"), - (0xD485, "1111 116E 11B4"), - (0xD486, "1111 116E 11B5"), - (0xD487, "1111 116E 11B6"), - (0xD488, "1111 116E 11B7"), - (0xD489, "1111 116E 11B8"), - (0xD48A, "1111 116E 11B9"), - (0xD48B, "1111 116E 11BA"), - (0xD48C, "1111 116E 11BB"), - (0xD48D, "1111 116E 11BC"), - (0xD48E, "1111 116E 11BD"), - (0xD48F, "1111 116E 11BE"), - (0xD490, "1111 116E 11BF"), - (0xD491, "1111 116E 11C0"), - (0xD492, "1111 116E 11C1"), - (0xD493, "1111 116E 11C2"), - (0xD494, "1111 116F"), - (0xD495, "1111 116F 11A8"), - (0xD496, "1111 116F 11A9"), - (0xD497, "1111 116F 11AA"), - (0xD498, "1111 116F 11AB"), - (0xD499, "1111 116F 11AC"), - (0xD49A, "1111 116F 11AD"), - (0xD49B, "1111 116F 11AE"), - (0xD49C, "1111 116F 11AF"), - (0xD49D, "1111 116F 11B0"), - (0xD49E, "1111 116F 11B1"), - (0xD49F, "1111 116F 11B2"), - (0xD4A0, "1111 116F 11B3"), - (0xD4A1, "1111 116F 11B4"), - (0xD4A2, "1111 116F 11B5"), - (0xD4A3, "1111 116F 11B6"), - (0xD4A4, "1111 116F 11B7"), - (0xD4A5, "1111 116F 11B8"), - (0xD4A6, "1111 116F 11B9"), - (0xD4A7, "1111 116F 11BA"), - (0xD4A8, "1111 116F 11BB"), - (0xD4A9, "1111 116F 11BC"), - (0xD4AA, "1111 116F 11BD"), - (0xD4AB, "1111 116F 11BE"), - (0xD4AC, "1111 116F 11BF"), - (0xD4AD, "1111 116F 11C0"), - (0xD4AE, "1111 116F 11C1"), - (0xD4AF, "1111 116F 11C2"), - (0xD4B0, "1111 1170"), - (0xD4B1, "1111 1170 11A8"), - (0xD4B2, "1111 1170 11A9"), - (0xD4B3, "1111 1170 11AA"), - (0xD4B4, "1111 1170 11AB"), - (0xD4B5, "1111 1170 11AC"), - (0xD4B6, "1111 1170 11AD"), - (0xD4B7, "1111 1170 11AE"), - (0xD4B8, "1111 1170 11AF"), - (0xD4B9, "1111 1170 11B0"), - (0xD4BA, "1111 1170 11B1"), - (0xD4BB, "1111 1170 11B2"), - (0xD4BC, "1111 1170 11B3"), - (0xD4BD, "1111 1170 11B4"), - (0xD4BE, "1111 1170 11B5"), - (0xD4BF, "1111 1170 11B6"), - (0xD4C0, "1111 1170 11B7"), - (0xD4C1, "1111 1170 11B8"), - (0xD4C2, "1111 1170 11B9"), - (0xD4C3, "1111 1170 11BA"), - (0xD4C4, "1111 1170 11BB"), - (0xD4C5, "1111 1170 11BC"), - (0xD4C6, "1111 1170 11BD"), - (0xD4C7, "1111 1170 11BE"), - (0xD4C8, "1111 1170 11BF"), - (0xD4C9, "1111 1170 11C0"), - (0xD4CA, "1111 1170 11C1"), - (0xD4CB, "1111 1170 11C2"), - (0xD4CC, "1111 1171"), - (0xD4CD, "1111 1171 11A8"), - (0xD4CE, "1111 1171 11A9"), - (0xD4CF, "1111 1171 11AA"), - (0xD4D0, "1111 1171 11AB"), - (0xD4D1, "1111 1171 11AC"), - (0xD4D2, "1111 1171 11AD"), - (0xD4D3, "1111 1171 11AE"), - (0xD4D4, "1111 1171 11AF"), - (0xD4D5, "1111 1171 11B0"), - (0xD4D6, "1111 1171 11B1"), - (0xD4D7, "1111 1171 11B2"), - (0xD4D8, "1111 1171 11B3"), - (0xD4D9, "1111 1171 11B4"), - (0xD4DA, "1111 1171 11B5"), - (0xD4DB, "1111 1171 11B6"), - (0xD4DC, "1111 1171 11B7"), - (0xD4DD, "1111 1171 11B8"), - (0xD4DE, "1111 1171 11B9"), - (0xD4DF, "1111 1171 11BA"), - (0xD4E0, "1111 1171 11BB"), - (0xD4E1, "1111 1171 11BC"), - (0xD4E2, "1111 1171 11BD"), - (0xD4E3, "1111 1171 11BE"), - (0xD4E4, "1111 1171 11BF"), - (0xD4E5, "1111 1171 11C0"), - (0xD4E6, "1111 1171 11C1"), - (0xD4E7, "1111 1171 11C2"), - (0xD4E8, "1111 1172"), - (0xD4E9, "1111 1172 11A8"), - (0xD4EA, "1111 1172 11A9"), - (0xD4EB, "1111 1172 11AA"), - (0xD4EC, "1111 1172 11AB"), - (0xD4ED, "1111 1172 11AC"), - (0xD4EE, "1111 1172 11AD"), - (0xD4EF, "1111 1172 11AE"), - (0xD4F0, "1111 1172 11AF"), - (0xD4F1, "1111 1172 11B0"), - (0xD4F2, "1111 1172 11B1"), - (0xD4F3, "1111 1172 11B2"), - (0xD4F4, "1111 1172 11B3"), - (0xD4F5, "1111 1172 11B4"), - (0xD4F6, "1111 1172 11B5"), - (0xD4F7, "1111 1172 11B6"), - (0xD4F8, "1111 1172 11B7"), - (0xD4F9, "1111 1172 11B8"), - (0xD4FA, "1111 1172 11B9"), - (0xD4FB, "1111 1172 11BA"), - (0xD4FC, "1111 1172 11BB"), - (0xD4FD, "1111 1172 11BC"), - (0xD4FE, "1111 1172 11BD"), - (0xD4FF, "1111 1172 11BE"), - (0xD500, "1111 1172 11BF"), - (0xD501, "1111 1172 11C0"), - (0xD502, "1111 1172 11C1"), - (0xD503, "1111 1172 11C2"), - (0xD504, "1111 1173"), - (0xD505, "1111 1173 11A8"), - (0xD506, "1111 1173 11A9"), - (0xD507, "1111 1173 11AA"), - (0xD508, "1111 1173 11AB"), - (0xD509, "1111 1173 11AC"), - (0xD50A, "1111 1173 11AD"), - (0xD50B, "1111 1173 11AE"), - (0xD50C, "1111 1173 11AF"), - (0xD50D, "1111 1173 11B0"), - (0xD50E, "1111 1173 11B1"), - (0xD50F, "1111 1173 11B2"), - (0xD510, "1111 1173 11B3"), - (0xD511, "1111 1173 11B4"), - (0xD512, "1111 1173 11B5"), - (0xD513, "1111 1173 11B6"), - (0xD514, "1111 1173 11B7"), - (0xD515, "1111 1173 11B8"), - (0xD516, "1111 1173 11B9"), - (0xD517, "1111 1173 11BA"), - (0xD518, "1111 1173 11BB"), - (0xD519, "1111 1173 11BC"), - (0xD51A, "1111 1173 11BD"), - (0xD51B, "1111 1173 11BE"), - (0xD51C, "1111 1173 11BF"), - (0xD51D, "1111 1173 11C0"), - (0xD51E, "1111 1173 11C1"), - (0xD51F, "1111 1173 11C2"), - (0xD520, "1111 1174"), - (0xD521, "1111 1174 11A8"), - (0xD522, "1111 1174 11A9"), - (0xD523, "1111 1174 11AA"), - (0xD524, "1111 1174 11AB"), - (0xD525, "1111 1174 11AC"), - (0xD526, "1111 1174 11AD"), - (0xD527, "1111 1174 11AE"), - (0xD528, "1111 1174 11AF"), - (0xD529, "1111 1174 11B0"), - (0xD52A, "1111 1174 11B1"), - (0xD52B, "1111 1174 11B2"), - (0xD52C, "1111 1174 11B3"), - (0xD52D, "1111 1174 11B4"), - (0xD52E, "1111 1174 11B5"), - (0xD52F, "1111 1174 11B6"), - (0xD530, "1111 1174 11B7"), - (0xD531, "1111 1174 11B8"), - (0xD532, "1111 1174 11B9"), - (0xD533, "1111 1174 11BA"), - (0xD534, "1111 1174 11BB"), - (0xD535, "1111 1174 11BC"), - (0xD536, "1111 1174 11BD"), - (0xD537, "1111 1174 11BE"), - (0xD538, "1111 1174 11BF"), - (0xD539, "1111 1174 11C0"), - (0xD53A, "1111 1174 11C1"), - (0xD53B, "1111 1174 11C2"), - (0xD53C, "1111 1175"), - (0xD53D, "1111 1175 11A8"), - (0xD53E, "1111 1175 11A9"), - (0xD53F, "1111 1175 11AA"), - (0xD540, "1111 1175 11AB"), - (0xD541, "1111 1175 11AC"), - (0xD542, "1111 1175 11AD"), - (0xD543, "1111 1175 11AE"), - (0xD544, "1111 1175 11AF"), - (0xD545, "1111 1175 11B0"), - (0xD546, "1111 1175 11B1"), - (0xD547, "1111 1175 11B2"), - (0xD548, "1111 1175 11B3"), - (0xD549, "1111 1175 11B4"), - (0xD54A, "1111 1175 11B5"), - (0xD54B, "1111 1175 11B6"), - (0xD54C, "1111 1175 11B7"), - (0xD54D, "1111 1175 11B8"), - (0xD54E, "1111 1175 11B9"), - (0xD54F, "1111 1175 11BA"), - (0xD550, "1111 1175 11BB"), - (0xD551, "1111 1175 11BC"), - (0xD552, "1111 1175 11BD"), - (0xD553, "1111 1175 11BE"), - (0xD554, "1111 1175 11BF"), - (0xD555, "1111 1175 11C0"), - (0xD556, "1111 1175 11C1"), - (0xD557, "1111 1175 11C2"), - (0xD558, "1112 1161"), - (0xD559, "1112 1161 11A8"), - (0xD55A, "1112 1161 11A9"), - (0xD55B, "1112 1161 11AA"), - (0xD55C, "1112 1161 11AB"), - (0xD55D, "1112 1161 11AC"), - (0xD55E, "1112 1161 11AD"), - (0xD55F, "1112 1161 11AE"), - (0xD560, "1112 1161 11AF"), - (0xD561, "1112 1161 11B0"), - (0xD562, "1112 1161 11B1"), - (0xD563, "1112 1161 11B2"), - (0xD564, "1112 1161 11B3"), - (0xD565, "1112 1161 11B4"), - (0xD566, "1112 1161 11B5"), - (0xD567, "1112 1161 11B6"), - (0xD568, "1112 1161 11B7"), - (0xD569, "1112 1161 11B8"), - (0xD56A, "1112 1161 11B9"), - (0xD56B, "1112 1161 11BA"), - (0xD56C, "1112 1161 11BB"), - (0xD56D, "1112 1161 11BC"), - (0xD56E, "1112 1161 11BD"), - (0xD56F, "1112 1161 11BE"), - (0xD570, "1112 1161 11BF"), - (0xD571, "1112 1161 11C0"), - (0xD572, "1112 1161 11C1"), - (0xD573, "1112 1161 11C2"), - (0xD574, "1112 1162"), - (0xD575, "1112 1162 11A8"), - (0xD576, "1112 1162 11A9"), - (0xD577, "1112 1162 11AA"), - (0xD578, "1112 1162 11AB"), - (0xD579, "1112 1162 11AC"), - (0xD57A, "1112 1162 11AD"), - (0xD57B, "1112 1162 11AE"), - (0xD57C, "1112 1162 11AF"), - (0xD57D, "1112 1162 11B0"), - (0xD57E, "1112 1162 11B1"), - (0xD57F, "1112 1162 11B2"), - (0xD580, "1112 1162 11B3"), - (0xD581, "1112 1162 11B4"), - (0xD582, "1112 1162 11B5"), - (0xD583, "1112 1162 11B6"), - (0xD584, "1112 1162 11B7"), - (0xD585, "1112 1162 11B8"), - (0xD586, "1112 1162 11B9"), - (0xD587, "1112 1162 11BA"), - (0xD588, "1112 1162 11BB"), - (0xD589, "1112 1162 11BC"), - (0xD58A, "1112 1162 11BD"), - (0xD58B, "1112 1162 11BE"), - (0xD58C, "1112 1162 11BF"), - (0xD58D, "1112 1162 11C0"), - (0xD58E, "1112 1162 11C1"), - (0xD58F, "1112 1162 11C2"), - (0xD590, "1112 1163"), - (0xD591, "1112 1163 11A8"), - (0xD592, "1112 1163 11A9"), - (0xD593, "1112 1163 11AA"), - (0xD594, "1112 1163 11AB"), - (0xD595, "1112 1163 11AC"), - (0xD596, "1112 1163 11AD"), - (0xD597, "1112 1163 11AE"), - (0xD598, "1112 1163 11AF"), - (0xD599, "1112 1163 11B0"), - (0xD59A, "1112 1163 11B1"), - (0xD59B, "1112 1163 11B2"), - (0xD59C, "1112 1163 11B3"), - (0xD59D, "1112 1163 11B4"), - (0xD59E, "1112 1163 11B5"), - (0xD59F, "1112 1163 11B6"), - (0xD5A0, "1112 1163 11B7"), - (0xD5A1, "1112 1163 11B8"), - (0xD5A2, "1112 1163 11B9"), - (0xD5A3, "1112 1163 11BA"), - (0xD5A4, "1112 1163 11BB"), - (0xD5A5, "1112 1163 11BC"), - (0xD5A6, "1112 1163 11BD"), - (0xD5A7, "1112 1163 11BE"), - (0xD5A8, "1112 1163 11BF"), - (0xD5A9, "1112 1163 11C0"), - (0xD5AA, "1112 1163 11C1"), - (0xD5AB, "1112 1163 11C2"), - (0xD5AC, "1112 1164"), - (0xD5AD, "1112 1164 11A8"), - (0xD5AE, "1112 1164 11A9"), - (0xD5AF, "1112 1164 11AA"), - (0xD5B0, "1112 1164 11AB"), - (0xD5B1, "1112 1164 11AC"), - (0xD5B2, "1112 1164 11AD"), - (0xD5B3, "1112 1164 11AE"), - (0xD5B4, "1112 1164 11AF"), - (0xD5B5, "1112 1164 11B0"), - (0xD5B6, "1112 1164 11B1"), - (0xD5B7, "1112 1164 11B2"), - (0xD5B8, "1112 1164 11B3"), - (0xD5B9, "1112 1164 11B4"), - (0xD5BA, "1112 1164 11B5"), - (0xD5BB, "1112 1164 11B6"), - (0xD5BC, "1112 1164 11B7"), - (0xD5BD, "1112 1164 11B8"), - (0xD5BE, "1112 1164 11B9"), - (0xD5BF, "1112 1164 11BA"), - (0xD5C0, "1112 1164 11BB"), - (0xD5C1, "1112 1164 11BC"), - (0xD5C2, "1112 1164 11BD"), - (0xD5C3, "1112 1164 11BE"), - (0xD5C4, "1112 1164 11BF"), - (0xD5C5, "1112 1164 11C0"), - (0xD5C6, "1112 1164 11C1"), - (0xD5C7, "1112 1164 11C2"), - (0xD5C8, "1112 1165"), - (0xD5C9, "1112 1165 11A8"), - (0xD5CA, "1112 1165 11A9"), - (0xD5CB, "1112 1165 11AA"), - (0xD5CC, "1112 1165 11AB"), - (0xD5CD, "1112 1165 11AC"), - (0xD5CE, "1112 1165 11AD"), - (0xD5CF, "1112 1165 11AE"), - (0xD5D0, "1112 1165 11AF"), - (0xD5D1, "1112 1165 11B0"), - (0xD5D2, "1112 1165 11B1"), - (0xD5D3, "1112 1165 11B2"), - (0xD5D4, "1112 1165 11B3"), - (0xD5D5, "1112 1165 11B4"), - (0xD5D6, "1112 1165 11B5"), - (0xD5D7, "1112 1165 11B6"), - (0xD5D8, "1112 1165 11B7"), - (0xD5D9, "1112 1165 11B8"), - (0xD5DA, "1112 1165 11B9"), - (0xD5DB, "1112 1165 11BA"), - (0xD5DC, "1112 1165 11BB"), - (0xD5DD, "1112 1165 11BC"), - (0xD5DE, "1112 1165 11BD"), - (0xD5DF, "1112 1165 11BE"), - (0xD5E0, "1112 1165 11BF"), - (0xD5E1, "1112 1165 11C0"), - (0xD5E2, "1112 1165 11C1"), - (0xD5E3, "1112 1165 11C2"), - (0xD5E4, "1112 1166"), - (0xD5E5, "1112 1166 11A8"), - (0xD5E6, "1112 1166 11A9"), - (0xD5E7, "1112 1166 11AA"), - (0xD5E8, "1112 1166 11AB"), - (0xD5E9, "1112 1166 11AC"), - (0xD5EA, "1112 1166 11AD"), - (0xD5EB, "1112 1166 11AE"), - (0xD5EC, "1112 1166 11AF"), - (0xD5ED, "1112 1166 11B0"), - (0xD5EE, "1112 1166 11B1"), - (0xD5EF, "1112 1166 11B2"), - (0xD5F0, "1112 1166 11B3"), - (0xD5F1, "1112 1166 11B4"), - (0xD5F2, "1112 1166 11B5"), - (0xD5F3, "1112 1166 11B6"), - (0xD5F4, "1112 1166 11B7"), - (0xD5F5, "1112 1166 11B8"), - (0xD5F6, "1112 1166 11B9"), - (0xD5F7, "1112 1166 11BA"), - (0xD5F8, "1112 1166 11BB"), - (0xD5F9, "1112 1166 11BC"), - (0xD5FA, "1112 1166 11BD"), - (0xD5FB, "1112 1166 11BE"), - (0xD5FC, "1112 1166 11BF"), - (0xD5FD, "1112 1166 11C0"), - (0xD5FE, "1112 1166 11C1"), - (0xD5FF, "1112 1166 11C2"), - (0xD600, "1112 1167"), - (0xD601, "1112 1167 11A8"), - (0xD602, "1112 1167 11A9"), - (0xD603, "1112 1167 11AA"), - (0xD604, "1112 1167 11AB"), - (0xD605, "1112 1167 11AC"), - (0xD606, "1112 1167 11AD"), - (0xD607, "1112 1167 11AE"), - (0xD608, "1112 1167 11AF"), - (0xD609, "1112 1167 11B0"), - (0xD60A, "1112 1167 11B1"), - (0xD60B, "1112 1167 11B2"), - (0xD60C, "1112 1167 11B3"), - (0xD60D, "1112 1167 11B4"), - (0xD60E, "1112 1167 11B5"), - (0xD60F, "1112 1167 11B6"), - (0xD610, "1112 1167 11B7"), - (0xD611, "1112 1167 11B8"), - (0xD612, "1112 1167 11B9"), - (0xD613, "1112 1167 11BA"), - (0xD614, "1112 1167 11BB"), - (0xD615, "1112 1167 11BC"), - (0xD616, "1112 1167 11BD"), - (0xD617, "1112 1167 11BE"), - (0xD618, "1112 1167 11BF"), - (0xD619, "1112 1167 11C0"), - (0xD61A, "1112 1167 11C1"), - (0xD61B, "1112 1167 11C2"), - (0xD61C, "1112 1168"), - (0xD61D, "1112 1168 11A8"), - (0xD61E, "1112 1168 11A9"), - (0xD61F, "1112 1168 11AA"), - (0xD620, "1112 1168 11AB"), - (0xD621, "1112 1168 11AC"), - (0xD622, "1112 1168 11AD"), - (0xD623, "1112 1168 11AE"), - (0xD624, "1112 1168 11AF"), - (0xD625, "1112 1168 11B0"), - (0xD626, "1112 1168 11B1"), - (0xD627, "1112 1168 11B2"), - (0xD628, "1112 1168 11B3"), - (0xD629, "1112 1168 11B4"), - (0xD62A, "1112 1168 11B5"), - (0xD62B, "1112 1168 11B6"), - (0xD62C, "1112 1168 11B7"), - (0xD62D, "1112 1168 11B8"), - (0xD62E, "1112 1168 11B9"), - (0xD62F, "1112 1168 11BA"), - (0xD630, "1112 1168 11BB"), - (0xD631, "1112 1168 11BC"), - (0xD632, "1112 1168 11BD"), - (0xD633, "1112 1168 11BE"), - (0xD634, "1112 1168 11BF"), - (0xD635, "1112 1168 11C0"), - (0xD636, "1112 1168 11C1"), - (0xD637, "1112 1168 11C2"), - (0xD638, "1112 1169"), - (0xD639, "1112 1169 11A8"), - (0xD63A, "1112 1169 11A9"), - (0xD63B, "1112 1169 11AA"), - (0xD63C, "1112 1169 11AB"), - (0xD63D, "1112 1169 11AC"), - (0xD63E, "1112 1169 11AD"), - (0xD63F, "1112 1169 11AE"), - (0xD640, "1112 1169 11AF"), - (0xD641, "1112 1169 11B0"), - (0xD642, "1112 1169 11B1"), - (0xD643, "1112 1169 11B2"), - (0xD644, "1112 1169 11B3"), - (0xD645, "1112 1169 11B4"), - (0xD646, "1112 1169 11B5"), - (0xD647, "1112 1169 11B6"), - (0xD648, "1112 1169 11B7"), - (0xD649, "1112 1169 11B8"), - (0xD64A, "1112 1169 11B9"), - (0xD64B, "1112 1169 11BA"), - (0xD64C, "1112 1169 11BB"), - (0xD64D, "1112 1169 11BC"), - (0xD64E, "1112 1169 11BD"), - (0xD64F, "1112 1169 11BE"), - (0xD650, "1112 1169 11BF"), - (0xD651, "1112 1169 11C0"), - (0xD652, "1112 1169 11C1"), - (0xD653, "1112 1169 11C2"), - (0xD654, "1112 116A"), - (0xD655, "1112 116A 11A8"), - (0xD656, "1112 116A 11A9"), - (0xD657, "1112 116A 11AA"), - (0xD658, "1112 116A 11AB"), - (0xD659, "1112 116A 11AC"), - (0xD65A, "1112 116A 11AD"), - (0xD65B, "1112 116A 11AE"), - (0xD65C, "1112 116A 11AF"), - (0xD65D, "1112 116A 11B0"), - (0xD65E, "1112 116A 11B1"), - (0xD65F, "1112 116A 11B2"), - (0xD660, "1112 116A 11B3"), - (0xD661, "1112 116A 11B4"), - (0xD662, "1112 116A 11B5"), - (0xD663, "1112 116A 11B6"), - (0xD664, "1112 116A 11B7"), - (0xD665, "1112 116A 11B8"), - (0xD666, "1112 116A 11B9"), - (0xD667, "1112 116A 11BA"), - (0xD668, "1112 116A 11BB"), - (0xD669, "1112 116A 11BC"), - (0xD66A, "1112 116A 11BD"), - (0xD66B, "1112 116A 11BE"), - (0xD66C, "1112 116A 11BF"), - (0xD66D, "1112 116A 11C0"), - (0xD66E, "1112 116A 11C1"), - (0xD66F, "1112 116A 11C2"), - (0xD670, "1112 116B"), - (0xD671, "1112 116B 11A8"), - (0xD672, "1112 116B 11A9"), - (0xD673, "1112 116B 11AA"), - (0xD674, "1112 116B 11AB"), - (0xD675, "1112 116B 11AC"), - (0xD676, "1112 116B 11AD"), - (0xD677, "1112 116B 11AE"), - (0xD678, "1112 116B 11AF"), - (0xD679, "1112 116B 11B0"), - (0xD67A, "1112 116B 11B1"), - (0xD67B, "1112 116B 11B2"), - (0xD67C, "1112 116B 11B3"), - (0xD67D, "1112 116B 11B4"), - (0xD67E, "1112 116B 11B5"), - (0xD67F, "1112 116B 11B6"), - (0xD680, "1112 116B 11B7"), - (0xD681, "1112 116B 11B8"), - (0xD682, "1112 116B 11B9"), - (0xD683, "1112 116B 11BA"), - (0xD684, "1112 116B 11BB"), - (0xD685, "1112 116B 11BC"), - (0xD686, "1112 116B 11BD"), - (0xD687, "1112 116B 11BE"), - (0xD688, "1112 116B 11BF"), - (0xD689, "1112 116B 11C0"), - (0xD68A, "1112 116B 11C1"), - (0xD68B, "1112 116B 11C2"), - (0xD68C, "1112 116C"), - (0xD68D, "1112 116C 11A8"), - (0xD68E, "1112 116C 11A9"), - (0xD68F, "1112 116C 11AA"), - (0xD690, "1112 116C 11AB"), - (0xD691, "1112 116C 11AC"), - (0xD692, "1112 116C 11AD"), - (0xD693, "1112 116C 11AE"), - (0xD694, "1112 116C 11AF"), - (0xD695, "1112 116C 11B0"), - (0xD696, "1112 116C 11B1"), - (0xD697, "1112 116C 11B2"), - (0xD698, "1112 116C 11B3"), - (0xD699, "1112 116C 11B4"), - (0xD69A, "1112 116C 11B5"), - (0xD69B, "1112 116C 11B6"), - (0xD69C, "1112 116C 11B7"), - (0xD69D, "1112 116C 11B8"), - (0xD69E, "1112 116C 11B9"), - (0xD69F, "1112 116C 11BA"), - (0xD6A0, "1112 116C 11BB"), - (0xD6A1, "1112 116C 11BC"), - (0xD6A2, "1112 116C 11BD"), - (0xD6A3, "1112 116C 11BE"), - (0xD6A4, "1112 116C 11BF"), - (0xD6A5, "1112 116C 11C0"), - (0xD6A6, "1112 116C 11C1"), - (0xD6A7, "1112 116C 11C2"), - (0xD6A8, "1112 116D"), - (0xD6A9, "1112 116D 11A8"), - (0xD6AA, "1112 116D 11A9"), - (0xD6AB, "1112 116D 11AA"), - (0xD6AC, "1112 116D 11AB"), - (0xD6AD, "1112 116D 11AC"), - (0xD6AE, "1112 116D 11AD"), - (0xD6AF, "1112 116D 11AE"), - (0xD6B0, "1112 116D 11AF"), - (0xD6B1, "1112 116D 11B0"), - (0xD6B2, "1112 116D 11B1"), - (0xD6B3, "1112 116D 11B2"), - (0xD6B4, "1112 116D 11B3"), - (0xD6B5, "1112 116D 11B4"), - (0xD6B6, "1112 116D 11B5"), - (0xD6B7, "1112 116D 11B6"), - (0xD6B8, "1112 116D 11B7"), - (0xD6B9, "1112 116D 11B8"), - (0xD6BA, "1112 116D 11B9"), - (0xD6BB, "1112 116D 11BA"), - (0xD6BC, "1112 116D 11BB"), - (0xD6BD, "1112 116D 11BC"), - (0xD6BE, "1112 116D 11BD"), - (0xD6BF, "1112 116D 11BE"), - (0xD6C0, "1112 116D 11BF"), - (0xD6C1, "1112 116D 11C0"), - (0xD6C2, "1112 116D 11C1"), - (0xD6C3, "1112 116D 11C2"), - (0xD6C4, "1112 116E"), - (0xD6C5, "1112 116E 11A8"), - (0xD6C6, "1112 116E 11A9"), - (0xD6C7, "1112 116E 11AA"), - (0xD6C8, "1112 116E 11AB"), - (0xD6C9, "1112 116E 11AC"), - (0xD6CA, "1112 116E 11AD"), - (0xD6CB, "1112 116E 11AE"), - (0xD6CC, "1112 116E 11AF"), - (0xD6CD, "1112 116E 11B0"), - (0xD6CE, "1112 116E 11B1"), - (0xD6CF, "1112 116E 11B2"), - (0xD6D0, "1112 116E 11B3"), - (0xD6D1, "1112 116E 11B4"), - (0xD6D2, "1112 116E 11B5"), - (0xD6D3, "1112 116E 11B6"), - (0xD6D4, "1112 116E 11B7"), - (0xD6D5, "1112 116E 11B8"), - (0xD6D6, "1112 116E 11B9"), - (0xD6D7, "1112 116E 11BA"), - (0xD6D8, "1112 116E 11BB"), - (0xD6D9, "1112 116E 11BC"), - (0xD6DA, "1112 116E 11BD"), - (0xD6DB, "1112 116E 11BE"), - (0xD6DC, "1112 116E 11BF"), - (0xD6DD, "1112 116E 11C0"), - (0xD6DE, "1112 116E 11C1"), - (0xD6DF, "1112 116E 11C2"), - (0xD6E0, "1112 116F"), - (0xD6E1, "1112 116F 11A8"), - (0xD6E2, "1112 116F 11A9"), - (0xD6E3, "1112 116F 11AA"), - (0xD6E4, "1112 116F 11AB"), - (0xD6E5, "1112 116F 11AC"), - (0xD6E6, "1112 116F 11AD"), - (0xD6E7, "1112 116F 11AE"), - (0xD6E8, "1112 116F 11AF"), - (0xD6E9, "1112 116F 11B0"), - (0xD6EA, "1112 116F 11B1"), - (0xD6EB, "1112 116F 11B2"), - (0xD6EC, "1112 116F 11B3"), - (0xD6ED, "1112 116F 11B4"), - (0xD6EE, "1112 116F 11B5"), - (0xD6EF, "1112 116F 11B6"), - (0xD6F0, "1112 116F 11B7"), - (0xD6F1, "1112 116F 11B8"), - (0xD6F2, "1112 116F 11B9"), - (0xD6F3, "1112 116F 11BA"), - (0xD6F4, "1112 116F 11BB"), - (0xD6F5, "1112 116F 11BC"), - (0xD6F6, "1112 116F 11BD"), - (0xD6F7, "1112 116F 11BE"), - (0xD6F8, "1112 116F 11BF"), - (0xD6F9, "1112 116F 11C0"), - (0xD6FA, "1112 116F 11C1"), - (0xD6FB, "1112 116F 11C2"), - (0xD6FC, "1112 1170"), - (0xD6FD, "1112 1170 11A8"), - (0xD6FE, "1112 1170 11A9"), - (0xD6FF, "1112 1170 11AA"), - (0xD700, "1112 1170 11AB"), - (0xD701, "1112 1170 11AC"), - (0xD702, "1112 1170 11AD"), - (0xD703, "1112 1170 11AE"), - (0xD704, "1112 1170 11AF"), - (0xD705, "1112 1170 11B0"), - (0xD706, "1112 1170 11B1"), - (0xD707, "1112 1170 11B2"), - (0xD708, "1112 1170 11B3"), - (0xD709, "1112 1170 11B4"), - (0xD70A, "1112 1170 11B5"), - (0xD70B, "1112 1170 11B6"), - (0xD70C, "1112 1170 11B7"), - (0xD70D, "1112 1170 11B8"), - (0xD70E, "1112 1170 11B9"), - (0xD70F, "1112 1170 11BA"), - (0xD710, "1112 1170 11BB"), - (0xD711, "1112 1170 11BC"), - (0xD712, "1112 1170 11BD"), - (0xD713, "1112 1170 11BE"), - (0xD714, "1112 1170 11BF"), - (0xD715, "1112 1170 11C0"), - (0xD716, "1112 1170 11C1"), - (0xD717, "1112 1170 11C2"), - (0xD718, "1112 1171"), - (0xD719, "1112 1171 11A8"), - (0xD71A, "1112 1171 11A9"), - (0xD71B, "1112 1171 11AA"), - (0xD71C, "1112 1171 11AB"), - (0xD71D, "1112 1171 11AC"), - (0xD71E, "1112 1171 11AD"), - (0xD71F, "1112 1171 11AE"), - (0xD720, "1112 1171 11AF"), - (0xD721, "1112 1171 11B0"), - (0xD722, "1112 1171 11B1"), - (0xD723, "1112 1171 11B2"), - (0xD724, "1112 1171 11B3"), - (0xD725, "1112 1171 11B4"), - (0xD726, "1112 1171 11B5"), - (0xD727, "1112 1171 11B6"), - (0xD728, "1112 1171 11B7"), - (0xD729, "1112 1171 11B8"), - (0xD72A, "1112 1171 11B9"), - (0xD72B, "1112 1171 11BA"), - (0xD72C, "1112 1171 11BB"), - (0xD72D, "1112 1171 11BC"), - (0xD72E, "1112 1171 11BD"), - (0xD72F, "1112 1171 11BE"), - (0xD730, "1112 1171 11BF"), - (0xD731, "1112 1171 11C0"), - (0xD732, "1112 1171 11C1"), - (0xD733, "1112 1171 11C2"), - (0xD734, "1112 1172"), - (0xD735, "1112 1172 11A8"), - (0xD736, "1112 1172 11A9"), - (0xD737, "1112 1172 11AA"), - (0xD738, "1112 1172 11AB"), - (0xD739, "1112 1172 11AC"), - (0xD73A, "1112 1172 11AD"), - (0xD73B, "1112 1172 11AE"), - (0xD73C, "1112 1172 11AF"), - (0xD73D, "1112 1172 11B0"), - (0xD73E, "1112 1172 11B1"), - (0xD73F, "1112 1172 11B2"), - (0xD740, "1112 1172 11B3"), - (0xD741, "1112 1172 11B4"), - (0xD742, "1112 1172 11B5"), - (0xD743, "1112 1172 11B6"), - (0xD744, "1112 1172 11B7"), - (0xD745, "1112 1172 11B8"), - (0xD746, "1112 1172 11B9"), - (0xD747, "1112 1172 11BA"), - (0xD748, "1112 1172 11BB"), - (0xD749, "1112 1172 11BC"), - (0xD74A, "1112 1172 11BD"), - (0xD74B, "1112 1172 11BE"), - (0xD74C, "1112 1172 11BF"), - (0xD74D, "1112 1172 11C0"), - (0xD74E, "1112 1172 11C1"), - (0xD74F, "1112 1172 11C2"), - (0xD750, "1112 1173"), - (0xD751, "1112 1173 11A8"), - (0xD752, "1112 1173 11A9"), - (0xD753, "1112 1173 11AA"), - (0xD754, "1112 1173 11AB"), - (0xD755, "1112 1173 11AC"), - (0xD756, "1112 1173 11AD"), - (0xD757, "1112 1173 11AE"), - (0xD758, "1112 1173 11AF"), - (0xD759, "1112 1173 11B0"), - (0xD75A, "1112 1173 11B1"), - (0xD75B, "1112 1173 11B2"), - (0xD75C, "1112 1173 11B3"), - (0xD75D, "1112 1173 11B4"), - (0xD75E, "1112 1173 11B5"), - (0xD75F, "1112 1173 11B6"), - (0xD760, "1112 1173 11B7"), - (0xD761, "1112 1173 11B8"), - (0xD762, "1112 1173 11B9"), - (0xD763, "1112 1173 11BA"), - (0xD764, "1112 1173 11BB"), - (0xD765, "1112 1173 11BC"), - (0xD766, "1112 1173 11BD"), - (0xD767, "1112 1173 11BE"), - (0xD768, "1112 1173 11BF"), - (0xD769, "1112 1173 11C0"), - (0xD76A, "1112 1173 11C1"), - (0xD76B, "1112 1173 11C2"), - (0xD76C, "1112 1174"), - (0xD76D, "1112 1174 11A8"), - (0xD76E, "1112 1174 11A9"), - (0xD76F, "1112 1174 11AA"), - (0xD770, "1112 1174 11AB"), - (0xD771, "1112 1174 11AC"), - (0xD772, "1112 1174 11AD"), - (0xD773, "1112 1174 11AE"), - (0xD774, "1112 1174 11AF"), - (0xD775, "1112 1174 11B0"), - (0xD776, "1112 1174 11B1"), - (0xD777, "1112 1174 11B2"), - (0xD778, "1112 1174 11B3"), - (0xD779, "1112 1174 11B4"), - (0xD77A, "1112 1174 11B5"), - (0xD77B, "1112 1174 11B6"), - (0xD77C, "1112 1174 11B7"), - (0xD77D, "1112 1174 11B8"), - (0xD77E, "1112 1174 11B9"), - (0xD77F, "1112 1174 11BA"), - (0xD780, "1112 1174 11BB"), - (0xD781, "1112 1174 11BC"), - (0xD782, "1112 1174 11BD"), - (0xD783, "1112 1174 11BE"), - (0xD784, "1112 1174 11BF"), - (0xD785, "1112 1174 11C0"), - (0xD786, "1112 1174 11C1"), - (0xD787, "1112 1174 11C2"), - (0xD788, "1112 1175"), - (0xD789, "1112 1175 11A8"), - (0xD78A, "1112 1175 11A9"), - (0xD78B, "1112 1175 11AA"), - (0xD78C, "1112 1175 11AB"), - (0xD78D, "1112 1175 11AC"), - (0xD78E, "1112 1175 11AD"), - (0xD78F, "1112 1175 11AE"), - (0xD790, "1112 1175 11AF"), - (0xD791, "1112 1175 11B0"), - (0xD792, "1112 1175 11B1"), - (0xD793, "1112 1175 11B2"), - (0xD794, "1112 1175 11B3"), - (0xD795, "1112 1175 11B4"), - (0xD796, "1112 1175 11B5"), - (0xD797, "1112 1175 11B6"), - (0xD798, "1112 1175 11B7"), - (0xD799, "1112 1175 11B8"), - (0xD79A, "1112 1175 11B9"), - (0xD79B, "1112 1175 11BA"), - (0xD79C, "1112 1175 11BB"), - (0xD79D, "1112 1175 11BC"), - (0xD79E, "1112 1175 11BD"), - (0xD79F, "1112 1175 11BE"), - (0xD7A0, "1112 1175 11BF"), - (0xD7A1, "1112 1175 11C0"), - (0xD7A2, "1112 1175 11C1"), - (0xD7A3, "1112 1175 11C2"), - (0xF900, "8C48"), - (0xF901, "66F4"), - (0xF902, "8ECA"), - (0xF903, "8CC8"), - (0xF904, "6ED1"), - (0xF905, "4E32"), - (0xF906, "53E5"), - (0xF907, "9F9C"), - (0xF908, "9F9C"), - (0xF909, "5951"), - (0xF90A, "91D1"), - (0xF90B, "5587"), - (0xF90C, "5948"), - (0xF90D, "61F6"), - (0xF90E, "7669"), - (0xF90F, "7F85"), - (0xF910, "863F"), - (0xF911, "87BA"), - (0xF912, "88F8"), - (0xF913, "908F"), - (0xF914, "6A02"), - (0xF915, "6D1B"), - (0xF916, "70D9"), - (0xF917, "73DE"), - (0xF918, "843D"), - (0xF919, "916A"), - (0xF91A, "99F1"), - (0xF91B, "4E82"), - (0xF91C, "5375"), - (0xF91D, "6B04"), - (0xF91E, "721B"), - (0xF91F, "862D"), - (0xF920, "9E1E"), - (0xF921, "5D50"), - (0xF922, "6FEB"), - (0xF923, "85CD"), - (0xF924, "8964"), - (0xF925, "62C9"), - (0xF926, "81D8"), - (0xF927, "881F"), - (0xF928, "5ECA"), - (0xF929, "6717"), - (0xF92A, "6D6A"), - (0xF92B, "72FC"), - (0xF92C, "90CE"), - (0xF92D, "4F86"), - (0xF92E, "51B7"), - (0xF92F, "52DE"), - (0xF930, "64C4"), - (0xF931, "6AD3"), - (0xF932, "7210"), - (0xF933, "76E7"), - (0xF934, "8001"), - (0xF935, "8606"), - (0xF936, "865C"), - (0xF937, "8DEF"), - (0xF938, "9732"), - (0xF939, "9B6F"), - (0xF93A, "9DFA"), - (0xF93B, "788C"), - (0xF93C, "797F"), - (0xF93D, "7DA0"), - (0xF93E, "83C9"), - (0xF93F, "9304"), - (0xF940, "9E7F"), - (0xF941, "8AD6"), - (0xF942, "58DF"), - (0xF943, "5F04"), - (0xF944, "7C60"), - (0xF945, "807E"), - (0xF946, "7262"), - (0xF947, "78CA"), - (0xF948, "8CC2"), - (0xF949, "96F7"), - (0xF94A, "58D8"), - (0xF94B, "5C62"), - (0xF94C, "6A13"), - (0xF94D, "6DDA"), - (0xF94E, "6F0F"), - (0xF94F, "7D2F"), - (0xF950, "7E37"), - (0xF951, "964B"), - (0xF952, "52D2"), - (0xF953, "808B"), - (0xF954, "51DC"), - (0xF955, "51CC"), - (0xF956, "7A1C"), - (0xF957, "7DBE"), - (0xF958, "83F1"), - (0xF959, "9675"), - (0xF95A, "8B80"), - (0xF95B, "62CF"), - (0xF95C, "6A02"), - (0xF95D, "8AFE"), - (0xF95E, "4E39"), - (0xF95F, "5BE7"), - (0xF960, "6012"), - (0xF961, "7387"), - (0xF962, "7570"), - (0xF963, "5317"), - (0xF964, "78FB"), - (0xF965, "4FBF"), - (0xF966, "5FA9"), - (0xF967, "4E0D"), - (0xF968, "6CCC"), - (0xF969, "6578"), - (0xF96A, "7D22"), - (0xF96B, "53C3"), - (0xF96C, "585E"), - (0xF96D, "7701"), - (0xF96E, "8449"), - (0xF96F, "8AAA"), - (0xF970, "6BBA"), - (0xF971, "8FB0"), - (0xF972, "6C88"), - (0xF973, "62FE"), - (0xF974, "82E5"), - (0xF975, "63A0"), - (0xF976, "7565"), - (0xF977, "4EAE"), - (0xF978, "5169"), - (0xF979, "51C9"), - (0xF97A, "6881"), - (0xF97B, "7CE7"), - (0xF97C, "826F"), - (0xF97D, "8AD2"), - (0xF97E, "91CF"), - (0xF97F, "52F5"), - (0xF980, "5442"), - (0xF981, "5973"), - (0xF982, "5EEC"), - (0xF983, "65C5"), - (0xF984, "6FFE"), - (0xF985, "792A"), - (0xF986, "95AD"), - (0xF987, "9A6A"), - (0xF988, "9E97"), - (0xF989, "9ECE"), - (0xF98A, "529B"), - (0xF98B, "66C6"), - (0xF98C, "6B77"), - (0xF98D, "8F62"), - (0xF98E, "5E74"), - (0xF98F, "6190"), - (0xF990, "6200"), - (0xF991, "649A"), - (0xF992, "6F23"), - (0xF993, "7149"), - (0xF994, "7489"), - (0xF995, "79CA"), - (0xF996, "7DF4"), - (0xF997, "806F"), - (0xF998, "8F26"), - (0xF999, "84EE"), - (0xF99A, "9023"), - (0xF99B, "934A"), - (0xF99C, "5217"), - (0xF99D, "52A3"), - (0xF99E, "54BD"), - (0xF99F, "70C8"), - (0xF9A0, "88C2"), - (0xF9A1, "8AAA"), - (0xF9A2, "5EC9"), - (0xF9A3, "5FF5"), - (0xF9A4, "637B"), - (0xF9A5, "6BAE"), - (0xF9A6, "7C3E"), - (0xF9A7, "7375"), - (0xF9A8, "4EE4"), - (0xF9A9, "56F9"), - (0xF9AA, "5BE7"), - (0xF9AB, "5DBA"), - (0xF9AC, "601C"), - (0xF9AD, "73B2"), - (0xF9AE, "7469"), - (0xF9AF, "7F9A"), - (0xF9B0, "8046"), - (0xF9B1, "9234"), - (0xF9B2, "96F6"), - (0xF9B3, "9748"), - (0xF9B4, "9818"), - (0xF9B5, "4F8B"), - (0xF9B6, "79AE"), - (0xF9B7, "91B4"), - (0xF9B8, "96B8"), - (0xF9B9, "60E1"), - (0xF9BA, "4E86"), - (0xF9BB, "50DA"), - (0xF9BC, "5BEE"), - (0xF9BD, "5C3F"), - (0xF9BE, "6599"), - (0xF9BF, "6A02"), - (0xF9C0, "71CE"), - (0xF9C1, "7642"), - (0xF9C2, "84FC"), - (0xF9C3, "907C"), - (0xF9C4, "9F8D"), - (0xF9C5, "6688"), - (0xF9C6, "962E"), - (0xF9C7, "5289"), - (0xF9C8, "677B"), - (0xF9C9, "67F3"), - (0xF9CA, "6D41"), - (0xF9CB, "6E9C"), - (0xF9CC, "7409"), - (0xF9CD, "7559"), - (0xF9CE, "786B"), - (0xF9CF, "7D10"), - (0xF9D0, "985E"), - (0xF9D1, "516D"), - (0xF9D2, "622E"), - (0xF9D3, "9678"), - (0xF9D4, "502B"), - (0xF9D5, "5D19"), - (0xF9D6, "6DEA"), - (0xF9D7, "8F2A"), - (0xF9D8, "5F8B"), - (0xF9D9, "6144"), - (0xF9DA, "6817"), - (0xF9DB, "7387"), - (0xF9DC, "9686"), - (0xF9DD, "5229"), - (0xF9DE, "540F"), - (0xF9DF, "5C65"), - (0xF9E0, "6613"), - (0xF9E1, "674E"), - (0xF9E2, "68A8"), - (0xF9E3, "6CE5"), - (0xF9E4, "7406"), - (0xF9E5, "75E2"), - (0xF9E6, "7F79"), - (0xF9E7, "88CF"), - (0xF9E8, "88E1"), - (0xF9E9, "91CC"), - (0xF9EA, "96E2"), - (0xF9EB, "533F"), - (0xF9EC, "6EBA"), - (0xF9ED, "541D"), - (0xF9EE, "71D0"), - (0xF9EF, "7498"), - (0xF9F0, "85FA"), - (0xF9F1, "96A3"), - (0xF9F2, "9C57"), - (0xF9F3, "9E9F"), - (0xF9F4, "6797"), - (0xF9F5, "6DCB"), - (0xF9F6, "81E8"), - (0xF9F7, "7ACB"), - (0xF9F8, "7B20"), - (0xF9F9, "7C92"), - (0xF9FA, "72C0"), - (0xF9FB, "7099"), - (0xF9FC, "8B58"), - (0xF9FD, "4EC0"), - (0xF9FE, "8336"), - (0xF9FF, "523A"), - (0xFA00, "5207"), - (0xFA01, "5EA6"), - (0xFA02, "62D3"), - (0xFA03, "7CD6"), - (0xFA04, "5B85"), - (0xFA05, "6D1E"), - (0xFA06, "66B4"), - (0xFA07, "8F3B"), - (0xFA08, "884C"), - (0xFA09, "964D"), - (0xFA0A, "898B"), - (0xFA0B, "5ED3"), - (0xFA0C, "5140"), - (0xFA0D, "55C0"), - (0xFA10, "585A"), - (0xFA12, "6674"), - (0xFA15, "51DE"), - (0xFA16, "732A"), - (0xFA17, "76CA"), - (0xFA18, "793C"), - (0xFA19, "795E"), - (0xFA1A, "7965"), - (0xFA1B, "798F"), - (0xFA1C, "9756"), - (0xFA1D, "7CBE"), - (0xFA1E, "7FBD"), - (0xFA20, "8612"), - (0xFA22, "8AF8"), - (0xFA25, "9038"), - (0xFA26, "90FD"), - (0xFA2A, "98EF"), - (0xFA2B, "98FC"), - (0xFA2C, "9928"), - (0xFA2D, "9DB4"), - (0xFA2E, "90DE"), - (0xFA2F, "96B7"), - (0xFA30, "4FAE"), - (0xFA31, "50E7"), - (0xFA32, "514D"), - (0xFA33, "52C9"), - (0xFA34, "52E4"), - (0xFA35, "5351"), - (0xFA36, "559D"), - (0xFA37, "5606"), - (0xFA38, "5668"), - (0xFA39, "5840"), - (0xFA3A, "58A8"), - (0xFA3B, "5C64"), - (0xFA3C, "5C6E"), - (0xFA3D, "6094"), - (0xFA3E, "6168"), - (0xFA3F, "618E"), - (0xFA40, "61F2"), - (0xFA41, "654F"), - (0xFA42, "65E2"), - (0xFA43, "6691"), - (0xFA44, "6885"), - (0xFA45, "6D77"), - (0xFA46, "6E1A"), - (0xFA47, "6F22"), - (0xFA48, "716E"), - (0xFA49, "722B"), - (0xFA4A, "7422"), - (0xFA4B, "7891"), - (0xFA4C, "793E"), - (0xFA4D, "7949"), - (0xFA4E, "7948"), - (0xFA4F, "7950"), - (0xFA50, "7956"), - (0xFA51, "795D"), - (0xFA52, "798D"), - (0xFA53, "798E"), - (0xFA54, "7A40"), - (0xFA55, "7A81"), - (0xFA56, "7BC0"), - (0xFA57, "7DF4"), - (0xFA58, "7E09"), - (0xFA59, "7E41"), - (0xFA5A, "7F72"), - (0xFA5B, "8005"), - (0xFA5C, "81ED"), - (0xFA5D, "8279"), - (0xFA5E, "8279"), - (0xFA5F, "8457"), - (0xFA60, "8910"), - (0xFA61, "8996"), - (0xFA62, "8B01"), - (0xFA63, "8B39"), - (0xFA64, "8CD3"), - (0xFA65, "8D08"), - (0xFA66, "8FB6"), - (0xFA67, "9038"), - (0xFA68, "96E3"), - (0xFA69, "97FF"), - (0xFA6A, "983B"), - (0xFA6B, "6075"), - (0xFA6C, "242EE"), - (0xFA6D, "8218"), - (0xFA70, "4E26"), - (0xFA71, "51B5"), - (0xFA72, "5168"), - (0xFA73, "4F80"), - (0xFA74, "5145"), - (0xFA75, "5180"), - (0xFA76, "52C7"), - (0xFA77, "52FA"), - (0xFA78, "559D"), - (0xFA79, "5555"), - (0xFA7A, "5599"), - (0xFA7B, "55E2"), - (0xFA7C, "585A"), - (0xFA7D, "58B3"), - (0xFA7E, "5944"), - (0xFA7F, "5954"), - (0xFA80, "5A62"), - (0xFA81, "5B28"), - (0xFA82, "5ED2"), - (0xFA83, "5ED9"), - (0xFA84, "5F69"), - (0xFA85, "5FAD"), - (0xFA86, "60D8"), - (0xFA87, "614E"), - (0xFA88, "6108"), - (0xFA89, "618E"), - (0xFA8A, "6160"), - (0xFA8B, "61F2"), - (0xFA8C, "6234"), - (0xFA8D, "63C4"), - (0xFA8E, "641C"), - (0xFA8F, "6452"), - (0xFA90, "6556"), - (0xFA91, "6674"), - (0xFA92, "6717"), - (0xFA93, "671B"), - (0xFA94, "6756"), - (0xFA95, "6B79"), - (0xFA96, "6BBA"), - (0xFA97, "6D41"), - (0xFA98, "6EDB"), - (0xFA99, "6ECB"), - (0xFA9A, "6F22"), - (0xFA9B, "701E"), - (0xFA9C, "716E"), - (0xFA9D, "77A7"), - (0xFA9E, "7235"), - (0xFA9F, "72AF"), - (0xFAA0, "732A"), - (0xFAA1, "7471"), - (0xFAA2, "7506"), - (0xFAA3, "753B"), - (0xFAA4, "761D"), - (0xFAA5, "761F"), - (0xFAA6, "76CA"), - (0xFAA7, "76DB"), - (0xFAA8, "76F4"), - (0xFAA9, "774A"), - (0xFAAA, "7740"), - (0xFAAB, "78CC"), - (0xFAAC, "7AB1"), - (0xFAAD, "7BC0"), - (0xFAAE, "7C7B"), - (0xFAAF, "7D5B"), - (0xFAB0, "7DF4"), - (0xFAB1, "7F3E"), - (0xFAB2, "8005"), - (0xFAB3, "8352"), - (0xFAB4, "83EF"), - (0xFAB5, "8779"), - (0xFAB6, "8941"), - (0xFAB7, "8986"), - (0xFAB8, "8996"), - (0xFAB9, "8ABF"), - (0xFABA, "8AF8"), - (0xFABB, "8ACB"), - (0xFABC, "8B01"), - (0xFABD, "8AFE"), - (0xFABE, "8AED"), - (0xFABF, "8B39"), - (0xFAC0, "8B8A"), - (0xFAC1, "8D08"), - (0xFAC2, "8F38"), - (0xFAC3, "9072"), - (0xFAC4, "9199"), - (0xFAC5, "9276"), - (0xFAC6, "967C"), - (0xFAC7, "96E3"), - (0xFAC8, "9756"), - (0xFAC9, "97DB"), - (0xFACA, "97FF"), - (0xFACB, "980B"), - (0xFACC, "983B"), - (0xFACD, "9B12"), - (0xFACE, "9F9C"), - (0xFACF, "2284A"), - (0xFAD0, "22844"), - (0xFAD1, "233D5"), - (0xFAD2, "3B9D"), - (0xFAD3, "4018"), - (0xFAD4, "4039"), - (0xFAD5, "25249"), - (0xFAD6, "25CD0"), - (0xFAD7, "27ED3"), - (0xFAD8, "9F43"), - (0xFAD9, "9F8E"), - (0xFB00, " 0066 0066"), - (0xFB01, " 0066 0069"), - (0xFB02, " 0066 006C"), - (0xFB03, " 0066 0066 0069"), - (0xFB04, " 0066 0066 006C"), - (0xFB05, " 017F 0074"), - (0xFB06, " 0073 0074"), - (0xFB13, " 0574 0576"), - (0xFB14, " 0574 0565"), - (0xFB15, " 0574 056B"), - (0xFB16, " 057E 0576"), - (0xFB17, " 0574 056D"), - (0xFB1D, "05D9 05B4"), - (0xFB1F, "05F2 05B7"), - (0xFB20, " 05E2"), - (0xFB21, " 05D0"), - (0xFB22, " 05D3"), - (0xFB23, " 05D4"), - (0xFB24, " 05DB"), - (0xFB25, " 05DC"), - (0xFB26, " 05DD"), - (0xFB27, " 05E8"), - (0xFB28, " 05EA"), - (0xFB29, " 002B"), - (0xFB2A, "05E9 05C1"), - (0xFB2B, "05E9 05C2"), - (0xFB2C, "FB49 05C1"), - (0xFB2D, "FB49 05C2"), - (0xFB2E, "05D0 05B7"), - (0xFB2F, "05D0 05B8"), - (0xFB30, "05D0 05BC"), - (0xFB31, "05D1 05BC"), - (0xFB32, "05D2 05BC"), - (0xFB33, "05D3 05BC"), - (0xFB34, "05D4 05BC"), - (0xFB35, "05D5 05BC"), - (0xFB36, "05D6 05BC"), - (0xFB38, "05D8 05BC"), - (0xFB39, "05D9 05BC"), - (0xFB3A, "05DA 05BC"), - (0xFB3B, "05DB 05BC"), - (0xFB3C, "05DC 05BC"), - (0xFB3E, "05DE 05BC"), - (0xFB40, "05E0 05BC"), - (0xFB41, "05E1 05BC"), - (0xFB43, "05E3 05BC"), - (0xFB44, "05E4 05BC"), - (0xFB46, "05E6 05BC"), - (0xFB47, "05E7 05BC"), - (0xFB48, "05E8 05BC"), - (0xFB49, "05E9 05BC"), - (0xFB4A, "05EA 05BC"), - (0xFB4B, "05D5 05B9"), - (0xFB4C, "05D1 05BF"), - (0xFB4D, "05DB 05BF"), - (0xFB4E, "05E4 05BF"), - (0xFB4F, " 05D0 05DC"), - (0xFB50, " 0671"), - (0xFB51, " 0671"), - (0xFB52, " 067B"), - (0xFB53, " 067B"), - (0xFB54, " 067B"), - (0xFB55, " 067B"), - (0xFB56, " 067E"), - (0xFB57, " 067E"), - (0xFB58, " 067E"), - (0xFB59, " 067E"), - (0xFB5A, " 0680"), - (0xFB5B, " 0680"), - (0xFB5C, " 0680"), - (0xFB5D, " 0680"), - (0xFB5E, " 067A"), - (0xFB5F, " 067A"), - (0xFB60, " 067A"), - (0xFB61, " 067A"), - (0xFB62, " 067F"), - (0xFB63, " 067F"), - (0xFB64, " 067F"), - (0xFB65, " 067F"), - (0xFB66, " 0679"), - (0xFB67, " 0679"), - (0xFB68, " 0679"), - (0xFB69, " 0679"), - (0xFB6A, " 06A4"), - (0xFB6B, " 06A4"), - (0xFB6C, " 06A4"), - (0xFB6D, " 06A4"), - (0xFB6E, " 06A6"), - (0xFB6F, " 06A6"), - (0xFB70, " 06A6"), - (0xFB71, " 06A6"), - (0xFB72, " 0684"), - (0xFB73, " 0684"), - (0xFB74, " 0684"), - (0xFB75, " 0684"), - (0xFB76, " 0683"), - (0xFB77, " 0683"), - (0xFB78, " 0683"), - (0xFB79, " 0683"), - (0xFB7A, " 0686"), - (0xFB7B, " 0686"), - (0xFB7C, " 0686"), - (0xFB7D, " 0686"), - (0xFB7E, " 0687"), - (0xFB7F, " 0687"), - (0xFB80, " 0687"), - (0xFB81, " 0687"), - (0xFB82, " 068D"), - (0xFB83, " 068D"), - (0xFB84, " 068C"), - (0xFB85, " 068C"), - (0xFB86, " 068E"), - (0xFB87, " 068E"), - (0xFB88, " 0688"), - (0xFB89, " 0688"), - (0xFB8A, " 0698"), - (0xFB8B, " 0698"), - (0xFB8C, " 0691"), - (0xFB8D, " 0691"), - (0xFB8E, " 06A9"), - (0xFB8F, " 06A9"), - (0xFB90, " 06A9"), - (0xFB91, " 06A9"), - (0xFB92, " 06AF"), - (0xFB93, " 06AF"), - (0xFB94, " 06AF"), - (0xFB95, " 06AF"), - (0xFB96, " 06B3"), - (0xFB97, " 06B3"), - (0xFB98, " 06B3"), - (0xFB99, " 06B3"), - (0xFB9A, " 06B1"), - (0xFB9B, " 06B1"), - (0xFB9C, " 06B1"), - (0xFB9D, " 06B1"), - (0xFB9E, " 06BA"), - (0xFB9F, " 06BA"), - (0xFBA0, " 06BB"), - (0xFBA1, " 06BB"), - (0xFBA2, " 06BB"), - (0xFBA3, " 06BB"), - (0xFBA4, " 06C0"), - (0xFBA5, " 06C0"), - (0xFBA6, " 06C1"), - (0xFBA7, " 06C1"), - (0xFBA8, " 06C1"), - (0xFBA9, " 06C1"), - (0xFBAA, " 06BE"), - (0xFBAB, " 06BE"), - (0xFBAC, " 06BE"), - (0xFBAD, " 06BE"), - (0xFBAE, " 06D2"), - (0xFBAF, " 06D2"), - (0xFBB0, " 06D3"), - (0xFBB1, " 06D3"), - (0xFBD3, " 06AD"), - (0xFBD4, " 06AD"), - (0xFBD5, " 06AD"), - (0xFBD6, " 06AD"), - (0xFBD7, " 06C7"), - (0xFBD8, " 06C7"), - (0xFBD9, " 06C6"), - (0xFBDA, " 06C6"), - (0xFBDB, " 06C8"), - (0xFBDC, " 06C8"), - (0xFBDD, " 0677"), - (0xFBDE, " 06CB"), - (0xFBDF, " 06CB"), - (0xFBE0, " 06C5"), - (0xFBE1, " 06C5"), - (0xFBE2, " 06C9"), - (0xFBE3, " 06C9"), - (0xFBE4, " 06D0"), - (0xFBE5, " 06D0"), - (0xFBE6, " 06D0"), - (0xFBE7, " 06D0"), - (0xFBE8, " 0649"), - (0xFBE9, " 0649"), - (0xFBEA, " 0626 0627"), - (0xFBEB, " 0626 0627"), - (0xFBEC, " 0626 06D5"), - (0xFBED, " 0626 06D5"), - (0xFBEE, " 0626 0648"), - (0xFBEF, " 0626 0648"), - (0xFBF0, " 0626 06C7"), - (0xFBF1, " 0626 06C7"), - (0xFBF2, " 0626 06C6"), - (0xFBF3, " 0626 06C6"), - (0xFBF4, " 0626 06C8"), - (0xFBF5, " 0626 06C8"), - (0xFBF6, " 0626 06D0"), - (0xFBF7, " 0626 06D0"), - (0xFBF8, " 0626 06D0"), - (0xFBF9, " 0626 0649"), - (0xFBFA, " 0626 0649"), - (0xFBFB, " 0626 0649"), - (0xFBFC, " 06CC"), - (0xFBFD, " 06CC"), - (0xFBFE, " 06CC"), - (0xFBFF, " 06CC"), - (0xFC00, " 0626 062C"), - (0xFC01, " 0626 062D"), - (0xFC02, " 0626 0645"), - (0xFC03, " 0626 0649"), - (0xFC04, " 0626 064A"), - (0xFC05, " 0628 062C"), - (0xFC06, " 0628 062D"), - (0xFC07, " 0628 062E"), - (0xFC08, " 0628 0645"), - (0xFC09, " 0628 0649"), - (0xFC0A, " 0628 064A"), - (0xFC0B, " 062A 062C"), - (0xFC0C, " 062A 062D"), - (0xFC0D, " 062A 062E"), - (0xFC0E, " 062A 0645"), - (0xFC0F, " 062A 0649"), - (0xFC10, " 062A 064A"), - (0xFC11, " 062B 062C"), - (0xFC12, " 062B 0645"), - (0xFC13, " 062B 0649"), - (0xFC14, " 062B 064A"), - (0xFC15, " 062C 062D"), - (0xFC16, " 062C 0645"), - (0xFC17, " 062D 062C"), - (0xFC18, " 062D 0645"), - (0xFC19, " 062E 062C"), - (0xFC1A, " 062E 062D"), - (0xFC1B, " 062E 0645"), - (0xFC1C, " 0633 062C"), - (0xFC1D, " 0633 062D"), - (0xFC1E, " 0633 062E"), - (0xFC1F, " 0633 0645"), - (0xFC20, " 0635 062D"), - (0xFC21, " 0635 0645"), - (0xFC22, " 0636 062C"), - (0xFC23, " 0636 062D"), - (0xFC24, " 0636 062E"), - (0xFC25, " 0636 0645"), - (0xFC26, " 0637 062D"), - (0xFC27, " 0637 0645"), - (0xFC28, " 0638 0645"), - (0xFC29, " 0639 062C"), - (0xFC2A, " 0639 0645"), - (0xFC2B, " 063A 062C"), - (0xFC2C, " 063A 0645"), - (0xFC2D, " 0641 062C"), - (0xFC2E, " 0641 062D"), - (0xFC2F, " 0641 062E"), - (0xFC30, " 0641 0645"), - (0xFC31, " 0641 0649"), - (0xFC32, " 0641 064A"), - (0xFC33, " 0642 062D"), - (0xFC34, " 0642 0645"), - (0xFC35, " 0642 0649"), - (0xFC36, " 0642 064A"), - (0xFC37, " 0643 0627"), - (0xFC38, " 0643 062C"), - (0xFC39, " 0643 062D"), - (0xFC3A, " 0643 062E"), - (0xFC3B, " 0643 0644"), - (0xFC3C, " 0643 0645"), - (0xFC3D, " 0643 0649"), - (0xFC3E, " 0643 064A"), - (0xFC3F, " 0644 062C"), - (0xFC40, " 0644 062D"), - (0xFC41, " 0644 062E"), - (0xFC42, " 0644 0645"), - (0xFC43, " 0644 0649"), - (0xFC44, " 0644 064A"), - (0xFC45, " 0645 062C"), - (0xFC46, " 0645 062D"), - (0xFC47, " 0645 062E"), - (0xFC48, " 0645 0645"), - (0xFC49, " 0645 0649"), - (0xFC4A, " 0645 064A"), - (0xFC4B, " 0646 062C"), - (0xFC4C, " 0646 062D"), - (0xFC4D, " 0646 062E"), - (0xFC4E, " 0646 0645"), - (0xFC4F, " 0646 0649"), - (0xFC50, " 0646 064A"), - (0xFC51, " 0647 062C"), - (0xFC52, " 0647 0645"), - (0xFC53, " 0647 0649"), - (0xFC54, " 0647 064A"), - (0xFC55, " 064A 062C"), - (0xFC56, " 064A 062D"), - (0xFC57, " 064A 062E"), - (0xFC58, " 064A 0645"), - (0xFC59, " 064A 0649"), - (0xFC5A, " 064A 064A"), - (0xFC5B, " 0630 0670"), - (0xFC5C, " 0631 0670"), - (0xFC5D, " 0649 0670"), - (0xFC5E, " 0020 064C 0651"), - (0xFC5F, " 0020 064D 0651"), - (0xFC60, " 0020 064E 0651"), - (0xFC61, " 0020 064F 0651"), - (0xFC62, " 0020 0650 0651"), - (0xFC63, " 0020 0651 0670"), - (0xFC64, " 0626 0631"), - (0xFC65, " 0626 0632"), - (0xFC66, " 0626 0645"), - (0xFC67, " 0626 0646"), - (0xFC68, " 0626 0649"), - (0xFC69, " 0626 064A"), - (0xFC6A, " 0628 0631"), - (0xFC6B, " 0628 0632"), - (0xFC6C, " 0628 0645"), - (0xFC6D, " 0628 0646"), - (0xFC6E, " 0628 0649"), - (0xFC6F, " 0628 064A"), - (0xFC70, " 062A 0631"), - (0xFC71, " 062A 0632"), - (0xFC72, " 062A 0645"), - (0xFC73, " 062A 0646"), - (0xFC74, " 062A 0649"), - (0xFC75, " 062A 064A"), - (0xFC76, " 062B 0631"), - (0xFC77, " 062B 0632"), - (0xFC78, " 062B 0645"), - (0xFC79, " 062B 0646"), - (0xFC7A, " 062B 0649"), - (0xFC7B, " 062B 064A"), - (0xFC7C, " 0641 0649"), - (0xFC7D, " 0641 064A"), - (0xFC7E, " 0642 0649"), - (0xFC7F, " 0642 064A"), - (0xFC80, " 0643 0627"), - (0xFC81, " 0643 0644"), - (0xFC82, " 0643 0645"), - (0xFC83, " 0643 0649"), - (0xFC84, " 0643 064A"), - (0xFC85, " 0644 0645"), - (0xFC86, " 0644 0649"), - (0xFC87, " 0644 064A"), - (0xFC88, " 0645 0627"), - (0xFC89, " 0645 0645"), - (0xFC8A, " 0646 0631"), - (0xFC8B, " 0646 0632"), - (0xFC8C, " 0646 0645"), - (0xFC8D, " 0646 0646"), - (0xFC8E, " 0646 0649"), - (0xFC8F, " 0646 064A"), - (0xFC90, " 0649 0670"), - (0xFC91, " 064A 0631"), - (0xFC92, " 064A 0632"), - (0xFC93, " 064A 0645"), - (0xFC94, " 064A 0646"), - (0xFC95, " 064A 0649"), - (0xFC96, " 064A 064A"), - (0xFC97, " 0626 062C"), - (0xFC98, " 0626 062D"), - (0xFC99, " 0626 062E"), - (0xFC9A, " 0626 0645"), - (0xFC9B, " 0626 0647"), - (0xFC9C, " 0628 062C"), - (0xFC9D, " 0628 062D"), - (0xFC9E, " 0628 062E"), - (0xFC9F, " 0628 0645"), - (0xFCA0, " 0628 0647"), - (0xFCA1, " 062A 062C"), - (0xFCA2, " 062A 062D"), - (0xFCA3, " 062A 062E"), - (0xFCA4, " 062A 0645"), - (0xFCA5, " 062A 0647"), - (0xFCA6, " 062B 0645"), - (0xFCA7, " 062C 062D"), - (0xFCA8, " 062C 0645"), - (0xFCA9, " 062D 062C"), - (0xFCAA, " 062D 0645"), - (0xFCAB, " 062E 062C"), - (0xFCAC, " 062E 0645"), - (0xFCAD, " 0633 062C"), - (0xFCAE, " 0633 062D"), - (0xFCAF, " 0633 062E"), - (0xFCB0, " 0633 0645"), - (0xFCB1, " 0635 062D"), - (0xFCB2, " 0635 062E"), - (0xFCB3, " 0635 0645"), - (0xFCB4, " 0636 062C"), - (0xFCB5, " 0636 062D"), - (0xFCB6, " 0636 062E"), - (0xFCB7, " 0636 0645"), - (0xFCB8, " 0637 062D"), - (0xFCB9, " 0638 0645"), - (0xFCBA, " 0639 062C"), - (0xFCBB, " 0639 0645"), - (0xFCBC, " 063A 062C"), - (0xFCBD, " 063A 0645"), - (0xFCBE, " 0641 062C"), - (0xFCBF, " 0641 062D"), - (0xFCC0, " 0641 062E"), - (0xFCC1, " 0641 0645"), - (0xFCC2, " 0642 062D"), - (0xFCC3, " 0642 0645"), - (0xFCC4, " 0643 062C"), - (0xFCC5, " 0643 062D"), - (0xFCC6, " 0643 062E"), - (0xFCC7, " 0643 0644"), - (0xFCC8, " 0643 0645"), - (0xFCC9, " 0644 062C"), - (0xFCCA, " 0644 062D"), - (0xFCCB, " 0644 062E"), - (0xFCCC, " 0644 0645"), - (0xFCCD, " 0644 0647"), - (0xFCCE, " 0645 062C"), - (0xFCCF, " 0645 062D"), - (0xFCD0, " 0645 062E"), - (0xFCD1, " 0645 0645"), - (0xFCD2, " 0646 062C"), - (0xFCD3, " 0646 062D"), - (0xFCD4, " 0646 062E"), - (0xFCD5, " 0646 0645"), - (0xFCD6, " 0646 0647"), - (0xFCD7, " 0647 062C"), - (0xFCD8, " 0647 0645"), - (0xFCD9, " 0647 0670"), - (0xFCDA, " 064A 062C"), - (0xFCDB, " 064A 062D"), - (0xFCDC, " 064A 062E"), - (0xFCDD, " 064A 0645"), - (0xFCDE, " 064A 0647"), - (0xFCDF, " 0626 0645"), - (0xFCE0, " 0626 0647"), - (0xFCE1, " 0628 0645"), - (0xFCE2, " 0628 0647"), - (0xFCE3, " 062A 0645"), - (0xFCE4, " 062A 0647"), - (0xFCE5, " 062B 0645"), - (0xFCE6, " 062B 0647"), - (0xFCE7, " 0633 0645"), - (0xFCE8, " 0633 0647"), - (0xFCE9, " 0634 0645"), - (0xFCEA, " 0634 0647"), - (0xFCEB, " 0643 0644"), - (0xFCEC, " 0643 0645"), - (0xFCED, " 0644 0645"), - (0xFCEE, " 0646 0645"), - (0xFCEF, " 0646 0647"), - (0xFCF0, " 064A 0645"), - (0xFCF1, " 064A 0647"), - (0xFCF2, " 0640 064E 0651"), - (0xFCF3, " 0640 064F 0651"), - (0xFCF4, " 0640 0650 0651"), - (0xFCF5, " 0637 0649"), - (0xFCF6, " 0637 064A"), - (0xFCF7, " 0639 0649"), - (0xFCF8, " 0639 064A"), - (0xFCF9, " 063A 0649"), - (0xFCFA, " 063A 064A"), - (0xFCFB, " 0633 0649"), - (0xFCFC, " 0633 064A"), - (0xFCFD, " 0634 0649"), - (0xFCFE, " 0634 064A"), - (0xFCFF, " 062D 0649"), - (0xFD00, " 062D 064A"), - (0xFD01, " 062C 0649"), - (0xFD02, " 062C 064A"), - (0xFD03, " 062E 0649"), - (0xFD04, " 062E 064A"), - (0xFD05, " 0635 0649"), - (0xFD06, " 0635 064A"), - (0xFD07, " 0636 0649"), - (0xFD08, " 0636 064A"), - (0xFD09, " 0634 062C"), - (0xFD0A, " 0634 062D"), - (0xFD0B, " 0634 062E"), - (0xFD0C, " 0634 0645"), - (0xFD0D, " 0634 0631"), - (0xFD0E, " 0633 0631"), - (0xFD0F, " 0635 0631"), - (0xFD10, " 0636 0631"), - (0xFD11, " 0637 0649"), - (0xFD12, " 0637 064A"), - (0xFD13, " 0639 0649"), - (0xFD14, " 0639 064A"), - (0xFD15, " 063A 0649"), - (0xFD16, " 063A 064A"), - (0xFD17, " 0633 0649"), - (0xFD18, " 0633 064A"), - (0xFD19, " 0634 0649"), - (0xFD1A, " 0634 064A"), - (0xFD1B, " 062D 0649"), - (0xFD1C, " 062D 064A"), - (0xFD1D, " 062C 0649"), - (0xFD1E, " 062C 064A"), - (0xFD1F, " 062E 0649"), - (0xFD20, " 062E 064A"), - (0xFD21, " 0635 0649"), - (0xFD22, " 0635 064A"), - (0xFD23, " 0636 0649"), - (0xFD24, " 0636 064A"), - (0xFD25, " 0634 062C"), - (0xFD26, " 0634 062D"), - (0xFD27, " 0634 062E"), - (0xFD28, " 0634 0645"), - (0xFD29, " 0634 0631"), - (0xFD2A, " 0633 0631"), - (0xFD2B, " 0635 0631"), - (0xFD2C, " 0636 0631"), - (0xFD2D, " 0634 062C"), - (0xFD2E, " 0634 062D"), - (0xFD2F, " 0634 062E"), - (0xFD30, " 0634 0645"), - (0xFD31, " 0633 0647"), - (0xFD32, " 0634 0647"), - (0xFD33, " 0637 0645"), - (0xFD34, " 0633 062C"), - (0xFD35, " 0633 062D"), - (0xFD36, " 0633 062E"), - (0xFD37, " 0634 062C"), - (0xFD38, " 0634 062D"), - (0xFD39, " 0634 062E"), - (0xFD3A, " 0637 0645"), - (0xFD3B, " 0638 0645"), - (0xFD3C, " 0627 064B"), - (0xFD3D, " 0627 064B"), - (0xFD50, " 062A 062C 0645"), - (0xFD51, " 062A 062D 062C"), - (0xFD52, " 062A 062D 062C"), - (0xFD53, " 062A 062D 0645"), - (0xFD54, " 062A 062E 0645"), - (0xFD55, " 062A 0645 062C"), - (0xFD56, " 062A 0645 062D"), - (0xFD57, " 062A 0645 062E"), - (0xFD58, " 062C 0645 062D"), - (0xFD59, " 062C 0645 062D"), - (0xFD5A, " 062D 0645 064A"), - (0xFD5B, " 062D 0645 0649"), - (0xFD5C, " 0633 062D 062C"), - (0xFD5D, " 0633 062C 062D"), - (0xFD5E, " 0633 062C 0649"), - (0xFD5F, " 0633 0645 062D"), - (0xFD60, " 0633 0645 062D"), - (0xFD61, " 0633 0645 062C"), - (0xFD62, " 0633 0645 0645"), - (0xFD63, " 0633 0645 0645"), - (0xFD64, " 0635 062D 062D"), - (0xFD65, " 0635 062D 062D"), - (0xFD66, " 0635 0645 0645"), - (0xFD67, " 0634 062D 0645"), - (0xFD68, " 0634 062D 0645"), - (0xFD69, " 0634 062C 064A"), - (0xFD6A, " 0634 0645 062E"), - (0xFD6B, " 0634 0645 062E"), - (0xFD6C, " 0634 0645 0645"), - (0xFD6D, " 0634 0645 0645"), - (0xFD6E, " 0636 062D 0649"), - (0xFD6F, " 0636 062E 0645"), - (0xFD70, " 0636 062E 0645"), - (0xFD71, " 0637 0645 062D"), - (0xFD72, " 0637 0645 062D"), - (0xFD73, " 0637 0645 0645"), - (0xFD74, " 0637 0645 064A"), - (0xFD75, " 0639 062C 0645"), - (0xFD76, " 0639 0645 0645"), - (0xFD77, " 0639 0645 0645"), - (0xFD78, " 0639 0645 0649"), - (0xFD79, " 063A 0645 0645"), - (0xFD7A, " 063A 0645 064A"), - (0xFD7B, " 063A 0645 0649"), - (0xFD7C, " 0641 062E 0645"), - (0xFD7D, " 0641 062E 0645"), - (0xFD7E, " 0642 0645 062D"), - (0xFD7F, " 0642 0645 0645"), - (0xFD80, " 0644 062D 0645"), - (0xFD81, " 0644 062D 064A"), - (0xFD82, " 0644 062D 0649"), - (0xFD83, " 0644 062C 062C"), - (0xFD84, " 0644 062C 062C"), - (0xFD85, " 0644 062E 0645"), - (0xFD86, " 0644 062E 0645"), - (0xFD87, " 0644 0645 062D"), - (0xFD88, " 0644 0645 062D"), - (0xFD89, " 0645 062D 062C"), - (0xFD8A, " 0645 062D 0645"), - (0xFD8B, " 0645 062D 064A"), - (0xFD8C, " 0645 062C 062D"), - (0xFD8D, " 0645 062C 0645"), - (0xFD8E, " 0645 062E 062C"), - (0xFD8F, " 0645 062E 0645"), - (0xFD92, " 0645 062C 062E"), - (0xFD93, " 0647 0645 062C"), - (0xFD94, " 0647 0645 0645"), - (0xFD95, " 0646 062D 0645"), - (0xFD96, " 0646 062D 0649"), - (0xFD97, " 0646 062C 0645"), - (0xFD98, " 0646 062C 0645"), - (0xFD99, " 0646 062C 0649"), - (0xFD9A, " 0646 0645 064A"), - (0xFD9B, " 0646 0645 0649"), - (0xFD9C, " 064A 0645 0645"), - (0xFD9D, " 064A 0645 0645"), - (0xFD9E, " 0628 062E 064A"), - (0xFD9F, " 062A 062C 064A"), - (0xFDA0, " 062A 062C 0649"), - (0xFDA1, " 062A 062E 064A"), - (0xFDA2, " 062A 062E 0649"), - (0xFDA3, " 062A 0645 064A"), - (0xFDA4, " 062A 0645 0649"), - (0xFDA5, " 062C 0645 064A"), - (0xFDA6, " 062C 062D 0649"), - (0xFDA7, " 062C 0645 0649"), - (0xFDA8, " 0633 062E 0649"), - (0xFDA9, " 0635 062D 064A"), - (0xFDAA, " 0634 062D 064A"), - (0xFDAB, " 0636 062D 064A"), - (0xFDAC, " 0644 062C 064A"), - (0xFDAD, " 0644 0645 064A"), - (0xFDAE, " 064A 062D 064A"), - (0xFDAF, " 064A 062C 064A"), - (0xFDB0, " 064A 0645 064A"), - (0xFDB1, " 0645 0645 064A"), - (0xFDB2, " 0642 0645 064A"), - (0xFDB3, " 0646 062D 064A"), - (0xFDB4, " 0642 0645 062D"), - (0xFDB5, " 0644 062D 0645"), - (0xFDB6, " 0639 0645 064A"), - (0xFDB7, " 0643 0645 064A"), - (0xFDB8, " 0646 062C 062D"), - (0xFDB9, " 0645 062E 064A"), - (0xFDBA, " 0644 062C 0645"), - (0xFDBB, " 0643 0645 0645"), - (0xFDBC, " 0644 062C 0645"), - (0xFDBD, " 0646 062C 062D"), - (0xFDBE, " 062C 062D 064A"), - (0xFDBF, " 062D 062C 064A"), - (0xFDC0, " 0645 062C 064A"), - (0xFDC1, " 0641 0645 064A"), - (0xFDC2, " 0628 062D 064A"), - (0xFDC3, " 0643 0645 0645"), - (0xFDC4, " 0639 062C 0645"), - (0xFDC5, " 0635 0645 0645"), - (0xFDC6, " 0633 062E 064A"), - (0xFDC7, " 0646 062C 064A"), - (0xFDF0, " 0635 0644 06D2"), - (0xFDF1, " 0642 0644 06D2"), - (0xFDF2, " 0627 0644 0644 0647"), - (0xFDF3, " 0627 0643 0628 0631"), - (0xFDF4, " 0645 062D 0645 062F"), - (0xFDF5, " 0635 0644 0639 0645"), - (0xFDF6, " 0631 0633 0648 0644"), - (0xFDF7, " 0639 0644 064A 0647"), - (0xFDF8, " 0648 0633 0644 0645"), - (0xFDF9, " 0635 0644 0649"), - (0xFDFA, " 0635 0644 0649 0020 0627 0644 0644 0647 0020 0639 0644 064A 0647 0020 0648 0633 0644 0645"), - (0xFDFB, " 062C 0644 0020 062C 0644 0627 0644 0647"), - (0xFDFC, " 0631 06CC 0627 0644"), - (0xFE10, " 002C"), - (0xFE11, " 3001"), - (0xFE12, " 3002"), - (0xFE13, " 003A"), - (0xFE14, " 003B"), - (0xFE15, " 0021"), - (0xFE16, " 003F"), - (0xFE17, " 3016"), - (0xFE18, " 3017"), - (0xFE19, " 2026"), - (0xFE30, " 2025"), - (0xFE31, " 2014"), - (0xFE32, " 2013"), - (0xFE33, " 005F"), - (0xFE34, " 005F"), - (0xFE35, " 0028"), - (0xFE36, " 0029"), - (0xFE37, " 007B"), - (0xFE38, " 007D"), - (0xFE39, " 3014"), - (0xFE3A, " 3015"), - (0xFE3B, " 3010"), - (0xFE3C, " 3011"), - (0xFE3D, " 300A"), - (0xFE3E, " 300B"), - (0xFE3F, " 3008"), - (0xFE40, " 3009"), - (0xFE41, " 300C"), - (0xFE42, " 300D"), - (0xFE43, " 300E"), - (0xFE44, " 300F"), - (0xFE47, " 005B"), - (0xFE48, " 005D"), - (0xFE49, " 203E"), - (0xFE4A, " 203E"), - (0xFE4B, " 203E"), - (0xFE4C, " 203E"), - (0xFE4D, " 005F"), - (0xFE4E, " 005F"), - (0xFE4F, " 005F"), - (0xFE50, " 002C"), - (0xFE51, " 3001"), - (0xFE52, " 002E"), - (0xFE54, " 003B"), - (0xFE55, " 003A"), - (0xFE56, " 003F"), - (0xFE57, " 0021"), - (0xFE58, " 2014"), - (0xFE59, " 0028"), - (0xFE5A, " 0029"), - (0xFE5B, " 007B"), - (0xFE5C, " 007D"), - (0xFE5D, " 3014"), - (0xFE5E, " 3015"), - (0xFE5F, " 0023"), - (0xFE60, " 0026"), - (0xFE61, " 002A"), - (0xFE62, " 002B"), - (0xFE63, " 002D"), - (0xFE64, " 003C"), - (0xFE65, " 003E"), - (0xFE66, " 003D"), - (0xFE68, " 005C"), - (0xFE69, " 0024"), - (0xFE6A, " 0025"), - (0xFE6B, " 0040"), - (0xFE70, " 0020 064B"), - (0xFE71, " 0640 064B"), - (0xFE72, " 0020 064C"), - (0xFE74, " 0020 064D"), - (0xFE76, " 0020 064E"), - (0xFE77, " 0640 064E"), - (0xFE78, " 0020 064F"), - (0xFE79, " 0640 064F"), - (0xFE7A, " 0020 0650"), - (0xFE7B, " 0640 0650"), - (0xFE7C, " 0020 0651"), - (0xFE7D, " 0640 0651"), - (0xFE7E, " 0020 0652"), - (0xFE7F, " 0640 0652"), - (0xFE80, " 0621"), - (0xFE81, " 0622"), - (0xFE82, " 0622"), - (0xFE83, " 0623"), - (0xFE84, " 0623"), - (0xFE85, " 0624"), - (0xFE86, " 0624"), - (0xFE87, " 0625"), - (0xFE88, " 0625"), - (0xFE89, " 0626"), - (0xFE8A, " 0626"), - (0xFE8B, " 0626"), - (0xFE8C, " 0626"), - (0xFE8D, " 0627"), - (0xFE8E, " 0627"), - (0xFE8F, " 0628"), - (0xFE90, " 0628"), - (0xFE91, " 0628"), - (0xFE92, " 0628"), - (0xFE93, " 0629"), - (0xFE94, " 0629"), - (0xFE95, " 062A"), - (0xFE96, " 062A"), - (0xFE97, " 062A"), - (0xFE98, " 062A"), - (0xFE99, " 062B"), - (0xFE9A, " 062B"), - (0xFE9B, " 062B"), - (0xFE9C, " 062B"), - (0xFE9D, " 062C"), - (0xFE9E, " 062C"), - (0xFE9F, " 062C"), - (0xFEA0, " 062C"), - (0xFEA1, " 062D"), - (0xFEA2, " 062D"), - (0xFEA3, " 062D"), - (0xFEA4, " 062D"), - (0xFEA5, " 062E"), - (0xFEA6, " 062E"), - (0xFEA7, " 062E"), - (0xFEA8, " 062E"), - (0xFEA9, " 062F"), - (0xFEAA, " 062F"), - (0xFEAB, " 0630"), - (0xFEAC, " 0630"), - (0xFEAD, " 0631"), - (0xFEAE, " 0631"), - (0xFEAF, " 0632"), - (0xFEB0, " 0632"), - (0xFEB1, " 0633"), - (0xFEB2, " 0633"), - (0xFEB3, " 0633"), - (0xFEB4, " 0633"), - (0xFEB5, " 0634"), - (0xFEB6, " 0634"), - (0xFEB7, " 0634"), - (0xFEB8, " 0634"), - (0xFEB9, " 0635"), - (0xFEBA, " 0635"), - (0xFEBB, " 0635"), - (0xFEBC, " 0635"), - (0xFEBD, " 0636"), - (0xFEBE, " 0636"), - (0xFEBF, " 0636"), - (0xFEC0, " 0636"), - (0xFEC1, " 0637"), - (0xFEC2, " 0637"), - (0xFEC3, " 0637"), - (0xFEC4, " 0637"), - (0xFEC5, " 0638"), - (0xFEC6, " 0638"), - (0xFEC7, " 0638"), - (0xFEC8, " 0638"), - (0xFEC9, " 0639"), - (0xFECA, " 0639"), - (0xFECB, " 0639"), - (0xFECC, " 0639"), - (0xFECD, " 063A"), - (0xFECE, " 063A"), - (0xFECF, " 063A"), - (0xFED0, " 063A"), - (0xFED1, " 0641"), - (0xFED2, " 0641"), - (0xFED3, " 0641"), - (0xFED4, " 0641"), - (0xFED5, " 0642"), - (0xFED6, " 0642"), - (0xFED7, " 0642"), - (0xFED8, " 0642"), - (0xFED9, " 0643"), - (0xFEDA, " 0643"), - (0xFEDB, " 0643"), - (0xFEDC, " 0643"), - (0xFEDD, " 0644"), - (0xFEDE, " 0644"), - (0xFEDF, " 0644"), - (0xFEE0, " 0644"), - (0xFEE1, " 0645"), - (0xFEE2, " 0645"), - (0xFEE3, " 0645"), - (0xFEE4, " 0645"), - (0xFEE5, " 0646"), - (0xFEE6, " 0646"), - (0xFEE7, " 0646"), - (0xFEE8, " 0646"), - (0xFEE9, " 0647"), - (0xFEEA, " 0647"), - (0xFEEB, " 0647"), - (0xFEEC, " 0647"), - (0xFEED, " 0648"), - (0xFEEE, " 0648"), - (0xFEEF, " 0649"), - (0xFEF0, " 0649"), - (0xFEF1, " 064A"), - (0xFEF2, " 064A"), - (0xFEF3, " 064A"), - (0xFEF4, " 064A"), - (0xFEF5, " 0644 0622"), - (0xFEF6, " 0644 0622"), - (0xFEF7, " 0644 0623"), - (0xFEF8, " 0644 0623"), - (0xFEF9, " 0644 0625"), - (0xFEFA, " 0644 0625"), - (0xFEFB, " 0644 0627"), - (0xFEFC, " 0644 0627"), - (0xFF01, " 0021"), - (0xFF02, " 0022"), - (0xFF03, " 0023"), - (0xFF04, " 0024"), - (0xFF05, " 0025"), - (0xFF06, " 0026"), - (0xFF07, " 0027"), - (0xFF08, " 0028"), - (0xFF09, " 0029"), - (0xFF0A, " 002A"), - (0xFF0B, " 002B"), - (0xFF0C, " 002C"), - (0xFF0D, " 002D"), - (0xFF0E, " 002E"), - (0xFF0F, " 002F"), - (0xFF10, " 0030"), - (0xFF11, " 0031"), - (0xFF12, " 0032"), - (0xFF13, " 0033"), - (0xFF14, " 0034"), - (0xFF15, " 0035"), - (0xFF16, " 0036"), - (0xFF17, " 0037"), - (0xFF18, " 0038"), - (0xFF19, " 0039"), - (0xFF1A, " 003A"), - (0xFF1B, " 003B"), - (0xFF1C, " 003C"), - (0xFF1D, " 003D"), - (0xFF1E, " 003E"), - (0xFF1F, " 003F"), - (0xFF20, " 0040"), - (0xFF21, " 0041"), - (0xFF22, " 0042"), - (0xFF23, " 0043"), - (0xFF24, " 0044"), - (0xFF25, " 0045"), - (0xFF26, " 0046"), - (0xFF27, " 0047"), - (0xFF28, " 0048"), - (0xFF29, " 0049"), - (0xFF2A, " 004A"), - (0xFF2B, " 004B"), - (0xFF2C, " 004C"), - (0xFF2D, " 004D"), - (0xFF2E, " 004E"), - (0xFF2F, " 004F"), - (0xFF30, " 0050"), - (0xFF31, " 0051"), - (0xFF32, " 0052"), - (0xFF33, " 0053"), - (0xFF34, " 0054"), - (0xFF35, " 0055"), - (0xFF36, " 0056"), - (0xFF37, " 0057"), - (0xFF38, " 0058"), - (0xFF39, " 0059"), - (0xFF3A, " 005A"), - (0xFF3B, " 005B"), - (0xFF3C, " 005C"), - (0xFF3D, " 005D"), - (0xFF3E, " 005E"), - (0xFF3F, " 005F"), - (0xFF40, " 0060"), - (0xFF41, " 0061"), - (0xFF42, " 0062"), - (0xFF43, " 0063"), - (0xFF44, " 0064"), - (0xFF45, " 0065"), - (0xFF46, " 0066"), - (0xFF47, " 0067"), - (0xFF48, " 0068"), - (0xFF49, " 0069"), - (0xFF4A, " 006A"), - (0xFF4B, " 006B"), - (0xFF4C, " 006C"), - (0xFF4D, " 006D"), - (0xFF4E, " 006E"), - (0xFF4F, " 006F"), - (0xFF50, " 0070"), - (0xFF51, " 0071"), - (0xFF52, " 0072"), - (0xFF53, " 0073"), - (0xFF54, " 0074"), - (0xFF55, " 0075"), - (0xFF56, " 0076"), - (0xFF57, " 0077"), - (0xFF58, " 0078"), - (0xFF59, " 0079"), - (0xFF5A, " 007A"), - (0xFF5B, " 007B"), - (0xFF5C, " 007C"), - (0xFF5D, " 007D"), - (0xFF5E, " 007E"), - (0xFF5F, " 2985"), - (0xFF60, " 2986"), - (0xFF61, " 3002"), - (0xFF62, " 300C"), - (0xFF63, " 300D"), - (0xFF64, " 3001"), - (0xFF65, " 30FB"), - (0xFF66, " 30F2"), - (0xFF67, " 30A1"), - (0xFF68, " 30A3"), - (0xFF69, " 30A5"), - (0xFF6A, " 30A7"), - (0xFF6B, " 30A9"), - (0xFF6C, " 30E3"), - (0xFF6D, " 30E5"), - (0xFF6E, " 30E7"), - (0xFF6F, " 30C3"), - (0xFF70, " 30FC"), - (0xFF71, " 30A2"), - (0xFF72, " 30A4"), - (0xFF73, " 30A6"), - (0xFF74, " 30A8"), - (0xFF75, " 30AA"), - (0xFF76, " 30AB"), - (0xFF77, " 30AD"), - (0xFF78, " 30AF"), - (0xFF79, " 30B1"), - (0xFF7A, " 30B3"), - (0xFF7B, " 30B5"), - (0xFF7C, " 30B7"), - (0xFF7D, " 30B9"), - (0xFF7E, " 30BB"), - (0xFF7F, " 30BD"), - (0xFF80, " 30BF"), - (0xFF81, " 30C1"), - (0xFF82, " 30C4"), - (0xFF83, " 30C6"), - (0xFF84, " 30C8"), - (0xFF85, " 30CA"), - (0xFF86, " 30CB"), - (0xFF87, " 30CC"), - (0xFF88, " 30CD"), - (0xFF89, " 30CE"), - (0xFF8A, " 30CF"), - (0xFF8B, " 30D2"), - (0xFF8C, " 30D5"), - (0xFF8D, " 30D8"), - (0xFF8E, " 30DB"), - (0xFF8F, " 30DE"), - (0xFF90, " 30DF"), - (0xFF91, " 30E0"), - (0xFF92, " 30E1"), - (0xFF93, " 30E2"), - (0xFF94, " 30E4"), - (0xFF95, " 30E6"), - (0xFF96, " 30E8"), - (0xFF97, " 30E9"), - (0xFF98, " 30EA"), - (0xFF99, " 30EB"), - (0xFF9A, " 30EC"), - (0xFF9B, " 30ED"), - (0xFF9C, " 30EF"), - (0xFF9D, " 30F3"), - (0xFF9E, " 3099"), - (0xFF9F, " 309A"), - (0xFFA0, " 3164"), - (0xFFA1, " 3131"), - (0xFFA2, " 3132"), - (0xFFA3, " 3133"), - (0xFFA4, " 3134"), - (0xFFA5, " 3135"), - (0xFFA6, " 3136"), - (0xFFA7, " 3137"), - (0xFFA8, " 3138"), - (0xFFA9, " 3139"), - (0xFFAA, " 313A"), - (0xFFAB, " 313B"), - (0xFFAC, " 313C"), - (0xFFAD, " 313D"), - (0xFFAE, " 313E"), - (0xFFAF, " 313F"), - (0xFFB0, " 3140"), - (0xFFB1, " 3141"), - (0xFFB2, " 3142"), - (0xFFB3, " 3143"), - (0xFFB4, " 3144"), - (0xFFB5, " 3145"), - (0xFFB6, " 3146"), - (0xFFB7, " 3147"), - (0xFFB8, " 3148"), - (0xFFB9, " 3149"), - (0xFFBA, " 314A"), - (0xFFBB, " 314B"), - (0xFFBC, " 314C"), - (0xFFBD, " 314D"), - (0xFFBE, " 314E"), - (0xFFC2, " 314F"), - (0xFFC3, " 3150"), - (0xFFC4, " 3151"), - (0xFFC5, " 3152"), - (0xFFC6, " 3153"), - (0xFFC7, " 3154"), - (0xFFCA, " 3155"), - (0xFFCB, " 3156"), - (0xFFCC, " 3157"), - (0xFFCD, " 3158"), - (0xFFCE, " 3159"), - (0xFFCF, " 315A"), - (0xFFD2, " 315B"), - (0xFFD3, " 315C"), - (0xFFD4, " 315D"), - (0xFFD5, " 315E"), - (0xFFD6, " 315F"), - (0xFFD7, " 3160"), - (0xFFDA, " 3161"), - (0xFFDB, " 3162"), - (0xFFDC, " 3163"), - (0xFFE0, " 00A2"), - (0xFFE1, " 00A3"), - (0xFFE2, " 00AC"), - (0xFFE3, " 00AF"), - (0xFFE4, " 00A6"), - (0xFFE5, " 00A5"), - (0xFFE6, " 20A9"), - (0xFFE8, " 2502"), - (0xFFE9, " 2190"), - (0xFFEA, " 2191"), - (0xFFEB, " 2192"), - (0xFFEC, " 2193"), - (0xFFED, " 25A0"), - (0xFFEE, " 25CB"), - (0x10781, " 02D0"), - (0x10782, " 02D1"), - (0x10783, " 00E6"), - (0x10784, " 0299"), - (0x10785, " 0253"), - (0x10787, " 02A3"), - (0x10788, " AB66"), - (0x10789, " 02A5"), - (0x1078A, " 02A4"), - (0x1078B, " 0256"), - (0x1078C, " 0257"), - (0x1078D, " 1D91"), - (0x1078E, " 0258"), - (0x1078F, " 025E"), - (0x10790, " 02A9"), - (0x10791, " 0264"), - (0x10792, " 0262"), - (0x10793, " 0260"), - (0x10794, " 029B"), - (0x10795, " 0127"), - (0x10796, " 029C"), - (0x10797, " 0267"), - (0x10798, " 0284"), - (0x10799, " 02AA"), - (0x1079A, " 02AB"), - (0x1079B, " 026C"), - (0x1079C, " 1DF04"), - (0x1079D, " A78E"), - (0x1079E, " 026E"), - (0x1079F, " 1DF05"), - (0x107A0, " 028E"), - (0x107A1, " 1DF06"), - (0x107A2, " 00F8"), - (0x107A3, " 0276"), - (0x107A4, " 0277"), - (0x107A5, " 0071"), - (0x107A6, " 027A"), - (0x107A7, " 1DF08"), - (0x107A8, " 027D"), - (0x107A9, " 027E"), - (0x107AA, " 0280"), - (0x107AB, " 02A8"), - (0x107AC, " 02A6"), - (0x107AD, " AB67"), - (0x107AE, " 02A7"), - (0x107AF, " 0288"), - (0x107B0, " 2C71"), - (0x107B2, " 028F"), - (0x107B3, " 02A1"), - (0x107B4, " 02A2"), - (0x107B5, " 0298"), - (0x107B6, " 01C0"), - (0x107B7, " 01C1"), - (0x107B8, " 01C2"), - (0x107B9, " 1DF0A"), - (0x107BA, " 1DF1E"), - (0x1109A, "11099 110BA"), - (0x1109C, "1109B 110BA"), - (0x110AB, "110A5 110BA"), - (0x1112E, "11131 11127"), - (0x1112F, "11132 11127"), - (0x1134B, "11347 1133E"), - (0x1134C, "11347 11357"), - (0x114BB, "114B9 114BA"), - (0x114BC, "114B9 114B0"), - (0x114BE, "114B9 114BD"), - (0x115BA, "115B8 115AF"), - (0x115BB, "115B9 115AF"), - (0x11938, "11935 11930"), - (0x1D15E, "1D157 1D165"), - (0x1D15F, "1D158 1D165"), - (0x1D160, "1D15F 1D16E"), - (0x1D161, "1D15F 1D16F"), - (0x1D162, "1D15F 1D170"), - (0x1D163, "1D15F 1D171"), - (0x1D164, "1D15F 1D172"), - (0x1D1BB, "1D1B9 1D165"), - (0x1D1BC, "1D1BA 1D165"), - (0x1D1BD, "1D1BB 1D16E"), - (0x1D1BE, "1D1BC 1D16E"), - (0x1D1BF, "1D1BB 1D16F"), - (0x1D1C0, "1D1BC 1D16F"), - (0x1D400, " 0041"), - (0x1D401, " 0042"), - (0x1D402, " 0043"), - (0x1D403, " 0044"), - (0x1D404, " 0045"), - (0x1D405, " 0046"), - (0x1D406, " 0047"), - (0x1D407, " 0048"), - (0x1D408, " 0049"), - (0x1D409, " 004A"), - (0x1D40A, " 004B"), - (0x1D40B, " 004C"), - (0x1D40C, " 004D"), - (0x1D40D, " 004E"), - (0x1D40E, " 004F"), - (0x1D40F, " 0050"), - (0x1D410, " 0051"), - (0x1D411, " 0052"), - (0x1D412, " 0053"), - (0x1D413, " 0054"), - (0x1D414, " 0055"), - (0x1D415, " 0056"), - (0x1D416, " 0057"), - (0x1D417, " 0058"), - (0x1D418, " 0059"), - (0x1D419, " 005A"), - (0x1D41A, " 0061"), - (0x1D41B, " 0062"), - (0x1D41C, " 0063"), - (0x1D41D, " 0064"), - (0x1D41E, " 0065"), - (0x1D41F, " 0066"), - (0x1D420, " 0067"), - (0x1D421, " 0068"), - (0x1D422, " 0069"), - (0x1D423, " 006A"), - (0x1D424, " 006B"), - (0x1D425, " 006C"), - (0x1D426, " 006D"), - (0x1D427, " 006E"), - (0x1D428, " 006F"), - (0x1D429, " 0070"), - (0x1D42A, " 0071"), - (0x1D42B, " 0072"), - (0x1D42C, " 0073"), - (0x1D42D, " 0074"), - (0x1D42E, " 0075"), - (0x1D42F, " 0076"), - (0x1D430, " 0077"), - (0x1D431, " 0078"), - (0x1D432, " 0079"), - (0x1D433, " 007A"), - (0x1D434, " 0041"), - (0x1D435, " 0042"), - (0x1D436, " 0043"), - (0x1D437, " 0044"), - (0x1D438, " 0045"), - (0x1D439, " 0046"), - (0x1D43A, " 0047"), - (0x1D43B, " 0048"), - (0x1D43C, " 0049"), - (0x1D43D, " 004A"), - (0x1D43E, " 004B"), - (0x1D43F, " 004C"), - (0x1D440, " 004D"), - (0x1D441, " 004E"), - (0x1D442, " 004F"), - (0x1D443, " 0050"), - (0x1D444, " 0051"), - (0x1D445, " 0052"), - (0x1D446, " 0053"), - (0x1D447, " 0054"), - (0x1D448, " 0055"), - (0x1D449, " 0056"), - (0x1D44A, " 0057"), - (0x1D44B, " 0058"), - (0x1D44C, " 0059"), - (0x1D44D, " 005A"), - (0x1D44E, " 0061"), - (0x1D44F, " 0062"), - (0x1D450, " 0063"), - (0x1D451, " 0064"), - (0x1D452, " 0065"), - (0x1D453, " 0066"), - (0x1D454, " 0067"), - (0x1D456, " 0069"), - (0x1D457, " 006A"), - (0x1D458, " 006B"), - (0x1D459, " 006C"), - (0x1D45A, " 006D"), - (0x1D45B, " 006E"), - (0x1D45C, " 006F"), - (0x1D45D, " 0070"), - (0x1D45E, " 0071"), - (0x1D45F, " 0072"), - (0x1D460, " 0073"), - (0x1D461, " 0074"), - (0x1D462, " 0075"), - (0x1D463, " 0076"), - (0x1D464, " 0077"), - (0x1D465, " 0078"), - (0x1D466, " 0079"), - (0x1D467, " 007A"), - (0x1D468, " 0041"), - (0x1D469, " 0042"), - (0x1D46A, " 0043"), - (0x1D46B, " 0044"), - (0x1D46C, " 0045"), - (0x1D46D, " 0046"), - (0x1D46E, " 0047"), - (0x1D46F, " 0048"), - (0x1D470, " 0049"), - (0x1D471, " 004A"), - (0x1D472, " 004B"), - (0x1D473, " 004C"), - (0x1D474, " 004D"), - (0x1D475, " 004E"), - (0x1D476, " 004F"), - (0x1D477, " 0050"), - (0x1D478, " 0051"), - (0x1D479, " 0052"), - (0x1D47A, " 0053"), - (0x1D47B, " 0054"), - (0x1D47C, " 0055"), - (0x1D47D, " 0056"), - (0x1D47E, " 0057"), - (0x1D47F, " 0058"), - (0x1D480, " 0059"), - (0x1D481, " 005A"), - (0x1D482, " 0061"), - (0x1D483, " 0062"), - (0x1D484, " 0063"), - (0x1D485, " 0064"), - (0x1D486, " 0065"), - (0x1D487, " 0066"), - (0x1D488, " 0067"), - (0x1D489, " 0068"), - (0x1D48A, " 0069"), - (0x1D48B, " 006A"), - (0x1D48C, " 006B"), - (0x1D48D, " 006C"), - (0x1D48E, " 006D"), - (0x1D48F, " 006E"), - (0x1D490, " 006F"), - (0x1D491, " 0070"), - (0x1D492, " 0071"), - (0x1D493, " 0072"), - (0x1D494, " 0073"), - (0x1D495, " 0074"), - (0x1D496, " 0075"), - (0x1D497, " 0076"), - (0x1D498, " 0077"), - (0x1D499, " 0078"), - (0x1D49A, " 0079"), - (0x1D49B, " 007A"), - (0x1D49C, " 0041"), - (0x1D49E, " 0043"), - (0x1D49F, " 0044"), - (0x1D4A2, " 0047"), - (0x1D4A5, " 004A"), - (0x1D4A6, " 004B"), - (0x1D4A9, " 004E"), - (0x1D4AA, " 004F"), - (0x1D4AB, " 0050"), - (0x1D4AC, " 0051"), - (0x1D4AE, " 0053"), - (0x1D4AF, " 0054"), - (0x1D4B0, " 0055"), - (0x1D4B1, " 0056"), - (0x1D4B2, " 0057"), - (0x1D4B3, " 0058"), - (0x1D4B4, " 0059"), - (0x1D4B5, " 005A"), - (0x1D4B6, " 0061"), - (0x1D4B7, " 0062"), - (0x1D4B8, " 0063"), - (0x1D4B9, " 0064"), - (0x1D4BB, " 0066"), - (0x1D4BD, " 0068"), - (0x1D4BE, " 0069"), - (0x1D4BF, " 006A"), - (0x1D4C0, " 006B"), - (0x1D4C1, " 006C"), - (0x1D4C2, " 006D"), - (0x1D4C3, " 006E"), - (0x1D4C5, " 0070"), - (0x1D4C6, " 0071"), - (0x1D4C7, " 0072"), - (0x1D4C8, " 0073"), - (0x1D4C9, " 0074"), - (0x1D4CA, " 0075"), - (0x1D4CB, " 0076"), - (0x1D4CC, " 0077"), - (0x1D4CD, " 0078"), - (0x1D4CE, " 0079"), - (0x1D4CF, " 007A"), - (0x1D4D0, " 0041"), - (0x1D4D1, " 0042"), - (0x1D4D2, " 0043"), - (0x1D4D3, " 0044"), - (0x1D4D4, " 0045"), - (0x1D4D5, " 0046"), - (0x1D4D6, " 0047"), - (0x1D4D7, " 0048"), - (0x1D4D8, " 0049"), - (0x1D4D9, " 004A"), - (0x1D4DA, " 004B"), - (0x1D4DB, " 004C"), - (0x1D4DC, " 004D"), - (0x1D4DD, " 004E"), - (0x1D4DE, " 004F"), - (0x1D4DF, " 0050"), - (0x1D4E0, " 0051"), - (0x1D4E1, " 0052"), - (0x1D4E2, " 0053"), - (0x1D4E3, " 0054"), - (0x1D4E4, " 0055"), - (0x1D4E5, " 0056"), - (0x1D4E6, " 0057"), - (0x1D4E7, " 0058"), - (0x1D4E8, " 0059"), - (0x1D4E9, " 005A"), - (0x1D4EA, " 0061"), - (0x1D4EB, " 0062"), - (0x1D4EC, " 0063"), - (0x1D4ED, " 0064"), - (0x1D4EE, " 0065"), - (0x1D4EF, " 0066"), - (0x1D4F0, " 0067"), - (0x1D4F1, " 0068"), - (0x1D4F2, " 0069"), - (0x1D4F3, " 006A"), - (0x1D4F4, " 006B"), - (0x1D4F5, " 006C"), - (0x1D4F6, " 006D"), - (0x1D4F7, " 006E"), - (0x1D4F8, " 006F"), - (0x1D4F9, " 0070"), - (0x1D4FA, " 0071"), - (0x1D4FB, " 0072"), - (0x1D4FC, " 0073"), - (0x1D4FD, " 0074"), - (0x1D4FE, " 0075"), - (0x1D4FF, " 0076"), - (0x1D500, " 0077"), - (0x1D501, " 0078"), - (0x1D502, " 0079"), - (0x1D503, " 007A"), - (0x1D504, " 0041"), - (0x1D505, " 0042"), - (0x1D507, " 0044"), - (0x1D508, " 0045"), - (0x1D509, " 0046"), - (0x1D50A, " 0047"), - (0x1D50D, " 004A"), - (0x1D50E, " 004B"), - (0x1D50F, " 004C"), - (0x1D510, " 004D"), - (0x1D511, " 004E"), - (0x1D512, " 004F"), - (0x1D513, " 0050"), - (0x1D514, " 0051"), - (0x1D516, " 0053"), - (0x1D517, " 0054"), - (0x1D518, " 0055"), - (0x1D519, " 0056"), - (0x1D51A, " 0057"), - (0x1D51B, " 0058"), - (0x1D51C, " 0059"), - (0x1D51E, " 0061"), - (0x1D51F, " 0062"), - (0x1D520, " 0063"), - (0x1D521, " 0064"), - (0x1D522, " 0065"), - (0x1D523, " 0066"), - (0x1D524, " 0067"), - (0x1D525, " 0068"), - (0x1D526, " 0069"), - (0x1D527, " 006A"), - (0x1D528, " 006B"), - (0x1D529, " 006C"), - (0x1D52A, " 006D"), - (0x1D52B, " 006E"), - (0x1D52C, " 006F"), - (0x1D52D, " 0070"), - (0x1D52E, " 0071"), - (0x1D52F, " 0072"), - (0x1D530, " 0073"), - (0x1D531, " 0074"), - (0x1D532, " 0075"), - (0x1D533, " 0076"), - (0x1D534, " 0077"), - (0x1D535, " 0078"), - (0x1D536, " 0079"), - (0x1D537, " 007A"), - (0x1D538, " 0041"), - (0x1D539, " 0042"), - (0x1D53B, " 0044"), - (0x1D53C, " 0045"), - (0x1D53D, " 0046"), - (0x1D53E, " 0047"), - (0x1D540, " 0049"), - (0x1D541, " 004A"), - (0x1D542, " 004B"), - (0x1D543, " 004C"), - (0x1D544, " 004D"), - (0x1D546, " 004F"), - (0x1D54A, " 0053"), - (0x1D54B, " 0054"), - (0x1D54C, " 0055"), - (0x1D54D, " 0056"), - (0x1D54E, " 0057"), - (0x1D54F, " 0058"), - (0x1D550, " 0059"), - (0x1D552, " 0061"), - (0x1D553, " 0062"), - (0x1D554, " 0063"), - (0x1D555, " 0064"), - (0x1D556, " 0065"), - (0x1D557, " 0066"), - (0x1D558, " 0067"), - (0x1D559, " 0068"), - (0x1D55A, " 0069"), - (0x1D55B, " 006A"), - (0x1D55C, " 006B"), - (0x1D55D, " 006C"), - (0x1D55E, " 006D"), - (0x1D55F, " 006E"), - (0x1D560, " 006F"), - (0x1D561, " 0070"), - (0x1D562, " 0071"), - (0x1D563, " 0072"), - (0x1D564, " 0073"), - (0x1D565, " 0074"), - (0x1D566, " 0075"), - (0x1D567, " 0076"), - (0x1D568, " 0077"), - (0x1D569, " 0078"), - (0x1D56A, " 0079"), - (0x1D56B, " 007A"), - (0x1D56C, " 0041"), - (0x1D56D, " 0042"), - (0x1D56E, " 0043"), - (0x1D56F, " 0044"), - (0x1D570, " 0045"), - (0x1D571, " 0046"), - (0x1D572, " 0047"), - (0x1D573, " 0048"), - (0x1D574, " 0049"), - (0x1D575, " 004A"), - (0x1D576, " 004B"), - (0x1D577, " 004C"), - (0x1D578, " 004D"), - (0x1D579, " 004E"), - (0x1D57A, " 004F"), - (0x1D57B, " 0050"), - (0x1D57C, " 0051"), - (0x1D57D, " 0052"), - (0x1D57E, " 0053"), - (0x1D57F, " 0054"), - (0x1D580, " 0055"), - (0x1D581, " 0056"), - (0x1D582, " 0057"), - (0x1D583, " 0058"), - (0x1D584, " 0059"), - (0x1D585, " 005A"), - (0x1D586, " 0061"), - (0x1D587, " 0062"), - (0x1D588, " 0063"), - (0x1D589, " 0064"), - (0x1D58A, " 0065"), - (0x1D58B, " 0066"), - (0x1D58C, " 0067"), - (0x1D58D, " 0068"), - (0x1D58E, " 0069"), - (0x1D58F, " 006A"), - (0x1D590, " 006B"), - (0x1D591, " 006C"), - (0x1D592, " 006D"), - (0x1D593, " 006E"), - (0x1D594, " 006F"), - (0x1D595, " 0070"), - (0x1D596, " 0071"), - (0x1D597, " 0072"), - (0x1D598, " 0073"), - (0x1D599, " 0074"), - (0x1D59A, " 0075"), - (0x1D59B, " 0076"), - (0x1D59C, " 0077"), - (0x1D59D, " 0078"), - (0x1D59E, " 0079"), - (0x1D59F, " 007A"), - (0x1D5A0, " 0041"), - (0x1D5A1, " 0042"), - (0x1D5A2, " 0043"), - (0x1D5A3, " 0044"), - (0x1D5A4, " 0045"), - (0x1D5A5, " 0046"), - (0x1D5A6, " 0047"), - (0x1D5A7, " 0048"), - (0x1D5A8, " 0049"), - (0x1D5A9, " 004A"), - (0x1D5AA, " 004B"), - (0x1D5AB, " 004C"), - (0x1D5AC, " 004D"), - (0x1D5AD, " 004E"), - (0x1D5AE, " 004F"), - (0x1D5AF, " 0050"), - (0x1D5B0, " 0051"), - (0x1D5B1, " 0052"), - (0x1D5B2, " 0053"), - (0x1D5B3, " 0054"), - (0x1D5B4, " 0055"), - (0x1D5B5, " 0056"), - (0x1D5B6, " 0057"), - (0x1D5B7, " 0058"), - (0x1D5B8, " 0059"), - (0x1D5B9, " 005A"), - (0x1D5BA, " 0061"), - (0x1D5BB, " 0062"), - (0x1D5BC, " 0063"), - (0x1D5BD, " 0064"), - (0x1D5BE, " 0065"), - (0x1D5BF, " 0066"), - (0x1D5C0, " 0067"), - (0x1D5C1, " 0068"), - (0x1D5C2, " 0069"), - (0x1D5C3, " 006A"), - (0x1D5C4, " 006B"), - (0x1D5C5, " 006C"), - (0x1D5C6, " 006D"), - (0x1D5C7, " 006E"), - (0x1D5C8, " 006F"), - (0x1D5C9, " 0070"), - (0x1D5CA, " 0071"), - (0x1D5CB, " 0072"), - (0x1D5CC, " 0073"), - (0x1D5CD, " 0074"), - (0x1D5CE, " 0075"), - (0x1D5CF, " 0076"), - (0x1D5D0, " 0077"), - (0x1D5D1, " 0078"), - (0x1D5D2, " 0079"), - (0x1D5D3, " 007A"), - (0x1D5D4, " 0041"), - (0x1D5D5, " 0042"), - (0x1D5D6, " 0043"), - (0x1D5D7, " 0044"), - (0x1D5D8, " 0045"), - (0x1D5D9, " 0046"), - (0x1D5DA, " 0047"), - (0x1D5DB, " 0048"), - (0x1D5DC, " 0049"), - (0x1D5DD, " 004A"), - (0x1D5DE, " 004B"), - (0x1D5DF, " 004C"), - (0x1D5E0, " 004D"), - (0x1D5E1, " 004E"), - (0x1D5E2, " 004F"), - (0x1D5E3, " 0050"), - (0x1D5E4, " 0051"), - (0x1D5E5, " 0052"), - (0x1D5E6, " 0053"), - (0x1D5E7, " 0054"), - (0x1D5E8, " 0055"), - (0x1D5E9, " 0056"), - (0x1D5EA, " 0057"), - (0x1D5EB, " 0058"), - (0x1D5EC, " 0059"), - (0x1D5ED, " 005A"), - (0x1D5EE, " 0061"), - (0x1D5EF, " 0062"), - (0x1D5F0, " 0063"), - (0x1D5F1, " 0064"), - (0x1D5F2, " 0065"), - (0x1D5F3, " 0066"), - (0x1D5F4, " 0067"), - (0x1D5F5, " 0068"), - (0x1D5F6, " 0069"), - (0x1D5F7, " 006A"), - (0x1D5F8, " 006B"), - (0x1D5F9, " 006C"), - (0x1D5FA, " 006D"), - (0x1D5FB, " 006E"), - (0x1D5FC, " 006F"), - (0x1D5FD, " 0070"), - (0x1D5FE, " 0071"), - (0x1D5FF, " 0072"), - (0x1D600, " 0073"), - (0x1D601, " 0074"), - (0x1D602, " 0075"), - (0x1D603, " 0076"), - (0x1D604, " 0077"), - (0x1D605, " 0078"), - (0x1D606, " 0079"), - (0x1D607, " 007A"), - (0x1D608, " 0041"), - (0x1D609, " 0042"), - (0x1D60A, " 0043"), - (0x1D60B, " 0044"), - (0x1D60C, " 0045"), - (0x1D60D, " 0046"), - (0x1D60E, " 0047"), - (0x1D60F, " 0048"), - (0x1D610, " 0049"), - (0x1D611, " 004A"), - (0x1D612, " 004B"), - (0x1D613, " 004C"), - (0x1D614, " 004D"), - (0x1D615, " 004E"), - (0x1D616, " 004F"), - (0x1D617, " 0050"), - (0x1D618, " 0051"), - (0x1D619, " 0052"), - (0x1D61A, " 0053"), - (0x1D61B, " 0054"), - (0x1D61C, " 0055"), - (0x1D61D, " 0056"), - (0x1D61E, " 0057"), - (0x1D61F, " 0058"), - (0x1D620, " 0059"), - (0x1D621, " 005A"), - (0x1D622, " 0061"), - (0x1D623, " 0062"), - (0x1D624, " 0063"), - (0x1D625, " 0064"), - (0x1D626, " 0065"), - (0x1D627, " 0066"), - (0x1D628, " 0067"), - (0x1D629, " 0068"), - (0x1D62A, " 0069"), - (0x1D62B, " 006A"), - (0x1D62C, " 006B"), - (0x1D62D, " 006C"), - (0x1D62E, " 006D"), - (0x1D62F, " 006E"), - (0x1D630, " 006F"), - (0x1D631, " 0070"), - (0x1D632, " 0071"), - (0x1D633, " 0072"), - (0x1D634, " 0073"), - (0x1D635, " 0074"), - (0x1D636, " 0075"), - (0x1D637, " 0076"), - (0x1D638, " 0077"), - (0x1D639, " 0078"), - (0x1D63A, " 0079"), - (0x1D63B, " 007A"), - (0x1D63C, " 0041"), - (0x1D63D, " 0042"), - (0x1D63E, " 0043"), - (0x1D63F, " 0044"), - (0x1D640, " 0045"), - (0x1D641, " 0046"), - (0x1D642, " 0047"), - (0x1D643, " 0048"), - (0x1D644, " 0049"), - (0x1D645, " 004A"), - (0x1D646, " 004B"), - (0x1D647, " 004C"), - (0x1D648, " 004D"), - (0x1D649, " 004E"), - (0x1D64A, " 004F"), - (0x1D64B, " 0050"), - (0x1D64C, " 0051"), - (0x1D64D, " 0052"), - (0x1D64E, " 0053"), - (0x1D64F, " 0054"), - (0x1D650, " 0055"), - (0x1D651, " 0056"), - (0x1D652, " 0057"), - (0x1D653, " 0058"), - (0x1D654, " 0059"), - (0x1D655, " 005A"), - (0x1D656, " 0061"), - (0x1D657, " 0062"), - (0x1D658, " 0063"), - (0x1D659, " 0064"), - (0x1D65A, " 0065"), - (0x1D65B, " 0066"), - (0x1D65C, " 0067"), - (0x1D65D, " 0068"), - (0x1D65E, " 0069"), - (0x1D65F, " 006A"), - (0x1D660, " 006B"), - (0x1D661, " 006C"), - (0x1D662, " 006D"), - (0x1D663, " 006E"), - (0x1D664, " 006F"), - (0x1D665, " 0070"), - (0x1D666, " 0071"), - (0x1D667, " 0072"), - (0x1D668, " 0073"), - (0x1D669, " 0074"), - (0x1D66A, " 0075"), - (0x1D66B, " 0076"), - (0x1D66C, " 0077"), - (0x1D66D, " 0078"), - (0x1D66E, " 0079"), - (0x1D66F, " 007A"), - (0x1D670, " 0041"), - (0x1D671, " 0042"), - (0x1D672, " 0043"), - (0x1D673, " 0044"), - (0x1D674, " 0045"), - (0x1D675, " 0046"), - (0x1D676, " 0047"), - (0x1D677, " 0048"), - (0x1D678, " 0049"), - (0x1D679, " 004A"), - (0x1D67A, " 004B"), - (0x1D67B, " 004C"), - (0x1D67C, " 004D"), - (0x1D67D, " 004E"), - (0x1D67E, " 004F"), - (0x1D67F, " 0050"), - (0x1D680, " 0051"), - (0x1D681, " 0052"), - (0x1D682, " 0053"), - (0x1D683, " 0054"), - (0x1D684, " 0055"), - (0x1D685, " 0056"), - (0x1D686, " 0057"), - (0x1D687, " 0058"), - (0x1D688, " 0059"), - (0x1D689, " 005A"), - (0x1D68A, " 0061"), - (0x1D68B, " 0062"), - (0x1D68C, " 0063"), - (0x1D68D, " 0064"), - (0x1D68E, " 0065"), - (0x1D68F, " 0066"), - (0x1D690, " 0067"), - (0x1D691, " 0068"), - (0x1D692, " 0069"), - (0x1D693, " 006A"), - (0x1D694, " 006B"), - (0x1D695, " 006C"), - (0x1D696, " 006D"), - (0x1D697, " 006E"), - (0x1D698, " 006F"), - (0x1D699, " 0070"), - (0x1D69A, " 0071"), - (0x1D69B, " 0072"), - (0x1D69C, " 0073"), - (0x1D69D, " 0074"), - (0x1D69E, " 0075"), - (0x1D69F, " 0076"), - (0x1D6A0, " 0077"), - (0x1D6A1, " 0078"), - (0x1D6A2, " 0079"), - (0x1D6A3, " 007A"), - (0x1D6A4, " 0131"), - (0x1D6A5, " 0237"), - (0x1D6A8, " 0391"), - (0x1D6A9, " 0392"), - (0x1D6AA, " 0393"), - (0x1D6AB, " 0394"), - (0x1D6AC, " 0395"), - (0x1D6AD, " 0396"), - (0x1D6AE, " 0397"), - (0x1D6AF, " 0398"), - (0x1D6B0, " 0399"), - (0x1D6B1, " 039A"), - (0x1D6B2, " 039B"), - (0x1D6B3, " 039C"), - (0x1D6B4, " 039D"), - (0x1D6B5, " 039E"), - (0x1D6B6, " 039F"), - (0x1D6B7, " 03A0"), - (0x1D6B8, " 03A1"), - (0x1D6B9, " 03F4"), - (0x1D6BA, " 03A3"), - (0x1D6BB, " 03A4"), - (0x1D6BC, " 03A5"), - (0x1D6BD, " 03A6"), - (0x1D6BE, " 03A7"), - (0x1D6BF, " 03A8"), - (0x1D6C0, " 03A9"), - (0x1D6C1, " 2207"), - (0x1D6C2, " 03B1"), - (0x1D6C3, " 03B2"), - (0x1D6C4, " 03B3"), - (0x1D6C5, " 03B4"), - (0x1D6C6, " 03B5"), - (0x1D6C7, " 03B6"), - (0x1D6C8, " 03B7"), - (0x1D6C9, " 03B8"), - (0x1D6CA, " 03B9"), - (0x1D6CB, " 03BA"), - (0x1D6CC, " 03BB"), - (0x1D6CD, " 03BC"), - (0x1D6CE, " 03BD"), - (0x1D6CF, " 03BE"), - (0x1D6D0, " 03BF"), - (0x1D6D1, " 03C0"), - (0x1D6D2, " 03C1"), - (0x1D6D3, " 03C2"), - (0x1D6D4, " 03C3"), - (0x1D6D5, " 03C4"), - (0x1D6D6, " 03C5"), - (0x1D6D7, " 03C6"), - (0x1D6D8, " 03C7"), - (0x1D6D9, " 03C8"), - (0x1D6DA, " 03C9"), - (0x1D6DB, " 2202"), - (0x1D6DC, " 03F5"), - (0x1D6DD, " 03D1"), - (0x1D6DE, " 03F0"), - (0x1D6DF, " 03D5"), - (0x1D6E0, " 03F1"), - (0x1D6E1, " 03D6"), - (0x1D6E2, " 0391"), - (0x1D6E3, " 0392"), - (0x1D6E4, " 0393"), - (0x1D6E5, " 0394"), - (0x1D6E6, " 0395"), - (0x1D6E7, " 0396"), - (0x1D6E8, " 0397"), - (0x1D6E9, " 0398"), - (0x1D6EA, " 0399"), - (0x1D6EB, " 039A"), - (0x1D6EC, " 039B"), - (0x1D6ED, " 039C"), - (0x1D6EE, " 039D"), - (0x1D6EF, " 039E"), - (0x1D6F0, " 039F"), - (0x1D6F1, " 03A0"), - (0x1D6F2, " 03A1"), - (0x1D6F3, " 03F4"), - (0x1D6F4, " 03A3"), - (0x1D6F5, " 03A4"), - (0x1D6F6, " 03A5"), - (0x1D6F7, " 03A6"), - (0x1D6F8, " 03A7"), - (0x1D6F9, " 03A8"), - (0x1D6FA, " 03A9"), - (0x1D6FB, " 2207"), - (0x1D6FC, " 03B1"), - (0x1D6FD, " 03B2"), - (0x1D6FE, " 03B3"), - (0x1D6FF, " 03B4"), - (0x1D700, " 03B5"), - (0x1D701, " 03B6"), - (0x1D702, " 03B7"), - (0x1D703, " 03B8"), - (0x1D704, " 03B9"), - (0x1D705, " 03BA"), - (0x1D706, " 03BB"), - (0x1D707, " 03BC"), - (0x1D708, " 03BD"), - (0x1D709, " 03BE"), - (0x1D70A, " 03BF"), - (0x1D70B, " 03C0"), - (0x1D70C, " 03C1"), - (0x1D70D, " 03C2"), - (0x1D70E, " 03C3"), - (0x1D70F, " 03C4"), - (0x1D710, " 03C5"), - (0x1D711, " 03C6"), - (0x1D712, " 03C7"), - (0x1D713, " 03C8"), - (0x1D714, " 03C9"), - (0x1D715, " 2202"), - (0x1D716, " 03F5"), - (0x1D717, " 03D1"), - (0x1D718, " 03F0"), - (0x1D719, " 03D5"), - (0x1D71A, " 03F1"), - (0x1D71B, " 03D6"), - (0x1D71C, " 0391"), - (0x1D71D, " 0392"), - (0x1D71E, " 0393"), - (0x1D71F, " 0394"), - (0x1D720, " 0395"), - (0x1D721, " 0396"), - (0x1D722, " 0397"), - (0x1D723, " 0398"), - (0x1D724, " 0399"), - (0x1D725, " 039A"), - (0x1D726, " 039B"), - (0x1D727, " 039C"), - (0x1D728, " 039D"), - (0x1D729, " 039E"), - (0x1D72A, " 039F"), - (0x1D72B, " 03A0"), - (0x1D72C, " 03A1"), - (0x1D72D, " 03F4"), - (0x1D72E, " 03A3"), - (0x1D72F, " 03A4"), - (0x1D730, " 03A5"), - (0x1D731, " 03A6"), - (0x1D732, " 03A7"), - (0x1D733, " 03A8"), - (0x1D734, " 03A9"), - (0x1D735, " 2207"), - (0x1D736, " 03B1"), - (0x1D737, " 03B2"), - (0x1D738, " 03B3"), - (0x1D739, " 03B4"), - (0x1D73A, " 03B5"), - (0x1D73B, " 03B6"), - (0x1D73C, " 03B7"), - (0x1D73D, " 03B8"), - (0x1D73E, " 03B9"), - (0x1D73F, " 03BA"), - (0x1D740, " 03BB"), - (0x1D741, " 03BC"), - (0x1D742, " 03BD"), - (0x1D743, " 03BE"), - (0x1D744, " 03BF"), - (0x1D745, " 03C0"), - (0x1D746, " 03C1"), - (0x1D747, " 03C2"), - (0x1D748, " 03C3"), - (0x1D749, " 03C4"), - (0x1D74A, " 03C5"), - (0x1D74B, " 03C6"), - (0x1D74C, " 03C7"), - (0x1D74D, " 03C8"), - (0x1D74E, " 03C9"), - (0x1D74F, " 2202"), - (0x1D750, " 03F5"), - (0x1D751, " 03D1"), - (0x1D752, " 03F0"), - (0x1D753, " 03D5"), - (0x1D754, " 03F1"), - (0x1D755, " 03D6"), - (0x1D756, " 0391"), - (0x1D757, " 0392"), - (0x1D758, " 0393"), - (0x1D759, " 0394"), - (0x1D75A, " 0395"), - (0x1D75B, " 0396"), - (0x1D75C, " 0397"), - (0x1D75D, " 0398"), - (0x1D75E, " 0399"), - (0x1D75F, " 039A"), - (0x1D760, " 039B"), - (0x1D761, " 039C"), - (0x1D762, " 039D"), - (0x1D763, " 039E"), - (0x1D764, " 039F"), - (0x1D765, " 03A0"), - (0x1D766, " 03A1"), - (0x1D767, " 03F4"), - (0x1D768, " 03A3"), - (0x1D769, " 03A4"), - (0x1D76A, " 03A5"), - (0x1D76B, " 03A6"), - (0x1D76C, " 03A7"), - (0x1D76D, " 03A8"), - (0x1D76E, " 03A9"), - (0x1D76F, " 2207"), - (0x1D770, " 03B1"), - (0x1D771, " 03B2"), - (0x1D772, " 03B3"), - (0x1D773, " 03B4"), - (0x1D774, " 03B5"), - (0x1D775, " 03B6"), - (0x1D776, " 03B7"), - (0x1D777, " 03B8"), - (0x1D778, " 03B9"), - (0x1D779, " 03BA"), - (0x1D77A, " 03BB"), - (0x1D77B, " 03BC"), - (0x1D77C, " 03BD"), - (0x1D77D, " 03BE"), - (0x1D77E, " 03BF"), - (0x1D77F, " 03C0"), - (0x1D780, " 03C1"), - (0x1D781, " 03C2"), - (0x1D782, " 03C3"), - (0x1D783, " 03C4"), - (0x1D784, " 03C5"), - (0x1D785, " 03C6"), - (0x1D786, " 03C7"), - (0x1D787, " 03C8"), - (0x1D788, " 03C9"), - (0x1D789, " 2202"), - (0x1D78A, " 03F5"), - (0x1D78B, " 03D1"), - (0x1D78C, " 03F0"), - (0x1D78D, " 03D5"), - (0x1D78E, " 03F1"), - (0x1D78F, " 03D6"), - (0x1D790, " 0391"), - (0x1D791, " 0392"), - (0x1D792, " 0393"), - (0x1D793, " 0394"), - (0x1D794, " 0395"), - (0x1D795, " 0396"), - (0x1D796, " 0397"), - (0x1D797, " 0398"), - (0x1D798, " 0399"), - (0x1D799, " 039A"), - (0x1D79A, " 039B"), - (0x1D79B, " 039C"), - (0x1D79C, " 039D"), - (0x1D79D, " 039E"), - (0x1D79E, " 039F"), - (0x1D79F, " 03A0"), - (0x1D7A0, " 03A1"), - (0x1D7A1, " 03F4"), - (0x1D7A2, " 03A3"), - (0x1D7A3, " 03A4"), - (0x1D7A4, " 03A5"), - (0x1D7A5, " 03A6"), - (0x1D7A6, " 03A7"), - (0x1D7A7, " 03A8"), - (0x1D7A8, " 03A9"), - (0x1D7A9, " 2207"), - (0x1D7AA, " 03B1"), - (0x1D7AB, " 03B2"), - (0x1D7AC, " 03B3"), - (0x1D7AD, " 03B4"), - (0x1D7AE, " 03B5"), - (0x1D7AF, " 03B6"), - (0x1D7B0, " 03B7"), - (0x1D7B1, " 03B8"), - (0x1D7B2, " 03B9"), - (0x1D7B3, " 03BA"), - (0x1D7B4, " 03BB"), - (0x1D7B5, " 03BC"), - (0x1D7B6, " 03BD"), - (0x1D7B7, " 03BE"), - (0x1D7B8, " 03BF"), - (0x1D7B9, " 03C0"), - (0x1D7BA, " 03C1"), - (0x1D7BB, " 03C2"), - (0x1D7BC, " 03C3"), - (0x1D7BD, " 03C4"), - (0x1D7BE, " 03C5"), - (0x1D7BF, " 03C6"), - (0x1D7C0, " 03C7"), - (0x1D7C1, " 03C8"), - (0x1D7C2, " 03C9"), - (0x1D7C3, " 2202"), - (0x1D7C4, " 03F5"), - (0x1D7C5, " 03D1"), - (0x1D7C6, " 03F0"), - (0x1D7C7, " 03D5"), - (0x1D7C8, " 03F1"), - (0x1D7C9, " 03D6"), - (0x1D7CA, " 03DC"), - (0x1D7CB, " 03DD"), - (0x1D7CE, " 0030"), - (0x1D7CF, " 0031"), - (0x1D7D0, " 0032"), - (0x1D7D1, " 0033"), - (0x1D7D2, " 0034"), - (0x1D7D3, " 0035"), - (0x1D7D4, " 0036"), - (0x1D7D5, " 0037"), - (0x1D7D6, " 0038"), - (0x1D7D7, " 0039"), - (0x1D7D8, " 0030"), - (0x1D7D9, " 0031"), - (0x1D7DA, " 0032"), - (0x1D7DB, " 0033"), - (0x1D7DC, " 0034"), - (0x1D7DD, " 0035"), - (0x1D7DE, " 0036"), - (0x1D7DF, " 0037"), - (0x1D7E0, " 0038"), - (0x1D7E1, " 0039"), - (0x1D7E2, " 0030"), - (0x1D7E3, " 0031"), - (0x1D7E4, " 0032"), - (0x1D7E5, " 0033"), - (0x1D7E6, " 0034"), - (0x1D7E7, " 0035"), - (0x1D7E8, " 0036"), - (0x1D7E9, " 0037"), - (0x1D7EA, " 0038"), - (0x1D7EB, " 0039"), - (0x1D7EC, " 0030"), - (0x1D7ED, " 0031"), - (0x1D7EE, " 0032"), - (0x1D7EF, " 0033"), - (0x1D7F0, " 0034"), - (0x1D7F1, " 0035"), - (0x1D7F2, " 0036"), - (0x1D7F3, " 0037"), - (0x1D7F4, " 0038"), - (0x1D7F5, " 0039"), - (0x1D7F6, " 0030"), - (0x1D7F7, " 0031"), - (0x1D7F8, " 0032"), - (0x1D7F9, " 0033"), - (0x1D7FA, " 0034"), - (0x1D7FB, " 0035"), - (0x1D7FC, " 0036"), - (0x1D7FD, " 0037"), - (0x1D7FE, " 0038"), - (0x1D7FF, " 0039"), - (0x1E030, " 0430"), - (0x1E031, " 0431"), - (0x1E032, " 0432"), - (0x1E033, " 0433"), - (0x1E034, " 0434"), - (0x1E035, " 0435"), - (0x1E036, " 0436"), - (0x1E037, " 0437"), - (0x1E038, " 0438"), - (0x1E039, " 043A"), - (0x1E03A, " 043B"), - (0x1E03B, " 043C"), - (0x1E03C, " 043E"), - (0x1E03D, " 043F"), - (0x1E03E, " 0440"), - (0x1E03F, " 0441"), - (0x1E040, " 0442"), - (0x1E041, " 0443"), - (0x1E042, " 0444"), - (0x1E043, " 0445"), - (0x1E044, " 0446"), - (0x1E045, " 0447"), - (0x1E046, " 0448"), - (0x1E047, " 044B"), - (0x1E048, " 044D"), - (0x1E049, " 044E"), - (0x1E04A, " A689"), - (0x1E04B, " 04D9"), - (0x1E04C, " 0456"), - (0x1E04D, " 0458"), - (0x1E04E, " 04E9"), - (0x1E04F, " 04AF"), - (0x1E050, " 04CF"), - (0x1E051, " 0430"), - (0x1E052, " 0431"), - (0x1E053, " 0432"), - (0x1E054, " 0433"), - (0x1E055, " 0434"), - (0x1E056, " 0435"), - (0x1E057, " 0436"), - (0x1E058, " 0437"), - (0x1E059, " 0438"), - (0x1E05A, " 043A"), - (0x1E05B, " 043B"), - (0x1E05C, " 043E"), - (0x1E05D, " 043F"), - (0x1E05E, " 0441"), - (0x1E05F, " 0443"), - (0x1E060, " 0444"), - (0x1E061, " 0445"), - (0x1E062, " 0446"), - (0x1E063, " 0447"), - (0x1E064, " 0448"), - (0x1E065, " 044A"), - (0x1E066, " 044B"), - (0x1E067, " 0491"), - (0x1E068, " 0456"), - (0x1E069, " 0455"), - (0x1E06A, " 045F"), - (0x1E06B, " 04AB"), - (0x1E06C, " A651"), - (0x1E06D, " 04B1"), - (0x1EE00, " 0627"), - (0x1EE01, " 0628"), - (0x1EE02, " 062C"), - (0x1EE03, " 062F"), - (0x1EE05, " 0648"), - (0x1EE06, " 0632"), - (0x1EE07, " 062D"), - (0x1EE08, " 0637"), - (0x1EE09, " 064A"), - (0x1EE0A, " 0643"), - (0x1EE0B, " 0644"), - (0x1EE0C, " 0645"), - (0x1EE0D, " 0646"), - (0x1EE0E, " 0633"), - (0x1EE0F, " 0639"), - (0x1EE10, " 0641"), - (0x1EE11, " 0635"), - (0x1EE12, " 0642"), - (0x1EE13, " 0631"), - (0x1EE14, " 0634"), - (0x1EE15, " 062A"), - (0x1EE16, " 062B"), - (0x1EE17, " 062E"), - (0x1EE18, " 0630"), - (0x1EE19, " 0636"), - (0x1EE1A, " 0638"), - (0x1EE1B, " 063A"), - (0x1EE1C, " 066E"), - (0x1EE1D, " 06BA"), - (0x1EE1E, " 06A1"), - (0x1EE1F, " 066F"), - (0x1EE21, " 0628"), - (0x1EE22, " 062C"), - (0x1EE24, " 0647"), - (0x1EE27, " 062D"), - (0x1EE29, " 064A"), - (0x1EE2A, " 0643"), - (0x1EE2B, " 0644"), - (0x1EE2C, " 0645"), - (0x1EE2D, " 0646"), - (0x1EE2E, " 0633"), - (0x1EE2F, " 0639"), - (0x1EE30, " 0641"), - (0x1EE31, " 0635"), - (0x1EE32, " 0642"), - (0x1EE34, " 0634"), - (0x1EE35, " 062A"), - (0x1EE36, " 062B"), - (0x1EE37, " 062E"), - (0x1EE39, " 0636"), - (0x1EE3B, " 063A"), - (0x1EE42, " 062C"), - (0x1EE47, " 062D"), - (0x1EE49, " 064A"), - (0x1EE4B, " 0644"), - (0x1EE4D, " 0646"), - (0x1EE4E, " 0633"), - (0x1EE4F, " 0639"), - (0x1EE51, " 0635"), - (0x1EE52, " 0642"), - (0x1EE54, " 0634"), - (0x1EE57, " 062E"), - (0x1EE59, " 0636"), - (0x1EE5B, " 063A"), - (0x1EE5D, " 06BA"), - (0x1EE5F, " 066F"), - (0x1EE61, " 0628"), - (0x1EE62, " 062C"), - (0x1EE64, " 0647"), - (0x1EE67, " 062D"), - (0x1EE68, " 0637"), - (0x1EE69, " 064A"), - (0x1EE6A, " 0643"), - (0x1EE6C, " 0645"), - (0x1EE6D, " 0646"), - (0x1EE6E, " 0633"), - (0x1EE6F, " 0639"), - (0x1EE70, " 0641"), - (0x1EE71, " 0635"), - (0x1EE72, " 0642"), - (0x1EE74, " 0634"), - (0x1EE75, " 062A"), - (0x1EE76, " 062B"), - (0x1EE77, " 062E"), - (0x1EE79, " 0636"), - (0x1EE7A, " 0638"), - (0x1EE7B, " 063A"), - (0x1EE7C, " 066E"), - (0x1EE7E, " 06A1"), - (0x1EE80, " 0627"), - (0x1EE81, " 0628"), - (0x1EE82, " 062C"), - (0x1EE83, " 062F"), - (0x1EE84, " 0647"), - (0x1EE85, " 0648"), - (0x1EE86, " 0632"), - (0x1EE87, " 062D"), - (0x1EE88, " 0637"), - (0x1EE89, " 064A"), - (0x1EE8B, " 0644"), - (0x1EE8C, " 0645"), - (0x1EE8D, " 0646"), - (0x1EE8E, " 0633"), - (0x1EE8F, " 0639"), - (0x1EE90, " 0641"), - (0x1EE91, " 0635"), - (0x1EE92, " 0642"), - (0x1EE93, " 0631"), - (0x1EE94, " 0634"), - (0x1EE95, " 062A"), - (0x1EE96, " 062B"), - (0x1EE97, " 062E"), - (0x1EE98, " 0630"), - (0x1EE99, " 0636"), - (0x1EE9A, " 0638"), - (0x1EE9B, " 063A"), - (0x1EEA1, " 0628"), - (0x1EEA2, " 062C"), - (0x1EEA3, " 062F"), - (0x1EEA5, " 0648"), - (0x1EEA6, " 0632"), - (0x1EEA7, " 062D"), - (0x1EEA8, " 0637"), - (0x1EEA9, " 064A"), - (0x1EEAB, " 0644"), - (0x1EEAC, " 0645"), - (0x1EEAD, " 0646"), - (0x1EEAE, " 0633"), - (0x1EEAF, " 0639"), - (0x1EEB0, " 0641"), - (0x1EEB1, " 0635"), - (0x1EEB2, " 0642"), - (0x1EEB3, " 0631"), - (0x1EEB4, " 0634"), - (0x1EEB5, " 062A"), - (0x1EEB6, " 062B"), - (0x1EEB7, " 062E"), - (0x1EEB8, " 0630"), - (0x1EEB9, " 0636"), - (0x1EEBA, " 0638"), - (0x1EEBB, " 063A"), - (0x1F100, " 0030 002E"), - (0x1F101, " 0030 002C"), - (0x1F102, " 0031 002C"), - (0x1F103, " 0032 002C"), - (0x1F104, " 0033 002C"), - (0x1F105, " 0034 002C"), - (0x1F106, " 0035 002C"), - (0x1F107, " 0036 002C"), - (0x1F108, " 0037 002C"), - (0x1F109, " 0038 002C"), - (0x1F10A, " 0039 002C"), - (0x1F110, " 0028 0041 0029"), - (0x1F111, " 0028 0042 0029"), - (0x1F112, " 0028 0043 0029"), - (0x1F113, " 0028 0044 0029"), - (0x1F114, " 0028 0045 0029"), - (0x1F115, " 0028 0046 0029"), - (0x1F116, " 0028 0047 0029"), - (0x1F117, " 0028 0048 0029"), - (0x1F118, " 0028 0049 0029"), - (0x1F119, " 0028 004A 0029"), - (0x1F11A, " 0028 004B 0029"), - (0x1F11B, " 0028 004C 0029"), - (0x1F11C, " 0028 004D 0029"), - (0x1F11D, " 0028 004E 0029"), - (0x1F11E, " 0028 004F 0029"), - (0x1F11F, " 0028 0050 0029"), - (0x1F120, " 0028 0051 0029"), - (0x1F121, " 0028 0052 0029"), - (0x1F122, " 0028 0053 0029"), - (0x1F123, " 0028 0054 0029"), - (0x1F124, " 0028 0055 0029"), - (0x1F125, " 0028 0056 0029"), - (0x1F126, " 0028 0057 0029"), - (0x1F127, " 0028 0058 0029"), - (0x1F128, " 0028 0059 0029"), - (0x1F129, " 0028 005A 0029"), - (0x1F12A, " 3014 0053 3015"), - (0x1F12B, " 0043"), - (0x1F12C, " 0052"), - (0x1F12D, " 0043 0044"), - (0x1F12E, " 0057 005A"), - (0x1F130, " 0041"), - (0x1F131, " 0042"), - (0x1F132, " 0043"), - (0x1F133, " 0044"), - (0x1F134, " 0045"), - (0x1F135, " 0046"), - (0x1F136, " 0047"), - (0x1F137, " 0048"), - (0x1F138, " 0049"), - (0x1F139, " 004A"), - (0x1F13A, " 004B"), - (0x1F13B, " 004C"), - (0x1F13C, " 004D"), - (0x1F13D, " 004E"), - (0x1F13E, " 004F"), - (0x1F13F, " 0050"), - (0x1F140, " 0051"), - (0x1F141, " 0052"), - (0x1F142, " 0053"), - (0x1F143, " 0054"), - (0x1F144, " 0055"), - (0x1F145, " 0056"), - (0x1F146, " 0057"), - (0x1F147, " 0058"), - (0x1F148, " 0059"), - (0x1F149, " 005A"), - (0x1F14A, " 0048 0056"), - (0x1F14B, " 004D 0056"), - (0x1F14C, " 0053 0044"), - (0x1F14D, " 0053 0053"), - (0x1F14E, " 0050 0050 0056"), - (0x1F14F, " 0057 0043"), - (0x1F16A, " 004D 0043"), - (0x1F16B, " 004D 0044"), - (0x1F16C, " 004D 0052"), - (0x1F190, " 0044 004A"), - (0x1F200, " 307B 304B"), - (0x1F201, " 30B3 30B3"), - (0x1F202, " 30B5"), - (0x1F210, " 624B"), - (0x1F211, " 5B57"), - (0x1F212, " 53CC"), - (0x1F213, " 30C7"), - (0x1F214, " 4E8C"), - (0x1F215, " 591A"), - (0x1F216, " 89E3"), - (0x1F217, " 5929"), - (0x1F218, " 4EA4"), - (0x1F219, " 6620"), - (0x1F21A, " 7121"), - (0x1F21B, " 6599"), - (0x1F21C, " 524D"), - (0x1F21D, " 5F8C"), - (0x1F21E, " 518D"), - (0x1F21F, " 65B0"), - (0x1F220, " 521D"), - (0x1F221, " 7D42"), - (0x1F222, " 751F"), - (0x1F223, " 8CA9"), - (0x1F224, " 58F0"), - (0x1F225, " 5439"), - (0x1F226, " 6F14"), - (0x1F227, " 6295"), - (0x1F228, " 6355"), - (0x1F229, " 4E00"), - (0x1F22A, " 4E09"), - (0x1F22B, " 904A"), - (0x1F22C, " 5DE6"), - (0x1F22D, " 4E2D"), - (0x1F22E, " 53F3"), - (0x1F22F, " 6307"), - (0x1F230, " 8D70"), - (0x1F231, " 6253"), - (0x1F232, " 7981"), - (0x1F233, " 7A7A"), - (0x1F234, " 5408"), - (0x1F235, " 6E80"), - (0x1F236, " 6709"), - (0x1F237, " 6708"), - (0x1F238, " 7533"), - (0x1F239, " 5272"), - (0x1F23A, " 55B6"), - (0x1F23B, " 914D"), - (0x1F240, " 3014 672C 3015"), - (0x1F241, " 3014 4E09 3015"), - (0x1F242, " 3014 4E8C 3015"), - (0x1F243, " 3014 5B89 3015"), - (0x1F244, " 3014 70B9 3015"), - (0x1F245, " 3014 6253 3015"), - (0x1F246, " 3014 76D7 3015"), - (0x1F247, " 3014 52DD 3015"), - (0x1F248, " 3014 6557 3015"), - (0x1F250, " 5F97"), - (0x1F251, " 53EF"), - (0x1FBF0, " 0030"), - (0x1FBF1, " 0031"), - (0x1FBF2, " 0032"), - (0x1FBF3, " 0033"), - (0x1FBF4, " 0034"), - (0x1FBF5, " 0035"), - (0x1FBF6, " 0036"), - (0x1FBF7, " 0037"), - (0x1FBF8, " 0038"), - (0x1FBF9, " 0039"), - (0x2F800, "4E3D"), - (0x2F801, "4E38"), - (0x2F802, "4E41"), - (0x2F803, "20122"), - (0x2F804, "4F60"), - (0x2F805, "4FAE"), - (0x2F806, "4FBB"), - (0x2F807, "5002"), - (0x2F808, "507A"), - (0x2F809, "5099"), - (0x2F80A, "50E7"), - (0x2F80B, "50CF"), - (0x2F80C, "349E"), - (0x2F80D, "2063A"), - (0x2F80E, "514D"), - (0x2F80F, "5154"), - (0x2F810, "5164"), - (0x2F811, "5177"), - (0x2F812, "2051C"), - (0x2F813, "34B9"), - (0x2F814, "5167"), - (0x2F815, "518D"), - (0x2F816, "2054B"), - (0x2F817, "5197"), - (0x2F818, "51A4"), - (0x2F819, "4ECC"), - (0x2F81A, "51AC"), - (0x2F81B, "51B5"), - (0x2F81C, "291DF"), - (0x2F81D, "51F5"), - (0x2F81E, "5203"), - (0x2F81F, "34DF"), - (0x2F820, "523B"), - (0x2F821, "5246"), - (0x2F822, "5272"), - (0x2F823, "5277"), - (0x2F824, "3515"), - (0x2F825, "52C7"), - (0x2F826, "52C9"), - (0x2F827, "52E4"), - (0x2F828, "52FA"), - (0x2F829, "5305"), - (0x2F82A, "5306"), - (0x2F82B, "5317"), - (0x2F82C, "5349"), - (0x2F82D, "5351"), - (0x2F82E, "535A"), - (0x2F82F, "5373"), - (0x2F830, "537D"), - (0x2F831, "537F"), - (0x2F832, "537F"), - (0x2F833, "537F"), - (0x2F834, "20A2C"), - (0x2F835, "7070"), - (0x2F836, "53CA"), - (0x2F837, "53DF"), - (0x2F838, "20B63"), - (0x2F839, "53EB"), - (0x2F83A, "53F1"), - (0x2F83B, "5406"), - (0x2F83C, "549E"), - (0x2F83D, "5438"), - (0x2F83E, "5448"), - (0x2F83F, "5468"), - (0x2F840, "54A2"), - (0x2F841, "54F6"), - (0x2F842, "5510"), - (0x2F843, "5553"), - (0x2F844, "5563"), - (0x2F845, "5584"), - (0x2F846, "5584"), - (0x2F847, "5599"), - (0x2F848, "55AB"), - (0x2F849, "55B3"), - (0x2F84A, "55C2"), - (0x2F84B, "5716"), - (0x2F84C, "5606"), - (0x2F84D, "5717"), - (0x2F84E, "5651"), - (0x2F84F, "5674"), - (0x2F850, "5207"), - (0x2F851, "58EE"), - (0x2F852, "57CE"), - (0x2F853, "57F4"), - (0x2F854, "580D"), - (0x2F855, "578B"), - (0x2F856, "5832"), - (0x2F857, "5831"), - (0x2F858, "58AC"), - (0x2F859, "214E4"), - (0x2F85A, "58F2"), - (0x2F85B, "58F7"), - (0x2F85C, "5906"), - (0x2F85D, "591A"), - (0x2F85E, "5922"), - (0x2F85F, "5962"), - (0x2F860, "216A8"), - (0x2F861, "216EA"), - (0x2F862, "59EC"), - (0x2F863, "5A1B"), - (0x2F864, "5A27"), - (0x2F865, "59D8"), - (0x2F866, "5A66"), - (0x2F867, "36EE"), - (0x2F868, "36FC"), - (0x2F869, "5B08"), - (0x2F86A, "5B3E"), - (0x2F86B, "5B3E"), - (0x2F86C, "219C8"), - (0x2F86D, "5BC3"), - (0x2F86E, "5BD8"), - (0x2F86F, "5BE7"), - (0x2F870, "5BF3"), - (0x2F871, "21B18"), - (0x2F872, "5BFF"), - (0x2F873, "5C06"), - (0x2F874, "5F53"), - (0x2F875, "5C22"), - (0x2F876, "3781"), - (0x2F877, "5C60"), - (0x2F878, "5C6E"), - (0x2F879, "5CC0"), - (0x2F87A, "5C8D"), - (0x2F87B, "21DE4"), - (0x2F87C, "5D43"), - (0x2F87D, "21DE6"), - (0x2F87E, "5D6E"), - (0x2F87F, "5D6B"), - (0x2F880, "5D7C"), - (0x2F881, "5DE1"), - (0x2F882, "5DE2"), - (0x2F883, "382F"), - (0x2F884, "5DFD"), - (0x2F885, "5E28"), - (0x2F886, "5E3D"), - (0x2F887, "5E69"), - (0x2F888, "3862"), - (0x2F889, "22183"), - (0x2F88A, "387C"), - (0x2F88B, "5EB0"), - (0x2F88C, "5EB3"), - (0x2F88D, "5EB6"), - (0x2F88E, "5ECA"), - (0x2F88F, "2A392"), - (0x2F890, "5EFE"), - (0x2F891, "22331"), - (0x2F892, "22331"), - (0x2F893, "8201"), - (0x2F894, "5F22"), - (0x2F895, "5F22"), - (0x2F896, "38C7"), - (0x2F897, "232B8"), - (0x2F898, "261DA"), - (0x2F899, "5F62"), - (0x2F89A, "5F6B"), - (0x2F89B, "38E3"), - (0x2F89C, "5F9A"), - (0x2F89D, "5FCD"), - (0x2F89E, "5FD7"), - (0x2F89F, "5FF9"), - (0x2F8A0, "6081"), - (0x2F8A1, "393A"), - (0x2F8A2, "391C"), - (0x2F8A3, "6094"), - (0x2F8A4, "226D4"), - (0x2F8A5, "60C7"), - (0x2F8A6, "6148"), - (0x2F8A7, "614C"), - (0x2F8A8, "614E"), - (0x2F8A9, "614C"), - (0x2F8AA, "617A"), - (0x2F8AB, "618E"), - (0x2F8AC, "61B2"), - (0x2F8AD, "61A4"), - (0x2F8AE, "61AF"), - (0x2F8AF, "61DE"), - (0x2F8B0, "61F2"), - (0x2F8B1, "61F6"), - (0x2F8B2, "6210"), - (0x2F8B3, "621B"), - (0x2F8B4, "625D"), - (0x2F8B5, "62B1"), - (0x2F8B6, "62D4"), - (0x2F8B7, "6350"), - (0x2F8B8, "22B0C"), - (0x2F8B9, "633D"), - (0x2F8BA, "62FC"), - (0x2F8BB, "6368"), - (0x2F8BC, "6383"), - (0x2F8BD, "63E4"), - (0x2F8BE, "22BF1"), - (0x2F8BF, "6422"), - (0x2F8C0, "63C5"), - (0x2F8C1, "63A9"), - (0x2F8C2, "3A2E"), - (0x2F8C3, "6469"), - (0x2F8C4, "647E"), - (0x2F8C5, "649D"), - (0x2F8C6, "6477"), - (0x2F8C7, "3A6C"), - (0x2F8C8, "654F"), - (0x2F8C9, "656C"), - (0x2F8CA, "2300A"), - (0x2F8CB, "65E3"), - (0x2F8CC, "66F8"), - (0x2F8CD, "6649"), - (0x2F8CE, "3B19"), - (0x2F8CF, "6691"), - (0x2F8D0, "3B08"), - (0x2F8D1, "3AE4"), - (0x2F8D2, "5192"), - (0x2F8D3, "5195"), - (0x2F8D4, "6700"), - (0x2F8D5, "669C"), - (0x2F8D6, "80AD"), - (0x2F8D7, "43D9"), - (0x2F8D8, "6717"), - (0x2F8D9, "671B"), - (0x2F8DA, "6721"), - (0x2F8DB, "675E"), - (0x2F8DC, "6753"), - (0x2F8DD, "233C3"), - (0x2F8DE, "3B49"), - (0x2F8DF, "67FA"), - (0x2F8E0, "6785"), - (0x2F8E1, "6852"), - (0x2F8E2, "6885"), - (0x2F8E3, "2346D"), - (0x2F8E4, "688E"), - (0x2F8E5, "681F"), - (0x2F8E6, "6914"), - (0x2F8E7, "3B9D"), - (0x2F8E8, "6942"), - (0x2F8E9, "69A3"), - (0x2F8EA, "69EA"), - (0x2F8EB, "6AA8"), - (0x2F8EC, "236A3"), - (0x2F8ED, "6ADB"), - (0x2F8EE, "3C18"), - (0x2F8EF, "6B21"), - (0x2F8F0, "238A7"), - (0x2F8F1, "6B54"), - (0x2F8F2, "3C4E"), - (0x2F8F3, "6B72"), - (0x2F8F4, "6B9F"), - (0x2F8F5, "6BBA"), - (0x2F8F6, "6BBB"), - (0x2F8F7, "23A8D"), - (0x2F8F8, "21D0B"), - (0x2F8F9, "23AFA"), - (0x2F8FA, "6C4E"), - (0x2F8FB, "23CBC"), - (0x2F8FC, "6CBF"), - (0x2F8FD, "6CCD"), - (0x2F8FE, "6C67"), - (0x2F8FF, "6D16"), - (0x2F900, "6D3E"), - (0x2F901, "6D77"), - (0x2F902, "6D41"), - (0x2F903, "6D69"), - (0x2F904, "6D78"), - (0x2F905, "6D85"), - (0x2F906, "23D1E"), - (0x2F907, "6D34"), - (0x2F908, "6E2F"), - (0x2F909, "6E6E"), - (0x2F90A, "3D33"), - (0x2F90B, "6ECB"), - (0x2F90C, "6EC7"), - (0x2F90D, "23ED1"), - (0x2F90E, "6DF9"), - (0x2F90F, "6F6E"), - (0x2F910, "23F5E"), - (0x2F911, "23F8E"), - (0x2F912, "6FC6"), - (0x2F913, "7039"), - (0x2F914, "701E"), - (0x2F915, "701B"), - (0x2F916, "3D96"), - (0x2F917, "704A"), - (0x2F918, "707D"), - (0x2F919, "7077"), - (0x2F91A, "70AD"), - (0x2F91B, "20525"), - (0x2F91C, "7145"), - (0x2F91D, "24263"), - (0x2F91E, "719C"), - (0x2F91F, "243AB"), - (0x2F920, "7228"), - (0x2F921, "7235"), - (0x2F922, "7250"), - (0x2F923, "24608"), - (0x2F924, "7280"), - (0x2F925, "7295"), - (0x2F926, "24735"), - (0x2F927, "24814"), - (0x2F928, "737A"), - (0x2F929, "738B"), - (0x2F92A, "3EAC"), - (0x2F92B, "73A5"), - (0x2F92C, "3EB8"), - (0x2F92D, "3EB8"), - (0x2F92E, "7447"), - (0x2F92F, "745C"), - (0x2F930, "7471"), - (0x2F931, "7485"), - (0x2F932, "74CA"), - (0x2F933, "3F1B"), - (0x2F934, "7524"), - (0x2F935, "24C36"), - (0x2F936, "753E"), - (0x2F937, "24C92"), - (0x2F938, "7570"), - (0x2F939, "2219F"), - (0x2F93A, "7610"), - (0x2F93B, "24FA1"), - (0x2F93C, "24FB8"), - (0x2F93D, "25044"), - (0x2F93E, "3FFC"), - (0x2F93F, "4008"), - (0x2F940, "76F4"), - (0x2F941, "250F3"), - (0x2F942, "250F2"), - (0x2F943, "25119"), - (0x2F944, "25133"), - (0x2F945, "771E"), - (0x2F946, "771F"), - (0x2F947, "771F"), - (0x2F948, "774A"), - (0x2F949, "4039"), - (0x2F94A, "778B"), - (0x2F94B, "4046"), - (0x2F94C, "4096"), - (0x2F94D, "2541D"), - (0x2F94E, "784E"), - (0x2F94F, "788C"), - (0x2F950, "78CC"), - (0x2F951, "40E3"), - (0x2F952, "25626"), - (0x2F953, "7956"), - (0x2F954, "2569A"), - (0x2F955, "256C5"), - (0x2F956, "798F"), - (0x2F957, "79EB"), - (0x2F958, "412F"), - (0x2F959, "7A40"), - (0x2F95A, "7A4A"), - (0x2F95B, "7A4F"), - (0x2F95C, "2597C"), - (0x2F95D, "25AA7"), - (0x2F95E, "25AA7"), - (0x2F95F, "7AEE"), - (0x2F960, "4202"), - (0x2F961, "25BAB"), - (0x2F962, "7BC6"), - (0x2F963, "7BC9"), - (0x2F964, "4227"), - (0x2F965, "25C80"), - (0x2F966, "7CD2"), - (0x2F967, "42A0"), - (0x2F968, "7CE8"), - (0x2F969, "7CE3"), - (0x2F96A, "7D00"), - (0x2F96B, "25F86"), - (0x2F96C, "7D63"), - (0x2F96D, "4301"), - (0x2F96E, "7DC7"), - (0x2F96F, "7E02"), - (0x2F970, "7E45"), - (0x2F971, "4334"), - (0x2F972, "26228"), - (0x2F973, "26247"), - (0x2F974, "4359"), - (0x2F975, "262D9"), - (0x2F976, "7F7A"), - (0x2F977, "2633E"), - (0x2F978, "7F95"), - (0x2F979, "7FFA"), - (0x2F97A, "8005"), - (0x2F97B, "264DA"), - (0x2F97C, "26523"), - (0x2F97D, "8060"), - (0x2F97E, "265A8"), - (0x2F97F, "8070"), - (0x2F980, "2335F"), - (0x2F981, "43D5"), - (0x2F982, "80B2"), - (0x2F983, "8103"), - (0x2F984, "440B"), - (0x2F985, "813E"), - (0x2F986, "5AB5"), - (0x2F987, "267A7"), - (0x2F988, "267B5"), - (0x2F989, "23393"), - (0x2F98A, "2339C"), - (0x2F98B, "8201"), - (0x2F98C, "8204"), - (0x2F98D, "8F9E"), - (0x2F98E, "446B"), - (0x2F98F, "8291"), - (0x2F990, "828B"), - (0x2F991, "829D"), - (0x2F992, "52B3"), - (0x2F993, "82B1"), - (0x2F994, "82B3"), - (0x2F995, "82BD"), - (0x2F996, "82E6"), - (0x2F997, "26B3C"), - (0x2F998, "82E5"), - (0x2F999, "831D"), - (0x2F99A, "8363"), - (0x2F99B, "83AD"), - (0x2F99C, "8323"), - (0x2F99D, "83BD"), - (0x2F99E, "83E7"), - (0x2F99F, "8457"), - (0x2F9A0, "8353"), - (0x2F9A1, "83CA"), - (0x2F9A2, "83CC"), - (0x2F9A3, "83DC"), - (0x2F9A4, "26C36"), - (0x2F9A5, "26D6B"), - (0x2F9A6, "26CD5"), - (0x2F9A7, "452B"), - (0x2F9A8, "84F1"), - (0x2F9A9, "84F3"), - (0x2F9AA, "8516"), - (0x2F9AB, "273CA"), - (0x2F9AC, "8564"), - (0x2F9AD, "26F2C"), - (0x2F9AE, "455D"), - (0x2F9AF, "4561"), - (0x2F9B0, "26FB1"), - (0x2F9B1, "270D2"), - (0x2F9B2, "456B"), - (0x2F9B3, "8650"), - (0x2F9B4, "865C"), - (0x2F9B5, "8667"), - (0x2F9B6, "8669"), - (0x2F9B7, "86A9"), - (0x2F9B8, "8688"), - (0x2F9B9, "870E"), - (0x2F9BA, "86E2"), - (0x2F9BB, "8779"), - (0x2F9BC, "8728"), - (0x2F9BD, "876B"), - (0x2F9BE, "8786"), - (0x2F9BF, "45D7"), - (0x2F9C0, "87E1"), - (0x2F9C1, "8801"), - (0x2F9C2, "45F9"), - (0x2F9C3, "8860"), - (0x2F9C4, "8863"), - (0x2F9C5, "27667"), - (0x2F9C6, "88D7"), - (0x2F9C7, "88DE"), - (0x2F9C8, "4635"), - (0x2F9C9, "88FA"), - (0x2F9CA, "34BB"), - (0x2F9CB, "278AE"), - (0x2F9CC, "27966"), - (0x2F9CD, "46BE"), - (0x2F9CE, "46C7"), - (0x2F9CF, "8AA0"), - (0x2F9D0, "8AED"), - (0x2F9D1, "8B8A"), - (0x2F9D2, "8C55"), - (0x2F9D3, "27CA8"), - (0x2F9D4, "8CAB"), - (0x2F9D5, "8CC1"), - (0x2F9D6, "8D1B"), - (0x2F9D7, "8D77"), - (0x2F9D8, "27F2F"), - (0x2F9D9, "20804"), - (0x2F9DA, "8DCB"), - (0x2F9DB, "8DBC"), - (0x2F9DC, "8DF0"), - (0x2F9DD, "208DE"), - (0x2F9DE, "8ED4"), - (0x2F9DF, "8F38"), - (0x2F9E0, "285D2"), - (0x2F9E1, "285ED"), - (0x2F9E2, "9094"), - (0x2F9E3, "90F1"), - (0x2F9E4, "9111"), - (0x2F9E5, "2872E"), - (0x2F9E6, "911B"), - (0x2F9E7, "9238"), - (0x2F9E8, "92D7"), - (0x2F9E9, "92D8"), - (0x2F9EA, "927C"), - (0x2F9EB, "93F9"), - (0x2F9EC, "9415"), - (0x2F9ED, "28BFA"), - (0x2F9EE, "958B"), - (0x2F9EF, "4995"), - (0x2F9F0, "95B7"), - (0x2F9F1, "28D77"), - (0x2F9F2, "49E6"), - (0x2F9F3, "96C3"), - (0x2F9F4, "5DB2"), - (0x2F9F5, "9723"), - (0x2F9F6, "29145"), - (0x2F9F7, "2921A"), - (0x2F9F8, "4A6E"), - (0x2F9F9, "4A76"), - (0x2F9FA, "97E0"), - (0x2F9FB, "2940A"), - (0x2F9FC, "4AB2"), - (0x2F9FD, "29496"), - (0x2F9FE, "980B"), - (0x2F9FF, "980B"), - (0x2FA00, "9829"), - (0x2FA01, "295B6"), - (0x2FA02, "98E2"), - (0x2FA03, "4B33"), - (0x2FA04, "9929"), - (0x2FA05, "99A7"), - (0x2FA06, "99C2"), - (0x2FA07, "99FE"), - (0x2FA08, "4BCE"), - (0x2FA09, "29B30"), - (0x2FA0A, "9B12"), - (0x2FA0B, "9C40"), - (0x2FA0C, "9CFD"), - (0x2FA0D, "4CCE"), - (0x2FA0E, "4CED"), - (0x2FA0F, "9D67"), - (0x2FA10, "2A0CE"), - (0x2FA11, "4CF8"), - (0x2FA12, "2A105"), - (0x2FA13, "2A20E"), - (0x2FA14, "2A291"), - (0x2FA15, "9EBB"), - (0x2FA16, "4D56"), - (0x2FA17, "9EF9"), - (0x2FA18, "9EFE"), - (0x2FA19, "9F05"), - (0x2FA1A, "9F0F"), - (0x2FA1B, "9F16"), - (0x2FA1C, "9F3B"), - (0x2FA1D, "2A600"), -]; diff --git a/crates/weavepy-vm/src/stdlib/unicodedata_mod.rs b/crates/weavepy-vm/src/stdlib/unicodedata_mod.rs index 9711a87..5adcad7 100644 --- a/crates/weavepy-vm/src/stdlib/unicodedata_mod.rs +++ b/crates/weavepy-vm/src/stdlib/unicodedata_mod.rs @@ -1,37 +1,30 @@ -//! The `unicodedata` built-in module — RFC 0023. +//! The `unicodedata` built-in module — RFC 0023, rebuilt on generated +//! UCD 15.1.0 tables in RFC 0050 WS4. //! //! Mirrors CPython 3.13's `Modules/unicodedata.c` surface, backed by -//! the `unicode-properties` and `unicode-normalization` crates which -//! ship the Unicode 16.0.0 data tables. We provide: +//! `stdlib/ucd` — packed tables produced by `tools/gen_ucd_tables.py` +//! probing host CPython 3.13 (whose database *is* UCD 15.1.0), including +//! the real `ucd_3_2_0` snapshot. Every property answer, name, and +//! normalization comes from the same data CPython ships: //! -//! - `name(chr[, default])` — Unicode character name (`'LATIN SMALL LETTER A'`). -//! - `lookup(name)` — name → char. -//! - `category(chr)` — general category (`Lu`, `Ll`, `Nd`, ...). -//! - `bidirectional(chr)` — bidi class (`L`, `R`, `EN`, ...). -//! - `combining(chr)` — canonical combining class (int). -//! - `mirrored(chr)` — 0/1 mirror property. -//! - `decimal(chr[, default])` — decimal digit value or default. -//! - `digit(chr[, default])` — digit value or default. -//! - `numeric(chr[, default])` — numeric value as a float. -//! - `decomposition(chr)` — canonical decomposition string. -//! - `normalize(form, unistr)` — NFC/NFD/NFKC/NFKD normalization. -//! - `is_normalized(form, unistr)` — predicate. -//! - `east_asian_width(chr)` — `N`/`Na`/`W`/`F`/`H`/`A`. -//! - `unidata_version` — version string. -//! - `ucd_3_2_0` — historical UCD subset (we expose the same object, -//! reads of any function on it delegate to current data because the -//! 3.2.0 snapshot is mostly used to derive identifier rules — not -//! bit-perfect, but enough for `unicodedata.ucd_3_2_0.name(...)`). +//! - `name(chr[, default])` / `lookup(name)` — full name database plus the +//! algorithmic Hangul-syllable and ideograph ranges. +//! - `category`, `bidirectional`, `combining`, `mirrored`, +//! `east_asian_width` — record properties. +//! - `decimal`/`digit`/`numeric` — numeric properties with CPython's +//! ValueError defaults. +//! - `decomposition(chr)` — raw UCD decomposition text (with ``). +//! - `normalize`/`is_normalized` — NFC/NFD/NFKC/NFKD from the same tables +//! (canonical composition pairs probed with exclusions applied). +//! - `unidata_version = "15.1.0"`, `ucd_3_2_0` — the genuine 3.2.0 delta. use crate::sync::Rc; use crate::sync::RefCell; -use unicode_normalization::UnicodeNormalization; -use unicode_properties::{GeneralCategory, UnicodeGeneralCategory}; - use crate::error::{type_error, value_error, RuntimeError}; use crate::import::ModuleCache; use crate::object::{BuiltinFn, DictData, DictKey, Object, PyModule}; +use crate::stdlib::ucd; pub fn build(_cache: &ModuleCache) -> Rc { let dict = Rc::new(RefCell::new(DictData::default())); @@ -43,36 +36,37 @@ pub fn build(_cache: &ModuleCache) -> Rc { ); d.insert( DictKey(Object::from_static("__doc__")), - Object::from_static("Access to the Unicode 16.0.0 character database."), + Object::from_static( + "This module provides access to the Unicode Character Database which \ + defines character properties for all Unicode characters.", + ), ); d.insert( DictKey(Object::from_static("unidata_version")), - Object::from_static("16.0.0"), + Object::from_static("15.1.0"), ); d.insert( DictKey(Object::from_static("ucd_3_2_0")), - // Same engine — the historical snapshot is only relevant - // for identifier-validation rules in PEP 3131 era code. Object::Module(build_inner_ucd()), ); for (name, fn_) in [ ( "name", - unicodedata_name as fn(&[Object]) -> Result, + nd_name as fn(&[Object]) -> Result, ), - ("lookup", unicodedata_lookup), - ("category", unicodedata_category), - ("bidirectional", unicodedata_bidirectional), - ("combining", unicodedata_combining), - ("mirrored", unicodedata_mirrored), - ("decimal", unicodedata_decimal), - ("digit", unicodedata_digit), - ("numeric", unicodedata_numeric), - ("decomposition", unicodedata_decomposition), - ("normalize", unicodedata_normalize), - ("is_normalized", unicodedata_is_normalized), - ("east_asian_width", unicodedata_east_asian_width), + ("lookup", nd_lookup), + ("category", nd_category), + ("bidirectional", nd_bidirectional), + ("combining", nd_combining), + ("mirrored", nd_mirrored), + ("decimal", nd_decimal), + ("digit", nd_digit), + ("numeric", nd_numeric), + ("decomposition", nd_decomposition), + ("normalize", nd_normalize), + ("is_normalized", nd_is_normalized), + ("east_asian_width", nd_east_asian_width), ] { d.insert(DictKey(Object::from_static(name)), builtin(name, fn_)); } @@ -96,29 +90,27 @@ fn build_inner_ucd() -> Rc { DictKey(Object::from_static("unidata_version")), Object::from_static("3.2.0"), ); - // Expose the *same* engine functions as the top-level module. The - // historical 3.2.0 snapshot shares WeavePy's current UCD tables (not - // bit-perfect for ancient code points), but consumers like - // `stringprep`/`encodings.idna` need the full surface — - // `normalize`/`bidirectional`/`category`/… — to run IDNA nameprep at - // all (`test_httplib.test_connect_with_tunnel_idna`). + // The genuine 3.2.0 snapshot: property records probed from CPython's + // own `unicodedata.ucd_3_2_0` (change-record deltas applied), names + // filtered by the 3.2.0 assigned set. `stringprep`/`encodings.idna` + // run IDNA nameprep on exactly CPython's answers. for (name, fn_) in [ ( "name", - unicodedata_name as fn(&[Object]) -> Result, + nd_name_32 as fn(&[Object]) -> Result, ), - ("lookup", unicodedata_lookup), - ("category", unicodedata_category), - ("bidirectional", unicodedata_bidirectional), - ("combining", unicodedata_combining), - ("mirrored", unicodedata_mirrored), - ("decimal", unicodedata_decimal), - ("digit", unicodedata_digit), - ("numeric", unicodedata_numeric), - ("decomposition", unicodedata_decomposition), - ("normalize", unicodedata_normalize), - ("is_normalized", unicodedata_is_normalized), - ("east_asian_width", unicodedata_east_asian_width), + ("lookup", nd_lookup_32), + ("category", nd_category_32), + ("bidirectional", nd_bidirectional_32), + ("combining", nd_combining_32), + ("mirrored", nd_mirrored_32), + ("decimal", nd_decimal_32), + ("digit", nd_digit_32), + ("numeric", nd_numeric_32), + ("decomposition", nd_decomposition_32), + ("normalize", nd_normalize_32), + ("is_normalized", nd_is_normalized_32), + ("east_asian_width", nd_east_asian_width_32), ] { d.insert(DictKey(Object::from_static(name)), builtin(name, fn_)); } @@ -144,8 +136,7 @@ fn builtin(name: &'static str, body: fn(&[Object]) -> Result Result { match args.first() { Some(obj) if obj.is_str() => { @@ -165,44 +156,23 @@ fn first_codepoint(args: &[Object], fn_name: &str) -> Result } } -fn category_str(g: GeneralCategory) -> &'static str { - match g { - GeneralCategory::UppercaseLetter => "Lu", - GeneralCategory::LowercaseLetter => "Ll", - GeneralCategory::TitlecaseLetter => "Lt", - GeneralCategory::ModifierLetter => "Lm", - GeneralCategory::OtherLetter => "Lo", - GeneralCategory::NonspacingMark => "Mn", - GeneralCategory::SpacingMark => "Mc", - GeneralCategory::EnclosingMark => "Me", - GeneralCategory::DecimalNumber => "Nd", - GeneralCategory::LetterNumber => "Nl", - GeneralCategory::OtherNumber => "No", - GeneralCategory::ConnectorPunctuation => "Pc", - GeneralCategory::DashPunctuation => "Pd", - GeneralCategory::OpenPunctuation => "Ps", - GeneralCategory::ClosePunctuation => "Pe", - GeneralCategory::InitialPunctuation => "Pi", - GeneralCategory::FinalPunctuation => "Pf", - GeneralCategory::OtherPunctuation => "Po", - GeneralCategory::MathSymbol => "Sm", - GeneralCategory::CurrencySymbol => "Sc", - GeneralCategory::ModifierSymbol => "Sk", - GeneralCategory::OtherSymbol => "So", - GeneralCategory::SpaceSeparator => "Zs", - GeneralCategory::LineSeparator => "Zl", - GeneralCategory::ParagraphSeparator => "Zp", - GeneralCategory::Control => "Cc", - GeneralCategory::Format => "Cf", - GeneralCategory::Surrogate => "Cs", - GeneralCategory::PrivateUse => "Co", - GeneralCategory::Unassigned => "Cn", - } -} +// --------------------------------------------------------------------------- +// property functions (shared impls; thin current/3.2.0 wrappers below) +// --------------------------------------------------------------------------- -fn unicodedata_name(args: &[Object]) -> Result { +/// In the 3.2.0 snapshot, code points that were unassigned in 3.2.0 must +/// answer as unassigned even though the shared record pool is current. +/// CPython gates this on the change-record "category changed to Cn" delta, +/// which the generator bakes directly into the 3.2.0 index — so `record()` +/// already answers correctly; only `name()` needs the assigned-set filter. +fn impl_name(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "name")?; - if let Some(name) = char::from_u32(cp).and_then(char_name) { + let known = if old && !ucd::assigned_in_32(cp) { + None + } else { + ucd::name(cp) + }; + if let Some(name) = known { return Ok(Object::from_str(name)); } if let Some(default) = args.get(1) { @@ -211,99 +181,55 @@ fn unicodedata_name(args: &[Object]) -> Result { Err(value_error("no such name")) } -fn unicodedata_lookup(args: &[Object]) -> Result { +fn impl_lookup(args: &[Object], old: bool) -> Result { let name = match args.first() { Some(Object::Str(s)) => s.to_string(), _ => return Err(type_error("lookup() argument 1 must be a string")), }; - if let Some(ch) = name_to_char(&name) { - return Ok(Object::from_str(ch.to_string())); + // Aliases and named sequences resolve only against the *current* + // database (CPython's `getcode(..., with_alias_and_seq=1)` is passed 0 + // for the `ucd_3_2_0` snapshot). + let resolved = if old { + ucd::lookup(&name) + } else { + ucd::lookup_with_aliases(&name) + }; + if let Some(cp) = resolved { + if !old || ucd::assigned_in_32(cp) { + return Ok(Object::str_from_codepoints(vec![cp])); + } + } + if !old { + if let Some(cps) = ucd::lookup_named_sequence(&name) { + return Ok(Object::str_from_codepoints(cps.to_vec())); + } } Err(key_error(format!("undefined character name '{name}'"))) } -fn unicodedata_category(args: &[Object]) -> Result { +fn impl_category(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "category")?; - match char::from_u32(cp) { - Some(ch) => Ok(Object::from_static(category_str(ch.general_category()))), - // A lone surrogate (U+D800..U+DFFF) has general category `Cs`. - None => Ok(Object::from_static("Cs")), - } + Ok(Object::from_static(ucd::record(cp, old).category())) } -fn unicodedata_bidirectional(args: &[Object]) -> Result { +fn impl_bidirectional(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "bidirectional")?; - // A lone surrogate carries the default Bidi class (`L`), matching the - // `Surrogate` arm below. - let Some(ch) = char::from_u32(cp) else { - return Ok(Object::from_static("L")); - }; - // Bidi class isn't exposed by unicode-properties directly; we - // approximate the common buckets using the general category. CPython - // also returns "" for unassigned chars. - let bidi = match ch.general_category() { - GeneralCategory::UppercaseLetter - | GeneralCategory::LowercaseLetter - | GeneralCategory::TitlecaseLetter - | GeneralCategory::OtherLetter - | GeneralCategory::ModifierLetter - | GeneralCategory::DecimalNumber => "L", - GeneralCategory::EnclosingMark - | GeneralCategory::NonspacingMark - | GeneralCategory::SpacingMark => "NSM", - GeneralCategory::OtherNumber | GeneralCategory::LetterNumber => "ON", - GeneralCategory::SpaceSeparator => "WS", - GeneralCategory::LineSeparator | GeneralCategory::ParagraphSeparator => "B", - GeneralCategory::ConnectorPunctuation - | GeneralCategory::DashPunctuation - | GeneralCategory::OpenPunctuation - | GeneralCategory::ClosePunctuation - | GeneralCategory::InitialPunctuation - | GeneralCategory::FinalPunctuation - | GeneralCategory::OtherPunctuation => "ON", - GeneralCategory::MathSymbol - | GeneralCategory::CurrencySymbol - | GeneralCategory::ModifierSymbol - | GeneralCategory::OtherSymbol => "ON", - GeneralCategory::Control => match ch as u32 { - 0x0A | 0x0D | 0x1C | 0x1D | 0x1E => "B", - 0x09 | 0x0B | 0x0C => "S", - _ => "BN", - }, - GeneralCategory::Format => "BN", - GeneralCategory::Surrogate | GeneralCategory::PrivateUse => "L", - GeneralCategory::Unassigned => "", - }; - Ok(Object::from_static(bidi)) + Ok(Object::from_static(ucd::record(cp, old).bidirectional())) } -fn unicodedata_combining(args: &[Object]) -> Result { +fn impl_combining(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "combining")?; - // Canonical combining class — we use 230 for common combining - // marks (the usual default) and 0 otherwise. The full table is - // not exposed by unicode-properties; this is a pragmatic - // approximation that gets the common `unicodedata.combining` - // usage (testing for non-zero) correct. Lone surrogates are 0. - Ok(Object::Int( - match char::from_u32(cp).map(|ch| ch.general_category()) { - Some(GeneralCategory::NonspacingMark) => 230, - _ => 0, - }, - )) + Ok(Object::Int(i64::from(ucd::record(cp, old).combining()))) } -fn unicodedata_mirrored(args: &[Object]) -> Result { +fn impl_mirrored(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "mirrored")?; - let mirrored = matches!( - char::from_u32(cp), - Some('(' | ')' | '[' | ']' | '{' | '}' | '<' | '>' | '\u{27E8}' | '\u{27E9}') - ); - Ok(Object::Int(i64::from(mirrored))) + Ok(Object::Int(i64::from(ucd::record(cp, old).mirrored()))) } -fn unicodedata_decimal(args: &[Object]) -> Result { +fn impl_decimal(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "decimal")?; - if let Some(d) = char::from_u32(cp).and_then(|ch| ch.to_digit(10)) { + if let Some(d) = ucd::record(cp, old).decimal() { return Ok(Object::Int(i64::from(d))); } if let Some(default) = args.get(1) { @@ -312,9 +238,9 @@ fn unicodedata_decimal(args: &[Object]) -> Result { Err(value_error("not a decimal")) } -fn unicodedata_digit(args: &[Object]) -> Result { +fn impl_digit(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "digit")?; - if let Some(d) = char::from_u32(cp).and_then(|ch| ch.to_digit(10)) { + if let Some(d) = ucd::record(cp, old).digit() { return Ok(Object::Int(i64::from(d))); } if let Some(default) = args.get(1) { @@ -323,33 +249,10 @@ fn unicodedata_digit(args: &[Object]) -> Result { Err(value_error("not a digit")) } -fn unicodedata_numeric(args: &[Object]) -> Result { +fn impl_numeric(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "numeric")?; - let ch = char::from_u32(cp); - if let Some(d) = ch.and_then(|c| c.to_digit(36)) { - if d < 10 { - return Ok(Object::Float(f64::from(d))); - } - } - // Cover the common Unicode fraction characters. - let v = match ch { - Some('½') => Some(0.5), - Some('⅓') => Some(1.0 / 3.0), - Some('¼') => Some(0.25), - Some('⅕') => Some(0.2), - Some('⅙') => Some(1.0 / 6.0), - Some('⅛') => Some(0.125), - Some('⅔') => Some(2.0 / 3.0), - Some('⅖') => Some(0.4), - Some('⅗') => Some(0.6), - Some('⅘') => Some(0.8), - Some('¾') => Some(0.75), - Some('⅝') => Some(0.625), - Some('⅞') => Some(0.875), - _ => None, - }; - if let Some(x) = v { - return Ok(Object::Float(x)); + if let Some(v) = ucd::record(cp, old).numeric() { + return Ok(Object::Float(v)); } if let Some(default) = args.get(1) { return Ok(default.clone()); @@ -357,1189 +260,103 @@ fn unicodedata_numeric(args: &[Object]) -> Result { Err(value_error("not a numeric character")) } -fn unicodedata_decomposition(args: &[Object]) -> Result { +fn impl_decomposition(args: &[Object], old: bool) -> Result { let cp = first_codepoint(args, "decomposition")?; - // Look up the authoritative UCD decomposition (canonical *and* - // compatibility, with the `` prefixes that NFD/NFKD can't recover), - // generated verbatim from CPython. Code points without a decomposition — - // including lone surrogates — return "". - let table = crate::stdlib::unicode_decomp_data::DECOMPOSITIONS; - match table.binary_search_by_key(&cp, |&(c, _)| c) { - Ok(i) => Ok(Object::from_static(table[i].1)), - Err(_) => Ok(Object::from_static("")), + Ok(Object::from_str( + ucd::record(cp, old).decomposition_string(), + )) +} + +fn impl_east_asian_width(args: &[Object], old: bool) -> Result { + let cp = first_codepoint(args, "east_asian_width")?; + Ok(Object::from_static(ucd::record(cp, old).east_asian_width())) +} + +fn arg_unistr_codepoints(args: &[Object], fname: &str) -> Result, RuntimeError> { + match args.get(1) { + Some(Object::Str(s)) => Ok(s.chars().map(|c| c as u32).collect()), + Some(Object::WStr(cps)) => Ok(cps.to_vec()), + _ => Err(type_error(format!("{fname}() unistr must be str"))), } } -fn unicodedata_normalize(args: &[Object]) -> Result { - let form = match args.first() { - Some(Object::Str(s)) => s.to_string(), - _ => return Err(type_error("normalize() form must be str")), - }; - let s = match args.get(1) { - Some(Object::Str(s)) => s.to_string(), - _ => return Err(type_error("normalize() unistr must be str")), - }; - let out: String = match form.as_str() { - "NFC" => s.nfc().collect(), - "NFD" => s.nfd().collect(), - "NFKC" => s.nfkc().collect(), - "NFKD" => s.nfkd().collect(), - _ => return Err(value_error(format!("invalid normalization form: {form}"))), - }; - Ok(Object::from_str(out)) +fn arg_form<'a>(args: &'a [Object], fname: &str) -> Result<&'a str, RuntimeError> { + match args.first() { + Some(Object::Str(s)) => Ok(s), + _ => Err(type_error(format!("{fname}() form must be str"))), + } } -fn unicodedata_is_normalized(args: &[Object]) -> Result { - let normalized = match unicodedata_normalize(args)? { - Object::Str(s) => s.to_string(), - _ => unreachable!(), - }; - let original = match args.get(1) { - Some(Object::Str(s)) => s.to_string(), - _ => return Err(type_error("is_normalized() unistr must be str")), - }; - Ok(Object::Bool(normalized == original)) +// The versioned-UCD behavior is baked into the generated 3.2.0 records: +// code points unassigned in 3.2.0 probe with no decomposition and ccc 0 +// (CPython's `nfd_nfkd` passes them through per code point), while +// composition always runs on the current pair table (CPython's `nfc_nfkc` +// has no version gate — `'\U00011935\U00011930'` composes even under +// `ucd_3_2_0`, exercised by `test_normalization`). + +fn impl_normalize(args: &[Object], old: bool) -> Result { + let form = arg_form(args, "normalize")?; + if !matches!(form, "NFC" | "NFD" | "NFKC" | "NFKD") { + return Err(value_error("invalid normalization form")); + } + let cps = arg_unistr_codepoints(args, "normalize")?; + let out = ucd::normalize(form, &cps, old); + Ok(Object::str_from_codepoints(out)) } -// East Asian Width (UAX #11) ranges for every non-Neutral code point, -// generated from the Unicode Character Database (UCD 13.0 — the table -// only lists non-`N` ranges, so lookups missing here are Neutral). -// Emoji presentation symbols are `W`, which `traceback`'s -// `_display_width` relies on for caret alignment under emoji. -const EAW_RANGES: &[(u32, u32, &str)] = &[ - (0x20, 0x7E, "Na"), - (0xA1, 0xA1, "A"), - (0xA2, 0xA3, "Na"), - (0xA4, 0xA4, "A"), - (0xA5, 0xA6, "Na"), - (0xA7, 0xA8, "A"), - (0xAA, 0xAA, "A"), - (0xAC, 0xAC, "Na"), - (0xAD, 0xAE, "A"), - (0xAF, 0xAF, "Na"), - (0xB0, 0xB4, "A"), - (0xB6, 0xBA, "A"), - (0xBC, 0xBF, "A"), - (0xC6, 0xC6, "A"), - (0xD0, 0xD0, "A"), - (0xD7, 0xD8, "A"), - (0xDE, 0xE1, "A"), - (0xE6, 0xE6, "A"), - (0xE8, 0xEA, "A"), - (0xEC, 0xED, "A"), - (0xF0, 0xF0, "A"), - (0xF2, 0xF3, "A"), - (0xF7, 0xFA, "A"), - (0xFC, 0xFC, "A"), - (0xFE, 0xFE, "A"), - (0x101, 0x101, "A"), - (0x111, 0x111, "A"), - (0x113, 0x113, "A"), - (0x11B, 0x11B, "A"), - (0x126, 0x127, "A"), - (0x12B, 0x12B, "A"), - (0x131, 0x133, "A"), - (0x138, 0x138, "A"), - (0x13F, 0x142, "A"), - (0x144, 0x144, "A"), - (0x148, 0x14B, "A"), - (0x14D, 0x14D, "A"), - (0x152, 0x153, "A"), - (0x166, 0x167, "A"), - (0x16B, 0x16B, "A"), - (0x1CE, 0x1CE, "A"), - (0x1D0, 0x1D0, "A"), - (0x1D2, 0x1D2, "A"), - (0x1D4, 0x1D4, "A"), - (0x1D6, 0x1D6, "A"), - (0x1D8, 0x1D8, "A"), - (0x1DA, 0x1DA, "A"), - (0x1DC, 0x1DC, "A"), - (0x251, 0x251, "A"), - (0x261, 0x261, "A"), - (0x2C4, 0x2C4, "A"), - (0x2C7, 0x2C7, "A"), - (0x2C9, 0x2CB, "A"), - (0x2CD, 0x2CD, "A"), - (0x2D0, 0x2D0, "A"), - (0x2D8, 0x2DB, "A"), - (0x2DD, 0x2DD, "A"), - (0x2DF, 0x2DF, "A"), - (0x300, 0x36F, "A"), - (0x378, 0x379, "F"), - (0x380, 0x383, "F"), - (0x38B, 0x38B, "F"), - (0x38D, 0x38D, "F"), - (0x391, 0x3A1, "A"), - (0x3A2, 0x3A2, "F"), - (0x3A3, 0x3A9, "A"), - (0x3B1, 0x3C1, "A"), - (0x3C3, 0x3C9, "A"), - (0x401, 0x401, "A"), - (0x410, 0x44F, "A"), - (0x451, 0x451, "A"), - (0x530, 0x530, "F"), - (0x557, 0x558, "F"), - (0x58B, 0x58C, "F"), - (0x590, 0x590, "F"), - (0x5C8, 0x5CF, "F"), - (0x5EB, 0x5EE, "F"), - (0x5F5, 0x5FF, "F"), - (0x61D, 0x61D, "F"), - (0x70E, 0x70E, "F"), - (0x74B, 0x74C, "F"), - (0x7B2, 0x7BF, "F"), - (0x7FB, 0x7FC, "F"), - (0x82E, 0x82F, "F"), - (0x83F, 0x83F, "F"), - (0x85C, 0x85D, "F"), - (0x85F, 0x85F, "F"), - (0x86B, 0x89F, "F"), - (0x8B5, 0x8B5, "F"), - (0x8C8, 0x8D2, "F"), - (0x984, 0x984, "F"), - (0x98D, 0x98E, "F"), - (0x991, 0x992, "F"), - (0x9A9, 0x9A9, "F"), - (0x9B1, 0x9B1, "F"), - (0x9B3, 0x9B5, "F"), - (0x9BA, 0x9BB, "F"), - (0x9C5, 0x9C6, "F"), - (0x9C9, 0x9CA, "F"), - (0x9CF, 0x9D6, "F"), - (0x9D8, 0x9DB, "F"), - (0x9DE, 0x9DE, "F"), - (0x9E4, 0x9E5, "F"), - (0x9FF, 0xA00, "F"), - (0xA04, 0xA04, "F"), - (0xA0B, 0xA0E, "F"), - (0xA11, 0xA12, "F"), - (0xA29, 0xA29, "F"), - (0xA31, 0xA31, "F"), - (0xA34, 0xA34, "F"), - (0xA37, 0xA37, "F"), - (0xA3A, 0xA3B, "F"), - (0xA3D, 0xA3D, "F"), - (0xA43, 0xA46, "F"), - (0xA49, 0xA4A, "F"), - (0xA4E, 0xA50, "F"), - (0xA52, 0xA58, "F"), - (0xA5D, 0xA5D, "F"), - (0xA5F, 0xA65, "F"), - (0xA77, 0xA80, "F"), - (0xA84, 0xA84, "F"), - (0xA8E, 0xA8E, "F"), - (0xA92, 0xA92, "F"), - (0xAA9, 0xAA9, "F"), - (0xAB1, 0xAB1, "F"), - (0xAB4, 0xAB4, "F"), - (0xABA, 0xABB, "F"), - (0xAC6, 0xAC6, "F"), - (0xACA, 0xACA, "F"), - (0xACE, 0xACF, "F"), - (0xAD1, 0xADF, "F"), - (0xAE4, 0xAE5, "F"), - (0xAF2, 0xAF8, "F"), - (0xB00, 0xB00, "F"), - (0xB04, 0xB04, "F"), - (0xB0D, 0xB0E, "F"), - (0xB11, 0xB12, "F"), - (0xB29, 0xB29, "F"), - (0xB31, 0xB31, "F"), - (0xB34, 0xB34, "F"), - (0xB3A, 0xB3B, "F"), - (0xB45, 0xB46, "F"), - (0xB49, 0xB4A, "F"), - (0xB4E, 0xB54, "F"), - (0xB58, 0xB5B, "F"), - (0xB5E, 0xB5E, "F"), - (0xB64, 0xB65, "F"), - (0xB78, 0xB81, "F"), - (0xB84, 0xB84, "F"), - (0xB8B, 0xB8D, "F"), - (0xB91, 0xB91, "F"), - (0xB96, 0xB98, "F"), - (0xB9B, 0xB9B, "F"), - (0xB9D, 0xB9D, "F"), - (0xBA0, 0xBA2, "F"), - (0xBA5, 0xBA7, "F"), - (0xBAB, 0xBAD, "F"), - (0xBBA, 0xBBD, "F"), - (0xBC3, 0xBC5, "F"), - (0xBC9, 0xBC9, "F"), - (0xBCE, 0xBCF, "F"), - (0xBD1, 0xBD6, "F"), - (0xBD8, 0xBE5, "F"), - (0xBFB, 0xBFF, "F"), - (0xC0D, 0xC0D, "F"), - (0xC11, 0xC11, "F"), - (0xC29, 0xC29, "F"), - (0xC3A, 0xC3C, "F"), - (0xC45, 0xC45, "F"), - (0xC49, 0xC49, "F"), - (0xC4E, 0xC54, "F"), - (0xC57, 0xC57, "F"), - (0xC5B, 0xC5F, "F"), - (0xC64, 0xC65, "F"), - (0xC70, 0xC76, "F"), - (0xC8D, 0xC8D, "F"), - (0xC91, 0xC91, "F"), - (0xCA9, 0xCA9, "F"), - (0xCB4, 0xCB4, "F"), - (0xCBA, 0xCBB, "F"), - (0xCC5, 0xCC5, "F"), - (0xCC9, 0xCC9, "F"), - (0xCCE, 0xCD4, "F"), - (0xCD7, 0xCDD, "F"), - (0xCDF, 0xCDF, "F"), - (0xCE4, 0xCE5, "F"), - (0xCF0, 0xCF0, "F"), - (0xCF3, 0xCFF, "F"), - (0xD0D, 0xD0D, "F"), - (0xD11, 0xD11, "F"), - (0xD45, 0xD45, "F"), - (0xD49, 0xD49, "F"), - (0xD50, 0xD53, "F"), - (0xD64, 0xD65, "F"), - (0xD80, 0xD80, "F"), - (0xD84, 0xD84, "F"), - (0xD97, 0xD99, "F"), - (0xDB2, 0xDB2, "F"), - (0xDBC, 0xDBC, "F"), - (0xDBE, 0xDBF, "F"), - (0xDC7, 0xDC9, "F"), - (0xDCB, 0xDCE, "F"), - (0xDD5, 0xDD5, "F"), - (0xDD7, 0xDD7, "F"), - (0xDE0, 0xDE5, "F"), - (0xDF0, 0xDF1, "F"), - (0xDF5, 0xE00, "F"), - (0xE3B, 0xE3E, "F"), - (0xE5C, 0xE80, "F"), - (0xE83, 0xE83, "F"), - (0xE85, 0xE85, "F"), - (0xE8B, 0xE8B, "F"), - (0xEA4, 0xEA4, "F"), - (0xEA6, 0xEA6, "F"), - (0xEBE, 0xEBF, "F"), - (0xEC5, 0xEC5, "F"), - (0xEC7, 0xEC7, "F"), - (0xECE, 0xECF, "F"), - (0xEDA, 0xEDB, "F"), - (0xEE0, 0xEFF, "F"), - (0xF48, 0xF48, "F"), - (0xF6D, 0xF70, "F"), - (0xF98, 0xF98, "F"), - (0xFBD, 0xFBD, "F"), - (0xFCD, 0xFCD, "F"), - (0xFDB, 0xFFF, "F"), - (0x10C6, 0x10C6, "F"), - (0x10C8, 0x10CC, "F"), - (0x10CE, 0x10CF, "F"), - (0x1100, 0x115F, "W"), - (0x1249, 0x1249, "F"), - (0x124E, 0x124F, "F"), - (0x1257, 0x1257, "F"), - (0x1259, 0x1259, "F"), - (0x125E, 0x125F, "F"), - (0x1289, 0x1289, "F"), - (0x128E, 0x128F, "F"), - (0x12B1, 0x12B1, "F"), - (0x12B6, 0x12B7, "F"), - (0x12BF, 0x12BF, "F"), - (0x12C1, 0x12C1, "F"), - (0x12C6, 0x12C7, "F"), - (0x12D7, 0x12D7, "F"), - (0x1311, 0x1311, "F"), - (0x1316, 0x1317, "F"), - (0x135B, 0x135C, "F"), - (0x137D, 0x137F, "F"), - (0x139A, 0x139F, "F"), - (0x13F6, 0x13F7, "F"), - (0x13FE, 0x13FF, "F"), - (0x169D, 0x169F, "F"), - (0x16F9, 0x16FF, "F"), - (0x170D, 0x170D, "F"), - (0x1715, 0x171F, "F"), - (0x1737, 0x173F, "F"), - (0x1754, 0x175F, "F"), - (0x176D, 0x176D, "F"), - (0x1771, 0x1771, "F"), - (0x1774, 0x177F, "F"), - (0x17DE, 0x17DF, "F"), - (0x17EA, 0x17EF, "F"), - (0x17FA, 0x17FF, "F"), - (0x180F, 0x180F, "F"), - (0x181A, 0x181F, "F"), - (0x1879, 0x187F, "F"), - (0x18AB, 0x18AF, "F"), - (0x18F6, 0x18FF, "F"), - (0x191F, 0x191F, "F"), - (0x192C, 0x192F, "F"), - (0x193C, 0x193F, "F"), - (0x1941, 0x1943, "F"), - (0x196E, 0x196F, "F"), - (0x1975, 0x197F, "F"), - (0x19AC, 0x19AF, "F"), - (0x19CA, 0x19CF, "F"), - (0x19DB, 0x19DD, "F"), - (0x1A1C, 0x1A1D, "F"), - (0x1A5F, 0x1A5F, "F"), - (0x1A7D, 0x1A7E, "F"), - (0x1A8A, 0x1A8F, "F"), - (0x1A9A, 0x1A9F, "F"), - (0x1AAE, 0x1AAF, "F"), - (0x1AC1, 0x1AFF, "F"), - (0x1B4C, 0x1B4F, "F"), - (0x1B7D, 0x1B7F, "F"), - (0x1BF4, 0x1BFB, "F"), - (0x1C38, 0x1C3A, "F"), - (0x1C4A, 0x1C4C, "F"), - (0x1C89, 0x1C8F, "F"), - (0x1CBB, 0x1CBC, "F"), - (0x1CC8, 0x1CCF, "F"), - (0x1CFB, 0x1CFF, "F"), - (0x1DFA, 0x1DFA, "F"), - (0x1F16, 0x1F17, "F"), - (0x1F1E, 0x1F1F, "F"), - (0x1F46, 0x1F47, "F"), - (0x1F4E, 0x1F4F, "F"), - (0x1F58, 0x1F58, "F"), - (0x1F5A, 0x1F5A, "F"), - (0x1F5C, 0x1F5C, "F"), - (0x1F5E, 0x1F5E, "F"), - (0x1F7E, 0x1F7F, "F"), - (0x1FB5, 0x1FB5, "F"), - (0x1FC5, 0x1FC5, "F"), - (0x1FD4, 0x1FD5, "F"), - (0x1FDC, 0x1FDC, "F"), - (0x1FF0, 0x1FF1, "F"), - (0x1FF5, 0x1FF5, "F"), - (0x1FFF, 0x1FFF, "F"), - (0x2010, 0x2010, "A"), - (0x2013, 0x2016, "A"), - (0x2018, 0x2019, "A"), - (0x201C, 0x201D, "A"), - (0x2020, 0x2022, "A"), - (0x2024, 0x2027, "A"), - (0x2030, 0x2030, "A"), - (0x2032, 0x2033, "A"), - (0x2035, 0x2035, "A"), - (0x203B, 0x203B, "A"), - (0x203E, 0x203E, "A"), - (0x2065, 0x2065, "F"), - (0x2072, 0x2073, "F"), - (0x2074, 0x2074, "A"), - (0x207F, 0x207F, "A"), - (0x2081, 0x2084, "A"), - (0x208F, 0x208F, "F"), - (0x209D, 0x209F, "F"), - (0x20A9, 0x20A9, "H"), - (0x20AC, 0x20AC, "A"), - (0x20C0, 0x20CF, "F"), - (0x20F1, 0x20FF, "F"), - (0x2103, 0x2103, "A"), - (0x2105, 0x2105, "A"), - (0x2109, 0x2109, "A"), - (0x2113, 0x2113, "A"), - (0x2116, 0x2116, "A"), - (0x2121, 0x2122, "A"), - (0x2126, 0x2126, "A"), - (0x212B, 0x212B, "A"), - (0x2153, 0x2154, "A"), - (0x215B, 0x215E, "A"), - (0x2160, 0x216B, "A"), - (0x2170, 0x2179, "A"), - (0x2189, 0x2189, "A"), - (0x218C, 0x218F, "F"), - (0x2190, 0x2199, "A"), - (0x21B8, 0x21B9, "A"), - (0x21D2, 0x21D2, "A"), - (0x21D4, 0x21D4, "A"), - (0x21E7, 0x21E7, "A"), - (0x2200, 0x2200, "A"), - (0x2202, 0x2203, "A"), - (0x2207, 0x2208, "A"), - (0x220B, 0x220B, "A"), - (0x220F, 0x220F, "A"), - (0x2211, 0x2211, "A"), - (0x2215, 0x2215, "A"), - (0x221A, 0x221A, "A"), - (0x221D, 0x2220, "A"), - (0x2223, 0x2223, "A"), - (0x2225, 0x2225, "A"), - (0x2227, 0x222C, "A"), - (0x222E, 0x222E, "A"), - (0x2234, 0x2237, "A"), - (0x223C, 0x223D, "A"), - (0x2248, 0x2248, "A"), - (0x224C, 0x224C, "A"), - (0x2252, 0x2252, "A"), - (0x2260, 0x2261, "A"), - (0x2264, 0x2267, "A"), - (0x226A, 0x226B, "A"), - (0x226E, 0x226F, "A"), - (0x2282, 0x2283, "A"), - (0x2286, 0x2287, "A"), - (0x2295, 0x2295, "A"), - (0x2299, 0x2299, "A"), - (0x22A5, 0x22A5, "A"), - (0x22BF, 0x22BF, "A"), - (0x2312, 0x2312, "A"), - (0x231A, 0x231B, "W"), - (0x2329, 0x232A, "W"), - (0x23E9, 0x23EC, "W"), - (0x23F0, 0x23F0, "W"), - (0x23F3, 0x23F3, "W"), - (0x2427, 0x243F, "F"), - (0x244B, 0x245F, "F"), - (0x2460, 0x24E9, "A"), - (0x24EB, 0x254B, "A"), - (0x2550, 0x2573, "A"), - (0x2580, 0x258F, "A"), - (0x2592, 0x2595, "A"), - (0x25A0, 0x25A1, "A"), - (0x25A3, 0x25A9, "A"), - (0x25B2, 0x25B3, "A"), - (0x25B6, 0x25B7, "A"), - (0x25BC, 0x25BD, "A"), - (0x25C0, 0x25C1, "A"), - (0x25C6, 0x25C8, "A"), - (0x25CB, 0x25CB, "A"), - (0x25CE, 0x25D1, "A"), - (0x25E2, 0x25E5, "A"), - (0x25EF, 0x25EF, "A"), - (0x25FD, 0x25FE, "W"), - (0x2605, 0x2606, "A"), - (0x2609, 0x2609, "A"), - (0x260E, 0x260F, "A"), - (0x2614, 0x2615, "W"), - (0x261C, 0x261C, "A"), - (0x261E, 0x261E, "A"), - (0x2640, 0x2640, "A"), - (0x2642, 0x2642, "A"), - (0x2648, 0x2653, "W"), - (0x2660, 0x2661, "A"), - (0x2663, 0x2665, "A"), - (0x2667, 0x266A, "A"), - (0x266C, 0x266D, "A"), - (0x266F, 0x266F, "A"), - (0x267F, 0x267F, "W"), - (0x2693, 0x2693, "W"), - (0x269E, 0x269F, "A"), - (0x26A1, 0x26A1, "W"), - (0x26AA, 0x26AB, "W"), - (0x26BD, 0x26BE, "W"), - (0x26BF, 0x26BF, "A"), - (0x26C4, 0x26C5, "W"), - (0x26C6, 0x26CD, "A"), - (0x26CE, 0x26CE, "W"), - (0x26CF, 0x26D3, "A"), - (0x26D4, 0x26D4, "W"), - (0x26D5, 0x26E1, "A"), - (0x26E3, 0x26E3, "A"), - (0x26E8, 0x26E9, "A"), - (0x26EA, 0x26EA, "W"), - (0x26EB, 0x26F1, "A"), - (0x26F2, 0x26F3, "W"), - (0x26F4, 0x26F4, "A"), - (0x26F5, 0x26F5, "W"), - (0x26F6, 0x26F9, "A"), - (0x26FA, 0x26FA, "W"), - (0x26FB, 0x26FC, "A"), - (0x26FD, 0x26FD, "W"), - (0x26FE, 0x26FF, "A"), - (0x2705, 0x2705, "W"), - (0x270A, 0x270B, "W"), - (0x2728, 0x2728, "W"), - (0x273D, 0x273D, "A"), - (0x274C, 0x274C, "W"), - (0x274E, 0x274E, "W"), - (0x2753, 0x2755, "W"), - (0x2757, 0x2757, "W"), - (0x2776, 0x277F, "A"), - (0x2795, 0x2797, "W"), - (0x27B0, 0x27B0, "W"), - (0x27BF, 0x27BF, "W"), - (0x27E6, 0x27ED, "Na"), - (0x2985, 0x2986, "Na"), - (0x2B1B, 0x2B1C, "W"), - (0x2B50, 0x2B50, "W"), - (0x2B55, 0x2B55, "W"), - (0x2B56, 0x2B59, "A"), - (0x2B74, 0x2B75, "F"), - (0x2B96, 0x2B96, "F"), - (0x2C2F, 0x2C2F, "F"), - (0x2C5F, 0x2C5F, "F"), - (0x2CF4, 0x2CF8, "F"), - (0x2D26, 0x2D26, "F"), - (0x2D28, 0x2D2C, "F"), - (0x2D2E, 0x2D2F, "F"), - (0x2D68, 0x2D6E, "F"), - (0x2D71, 0x2D7E, "F"), - (0x2D97, 0x2D9F, "F"), - (0x2DA7, 0x2DA7, "F"), - (0x2DAF, 0x2DAF, "F"), - (0x2DB7, 0x2DB7, "F"), - (0x2DBF, 0x2DBF, "F"), - (0x2DC7, 0x2DC7, "F"), - (0x2DCF, 0x2DCF, "F"), - (0x2DD7, 0x2DD7, "F"), - (0x2DDF, 0x2DDF, "F"), - (0x2E53, 0x2E7F, "F"), - (0x2E80, 0x2E99, "W"), - (0x2E9A, 0x2E9A, "F"), - (0x2E9B, 0x2EF3, "W"), - (0x2EF4, 0x2EFF, "F"), - (0x2F00, 0x2FD5, "W"), - (0x2FD6, 0x2FEF, "F"), - (0x2FF0, 0x2FFB, "W"), - (0x2FFC, 0x3000, "F"), - (0x3001, 0x303E, "W"), - (0x3040, 0x3040, "F"), - (0x3041, 0x3096, "W"), - (0x3097, 0x3098, "F"), - (0x3099, 0x30FF, "W"), - (0x3100, 0x3104, "F"), - (0x3105, 0x312F, "W"), - (0x3130, 0x3130, "F"), - (0x3131, 0x318E, "W"), - (0x318F, 0x318F, "F"), - (0x3190, 0x31E3, "W"), - (0x31E4, 0x31EF, "F"), - (0x31F0, 0x321E, "W"), - (0x321F, 0x321F, "F"), - (0x3220, 0x3247, "W"), - (0x3248, 0x324F, "A"), - (0x3250, 0x4DBF, "W"), - (0x4E00, 0x9FFC, "W"), - (0x9FFD, 0x9FFF, "F"), - (0xA000, 0xA48C, "W"), - (0xA48D, 0xA48F, "F"), - (0xA490, 0xA4C6, "W"), - (0xA4C7, 0xA4CF, "F"), - (0xA62C, 0xA63F, "F"), - (0xA6F8, 0xA6FF, "F"), - (0xA7C0, 0xA7C1, "F"), - (0xA7CB, 0xA7F4, "F"), - (0xA82D, 0xA82F, "F"), - (0xA83A, 0xA83F, "F"), - (0xA878, 0xA87F, "F"), - (0xA8C6, 0xA8CD, "F"), - (0xA8DA, 0xA8DF, "F"), - (0xA954, 0xA95E, "F"), - (0xA960, 0xA97C, "W"), - (0xA97D, 0xA97F, "F"), - (0xA9CE, 0xA9CE, "F"), - (0xA9DA, 0xA9DD, "F"), - (0xA9FF, 0xA9FF, "F"), - (0xAA37, 0xAA3F, "F"), - (0xAA4E, 0xAA4F, "F"), - (0xAA5A, 0xAA5B, "F"), - (0xAAC3, 0xAADA, "F"), - (0xAAF7, 0xAB00, "F"), - (0xAB07, 0xAB08, "F"), - (0xAB0F, 0xAB10, "F"), - (0xAB17, 0xAB1F, "F"), - (0xAB27, 0xAB27, "F"), - (0xAB2F, 0xAB2F, "F"), - (0xAB6C, 0xAB6F, "F"), - (0xABEE, 0xABEF, "F"), - (0xABFA, 0xABFF, "F"), - (0xAC00, 0xD7A3, "W"), - (0xD7A4, 0xD7AF, "F"), - (0xD7C7, 0xD7CA, "F"), - (0xD7FC, 0xD7FF, "F"), - (0xE000, 0xF8FF, "A"), - (0xF900, 0xFA6D, "W"), - (0xFA6E, 0xFA6F, "F"), - (0xFA70, 0xFAD9, "W"), - (0xFADA, 0xFAFF, "F"), - (0xFB07, 0xFB12, "F"), - (0xFB18, 0xFB1C, "F"), - (0xFB37, 0xFB37, "F"), - (0xFB3D, 0xFB3D, "F"), - (0xFB3F, 0xFB3F, "F"), - (0xFB42, 0xFB42, "F"), - (0xFB45, 0xFB45, "F"), - (0xFBC2, 0xFBD2, "F"), - (0xFD40, 0xFD4F, "F"), - (0xFD90, 0xFD91, "F"), - (0xFDC8, 0xFDEF, "F"), - (0xFDFE, 0xFDFF, "F"), - (0xFE00, 0xFE0F, "A"), - (0xFE10, 0xFE19, "W"), - (0xFE1A, 0xFE1F, "F"), - (0xFE30, 0xFE52, "W"), - (0xFE53, 0xFE53, "F"), - (0xFE54, 0xFE66, "W"), - (0xFE67, 0xFE67, "F"), - (0xFE68, 0xFE6B, "W"), - (0xFE6C, 0xFE6F, "F"), - (0xFE75, 0xFE75, "F"), - (0xFEFD, 0xFEFE, "F"), - (0xFF00, 0xFF60, "F"), - (0xFF61, 0xFFBE, "H"), - (0xFFBF, 0xFFC1, "F"), - (0xFFC2, 0xFFC7, "H"), - (0xFFC8, 0xFFC9, "F"), - (0xFFCA, 0xFFCF, "H"), - (0xFFD0, 0xFFD1, "F"), - (0xFFD2, 0xFFD7, "H"), - (0xFFD8, 0xFFD9, "F"), - (0xFFDA, 0xFFDC, "H"), - (0xFFDD, 0xFFE7, "F"), - (0xFFE8, 0xFFEE, "H"), - (0xFFEF, 0xFFF8, "F"), - (0xFFFD, 0xFFFD, "A"), - (0xFFFE, 0xFFFF, "F"), - (0x1000C, 0x1000C, "F"), - (0x10027, 0x10027, "F"), - (0x1003B, 0x1003B, "F"), - (0x1003E, 0x1003E, "F"), - (0x1004E, 0x1004F, "F"), - (0x1005E, 0x1007F, "F"), - (0x100FB, 0x100FF, "F"), - (0x10103, 0x10106, "F"), - (0x10134, 0x10136, "F"), - (0x1018F, 0x1018F, "F"), - (0x1019D, 0x1019F, "F"), - (0x101A1, 0x101CF, "F"), - (0x101FE, 0x1027F, "F"), - (0x1029D, 0x1029F, "F"), - (0x102D1, 0x102DF, "F"), - (0x102FC, 0x102FF, "F"), - (0x10324, 0x1032C, "F"), - (0x1034B, 0x1034F, "F"), - (0x1037B, 0x1037F, "F"), - (0x1039E, 0x1039E, "F"), - (0x103C4, 0x103C7, "F"), - (0x103D6, 0x103FF, "F"), - (0x1049E, 0x1049F, "F"), - (0x104AA, 0x104AF, "F"), - (0x104D4, 0x104D7, "F"), - (0x104FC, 0x104FF, "F"), - (0x10528, 0x1052F, "F"), - (0x10564, 0x1056E, "F"), - (0x10570, 0x105FF, "F"), - (0x10737, 0x1073F, "F"), - (0x10756, 0x1075F, "F"), - (0x10768, 0x107FF, "F"), - (0x10806, 0x10807, "F"), - (0x10809, 0x10809, "F"), - (0x10836, 0x10836, "F"), - (0x10839, 0x1083B, "F"), - (0x1083D, 0x1083E, "F"), - (0x10856, 0x10856, "F"), - (0x1089F, 0x108A6, "F"), - (0x108B0, 0x108DF, "F"), - (0x108F3, 0x108F3, "F"), - (0x108F6, 0x108FA, "F"), - (0x1091C, 0x1091E, "F"), - (0x1093A, 0x1093E, "F"), - (0x10940, 0x1097F, "F"), - (0x109B8, 0x109BB, "F"), - (0x109D0, 0x109D1, "F"), - (0x10A04, 0x10A04, "F"), - (0x10A07, 0x10A0B, "F"), - (0x10A14, 0x10A14, "F"), - (0x10A18, 0x10A18, "F"), - (0x10A36, 0x10A37, "F"), - (0x10A3B, 0x10A3E, "F"), - (0x10A49, 0x10A4F, "F"), - (0x10A59, 0x10A5F, "F"), - (0x10AA0, 0x10ABF, "F"), - (0x10AE7, 0x10AEA, "F"), - (0x10AF7, 0x10AFF, "F"), - (0x10B36, 0x10B38, "F"), - (0x10B56, 0x10B57, "F"), - (0x10B73, 0x10B77, "F"), - (0x10B92, 0x10B98, "F"), - (0x10B9D, 0x10BA8, "F"), - (0x10BB0, 0x10BFF, "F"), - (0x10C49, 0x10C7F, "F"), - (0x10CB3, 0x10CBF, "F"), - (0x10CF3, 0x10CF9, "F"), - (0x10D28, 0x10D2F, "F"), - (0x10D3A, 0x10E5F, "F"), - (0x10E7F, 0x10E7F, "F"), - (0x10EAA, 0x10EAA, "F"), - (0x10EAE, 0x10EAF, "F"), - (0x10EB2, 0x10EFF, "F"), - (0x10F28, 0x10F2F, "F"), - (0x10F5A, 0x10FAF, "F"), - (0x10FCC, 0x10FDF, "F"), - (0x10FF7, 0x10FFF, "F"), - (0x1104E, 0x11051, "F"), - (0x11070, 0x1107E, "F"), - (0x110C2, 0x110CC, "F"), - (0x110CE, 0x110CF, "F"), - (0x110E9, 0x110EF, "F"), - (0x110FA, 0x110FF, "F"), - (0x11135, 0x11135, "F"), - (0x11148, 0x1114F, "F"), - (0x11177, 0x1117F, "F"), - (0x111E0, 0x111E0, "F"), - (0x111F5, 0x111FF, "F"), - (0x11212, 0x11212, "F"), - (0x1123F, 0x1127F, "F"), - (0x11287, 0x11287, "F"), - (0x11289, 0x11289, "F"), - (0x1128E, 0x1128E, "F"), - (0x1129E, 0x1129E, "F"), - (0x112AA, 0x112AF, "F"), - (0x112EB, 0x112EF, "F"), - (0x112FA, 0x112FF, "F"), - (0x11304, 0x11304, "F"), - (0x1130D, 0x1130E, "F"), - (0x11311, 0x11312, "F"), - (0x11329, 0x11329, "F"), - (0x11331, 0x11331, "F"), - (0x11334, 0x11334, "F"), - (0x1133A, 0x1133A, "F"), - (0x11345, 0x11346, "F"), - (0x11349, 0x1134A, "F"), - (0x1134E, 0x1134F, "F"), - (0x11351, 0x11356, "F"), - (0x11358, 0x1135C, "F"), - (0x11364, 0x11365, "F"), - (0x1136D, 0x1136F, "F"), - (0x11375, 0x113FF, "F"), - (0x1145C, 0x1145C, "F"), - (0x11462, 0x1147F, "F"), - (0x114C8, 0x114CF, "F"), - (0x114DA, 0x1157F, "F"), - (0x115B6, 0x115B7, "F"), - (0x115DE, 0x115FF, "F"), - (0x11645, 0x1164F, "F"), - (0x1165A, 0x1165F, "F"), - (0x1166D, 0x1167F, "F"), - (0x116B9, 0x116BF, "F"), - (0x116CA, 0x116FF, "F"), - (0x1171B, 0x1171C, "F"), - (0x1172C, 0x1172F, "F"), - (0x11740, 0x117FF, "F"), - (0x1183C, 0x1189F, "F"), - (0x118F3, 0x118FE, "F"), - (0x11907, 0x11908, "F"), - (0x1190A, 0x1190B, "F"), - (0x11914, 0x11914, "F"), - (0x11917, 0x11917, "F"), - (0x11936, 0x11936, "F"), - (0x11939, 0x1193A, "F"), - (0x11947, 0x1194F, "F"), - (0x1195A, 0x1199F, "F"), - (0x119A8, 0x119A9, "F"), - (0x119D8, 0x119D9, "F"), - (0x119E5, 0x119FF, "F"), - (0x11A48, 0x11A4F, "F"), - (0x11AA3, 0x11ABF, "F"), - (0x11AF9, 0x11BFF, "F"), - (0x11C09, 0x11C09, "F"), - (0x11C37, 0x11C37, "F"), - (0x11C46, 0x11C4F, "F"), - (0x11C6D, 0x11C6F, "F"), - (0x11C90, 0x11C91, "F"), - (0x11CA8, 0x11CA8, "F"), - (0x11CB7, 0x11CFF, "F"), - (0x11D07, 0x11D07, "F"), - (0x11D0A, 0x11D0A, "F"), - (0x11D37, 0x11D39, "F"), - (0x11D3B, 0x11D3B, "F"), - (0x11D3E, 0x11D3E, "F"), - (0x11D48, 0x11D4F, "F"), - (0x11D5A, 0x11D5F, "F"), - (0x11D66, 0x11D66, "F"), - (0x11D69, 0x11D69, "F"), - (0x11D8F, 0x11D8F, "F"), - (0x11D92, 0x11D92, "F"), - (0x11D99, 0x11D9F, "F"), - (0x11DAA, 0x11EDF, "F"), - (0x11EF9, 0x11FAF, "F"), - (0x11FB1, 0x11FBF, "F"), - (0x11FF2, 0x11FFE, "F"), - (0x1239A, 0x123FF, "F"), - (0x1246F, 0x1246F, "F"), - (0x12475, 0x1247F, "F"), - (0x12544, 0x12FFF, "F"), - (0x1342F, 0x1342F, "F"), - (0x13439, 0x143FF, "F"), - (0x14647, 0x167FF, "F"), - (0x16A39, 0x16A3F, "F"), - (0x16A5F, 0x16A5F, "F"), - (0x16A6A, 0x16A6D, "F"), - (0x16A70, 0x16ACF, "F"), - (0x16AEE, 0x16AEF, "F"), - (0x16AF6, 0x16AFF, "F"), - (0x16B46, 0x16B4F, "F"), - (0x16B5A, 0x16B5A, "F"), - (0x16B62, 0x16B62, "F"), - (0x16B78, 0x16B7C, "F"), - (0x16B90, 0x16E3F, "F"), - (0x16E9B, 0x16EFF, "F"), - (0x16F4B, 0x16F4E, "F"), - (0x16F88, 0x16F8E, "F"), - (0x16FA0, 0x16FDF, "F"), - (0x16FE0, 0x16FE4, "W"), - (0x16FE5, 0x16FEF, "F"), - (0x16FF0, 0x16FF1, "W"), - (0x16FF2, 0x16FFF, "F"), - (0x17000, 0x187F7, "W"), - (0x187F8, 0x187FF, "F"), - (0x18800, 0x18CD5, "W"), - (0x18CD6, 0x18CFF, "F"), - (0x18D00, 0x18D08, "W"), - (0x18D09, 0x1AFFF, "F"), - (0x1B000, 0x1B11E, "W"), - (0x1B11F, 0x1B14F, "F"), - (0x1B150, 0x1B152, "W"), - (0x1B153, 0x1B163, "F"), - (0x1B164, 0x1B167, "W"), - (0x1B168, 0x1B16F, "F"), - (0x1B170, 0x1B2FB, "W"), - (0x1B2FC, 0x1BBFF, "F"), - (0x1BC6B, 0x1BC6F, "F"), - (0x1BC7D, 0x1BC7F, "F"), - (0x1BC89, 0x1BC8F, "F"), - (0x1BC9A, 0x1BC9B, "F"), - (0x1BCA4, 0x1CFFF, "F"), - (0x1D0F6, 0x1D0FF, "F"), - (0x1D127, 0x1D128, "F"), - (0x1D1E9, 0x1D1FF, "F"), - (0x1D246, 0x1D2DF, "F"), - (0x1D2F4, 0x1D2FF, "F"), - (0x1D357, 0x1D35F, "F"), - (0x1D379, 0x1D3FF, "F"), - (0x1D455, 0x1D455, "F"), - (0x1D49D, 0x1D49D, "F"), - (0x1D4A0, 0x1D4A1, "F"), - (0x1D4A3, 0x1D4A4, "F"), - (0x1D4A7, 0x1D4A8, "F"), - (0x1D4AD, 0x1D4AD, "F"), - (0x1D4BA, 0x1D4BA, "F"), - (0x1D4BC, 0x1D4BC, "F"), - (0x1D4C4, 0x1D4C4, "F"), - (0x1D506, 0x1D506, "F"), - (0x1D50B, 0x1D50C, "F"), - (0x1D515, 0x1D515, "F"), - (0x1D51D, 0x1D51D, "F"), - (0x1D53A, 0x1D53A, "F"), - (0x1D53F, 0x1D53F, "F"), - (0x1D545, 0x1D545, "F"), - (0x1D547, 0x1D549, "F"), - (0x1D551, 0x1D551, "F"), - (0x1D6A6, 0x1D6A7, "F"), - (0x1D7CC, 0x1D7CD, "F"), - (0x1DA8C, 0x1DA9A, "F"), - (0x1DAA0, 0x1DAA0, "F"), - (0x1DAB0, 0x1DFFF, "F"), - (0x1E007, 0x1E007, "F"), - (0x1E019, 0x1E01A, "F"), - (0x1E022, 0x1E022, "F"), - (0x1E025, 0x1E025, "F"), - (0x1E02B, 0x1E0FF, "F"), - (0x1E12D, 0x1E12F, "F"), - (0x1E13E, 0x1E13F, "F"), - (0x1E14A, 0x1E14D, "F"), - (0x1E150, 0x1E2BF, "F"), - (0x1E2FA, 0x1E2FE, "F"), - (0x1E300, 0x1E7FF, "F"), - (0x1E8C5, 0x1E8C6, "F"), - (0x1E8D7, 0x1E8FF, "F"), - (0x1E94C, 0x1E94F, "F"), - (0x1E95A, 0x1E95D, "F"), - (0x1E960, 0x1EC70, "F"), - (0x1ECB5, 0x1ED00, "F"), - (0x1ED3E, 0x1EDFF, "F"), - (0x1EE04, 0x1EE04, "F"), - (0x1EE20, 0x1EE20, "F"), - (0x1EE23, 0x1EE23, "F"), - (0x1EE25, 0x1EE26, "F"), - (0x1EE28, 0x1EE28, "F"), - (0x1EE33, 0x1EE33, "F"), - (0x1EE38, 0x1EE38, "F"), - (0x1EE3A, 0x1EE3A, "F"), - (0x1EE3C, 0x1EE41, "F"), - (0x1EE43, 0x1EE46, "F"), - (0x1EE48, 0x1EE48, "F"), - (0x1EE4A, 0x1EE4A, "F"), - (0x1EE4C, 0x1EE4C, "F"), - (0x1EE50, 0x1EE50, "F"), - (0x1EE53, 0x1EE53, "F"), - (0x1EE55, 0x1EE56, "F"), - (0x1EE58, 0x1EE58, "F"), - (0x1EE5A, 0x1EE5A, "F"), - (0x1EE5C, 0x1EE5C, "F"), - (0x1EE5E, 0x1EE5E, "F"), - (0x1EE60, 0x1EE60, "F"), - (0x1EE63, 0x1EE63, "F"), - (0x1EE65, 0x1EE66, "F"), - (0x1EE6B, 0x1EE6B, "F"), - (0x1EE73, 0x1EE73, "F"), - (0x1EE78, 0x1EE78, "F"), - (0x1EE7D, 0x1EE7D, "F"), - (0x1EE7F, 0x1EE7F, "F"), - (0x1EE8A, 0x1EE8A, "F"), - (0x1EE9C, 0x1EEA0, "F"), - (0x1EEA4, 0x1EEA4, "F"), - (0x1EEAA, 0x1EEAA, "F"), - (0x1EEBC, 0x1EEEF, "F"), - (0x1EEF2, 0x1EFFF, "F"), - (0x1F004, 0x1F004, "W"), - (0x1F02C, 0x1F02F, "F"), - (0x1F094, 0x1F09F, "F"), - (0x1F0AF, 0x1F0B0, "F"), - (0x1F0C0, 0x1F0C0, "F"), - (0x1F0CF, 0x1F0CF, "W"), - (0x1F0D0, 0x1F0D0, "F"), - (0x1F0F6, 0x1F0FF, "F"), - (0x1F100, 0x1F10A, "A"), - (0x1F110, 0x1F12D, "A"), - (0x1F130, 0x1F169, "A"), - (0x1F170, 0x1F18D, "A"), - (0x1F18E, 0x1F18E, "W"), - (0x1F18F, 0x1F190, "A"), - (0x1F191, 0x1F19A, "W"), - (0x1F19B, 0x1F1AC, "A"), - (0x1F1AE, 0x1F1E5, "F"), - (0x1F200, 0x1F202, "W"), - (0x1F203, 0x1F20F, "F"), - (0x1F210, 0x1F23B, "W"), - (0x1F23C, 0x1F23F, "F"), - (0x1F240, 0x1F248, "W"), - (0x1F249, 0x1F24F, "F"), - (0x1F250, 0x1F251, "W"), - (0x1F252, 0x1F25F, "F"), - (0x1F260, 0x1F265, "W"), - (0x1F266, 0x1F2FF, "F"), - (0x1F300, 0x1F320, "W"), - (0x1F32D, 0x1F335, "W"), - (0x1F337, 0x1F37C, "W"), - (0x1F37E, 0x1F393, "W"), - (0x1F3A0, 0x1F3CA, "W"), - (0x1F3CF, 0x1F3D3, "W"), - (0x1F3E0, 0x1F3F0, "W"), - (0x1F3F4, 0x1F3F4, "W"), - (0x1F3F8, 0x1F43E, "W"), - (0x1F440, 0x1F440, "W"), - (0x1F442, 0x1F4FC, "W"), - (0x1F4FF, 0x1F53D, "W"), - (0x1F54B, 0x1F54E, "W"), - (0x1F550, 0x1F567, "W"), - (0x1F57A, 0x1F57A, "W"), - (0x1F595, 0x1F596, "W"), - (0x1F5A4, 0x1F5A4, "W"), - (0x1F5FB, 0x1F64F, "W"), - (0x1F680, 0x1F6C5, "W"), - (0x1F6CC, 0x1F6CC, "W"), - (0x1F6D0, 0x1F6D2, "W"), - (0x1F6D5, 0x1F6D7, "W"), - (0x1F6D8, 0x1F6DF, "F"), - (0x1F6EB, 0x1F6EC, "W"), - (0x1F6ED, 0x1F6EF, "F"), - (0x1F6F4, 0x1F6FC, "W"), - (0x1F6FD, 0x1F6FF, "F"), - (0x1F774, 0x1F77F, "F"), - (0x1F7D9, 0x1F7DF, "F"), - (0x1F7E0, 0x1F7EB, "W"), - (0x1F7EC, 0x1F7FF, "F"), - (0x1F80C, 0x1F80F, "F"), - (0x1F848, 0x1F84F, "F"), - (0x1F85A, 0x1F85F, "F"), - (0x1F888, 0x1F88F, "F"), - (0x1F8AE, 0x1F8AF, "F"), - (0x1F8B2, 0x1F8FF, "F"), - (0x1F90C, 0x1F93A, "W"), - (0x1F93C, 0x1F945, "W"), - (0x1F947, 0x1F978, "W"), - (0x1F979, 0x1F979, "F"), - (0x1F97A, 0x1F9CB, "W"), - (0x1F9CC, 0x1F9CC, "F"), - (0x1F9CD, 0x1F9FF, "W"), - (0x1FA54, 0x1FA5F, "F"), - (0x1FA6E, 0x1FA6F, "F"), - (0x1FA70, 0x1FA74, "W"), - (0x1FA75, 0x1FA77, "F"), - (0x1FA78, 0x1FA7A, "W"), - (0x1FA7B, 0x1FA7F, "F"), - (0x1FA80, 0x1FA86, "W"), - (0x1FA87, 0x1FA8F, "F"), - (0x1FA90, 0x1FAA8, "W"), - (0x1FAA9, 0x1FAAF, "F"), - (0x1FAB0, 0x1FAB6, "W"), - (0x1FAB7, 0x1FABF, "F"), - (0x1FAC0, 0x1FAC2, "W"), - (0x1FAC3, 0x1FACF, "F"), - (0x1FAD0, 0x1FAD6, "W"), - (0x1FAD7, 0x1FAFF, "F"), - (0x1FB93, 0x1FB93, "F"), - (0x1FBCB, 0x1FBEF, "F"), - (0x1FBFA, 0x1FFFF, "F"), - (0x20000, 0x2A6DD, "W"), - (0x2A6DE, 0x2A6FF, "F"), - (0x2A700, 0x2B734, "W"), - (0x2B735, 0x2B73F, "F"), - (0x2B740, 0x2B81D, "W"), - (0x2B81E, 0x2B81F, "F"), - (0x2B820, 0x2CEA1, "W"), - (0x2CEA2, 0x2CEAF, "F"), - (0x2CEB0, 0x2EBE0, "W"), - (0x2EBE1, 0x2F7FF, "F"), - (0x2F800, 0x2FA1D, "W"), - (0x2FA1E, 0x2FFFF, "F"), - (0x30000, 0x3134A, "W"), - (0x3134B, 0xE0000, "F"), - (0xE0002, 0xE001F, "F"), - (0xE0080, 0xE00FF, "F"), - (0xE0100, 0xE01EF, "A"), - (0xE01F0, 0xEFFFF, "F"), - (0xF0000, 0xFFFFD, "A"), - (0xFFFFE, 0xFFFFF, "F"), - (0x0010_0000, 0x0010_FFFD, "A"), - (0x0010_FFFE, 0x0010_FFFF, "F"), -]; +fn impl_is_normalized(args: &[Object], old: bool) -> Result { + let form = arg_form(args, "is_normalized")?; + if !matches!(form, "NFC" | "NFD" | "NFKC" | "NFKD") { + return Err(value_error("invalid normalization form")); + } + let cps = arg_unistr_codepoints(args, "is_normalized")?; + Ok(Object::Bool(ucd::normalize(form, &cps, old) == cps)) +} -fn unicodedata_east_asian_width(args: &[Object]) -> Result { - let code = first_codepoint(args, "east_asian_width")?; - let idx = EAW_RANGES.partition_point(|&(start, _, _)| start <= code); - let class = if idx > 0 { - let (_, end, cls) = EAW_RANGES[idx - 1]; - if code <= end { - cls - } else { - "N" +macro_rules! nd_pair { + ($cur:ident, $old:ident, $impl_:ident) => { + fn $cur(args: &[Object]) -> Result { + $impl_(args, false) + } + fn $old(args: &[Object]) -> Result { + $impl_(args, true) } - } else { - "N" }; - Ok(Object::from_static(class)) } +nd_pair!(nd_name, nd_name_32, impl_name); +nd_pair!(nd_lookup, nd_lookup_32, impl_lookup); +nd_pair!(nd_category, nd_category_32, impl_category); +nd_pair!(nd_bidirectional, nd_bidirectional_32, impl_bidirectional); +nd_pair!(nd_combining, nd_combining_32, impl_combining); +nd_pair!(nd_mirrored, nd_mirrored_32, impl_mirrored); +nd_pair!(nd_decimal, nd_decimal_32, impl_decimal); +nd_pair!(nd_digit, nd_digit_32, impl_digit); +nd_pair!(nd_numeric, nd_numeric_32, impl_numeric); +nd_pair!(nd_decomposition, nd_decomposition_32, impl_decomposition); +nd_pair!(nd_normalize, nd_normalize_32, impl_normalize); +nd_pair!(nd_is_normalized, nd_is_normalized_32, impl_is_normalized); +nd_pair!( + nd_east_asian_width, + nd_east_asian_width_32, + impl_east_asian_width +); + fn key_error(msg: impl Into) -> RuntimeError { crate::error::key_error(msg) } -// ----- Unicode name database (compact, lookup-on-demand) ----- +// --------------------------------------------------------------------------- +// crate-internal name helpers (codecs `namereplace` + `\N{...}` decode) +// --------------------------------------------------------------------------- -/// Look up the canonical Unicode character name for `ch`. We embed -/// names for ASCII controls, the basic Latin range, and the common -/// Latin/Greek/Cyrillic blocks. Beyond that we generate names of -/// the form `` so callers with `default=None` still see a -/// usable identifier. CPython returns the full UCD name for every -/// character; matching that would require shipping the ~600 KB -/// nameslist; we deliberately ship a smaller subset that covers -/// the common script blocks. -fn char_name(ch: char) -> Option { - // The full UCD name table (e.g. 'a' -> "LATIN SMALL LETTER A", - // '•' -> "BULLET"). CPython's `unicodedata.name` raises for control - // and unassigned code points, which `unicode_names2::name` also - // reports as `None`, so the caller's "no such name" path matches. - if let Some(name) = unicode_names2::name(ch) { - return Some(name.to_string()); - } - None +/// Canonical UCD 15.1.0 name for `ch` (CPython raises for controls and +/// unassigned code points; those return `None` here). +pub(crate) fn char_name(ch: char) -> Option { + ucd::name(ch as u32) } -/// Reverse-look-up — `unicodedata.lookup('LATIN SMALL LETTER A') == 'a'`. -/// Supports the names we synthesise plus a small hand-rolled table of -/// commonly looked-up sequences. -fn name_to_char(name: &str) -> Option { - // Full UCD name table first — this is the authoritative source for - // `unicodedata.lookup` and `\N{NAME}` (e.g. "BULLET", "NO-BREAK - // SPACE", "GREEK SMALL LETTER ALPHA"). - if let Some(ch) = unicode_names2::character(name) { - return Some(ch); - } - // Hex form `U+1234`. - if let Some(rest) = name.strip_prefix("U+") { - if let Ok(n) = u32::from_str_radix(rest.trim(), 16) { - return char::from_u32(n); - } - } - // Synthesised LATIN forms. - let upper = name.to_ascii_uppercase(); - if let Some(rest) = upper.strip_prefix("LATIN-1 CAPITAL LETTER ") { - if let Some(c) = rest.chars().next() { - return Some(c); - } - } - if let Some(rest) = upper.strip_prefix("LATIN-1 SMALL LETTER ") { - if let Some(c) = rest.chars().next() { - return Some(c.to_ascii_lowercase()); - } - } - if let Some(rest) = upper.strip_prefix("LATIN-1 DIGIT ") { - if let Some(c) = rest.chars().next() { - return Some(c); - } - } - // Common single-named characters. - Some(match upper.as_str() { - "NULL" => '\0', - "BELL" | "ALERT" => '\u{07}', - "BACKSPACE" => '\u{08}', - "TAB" | "CHARACTER TABULATION" | "HORIZONTAL TAB" => '\t', - "LINE FEED" | "NEWLINE" => '\n', - "VERTICAL TAB" | "LINE TABULATION" => '\u{0B}', - "FORM FEED" => '\u{0C}', - "CARRIAGE RETURN" => '\r', - "ESCAPE" => '\u{1B}', - "SPACE" => ' ', - "EXCLAMATION MARK" => '!', - "QUOTATION MARK" => '"', - "NUMBER SIGN" => '#', - "DOLLAR SIGN" => '$', - "PERCENT SIGN" => '%', - "AMPERSAND" => '&', - "APOSTROPHE" => '\'', - "LEFT PARENTHESIS" => '(', - "RIGHT PARENTHESIS" => ')', - "ASTERISK" => '*', - "PLUS SIGN" => '+', - "COMMA" => ',', - "HYPHEN-MINUS" => '-', - "FULL STOP" => '.', - "SOLIDUS" => '/', - "COLON" => ':', - "SEMICOLON" => ';', - "LESS-THAN SIGN" => '<', - "EQUALS SIGN" => '=', - "GREATER-THAN SIGN" => '>', - "QUESTION MARK" => '?', - "COMMERCIAL AT" => '@', - "LEFT SQUARE BRACKET" => '[', - "REVERSE SOLIDUS" => '\\', - "RIGHT SQUARE BRACKET" => ']', - "CIRCUMFLEX ACCENT" => '^', - "LOW LINE" => '_', - "GRAVE ACCENT" => '`', - "LEFT CURLY BRACKET" => '{', - "VERTICAL LINE" => '|', - "RIGHT CURLY BRACKET" => '}', - "TILDE" => '~', - "GREEK SMALL LETTER ALPHA" => 'α', - "GREEK SMALL LETTER BETA" => 'β', - "GREEK SMALL LETTER GAMMA" => 'γ', - "GREEK SMALL LETTER DELTA" => 'δ', - "GREEK SMALL LETTER EPSILON" => 'ε', - "GREEK SMALL LETTER PI" => 'π', - "GREEK SMALL LETTER SIGMA" => 'σ', - "GREEK SMALL LETTER OMEGA" => 'ω', - "GREEK CAPITAL LETTER ALPHA" => 'Α', - "GREEK CAPITAL LETTER OMEGA" => 'Ω', - "GREEK CAPITAL LETTER SIGMA" => 'Σ', - "EM DASH" => '—', - "EN DASH" => '–', - "HORIZONTAL ELLIPSIS" => '…', - "LATIN CAPITAL LETTER E WITH ACUTE" => 'É', - "LATIN SMALL LETTER E WITH ACUTE" => 'é', - "LATIN SMALL LETTER N WITH TILDE" => 'ñ', - "LATIN CAPITAL LETTER N WITH TILDE" => 'Ñ', - "LATIN SMALL LETTER A WITH RING ABOVE" => 'å', - "LATIN CAPITAL LETTER A WITH RING ABOVE" => 'Å', - "INFINITY" => '∞', - "BLACK CIRCLE" => '●', - "WHITE CIRCLE" => '○', - _ => return None, - }) +/// Reverse lookup for `\N{NAME}` escapes and `unicodedata.lookup`. +pub(crate) fn name_to_char(name: &str) -> Option { + ucd::lookup(name).and_then(char::from_u32) } diff --git a/crates/weavepy-vm/src/unicode_case.rs b/crates/weavepy-vm/src/unicode_case.rs new file mode 100644 index 0000000..bc5d5eb --- /dev/null +++ b/crates/weavepy-vm/src/unicode_case.rs @@ -0,0 +1,213 @@ +//! String-level Unicode case operations — RFC 0050 WS4. +//! +//! Mirrors CPython's `do_upper`/`do_lower`/`do_title`/`do_capitalize`/ +//! `do_swapcase`/`do_casefold` (Objects/unicodeobject.c) over the generated +//! UCD 15.1.0 case tables, including the Final_Sigma rule and the full +//! (multi-code-point) SpecialCasing expansions. + +use crate::stdlib::ucd; + +const CAPITAL_SIGMA: u32 = 0x3A3; +const FINAL_SIGMA: u32 = 0x3C2; +const SMALL_SIGMA: u32 = 0x3C3; + +fn push_cps(out: &mut String, map: ucd::CaseMap) { + for &cp in map.as_slice() { + out.push(char::from_u32(cp).expect("case mapping is scalar")); + } +} + +/// `handle_capital_sigma`: Σ lowercases to ς at the end of a cased run +/// (Unicode 3.13.2 Final_Sigma; scans the *original* string). +fn capital_sigma_at(cps: &[char], i: usize) -> u32 { + let mut j = i; + let before_cased = loop { + if j == 0 { + break false; + } + j -= 1; + let c = cps[j] as u32; + if !ucd::is_case_ignorable(c) { + break ucd::is_cased(c); + } + }; + if !before_cased { + return SMALL_SIGMA; + } + let mut j = i + 1; + while j < cps.len() { + let c = cps[j] as u32; + if !ucd::is_case_ignorable(c) { + return if ucd::is_cased(c) { + SMALL_SIGMA + } else { + FINAL_SIGMA + }; + } + j += 1; + } + FINAL_SIGMA +} + +/// CPython's `lower_ucs4`: ToLowerFull with the capital-sigma special case. +fn lower_at(cps: &[char], i: usize) -> ucd::CaseMap { + let c = cps[i] as u32; + if c == CAPITAL_SIGMA { + ucd::CaseMap::single(capital_sigma_at(cps, i)) + } else { + ucd::to_lower_full(c) + } +} + +pub fn lower(s: &str) -> String { + let cps: Vec = s.chars().collect(); + let mut out = String::with_capacity(s.len()); + for i in 0..cps.len() { + push_cps(&mut out, lower_at(&cps, i)); + } + out +} + +pub fn upper(s: &str) -> String { + let mut out = String::with_capacity(s.len()); + for c in s.chars() { + push_cps(&mut out, ucd::to_upper_full(c as u32)); + } + out +} + +/// `str.casefold()` — context-free full fold (no Final_Sigma). +pub fn casefold(s: &str) -> String { + let mut out = String::with_capacity(s.len()); + for c in s.chars() { + push_cps(&mut out, ucd::to_fold_full(c as u32)); + } + out +} + +pub fn title(s: &str) -> String { + let cps: Vec = s.chars().collect(); + let mut out = String::with_capacity(s.len()); + let mut previous_is_cased = false; + for i in 0..cps.len() { + if previous_is_cased { + push_cps(&mut out, lower_at(&cps, i)); + } else { + push_cps(&mut out, ucd::to_title_full(cps[i] as u32)); + } + previous_is_cased = ucd::is_cased(cps[i] as u32); + } + out +} + +/// `str.capitalize()` — first char titlecased (3.8+ semantics), rest +/// lowered with the sigma rule. +pub fn capitalize(s: &str) -> String { + let cps: Vec = s.chars().collect(); + let mut out = String::with_capacity(s.len()); + if let Some(&first) = cps.first() { + push_cps(&mut out, ucd::to_title_full(first as u32)); + } + for i in 1..cps.len() { + push_cps(&mut out, lower_at(&cps, i)); + } + out +} + +pub fn swapcase(s: &str) -> String { + let cps: Vec = s.chars().collect(); + let mut out = String::with_capacity(s.len()); + for i in 0..cps.len() { + let c = cps[i] as u32; + let flags = ucd::case_flags(c); + if flags & ucd::FLAG_UPPER != 0 { + push_cps(&mut out, lower_at(&cps, i)); + } else if flags & ucd::FLAG_LOWER != 0 { + push_cps(&mut out, ucd::to_upper_full(c)); + } else { + out.push(cps[i]); + } + } + out +} + +/// `Py_UNICODE_ISSPACE` — differs from Rust's `char::is_whitespace` (e.g. +/// U+001C..U+001F are Python whitespace). +pub fn is_space(c: char) -> bool { + ucd::case_flags(c as u32) & ucd::FLAG_SPACE != 0 +} + +pub fn is_alpha(c: char) -> bool { + ucd::case_flags(c as u32) & ucd::FLAG_ALPHA != 0 +} + +pub fn is_alnum(c: char) -> bool { + ucd::case_flags(c as u32) & ucd::FLAG_ALNUM != 0 +} + +pub fn is_printable(c: char) -> bool { + ucd::case_flags(c as u32) & ucd::FLAG_PRINTABLE != 0 +} + +pub fn is_xid_start(c: char) -> bool { + ucd::case_flags(c as u32) & ucd::FLAG_XID_START != 0 +} + +pub fn is_xid_continue(c: char) -> bool { + ucd::case_flags(c as u32) & ucd::FLAG_XID_CONTINUE != 0 +} + +/// `unicode_isupper_impl`: no lower/title chars and at least one upper. +pub fn str_isupper(s: &str) -> bool { + let mut cased = false; + for c in s.chars() { + let f = ucd::case_flags(c as u32); + if f & (ucd::FLAG_LOWER | ucd::FLAG_TITLE) != 0 { + return false; + } + if f & ucd::FLAG_UPPER != 0 { + cased = true; + } + } + cased +} + +/// `unicode_islower_impl`: no upper/title chars and at least one lower. +pub fn str_islower(s: &str) -> bool { + let mut cased = false; + for c in s.chars() { + let f = ucd::case_flags(c as u32); + if f & (ucd::FLAG_UPPER | ucd::FLAG_TITLE) != 0 { + return false; + } + if f & ucd::FLAG_LOWER != 0 { + cased = true; + } + } + cased +} + +/// `unicode_istitle_impl`: cased runs start upper/title, and >=1 cased char. +pub fn str_istitle(s: &str) -> bool { + let mut cased = false; + let mut previous_is_cased = false; + for c in s.chars() { + let f = ucd::case_flags(c as u32); + if f & (ucd::FLAG_UPPER | ucd::FLAG_TITLE) != 0 { + if previous_is_cased { + return false; + } + previous_is_cased = true; + cased = true; + } else if f & ucd::FLAG_LOWER != 0 { + if !previous_is_cased { + return false; + } + previous_is_cased = true; + cased = true; + } else { + previous_is_cased = false; + } + } + cased +} diff --git a/crates/weavepy/src/lib.rs b/crates/weavepy/src/lib.rs index 952e544..4e14aad 100644 --- a/crates/weavepy/src/lib.rs +++ b/crates/weavepy/src/lib.rs @@ -275,6 +275,9 @@ pub fn run_source_with_options(source: &str, opts: &RunOptions) -> Result<(), Er source }; install_capi_loader(); + // `\N{NAME}` escapes resolve through the VM's UCD tables even for this + // pre-interpreter parse of the main module. + vm::install_parser_unicode_hook(); // Tokenizer-collected invalid-escape diagnostics (CPython's // `SyntaxWarning`s) are replayed through the `warnings` machinery // once the interpreter is up, just before the module body runs. diff --git a/docs/rfcs/0050-faithful-unicode-codecs-cjk-ucd.md b/docs/rfcs/0050-faithful-unicode-codecs-cjk-ucd.md new file mode 100644 index 0000000..efbb011 --- /dev/null +++ b/docs/rfcs/0050-faithful-unicode-codecs-cjk-ucd.md @@ -0,0 +1,427 @@ +# RFC 0050: Faithful Unicode — codec machinery completion, CJK multibyte codecs, UCD 15.1, locale/UTF-8 mode, and the severity-1 VM crashes + +- **Status**: Draft +- **Authors**: WeavePy authors +- **Created**: 2026-07-11 +- **Tracking issue**: TBD +- **Builds on**: RFC 0040 (WTF-8 `Object::WStr` storage + PEP 383 + `surrogateescape` filenames), RFC 0019 (`_codecs` native module), + RFC 0049 (wave-5 measured whole-suite baseline + the six built-in + error-handler callables). + +## Summary + +Close the Unicode/codec failure cluster — the largest single cluster +in the RFC 0049 measured baseline — by finishing the codec machinery +that RFC 0040's WTF-8 storage arc made possible but did not complete. +Concretely: (1) complete the `codecs` module surface to the documented +CPython 3.13 API (per-codec `_codecs` entry points, `EncodedFile`, +`StreamRecoder`, faithful `StreamReader`/`StreamWriter` semantics, +custom error-handler callbacks honored by the *native* encode/decode +engines); (2) ship the CJK multibyte codec stack — a native +`_multibytecodec` plus `_codecs_cn/_codecs_jp/_codecs_kr/_codecs_tw/ +_codecs_hk/_codecs_iso2022` backed by mapping tables generated from +host CPython 3.13, and the ~20 missing `encodings.*` wrapper modules +vendored verbatim; (3) re-base `unicodedata` (and the str-method case +tables that feed `test_stringprep` and identifier rules) on generated +UCD **15.1.0** tables, eliminating the measured Unicode-16.0 crate +skew; (4) finish PEP 540 UTF-8 mode (stdio `surrogateescape`/ +`backslashreplace` error defaults, `PYTHONUTF8`) and give `_locale` a +real libc backend; and (5) fix the three severity-1 VM crashes the +baseline records (`env::args()` panic on non-UTF-8 argv, `eval`/`exec` +on free-variable code, and `f_lineno` trace jumps that never move the +program counter). + +## Motivation + +The RFC 0049 baseline names Unicode/codecs as the largest failure +cluster and repeatedly annotates rows with "deferred to the WTF-8 +arc". The storage half of that arc landed in RFC 0040 — `chr(0xD800)`, +lone-surrogate literals, `os.fsencode` PEP 383 round-trips all work — +but the codec *machinery* half never followed. The measured cost +today: + +- `cpython/Lib/test/test_codecs.py`: 284 tests, **118 fail + 226 + error** (measured on `main`, 2026-07-11). The failures are not + storage failures; they are missing module attributes + (`codecs.utf_7_decode`, `unicode_escape_decode`, + `readbuffer_encode`, `charmap_build`, `EncodedFile`, + `StreamRecoder`, `encodings._cache`), stream-codec semantics + (`StreamReader.readline(keepends=)`, partial-input buffering, + `seek`/`reset` state), strictness gaps ("`UnicodeDecodeError` not + raised" × 38), and custom `register_error` handlers that the native + fast paths never consult. +- The seven `test_codecencodings_*`/`test_multibytecodec` labels and + five `test_codecmaps_*` labels are red for one reason: the CJK + codec stack does not exist (`ModuleNotFoundError: + _multibytecodec`, `LookupError: unknown encoding: big5hkscs`, …). +- `test_unicodedata` is *skipped* for UCD-version skew: the engine + ships Unicode 16.0.0 via the `unicode-properties`/`unicode_names2` + crates while CPython 3.13 pins **15.1.0**. A conformance suite + graded against CPython 3.13 must match CPython 3.13's database. +- `test_utf8_mode` fails on stdio error handlers (`utf-8/strict` + where CPython reports `utf-8/surrogateescape`), and `PYTHONUTF8` + is documented in `--help-env` but never read. +- `test__locale` fails because `_locale` is a C-locale stub + (`localeconv()['decimal_point']` is always `"."`). + +Beyond the label count: `surrogateescape` is CPython's filesystem +error handler on POSIX. Real programs hit these paths whenever argv, +environment variables, or filenames contain bytes that are not valid +UTF-8 — and today a non-UTF-8 argv **panics the VM** (`test_cmd_line`, +severity 1). A drop-in replacement cannot crash where CPython +degrades gracefully. The two other recorded InternalError crashes +(`test_scope`, `test_sys_settrace`) ride along in this RFC because +engine-integrity bugs should not wait for a thematic wave of their +own. + +## CPython reference + +- **Codec machinery**: `Modules/_codecsmodule.c`, + `Python/codecs.c` (error-handler registry + built-in handlers), + `Lib/codecs.py` (`EncodedFile`, `StreamRecoder`, `StreamReader` + buffering semantics), `Lib/encodings/__init__.py` (search + function + `_cache`). Docs: `Doc/library/codecs.rst`. Tests: + `Lib/test/test_codecs.py`, `Lib/test/test_codeccallbacks.py`, + `Lib/test/test_charmapcodec.py`. +- **Error handlers**: PEP 293 (codec error callbacks), PEP 383 + (`surrogateescape`), `surrogatepass` in + `Python/codecs.c:PyCodec_SurrogatePassErrors` (UTF-8/16/32 + variants). +- **CJK codecs**: `Modules/cjkcodecs/` (`multibytecodec.c`, the + `_codecs_cn/jp/kr/tw/hk/iso2022` modules and their `*.map` + tables), `Lib/encodings/{gbk,gb2312,gb18030,big5,big5hkscs,cp932, + cp949,cp950,euc_jp,euc_kr,euc_jis_2004,euc_jisx0213,shift_jis, + shift_jis_2004,shift_jisx0213,johab,hz,iso2022_jp,iso2022_jp_1, + iso2022_jp_2,iso2022_jp_2004,iso2022_jp_3,iso2022_jp_ext, + iso2022_kr}.py`. Tests: `Lib/test/test_multibytecodec.py`, + `Lib/test/test_codecencodings_*.py`, `Lib/test/test_codecmaps_*.py`, + data in `Lib/test/cjkencodings/`. +- **UCD**: `Modules/unicodedata_db.h` and `Tools/unicode/makeunicodedata.py` + (CPython generates its database; we generate ours the same way, from + the same pinned UCD 15.1.0 via host CPython 3.13), + `Doc/library/unicodedata.rst`. Tests: `Lib/test/test_unicodedata.py`, + `Lib/test/test_ucn.py`, `Lib/test/test_stringprep.py` (RFC 3454 over + UCD 3.2 tables in `Lib/stringprep.py`). +- **UTF-8 mode / locale**: PEP 540, PEP 538, + `Python/preconfig.c` (`PYTHONUTF8`, `-X utf8`), + `Python/pylifecycle.c` (stdio error-handler selection), + `Modules/_localemodule.c`. Tests: `Lib/test/test_utf8_mode.py`, + `Lib/test/test__locale.py`. +- **Crashes**: `Python/getargs.c`/`Modules/main.c` argv decoding + (`Py_DecodeLocale`, PEP 383); `Python/ceval.c` `eval`/`exec` + free-variable guard (`code object passed to exec() may not contain + free variables`); `Objects/frameobject.c:frame_setlineno` (the + authoritative "set next line" semantics: line→offset mapping, + block-stack reconciliation, the exhaustive "can't jump into/out + of…" error taxonomy). Tests: `Lib/test/test_cmd_line.py`, + `Lib/test/test_scope.py`, `Lib/test/test_sys_settrace.py` + (`JumpTestCase`). + +## Current baseline (measured starting point) + +From `tests/regrtest/expectations.toml` (RFC 0049 sweep) and fresh +probes on `main` (2026-07-11): + +| Label | Status | First failure | +|-------|--------|---------------| +| `test_codecs.py` | fail | 118 F / 226 E of 284 — module surface + stream semantics + strictness | +| `test_codeccallbacks.py` | fail | custom handlers unseen by native paths; `codecs.charmap_build` missing | +| `test_codecencodings_{cn,hk,iso2022,jp,kr,tw}.py` | fail ×6 | `LookupError: unknown encoding` / `ModuleNotFoundError: _multibytecodec` | +| `test_codecmaps_{cn,hk,jp,kr,tw}.py` | fail ×5 | same | +| `test_multibytecodec.py` | fail | `ModuleNotFoundError: No module named '_multibytecodec'` | +| `test_charmapcodec.py` | fail | charmap codec surface | +| `test_unicodedata.py` | skip | UCD 16.0 vs 15.1 skew + NormalizationTest budget | +| `test_ucn.py` | fail | `\N{...}` name-alias/named-sequence gaps (UCD skew) | +| `test_stringprep.py` | fail | RFC 3454 table drift (case/property tables) | +| `test_utf8_mode.py` | fail | stdio `strict` where CPython has `surrogateescape`; `PYTHONUTF8` unread | +| `test__locale.py` | fail | `_locale` is a C-locale stub (`'.' != ','`) | +| `test_cmd_line.py` | fail | **panic**: `env::args()` unwraps non-UTF-8 argv | +| `test_scope.py` | fail | **InternalError**: `bad cell index` — `eval(g.__code__)` with freevars | +| `test_sys_settrace.py` | fail | **InternalError**: `FOR_ITER no iter` — `f_lineno` jumps are cosmetic | + +Adjacent rows expected to improve but not gating: `test_str.py` +(encoding-edge residuals), `test_io.py` edges, `test_repl`/`test_site` +stdio-encoding interactions. + +## Detailed design + +### WS1 — Severity-1 VM crashes · ~1.5K LOC + +1. **Non-UTF-8 argv** (`crates/weavepy-cli/src/main.rs:530,679`). + Replace `env::args()` with `env::args_os()` and decode each + argument with UTF-8 + `surrogateescape` (PEP 383, matching + `Py_DecodeLocale` under UTF-8 mode) into the existing + `Str`/`WStr`-aware constructor path. `sys.argv` entries containing + undecodable bytes become `WStr` values that round-trip through + `os.fsencode`, exactly as CPython. The same helper feeds the + multiprocessing child re-exec path. `Interpreter::set_argv` + (`weavepy-vm/src/lib.rs`) grows a code-point-aware variant. +2. **`eval`/`exec` on free-variable code** + (`weavepy-vm/src/lib.rs`, `do_eval_call`/`do_exec_call`). Guard + before `make_frame`: if the code object has non-empty + `co_freevars`, raise `TypeError("code object passed to eval() may + not contain free variables")` (resp. `exec()`), CPython-verbatim. +3. **Real `f_lineno` assignment** (`weavepy-vm/src/lib.rs` frame + attribute setter + `weavepy-vm/src/object.rs` frame state). + Implement CPython's `frame_setlineno`: only legal from a `'line'` + trace event; map the target line to a bytecode offset via the line + table; compute the value/block-stack depth delta between source + and target using the same exception-table/stack-effect analysis + the compiler already has; refuse illegal jumps with CPython's + error messages (into/out of `for` iterators except backward jumps + that re-`GET_ITER`… — follow 3.13's rules: pop iterators and exit + `with`/`finally` blocks when jumping out, forbid jumping *into* + any block); set the live frame `pc`, truncate/adjust the stack, + clear `override_lineno`. `FOR_ITER`'s empty-stack InternalError + becomes unreachable through legal jumps; keep it as a hard + invariant. + +### WS2 — `codecs`/`_codecs` module surface completion · ~4K LOC + +Bring `crates/weavepy-vm/src/stdlib/codecs_mod.rs` + +`stdlib/python/codecs.py` to the documented 3.13 surface: + +1. **Per-codec `_codecs` entry points**, re-exported by `codecs`: + `utf_7_encode/decode`, `utf_8_encode/decode`, `utf_16_*`, + `utf_32_*` (+ `_le`/`_be`/`_ex` variants with the + `(result, consumed[, byteorder])` tuple shapes), + `latin_1_*`, `ascii_*`, `charmap_encode/decode/build`, + `unicode_escape_encode/decode`, `raw_unicode_escape_*`, + `readbuffer_encode`, `escape_encode/decode`. Each takes the + standard `(input, errors=None[, final])` signature and returns + CPython's exact tuple shape. +2. **UTF-7 as a real first-class codec** (encode + incremental + decode with base64-state carryover), replacing the `encoding_rs` + passthrough that cannot represent partial-shift state. +3. **Stream layer**: `codecs.EncodedFile`, `codecs.StreamRecoder`, + and faithful `StreamReader` semantics — `readline(size, keepends)`, + `read(size, chars, firstline)`, charbuffer/bytebuffer carry, + `seek`/`reset`. These are pure-Python in CPython's `Lib/codecs.py`; + we adopt the verbatim implementations and make the incremental + codec objects they depend on real. +4. **Error-handler unification.** Native encoders/decoders currently + hardcode the known handlers. Restructure to CPython's model: the + engine attempts the fast path; on error it *looks up the handler + by name* (built-ins dispatch to native implementations; anything + else calls the registered Python callable with a real + `UnicodeEncodeError`/`UnicodeDecodeError`/`UnicodeTranslateError` + carrying `object`/`start`/`end`/`reason`), applies the + `(replacement, new_position)` result — including **bytes** + replacements on encode (PEP 383 requires it) and backward + positions — and continues. This single change is what + `test_codeccallbacks.py` actually tests. +5. **Strictness sweep**: the 38 "`UnicodeDecodeError` not raised" + rows — UTF-8 (reject surrogates and over-long forms in strict + mode; `surrogatepass` accepts *only* the exact CESU-8 forms), + UTF-16/32 (truncated data, `\ud800` strict-encode rejection), + and the escape codecs (trailing `\`, `\x` without two hex + digits → `ValueError` with CPython's messages, invalid-escape + `DeprecationWarning` parity). +6. **`encodings` package internals**: `encodings._cache`, + `encodings._unknown`, `search_function` shape, + `encodings.normalize_encoding` (the tests import these), plus + `codecs.lookup()` returning a real populated `CodecInfo` with + `_is_text_encoding`. + +### WS3 — `_multibytecodec` + CJK codec modules · ~6K LOC + generated tables + +The centerpiece. Native `crates/weavepy-vm/src/stdlib/ +multibytecodec_mod.rs` implementing CPython's +`Modules/cjkcodecs/multibytecodec.c` object model: + +- `MultibyteCodec` (opaque codec handle with `encode`/`decode`), + `MultibyteIncrementalEncoder`, `MultibyteIncrementalDecoder` + (with `getstate`/`setstate` returning CPython's shapes), + `MultibyteStreamReader`, `MultibyteStreamWriter`. +- Error-handler integration goes through the WS2 unified callback + machinery (CJK tests exercise custom handlers heavily). + +Codec engines, one per family, in +`crates/weavepy-vm/src/stdlib/cjkcodecs/`: + +- **cn**: gb2312, gbk, gb18030 (incl. the 4-byte linear region), + hz (stateful `~{`/`~}` shifts). +- **jp**: cp932, euc_jp, euc_jis_2004, euc_jisx0213, shift_jis, + shift_jis_2004, shift_jisx0213, and the stateful + iso2022_jp/_1/_2/_2004/_3/_ext family (escape-sequence state + machine shared with **iso2022** kr). +- **kr**: euc_kr (incl. the 8-byte UHC extension semantics of + cp949), cp949, johab, iso2022_kr. +- **tw**: big5, cp950. +- **hk**: big5hkscs (incl. the U+00CA-style double-codepoint + mappings and the `\N{...}` compatibility points that WHATWG big5 + gets wrong). + +Mapping tables are **generated from host CPython 3.13** by a new +`tools/gen_cjk_tables.py`: for every codec, exhaustively round-trip +the byte space and the BMP+SIP code-point space through CPython's +codec, emitting dense range-compressed decode tables and sorted +encode tables as packed `&'static [u8]` blobs (`include_bytes!` from +`crates/weavepy-vm/src/stdlib/cjkcodecs/tables/*.bin`, with a small +loader; regeneration is a checked-in, reproducible script, mirroring +CPython's own `Tools/unicode/` generation story). `encoding_rs` stays +for the WHATWG single-byte encodings but is **no longer consulted for +CJK** — its WHATWG semantics diverge from CPython's tables precisely +where the tests look. + +The ~24 `encodings/*.py` CJK wrapper modules are vendored verbatim +from CPython (`getregentry()` over `_codecs_*.getcodec` + +`_multibytecodec` incremental/stream classes) and added to +`frozen_sources()`. + +### WS4 — `unicodedata` on UCD 15.1.0 · ~2K LOC + generated tables + +Replace the crate-backed engine in +`stdlib/unicodedata_mod.rs` with generated tables pinned to CPython +3.13's database, produced by `tools/gen_ucd_tables.py` running under +host CPython 3.13 (whose `unicodedata` *is* UCD 15.1.0): + +- Per-code-point record (category, bidirectional, combining, + mirrored, east_asian_width, decimal/digit/numeric, decomposition + type+mapping) in the two-level trie layout CPython itself uses + (`makeunicodedata.py` splitbins), packed via `include_bytes!`. +- `name()`/`lookup()` from a generated name index (replacing + `unicode_names2`), including PEP 3131 name aliases and named + sequences (`test_ucn` exercises both) and the `ucd_3_2_0` snapshot + object (delta table against 3.2, as CPython ships). +- NFC/NFD/NFKC/NFKD + `is_normalized` quick-check from the same + tables (replacing `unicode-normalization` in the module; the + parser's NFKC identifier fold switches to the same source of + truth). +- Retire `unicode_decomp_data.rs` and the crate deps from the + module; `unidata_version` becomes `"15.1.0"`. +- Feed the same generation pass into the str-method tables that + `test_stringprep` and `str.title()/casefold()/isidentifier()` + depend on (`XID_Start`/`XID_Continue`, Cased/Case_Ignorable, + full case folding), replacing the ad-hoc `casefold_char()` overlay. + +### WS5 — UTF-8 mode, stdio encoding, and real `_locale` · ~2K LOC + +1. **`PYTHONUTF8`** read in `weavepy-cli` `EnvOverrides::from_env()` + (respecting `-E`/`-I`), combined with `-X utf8` per PEP 540 + precedence, driving `sys.flags.utf8_mode`. +2. **Stdio error handlers**: under UTF-8 mode, `sys.stdin`/`stdout` + get `errors="surrogateescape"` and `sys.stderr` + `errors="backslashreplace"` (CPython always uses + `backslashreplace` for stderr regardless of mode); + `PYTHONIOENCODING` (`encoding[:errors]`) overrides both. Fix + `PyFile::errors_name()` defaults and the `encoding`/`errors` + reporting on the std streams. +3. **Real `_locale`** (`stdlib/locale_mod.rs`): back + `setlocale`/`localeconv`/`nl_langinfo`/`strcoll`/`strxfrm` with + libc (the `libc` crate is already a dependency), including the + `localeconv` grouping/decimal-point fields `test__locale` checks + across the locales it probes (skipping gracefully where the host + lacks a locale, as CPython's test does). `locale.getpreferredencoding` + and `locale.getlocale` become locale-aware, with PEP 538/540 + coercion semantics preserved. + +### WS6 — Fixtures + measured baseline rewrite · ~1K LOC + +- New bundled regrtests: WTF-8 argv/env round-trip (spawns a child + with non-UTF-8 argv), CJK codec round-trip against + `Lib/test/cjkencodings/` data, error-handler callback protocol, + UCD version + `name`/`lookup` spot checks, stdio error-handler + matrix, and a `f_lineno` jump matrix mirroring `JumpTestCase` + shapes. +- Re-run the full sweep (`--all-cpython --no-check --mode subprocess + --jobs 8`) and rewrite the touched rows of + `tests/regrtest/expectations.toml` to the new measured reality — + same policy as RFC 0049: green rows lose their entry, red rows + carry the measured first failure. + +## Measured targets + +Labels this RFC intends to flip to `pass` (from the baseline table +above): `test_codecs`, `test_codeccallbacks`, `test_charmapcodec`, +`test_codecencodings_{cn,hk,iso2022,jp,kr,tw}`, +`test_codecmaps_{cn,hk,jp,kr,tw}`, `test_multibytecodec`, +`test_unicodedata` (un-skipped; NormalizationTest may stay +budget-capped — if so the row records that explicitly), +`test_ucn`, `test_stringprep`, `test_utf8_mode`, `test__locale`, +and the three crash rows (`test_cmd_line`, `test_scope`, +`test_sys_settrace`) at minimum crash-free with measured residuals. +That is **up to 20 labels**, plus expected residual improvements in +`test_str`, `test_io`, and the CLI family. + +Hard acceptance floor: zero Rust panics / InternalErrors across the +whole sweep; `--check` green against the rewritten baseline; no +regression on any currently-green row; `cargo fmt` + `clippy -D +warnings` + full workspace tests green. + +## Non-goals / Drawbacks + +- **No PEP 393 storage rewrite.** RFC 0040's dual `Str`/`WStr` + representation stays; this RFC closes machinery gaps, not storage. + The C-API mirror already fabricates PEP 393 bodies for extensions. +- **`test_locale` (the frozen `locale.py` suite) stays skipped** — + it needs `setlocale` to succeed for specific locales in CI; WS5 + makes `_locale` real but the row stays measured, not promised. +- **No `aliases.py` beyond CPython's.** Alias behavior is vendored, + not extended. +- Generated tables add ~1–2 MB of packed data to the binary. CPython + carries the same data (`unicodedata` ≈ 1.2 MB, cjkcodecs maps + ≈ 1 MB); we accept the size for fidelity. Regeneration requires a + host CPython 3.13, documented in the tool headers. +- The `f_lineno` jump implementation is the riskiest piece (stack + reconciliation); it is deliberately scoped to CPython 3.13's legal + jump set, with illegal jumps raising CPython's exact errors rather + than attempting best-effort execution. + +## Alternatives + +- **Keep `encoding_rs` for CJK.** Rejected: WHATWG mapping semantics + (big5 vs cp950, euc-jp extension rows, gb18030-2022 updates) + diverge from CPython's tables exactly where `test_codecmaps_*` + looks; no incremental-state surface compatible with + `_multibytecodec`'s `getstate`/`setstate` contract. +- **Port CPython's C `cjkcodecs` verbatim.** The table *data* is + what matters; the C state machines are small. Generating tables + from the host oracle gives byte-identical behavior with far less + transliteration risk than porting `_codecs_iso2022.c` line by line. +- **Upgrade conformance to Unicode 16 instead of downgrading tables.** + Rejected: CPython 3.13 is the spec; its tests hardcode 15.1.0 + behavior (`test_ucn` aliases, East Asian widths). +- **Leave the crashes to a dedicated hardening RFC.** Rejected: + two of the three are in this RFC's blast radius anyway (argv + decoding is PEP 383; settrace jumps gate `test_sys_settrace`, + which the observability arc of RFC 0031 already claims). + +## Prior art + +- **CPython** generates both its UCD and CJK tables + (`Tools/unicode/makeunicodedata.py`, `Tools/unicode/genmap_*.py`); + this RFC adopts the same generate-don't-transcribe philosophy with + CPython itself as the oracle. +- **PyPy** implements `_multibytecodec` in RPython over the same + CPython-derived map files — evidence that the object model ports + cleanly without the C code. +- **RustPython** vendors `unicode_names2`/`unicode-casing` crates and + carries known UCD-version skew against CPython — the exact trap + this RFC removes. + +## Unresolved questions + +- Whether `test_unicodedata`'s full `NormalizationTest` sweep fits + the per-test budget once tables are native (expected: yes in + release; the row records the measured answer). +- How far `test__locale` can go in CI where only `C`/`POSIX`/UTF-8 + locales are installed (the test skips per-locale; the row records + the measured verdict). +- Whether `iso2022_jp_2004`/`_3` corner mappings (JIS X 0213 plane-2) + need the `euc_jis_2004` frozen fallback retired or kept as the + table source. + +## Future work + +- The remaining `test_codecs` locale-codec rows that require + `_testinternalcapi.EncodeLocaleEx`/`DecodeLocaleEx` (C-API test + shims, not codec behavior). +- `str` method UCD fidelity beyond stringprep's needs (full + `str.title()` Cased/Case_Ignorable rules) — started here, finished + alongside the `test_str` residual cluster. +- PEP 686 (UTF-8 mode by default in 3.15) tracking. +- The wave-6 conformance sweep of the core-language cluster + (`test_builtin`, `test_syntax`, compiler/dis parity) — explicitly + *not* this RFC. diff --git a/tests/regrtest/expectations.toml b/tests/regrtest/expectations.toml index b69ac12..41e8ba7 100644 --- a/tests/regrtest/expectations.toml +++ b/tests/regrtest/expectations.toml @@ -45,8 +45,8 @@ status = "fail" reason = "measured (RFC 0049 wave-5 full-suite baseline): Dur\u2026[truncated]" [tests."cpython/Lib/test/test__locale.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): AssertionError: '.' != ','" +status = "pass" +reason = "RFC 0050 WS5: real libc-backed _locale — setlocale/localeconv/nl_langinfo (with the full langinfo constant table incl. RADIXCHAR/THOUSEP/ERA/ALT_DIGITS), wcscoll/wcsxfrm collation, getencoding via nl_langinfo(CODESET), and locale strings decoded with mbstowcs under the current LC_CTYPE. LC_CTYPE is adopted from the environment at interpreter start (CPython's _Py_SetLocaleFromEnv). ALT_DIGITS/ERA subtests skip on macOS exactly as CPython does (the host locales don't carry that data)." [tests."cpython/Lib/test/test__opcode.py"] status = "fail" @@ -165,7 +165,7 @@ reason = "measured (RFC 0049 wave-5 full-suite baseline): AssertionError: Failed [tests."cpython/Lib/test/test_cmd_line.py"] status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): thread 'weavepy-main' (317296) panicked at /rustc/2d8144b7880597b6e6d3dfd63a9a9efae3f533d3/library/std/src/env.rs:876:51:" +reason = "measured (RFC 0050 WS5 re-baseline): crash-free — the env.rs Rust panic from the wave-5 baseline is gone. 60 run, 31 residual failures across CLI surface gaps (-X option matrix, stdin/tty prompts, warning-option plumbing), no panics or InternalErrors." [tests."cpython/Lib/test/test_cmd_line_script.py"] status = "timeout" @@ -180,36 +180,37 @@ status = "fail" reason = "measured (RFC 0049 wave-5 full-suite baseline): ValueError: substring not found" [tests."cpython/Lib/test/test_codeccallbacks.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): TypeError," +status = "pass" +reason = "RFC 0050 WS2: passes end-to-end (40 tests, 0F/0E). Unified codec engine (codecs_engine.rs) drives all UTF-family encode/decode with full custom error-handler protocol: handler resolution via codecs.lookup_error, exc.object mutation with re-validation, position clamping/negative-index semantics, byte- and str-replacement alignment rules for UTF-16/32, and CPython's strict UnicodeError constructor/attribute validation." [tests."cpython/Lib/test/test_codecencodings_cn.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): ^^^^^^^\u2026[truncated]" +status = "pass" +reason = "RFC 0050 WS3: passes (76 tests, 2 skips). gb2312/gbk/gb18030/hz via the frozen _codec_cjk_dbcs + _codec_cjk_ext modules with CPython-parity tables and multibytecodec.c error/state protocol." [tests."cpython/Lib/test/test_codecencodings_hk.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): LookupError: unknown encodi\u2026[truncated]" +status = "pass" +reason = "RFC 0050 WS3: passes (19 tests). big5hkscs (incl. combining pairs and the stateful pair-lookahead encoder) via the frozen _codec_cjk_dbcs module." [tests."cpython/Lib/test/test_codecencodings_iso2022.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): \u2026[truncated]" +status = "pass" +reason = "RFC 0050 WS3: passes (95 tests, 1 skip). All seven iso2022_* variants via the frozen _codec_cjk_ext state machines ported from _codecs_iso2022.c." [tests."cpython/Lib/test/test_codecencodings_jp.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): File '', line 988, in\u2026[truncated]" +status = "pass" +reason = "RFC 0050 WS3: passes (133 tests). cp932/euc_jp/shift_jis + the JIS X 0213 family (euc_jis_2004, shift_jis_2004, euc_jisx0213, shift_jisx0213) via the frozen CJK codec modules." [tests."cpython/Lib/test/test_codecencodings_kr.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): raise LookupError('unknown encoding: ' + encoding) fro\u2026[truncated]" +status = "pass" +reason = "RFC 0050 WS3: passes (57 tests). euc_kr (incl. 8-byte jamo make-up sequences), cp949 and johab via the frozen CJK codec modules." [tests."cpython/Lib/test/test_codecencodings_tw.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): File '', line 795, in asser\u2026[truncated]" +status = "pass" +reason = "RFC 0050 WS3: passes (19 tests). big5/cp950 via the frozen _codec_cjk_dbcs module." [tests."cpython/Lib/test/test_codecs.py"] -status = "fail" -reason = "measured (RFC 0038 WS-A): 21 pass, 14 fail, 214 error. Dominated by the `surrogateescape`/`surrogatepass` error handlers (`ValueError: unknown error handler: surrogateescape`), which require lone-surrogate-preserving (WTF-8) str storage \u2014 the same str-representation change that gates test_posixpath. Deferred to the WTF-8 arc (wave 4)." +status = "pass" +timeout_seconds = 120 +reason = "RFC 0050 WS2+WS3: passes end-to-end (284 run, 13 skip). WS2 delivered error-handler unification, UTF-7, stateful UTF-16/32 decoders, the stream layer, unicode-escape handler protocol, 57 vendored charmap codepages, and the IDNA/punycode/nameprep surface. WS3 added the stateful CJK escape codecs (_codec_cjk_ext: hz, iso2022_jp/_1/_2/_2004/_3/_ext, iso2022_kr, johab, shift_jis_2004/shift_jisx0213) plus the euc_jisx0213 2000-emulation variant, ported from Modules/cjkcodecs and differentially verified against CPython 3.13." [tests."cpython/Lib/test/test_codeop.py"] status = "fail" @@ -612,7 +613,7 @@ reason = "RFC 0039 WS6: native libc-backed select.kqueue/kevent" [tests."cpython/Lib/test/test_linecache.py"] status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): FileNotFoundError: [Errno 2] No such file or directory: 'linecache.py'" +reason = "RFC 0050 WS3: 26/28 pass (was 2F/11E). The two residual cases (test_getline, test_clearcache) open `os.path.dirname(linecache.__file__) + '/linecache.py'`; WeavePy's linecache is a frozen module (``) whose source intentionally differs from the vendored CPython copy, so there is no honest on-disk `__file__` to report." [tests."cpython/Lib/test/test_list.py"] status = "pass" @@ -690,8 +691,8 @@ status = "fail" reason = "measured (RFC 0049 wave-5 full-suite baseline): File '/Users/owencarey/Documents/weavefoundry/weavepy/vendor/\u2026[truncated]" [tests."cpython/Lib/test/test_multibytecodec.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): ModuleNotFoundError: No module named '_multibytecodec'" +status = "pass" +reason = "RFC 0050 WS3: passes (36 tests, 1 cpython_only skip). Frozen _multibytecodec surface + the multibytecodec.c getstate/setstate C layout (length-prefixed UTF-8 pending, 8 codec state bytes, OverflowError/UnicodeError validation) implemented in _cjk_common and the three frozen CJK codec modules." [tests."cpython/Lib/test/test_multiprocessing_fork.py"] status = "skip" @@ -873,8 +874,8 @@ status = "fail" reason = "random: Mersenne Twister state save/load + SystemRandom" [tests."cpython/Lib/test/test_range.py"] -status = "timeout" -reason = "measured (RFC 0049 wave-5 full-suite baseline): killed after 60s" +status = "fail" +reason = "measured (RFC 0050 WS5 re-baseline): the suite now completes inside the budget (was: killed after 60s), surfacing three pre-existing engine gaps — range attribute assignment raises TypeError instead of AttributeError (test_attributes), range() over ints beyond i64 overflows (test_comparison, 2**200 bounds), and float membership `5.0 in range(10)` is False (test_contains). Object-model follow-ups outside RFC 0050's codec/UCD scope." [tests."cpython/Lib/test/test_re.py"] status = "fail" @@ -914,7 +915,7 @@ reason = "measured (RFC 0039): passes end-to-end \u2014 sched.scheduler enterabs [tests."cpython/Lib/test/test_scope.py"] status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): InternalError: bad cell index" +reason = "measured (RFC 0050 WS5 re-baseline): crash-free — the 'bad cell index' InternalError from the wave-5 baseline is gone. 4 residual NameErrors around class-body free-variable scoping (e.g. a method closing over an enclosing function's local shadowed by a class attribute); compiler symbol-table follow-up." [tests."cpython/Lib/test/test_secrets.py"] status = "fail" @@ -1012,8 +1013,8 @@ status = "pass" reason = "WS2c: tokenizer now records invalid-escape / oversized-octal SyntaxWarnings (with exact backslash offsets) and the compile path replays them via warnings.warn_explicit (escalating to a located SyntaxError under an 'error' filter); bytes literals reject non-ASCII and bad prefixes (ur/ru/bb/rr/...) raise SyntaxError. All 20 tests pass." [tests."cpython/Lib/test/test_stringprep.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): AssertionError: False is not true" +status = "pass" +reason = "RFC 0050 WS4: unicodedata rebuilt on generated UCD 15.1.0 tables (matching CPython 3.13's pinned database), so the stringprep table predicates line up." [tests."cpython/Lib/test/test_strptime.py"] status = "fail" @@ -1066,7 +1067,7 @@ reason = "measured (RFC 0049 wave-5 full-suite baseline): AssertionError: Expect [tests."cpython/Lib/test/test_sys_settrace.py"] status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): InternalError: FOR_ITER no iter [other run: timeout]" +reason = "measured (RFC 0050 WS5 re-baseline): crash-free and inside the budget — the 'FOR_ITER no iter' InternalError and the timeout from the wave-5 baseline are gone. 449 run in ~4s; 159F/16E residual, dominated by the JumpTestCase f_lineno-assignment matrix (frame.f_lineno jumps are not yet implemented) plus line-event granularity diffs; tracked as RFC 0050 follow-up work." [tests."cpython/Lib/test/test_sysconfig.py"] status = "fail" @@ -1099,8 +1100,8 @@ reason = "measured: passes end-to-end after wiring `open(opener=...)` + file-des [tests."cpython/Lib/test/test_threading.py"] status = "pass" -timeout_seconds = 300 -reason = "RFC 0039: real OS threads with cooperative GIL hand-off, faithful Lock/RLock (subclassable `_thread.RLock`), thread-death thread-local cleanup (foreign-thread `_DummyThread` reaping), and prompt refcount reclamation of acyclic garbage \u2014 including the cross-thread `Thread.run` teardown cycle (`test_no_refcycle_through_target`) swept on `join()`. All 213 tests pass (29 skips for CPython-only knobs). 180s: the suite runs ~32s standalone; with the main thread participating in GIL hand-offs it exceeds the 60s cap under 4-way parallel worker load." +timeout_seconds = 600 +reason = "RFC 0039: real OS threads with cooperative GIL hand-off, faithful Lock/RLock (subclassable `_thread.RLock`), thread-death thread-local cleanup (foreign-thread `_DummyThread` reaping), and prompt refcount reclamation of acyclic garbage \u2014 including the cross-thread `Thread.run` teardown cycle (`test_no_refcycle_through_target`) swept on `join()`. All 213 tests pass (29 skips for CPython-only knobs). 600s: the suite runs ~32s standalone and passes under moderate load, but with the main thread participating in GIL hand-offs it has been observed exceeding even 300s under full parallel sweep load (RFC 0050 WS6 re-measure); the raised budget keeps the verdict about correctness, not scheduler contention." [tests."cpython/Lib/test/test_threading_local.py"] status = "fail" @@ -1167,20 +1168,20 @@ status = "fail" reason = "typing: PEP 695 type aliases + ParamSpec.kwargs" [tests."cpython/Lib/test/test_ucn.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): node_or_string = parse(node_or_string.lstrip(' \\t'), mode='e\u2026[truncated]" +status = "pass" +reason = "RFC 0050 WS4: \\N{...} and unicodedata.lookup resolve through the generated UCD 15.1.0 tables — canonical + algorithmic names (incl. lookup-only Tangut), NameAliases, and NamedSequences (lookup-only, rejected by \\N and ucd_3_2_0)." [tests."cpython/Lib/test/test_unicode_identifiers.py"] status = "pass" reason = "PEP 3131: parser NFKC-normalizes identifiers and compile()/import raise SyntaxError with CPython .msg/.lineno/.offset for the badsyntax_3131 fixture (RFC 0037 WS2/WS5)" [tests."cpython/Lib/test/test_unicodedata.py"] -status = "skip" -reason = "RFC 0036: name/lookup now use the full UCD table (unicode_names2), but the full NormalizationTest sweep exceeds the per-test budget and residual failures track the UCD-version skew (engine ships 16.0.0, CPython 3.13 pins 15.1.0)" +status = "pass" +reason = "RFC 0050 WS4: unicodedata rebuilt on generated UCD 15.1.0 tables probed from CPython 3.13 (records/names/normalization + ucd_3_2_0 snapshot with NormalizationCorrections), str case methods/predicates rewired to the same tables (method checksum matches), and \\N escapes honour a poisoned sys.modules['unicodedata']. Full suite green." [tests."cpython/Lib/test/test_unittest.py"] -status = "timeout" -reason = "measured (RFC 0049 wave-5 full-suite baseline): killed after 60s" +status = "fail" +reason = "measured (RFC 0050 WS5 re-baseline): the suite now finishes inside the budget (~33s; was killed after 60s) and grades fail — a large residual cluster around unittest.mock/loader internals unrelated to this RFC's codec/UCD scope." [tests."cpython/Lib/test/test_unpack.py"] status = "pass" @@ -1221,12 +1222,12 @@ timeout_seconds = 180 reason = "measured (RFC 0049): UserString F cluster mirrors test_str residuals; ~54s to verdict, budget raised" [tests."cpython/Lib/test/test_utf8_mode.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): AssertionError: Lists differ: ['stdin: utf-8/strict', 'stdout: utf-8/strict', 'stderr: utf-8/strict'] != ['stdin: utf-8/surrogateescape', 'stdout: utf-8/surroga" +status = "pass" +reason = "RFC 0050 WS5: PEP 540 done — PYTHONUTF8 env var (with the invalid-value fatal error), -X utf8 priority, and the C/POSIX-locale default drive sys.flags.utf8_mode; stdio error handlers match config_init_stdio (stdin/stdout surrogateescape under UTF-8 mode or a coercion-target locale, strict when PYTHONIOENCODING gives an encoding, stderr always backslashreplace) and sys.std*.encoding reports the canonical codec name (latin1 → iso8859-1). One skip: sys.stdout is not a TTY (device_encoding)." [tests."cpython/Lib/test/test_utf8source.py"] -status = "fail" -reason = "measured (RFC 0049 wave-5 full-suite baseline): ImportError: failed to read '/Users/owencarey/Documents/weavefoundry/weavepy/vendor/cpython/Lib/test/tokenizedata/badsyntax_pep3120.py': stream did not contain " +status = "pass" +reason = "RFC 0050 WS3/WS4: imported modules now decode through the PEP 263 BOM/coding-cookie path (registry-backed codecs included) instead of a strict-UTF-8 read_to_string, so the tokenizedata fixtures load and error like CPython." [tests."cpython/Lib/test/test_uuid.py"] status = "pass" diff --git a/tests/regrtest/test_rfc0050_cjk_corpus.py b/tests/regrtest/test_rfc0050_cjk_corpus.py new file mode 100644 index 0000000..538ccee --- /dev/null +++ b/tests/regrtest/test_rfc0050_cjk_corpus.py @@ -0,0 +1,52 @@ +"""RFC 0050 WS6 — CJK codec round-trip over CPython's cjkencodings corpus. + +Each `.txt` / `-utf8.txt` pair under +`vendor/cpython/Lib/test/cjkencodings/` must decode and re-encode +byte-for-byte through the frozen CJK engines, exactly as +`test_multibytecodec_support.TestBase.test_chunkcoding` grades. +Skips silently when the vendored corpus is absent. +""" + +import os +import sys + +HERE = os.path.dirname(os.path.abspath(__file__)) +CORPUS = os.path.normpath( + os.path.join(HERE, "..", "..", "vendor", "cpython", "Lib", "test", "cjkencodings") +) + +if not os.path.isdir(CORPUS): + print("cjk corpus: skipped (vendored cjkencodings data not found)") + sys.exit(0) + +# File-name stem → codec name (mirrors test_codecencodings_* supported map). +CODECS = [ + "big5", "big5hkscs", "cp949", "euc_jisx0213", "euc_jp", "euc_kr", + "gb18030", "gb2312", "gbk", "hz", "iso2022_jp", "iso2022_kr", + "johab", "shift_jis", "shift_jisx0213", +] + +checked = 0 +for name in CODECS: + raw_path = os.path.join(CORPUS, f"{name}.txt") + ref_path = os.path.join(CORPUS, f"{name}-utf8.txt") + if not (os.path.exists(raw_path) and os.path.exists(ref_path)): + continue + with open(raw_path, "rb") as f: + raw = f.read() + with open(ref_path, "rb") as f: + text = f.read().decode("utf-8") + decoded = raw.decode(name) + assert decoded == text, f"{name}: decode mismatch" + # euc_jisx0213/shift_jisx0213 hold combining pairs that re-encode to + # equivalent-but-different bytes in CPython too; round-trip the text + # through encode→decode instead for those, byte-exact for the rest. + encoded = text.encode(name) + if name in ("euc_jisx0213", "shift_jisx0213"): + assert encoded.decode(name) == text, f"{name}: re-decode mismatch" + else: + assert encoded == raw, f"{name}: encode mismatch" + checked += 1 + +assert checked >= 10, f"only {checked} corpus pairs found — corpus layout changed?" +print(f"cjk corpus round-trip ok ({checked} codecs)") diff --git a/tests/regrtest/test_rfc0050_stdio_wtf8.py b/tests/regrtest/test_rfc0050_stdio_wtf8.py new file mode 100644 index 0000000..8eee043 --- /dev/null +++ b/tests/regrtest/test_rfc0050_stdio_wtf8.py @@ -0,0 +1,100 @@ +"""RFC 0050 WS6 — stdio error-handler matrix + WTF-8 argv round-trip. + +Spawns child interpreters (sys.executable) to pin the PEP 540/538 +startup surface WS5 implemented: PYTHONUTF8 precedence, the stdio +error-handler defaults, PYTHONIOENCODING normalization, and PEP 383 +surrogateescape argv round-tripping of non-UTF-8 bytes. +""" + +import os +import subprocess +import sys + +PY = sys.executable + + +def run(args, env_extra=None, expect_fail=False): + env = dict(os.environ) + env.pop("PYTHONUTF8", None) + env.pop("PYTHONIOENCODING", None) + if env_extra: + env.update(env_extra) + proc = subprocess.run( + [PY, *args], env=env, capture_output=True, text=True, timeout=60 + ) + if expect_fail: + assert proc.returncode != 0, (args, proc.returncode, proc.stderr) + return proc.stderr.strip() + assert proc.returncode == 0, (args, proc.returncode, proc.stderr) + return proc.stdout.strip() + + +FLAG = "import sys; print(sys.flags.utf8_mode)" +STDIO = ( + "import sys;" + "print(sys.stdin.encoding, sys.stdin.errors," + " sys.stdout.encoding, sys.stdout.errors," + " sys.stderr.encoding, sys.stderr.errors)" +) + +# PYTHONUTF8 drives sys.flags.utf8_mode; -X utf8 wins; -E ignores the env. +assert run(["-c", FLAG], {"PYTHONUTF8": "1"}) == "1" +assert run(["-c", FLAG], {"PYTHONUTF8": "0"}) == "0" +assert run(["-X", "utf8=0", "-c", FLAG], {"PYTHONUTF8": "1"}) == "0" +assert run(["-X", "utf8", "-c", FLAG], {"PYTHONUTF8": "0"}) == "1" +err = run(["-c", FLAG], {"PYTHONUTF8": "bogus"}, expect_fail=True) +assert "invalid PYTHONUTF8 environment variable value" in err, err +# The C/POSIX locale enables the mode by default (PEP 540). +assert run(["-c", FLAG], {"LC_ALL": "C", "PYTHONUTF8": ""}) == "1" + +# Stdio error handlers under UTF-8 mode: stdin/stdout surrogateescape, +# stderr always backslashreplace. +out = run(["-X", "utf8", "-c", STDIO], {"PYTHONIOENCODING": ""}) +assert out.split() == [ + "utf-8", "surrogateescape", + "utf-8", "surrogateescape", + "utf-8", "backslashreplace", +], out + +# PYTHONIOENCODING beats UTF-8 mode; the encoding half is reported under +# its canonical codec name and forces strict on stdin/stdout — stderr +# stays backslashreplace. +out = run(["-X", "utf8", "-c", STDIO], {"PYTHONIOENCODING": "latin1"}) +assert out.split() == [ + "iso8859-1", "strict", + "iso8859-1", "strict", + "iso8859-1", "backslashreplace", +], out + +# An errors-only spec (":handler") applies to stdin/stdout only. +out = run(["-X", "utf8", "-c", STDIO], {"PYTHONIOENCODING": ":namereplace"}) +assert out.split() == [ + "utf-8", "namereplace", + "utf-8", "namereplace", + "utf-8", "backslashreplace", +], out + +# --------------------------------------------------------------------------- +# WTF-8 / PEP 383: a non-UTF-8 argv byte round-trips through the child's +# sys.argv (as a lone surrogate) back to the same OS bytes on stdout. +# --------------------------------------------------------------------------- + +env = dict(os.environ) +proc = subprocess.run( + [PY.encode(), b"-c", + b"import sys; sys.stdout.buffer.write(sys.argv[1].encode('utf-8', 'surrogateescape'))", + b"a\xffb"], + env=env, capture_output=True, timeout=60, +) +assert proc.returncode == 0, proc.stderr +assert proc.stdout == b"a\xffb", proc.stdout + +# The same escape must be visible as a lone surrogate inside the child. +proc = subprocess.run( + [PY.encode(), b"-c", b"import sys; print(ascii(sys.argv[1]))", b"a\xffb"], + env=env, capture_output=True, timeout=60, +) +assert proc.returncode == 0, proc.stderr +assert proc.stdout.decode().strip() == "'a\\udcffb'", proc.stdout + +print("stdio matrix + wtf8 argv round-trip ok") diff --git a/tests/regrtest/test_rfc0050_unicode_codecs.py b/tests/regrtest/test_rfc0050_unicode_codecs.py new file mode 100644 index 0000000..5c6ac57 --- /dev/null +++ b/tests/regrtest/test_rfc0050_unicode_codecs.py @@ -0,0 +1,133 @@ +"""RFC 0050 WS6 — Unicode/codec machinery invariants. + +Pins the WS2–WS5 surface in-process (no CPython checkout needed): +the error-handler callback protocol, UCD 15.1.0 name/lookup/property +spot checks, CPython-parity str case mappings and predicates, and the +CJK codec round-trip semantics the frozen `_codec_cjk_*` engines +implement. +""" + +import codecs +import sys +import unicodedata + + +# --------------------------------------------------------------------------- +# Error-handler callback protocol: a registered handler receives the exact +# exception CPython builds (object/start/end/reason attributes), and its +# (replacement, new_position) result is honoured — including a negative +# position (counts from the end) and a bytes replacement on encode. +# --------------------------------------------------------------------------- + +seen = [] + + +def handler(exc): + seen.append((type(exc).__name__, exc.object[exc.start:exc.end], exc.start, exc.end)) + return ("?", exc.end) + + +codecs.register_error("rfc0050-probe", handler) + +assert "ab\udc80cd".encode("ascii", "rfc0050-probe") == b"ab?cd" +assert seen[-1] == ("UnicodeEncodeError", "\udc80", 2, 3) + +assert b"ab\xffcd".decode("ascii", "rfc0050-probe") == "ab?cd" +assert seen[-1] == ("UnicodeDecodeError", b"\xff", 2, 3) + +# Built-in handlers, one probe each (the WS2 strictness sweep). +assert "a\udc80b".encode("utf-8", "surrogateescape") == b"a\x80b" +assert b"a\x80b".decode("utf-8", "surrogateescape") == "a\udc80b" +assert "a\u20acb".encode("ascii", "backslashreplace") == b"a\\u20acb" +assert "a\u20acb".encode("ascii", "namereplace") == b"a\\N{EURO SIGN}b" +assert "a\u20acb".encode("ascii", "xmlcharrefreplace") == b"a€b" +assert b"a\xffb".decode("utf-8", "replace") == "a\ufffdb" +try: + b"\xff".decode("utf-8") +except UnicodeDecodeError as e: + assert e.reason == "invalid start byte", e.reason +else: + raise AssertionError("strict utf-8 decode of 0xff must raise") + +# --------------------------------------------------------------------------- +# unicodedata: UCD 15.1.0 with aliases, named sequences, and algorithmic +# names (WS4). +# --------------------------------------------------------------------------- + +assert unicodedata.unidata_version == "15.1.0", unicodedata.unidata_version +assert unicodedata.name("\u20ac") == "EURO SIGN" +assert unicodedata.lookup("EURO SIGN") == "\u20ac" +# Alias (NameAliases.txt) and a lookup-only algorithmic range (Tangut). +assert unicodedata.lookup("LATIN SMALL LETTER GHA") == "\u01a3" +assert unicodedata.lookup("CJK UNIFIED IDEOGRAPH-4E00") == "\u4e00" +assert unicodedata.lookup("TANGUT IDEOGRAPH-17000") == "\U00017000" +# Named sequence (NamedSequences.txt). +assert unicodedata.lookup("LATIN SMALL LETTER A WITH MACRON AND GRAVE") == "\u0101\u0300" +# Hangul syllable algorithmic name round-trip. +assert unicodedata.name("\uac00") == "HANGUL SYLLABLE GA" +assert unicodedata.lookup("HANGUL SYLLABLE GA") == "\uac00" +# Properties + normalization spot checks. +assert unicodedata.category("\u0301") == "Mn" +assert unicodedata.decimal("\u0660") == 0 +assert unicodedata.numeric("\u00bd") == 0.5 +assert unicodedata.normalize("NFC", "e\u0301") == "\u00e9" +assert unicodedata.normalize("NFD", "\u00e9") == "e\u0301" +assert unicodedata.normalize("NFKC", "\ufb01") == "fi" +assert unicodedata.is_normalized("NFC", "\u00e9") + +# --------------------------------------------------------------------------- +# str case mappings / predicates ride the same generated tables (WS4). +# --------------------------------------------------------------------------- + +assert "\u00df".upper() == "SS" # sharp s expands +assert "\u0130".lower() == "i\u0307" # dotted capital I +assert "\u01c5".istitle() # Lt titlecase digraph +assert "\ufb01".casefold() == "fi" # ligature folds +assert "\u1e9e".casefold() == "ss" # capital sharp s +assert "\u03a3ΑΒ".title() == "Σαβ" +assert "ΟΔΟΣ".lower() == "οδος" # Final_Sigma rule +assert "\u001c".isspace() and " \u001d x ".split() == ["x"] +assert not "\u0345".isalpha() # Mn: not alpha in CPython (unlike Rust) + +# --------------------------------------------------------------------------- +# CJK codecs (WS3): incremental/stateful semantics and known mappings. +# --------------------------------------------------------------------------- + +# Representative two-way mappings, one per engine family. +assert "\u4e00".encode("gbk") == b"\xd2\xbb" +assert b"\xd2\xbb".decode("gbk") == "\u4e00" +assert "\U00020000".encode("gb18030") == b"\x95\x32\x82\x36" # 4-byte form +assert b"\x95\x32\x82\x36".decode("gb18030") == "\U00020000" +assert "\u4e00".encode("big5") == b"\xa4\x40" +assert "\u4e00".encode("euc_kr") == b"\xec\xe9" +assert "\uac02".encode("euc_kr") == b"\xa4\xd4\xa4\xa1\xa4\xbf\xa4\xa2" # Jamo composition +assert "\u3042".encode("shift_jis") == b"\x82\xa0" +assert "\u3042".encode("euc_jp") == b"\xa4\xa2" +# Stateful escape codecs reset per one-shot call. +assert "\u4e00".encode("iso2022_jp") == b"\x1b$B0l\x1b(B" +assert b"\x1b$B0l\x1b(B".decode("iso2022_jp") == "\u4e00" +assert "\u4e00".encode("hz") == b"~{R;~}" +# Incremental decoder holds partial multi-byte sequences across feeds. +dec = codecs.getincrementaldecoder("gb18030")() +assert dec.decode(b"\x95\x32") == "" +assert dec.decode(b"\x82\x36") == "\U00020000" +# Incremental encoder state survives a getstate/setstate round-trip. +enc = codecs.getincrementalencoder("iso2022_jp")() +first = enc.encode("\u4e00") +state = enc.getstate() +enc2 = codecs.getincrementalencoder("iso2022_jp")() +enc2.setstate(state) +assert first + enc2.encode("\u4e01", final=True) == "\u4e00\u4e01".encode("iso2022_jp") + +# --------------------------------------------------------------------------- +# Registry error surface. +# --------------------------------------------------------------------------- + +try: + codecs.lookup("rfc0050-no-such-codec") +except LookupError as e: + assert "unknown encoding" in str(e) +else: + raise AssertionError("unknown codec must raise LookupError") + +print("rfc0050 unicode/codec invariants ok") diff --git a/tools/data/NameAliases-15.1.0.txt b/tools/data/NameAliases-15.1.0.txt new file mode 100644 index 0000000..1e6f502 --- /dev/null +++ b/tools/data/NameAliases-15.1.0.txt @@ -0,0 +1,570 @@ +# NameAliases-15.1.0.txt +# Date: 2023-01-05 +# © 2023 Unicode®, Inc. +# For terms of use, see https://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see https://www.unicode.org/reports/tr44/ +# +# This file is a normative contributory data file in the +# Unicode Character Database. +# +# This file defines the formal name aliases for Unicode characters. +# +# For informative aliases, see NamesList.txt +# +# The formal name aliases are divided into five types, each with a distinct label. +# +# Type Labels: +# +# 1. correction +# Corrections for serious problems in the character names +# 2. control +# ISO 6429 names for C0 and C1 control functions, and other +# commonly occurring names for control codes +# 3. alternate +# A few widely used alternate names for format characters +# 4. figment +# Several documented labels for C1 control code points which +# were never actually approved in any standard +# 5. abbreviation +# Commonly occurring abbreviations (or acronyms) for control codes, +# format characters, spaces, and variation selectors +# +# The formal name aliases are part of the Unicode character namespace, which +# includes the character names and the names of named character sequences. +# The inclusion of ISO 6429 names and other commonly occurring names and +# abbreviations for control codes and format characters as formal name aliases +# is to help avoid name collisions between Unicode character names and the +# labels which commonly appear in text and/or in implementations such as regex, for +# control codes (which for historical reasons have no Unicode character name) +# or for format characters. +# +# For documentation, see NamesList.html and https://www.unicode.org/reports/tr44/ +# +# FORMAT +# +# Each line has three fields, as described here: +# +# First field: Code point +# Second field: Alias +# Third field: Type +# +# The type labels used are defined above. As for property values, comparisons +# of type labels should ignore case. +# +# The type labels can be mapped to other strings for display, if desired. +# +# In case multiple aliases are assigned, additional aliases +# are provided on separate lines. Parsers of this data file should +# take note that the same code point can (and does) occur more than once. +# +# Note that currently the only instances of multiple aliases of the same +# type for a single code point are either of type "control" or "abbreviation". +# An alias of type "abbreviation" can, in principle, be added for any code +# point, although currently aliases of type "correction" do not have +# any additional aliases of type "abbreviation". Such relationships +# are not enforced by stability policies. +# +#----------------------------------------------------------------- + +0000;NULL;control +0000;NUL;abbreviation +0001;START OF HEADING;control +0001;SOH;abbreviation +0002;START OF TEXT;control +0002;STX;abbreviation +0003;END OF TEXT;control +0003;ETX;abbreviation +0004;END OF TRANSMISSION;control +0004;EOT;abbreviation +0005;ENQUIRY;control +0005;ENQ;abbreviation +0006;ACKNOWLEDGE;control +0006;ACK;abbreviation + +# Note that no formal name alias for the ISO 6429 "BELL" is +# provided for U+0007, because of the existing name collision +# with U+1F514 BELL. + +0007;ALERT;control +0007;BEL;abbreviation + +0008;BACKSPACE;control +0008;BS;abbreviation +0009;CHARACTER TABULATION;control +0009;HORIZONTAL TABULATION;control +0009;HT;abbreviation +0009;TAB;abbreviation +000A;LINE FEED;control +000A;NEW LINE;control +000A;END OF LINE;control +000A;LF;abbreviation +000A;NL;abbreviation +000A;EOL;abbreviation +000B;LINE TABULATION;control +000B;VERTICAL TABULATION;control +000B;VT;abbreviation +000C;FORM FEED;control +000C;FF;abbreviation +000D;CARRIAGE RETURN;control +000D;CR;abbreviation +000E;SHIFT OUT;control +000E;LOCKING-SHIFT ONE;control +000E;SO;abbreviation +000F;SHIFT IN;control +000F;LOCKING-SHIFT ZERO;control +000F;SI;abbreviation +0010;DATA LINK ESCAPE;control +0010;DLE;abbreviation +0011;DEVICE CONTROL ONE;control +0011;DC1;abbreviation +0012;DEVICE CONTROL TWO;control +0012;DC2;abbreviation +0013;DEVICE CONTROL THREE;control +0013;DC3;abbreviation +0014;DEVICE CONTROL FOUR;control +0014;DC4;abbreviation +0015;NEGATIVE ACKNOWLEDGE;control +0015;NAK;abbreviation +0016;SYNCHRONOUS IDLE;control +0016;SYN;abbreviation +0017;END OF TRANSMISSION BLOCK;control +0017;ETB;abbreviation +0018;CANCEL;control +0018;CAN;abbreviation +0019;END OF MEDIUM;control +0019;EOM;abbreviation +0019;EM;abbreviation +001A;SUBSTITUTE;control +001A;SUB;abbreviation +001B;ESCAPE;control +001B;ESC;abbreviation +001C;INFORMATION SEPARATOR FOUR;control +001C;FILE SEPARATOR;control +001C;FS;abbreviation +001D;INFORMATION SEPARATOR THREE;control +001D;GROUP SEPARATOR;control +001D;GS;abbreviation +001E;INFORMATION SEPARATOR TWO;control +001E;RECORD SEPARATOR;control +001E;RS;abbreviation +001F;INFORMATION SEPARATOR ONE;control +001F;UNIT SEPARATOR;control +001F;US;abbreviation +0020;SP;abbreviation +007F;DELETE;control +007F;DEL;abbreviation + +# PADDING CHARACTER and HIGH OCTET PRESET represent +# architectural concepts initially proposed for early +# drafts of ISO/IEC 10646-1. They were never actually +# approved or standardized: hence their designation +# here as the "figment" type. Formal name aliases +# (and corresponding abbreviations) for these code +# points are included here because these names leaked +# out from the draft documents and were published in +# at least one RFC whose names for code points were +# implemented in Perl regex expressions. + +0080;PADDING CHARACTER;figment +0080;PAD;abbreviation +0081;HIGH OCTET PRESET;figment +0081;HOP;abbreviation + +0082;BREAK PERMITTED HERE;control +0082;BPH;abbreviation +0083;NO BREAK HERE;control +0083;NBH;abbreviation +0084;INDEX;control +0084;IND;abbreviation +0085;NEXT LINE;control +0085;NEL;abbreviation +0086;START OF SELECTED AREA;control +0086;SSA;abbreviation +0087;END OF SELECTED AREA;control +0087;ESA;abbreviation +0088;CHARACTER TABULATION SET;control +0088;HORIZONTAL TABULATION SET;control +0088;HTS;abbreviation +0089;CHARACTER TABULATION WITH JUSTIFICATION;control +0089;HORIZONTAL TABULATION WITH JUSTIFICATION;control +0089;HTJ;abbreviation +008A;LINE TABULATION SET;control +008A;VERTICAL TABULATION SET;control +008A;VTS;abbreviation +008B;PARTIAL LINE FORWARD;control +008B;PARTIAL LINE DOWN;control +008B;PLD;abbreviation +008C;PARTIAL LINE BACKWARD;control +008C;PARTIAL LINE UP;control +008C;PLU;abbreviation +008D;REVERSE LINE FEED;control +008D;REVERSE INDEX;control +008D;RI;abbreviation +008E;SINGLE SHIFT TWO;control +008E;SINGLE-SHIFT-2;control +008E;SS2;abbreviation +008F;SINGLE SHIFT THREE;control +008F;SINGLE-SHIFT-3;control +008F;SS3;abbreviation +0090;DEVICE CONTROL STRING;control +0090;DCS;abbreviation +0091;PRIVATE USE ONE;control +0091;PRIVATE USE-1;control +0091;PU1;abbreviation +0092;PRIVATE USE TWO;control +0092;PRIVATE USE-2;control +0092;PU2;abbreviation +0093;SET TRANSMIT STATE;control +0093;STS;abbreviation +0094;CANCEL CHARACTER;control +0094;CCH;abbreviation +0095;MESSAGE WAITING;control +0095;MW;abbreviation +0096;START OF GUARDED AREA;control +0096;START OF PROTECTED AREA;control +0096;SPA;abbreviation +0097;END OF GUARDED AREA;control +0097;END OF PROTECTED AREA;control +0097;EPA;abbreviation +0098;START OF STRING;control +0098;SOS;abbreviation + +# SINGLE GRAPHIC CHARACTER INTRODUCER is another +# architectural concept from early drafts of ISO/IEC 10646-1 +# which was never approved and standardized. + +0099;SINGLE GRAPHIC CHARACTER INTRODUCER;figment +0099;SGC;abbreviation + +009A;SINGLE CHARACTER INTRODUCER;control +009A;SCI;abbreviation +009B;CONTROL SEQUENCE INTRODUCER;control +009B;CSI;abbreviation +009C;STRING TERMINATOR;control +009C;ST;abbreviation +009D;OPERATING SYSTEM COMMAND;control +009D;OSC;abbreviation +009E;PRIVACY MESSAGE;control +009E;PM;abbreviation +009F;APPLICATION PROGRAM COMMAND;control +009F;APC;abbreviation +00A0;NBSP;abbreviation +00AD;SHY;abbreviation +01A2;LATIN CAPITAL LETTER GHA;correction +01A3;LATIN SMALL LETTER GHA;correction +034F;CGJ;abbreviation +0616;ARABIC SMALL HIGH LIGATURE ALEF WITH YEH BARREE;correction +061C;ALM;abbreviation +0709;SYRIAC SUBLINEAR COLON SKEWED LEFT;correction +0CDE;KANNADA LETTER LLLA;correction +0E9D;LAO LETTER FO FON;correction +0E9F;LAO LETTER FO FAY;correction +0EA3;LAO LETTER RO;correction +0EA5;LAO LETTER LO;correction +0FD0;TIBETAN MARK BKA- SHOG GI MGO RGYAN;correction +11EC;HANGUL JONGSEONG YESIEUNG-KIYEOK;correction +11ED;HANGUL JONGSEONG YESIEUNG-SSANGKIYEOK;correction +11EE;HANGUL JONGSEONG SSANGYESIEUNG;correction +11EF;HANGUL JONGSEONG YESIEUNG-KHIEUKH;correction +180B;FVS1;abbreviation +180C;FVS2;abbreviation +180D;FVS3;abbreviation +180E;MVS;abbreviation +180F;FVS4;abbreviation +1BBD;SUNDANESE LETTER ARCHAIC I;correction +200B;ZWSP;abbreviation +200C;ZWNJ;abbreviation +200D;ZWJ;abbreviation +200E;LRM;abbreviation +200F;RLM;abbreviation +202A;LRE;abbreviation +202B;RLE;abbreviation +202C;PDF;abbreviation +202D;LRO;abbreviation +202E;RLO;abbreviation +202F;NNBSP;abbreviation +205F;MMSP;abbreviation +2060;WJ;abbreviation +2066;LRI;abbreviation +2067;RLI;abbreviation +2068;FSI;abbreviation +2069;PDI;abbreviation +2118;WEIERSTRASS ELLIPTIC FUNCTION;correction +2448;MICR ON US SYMBOL;correction +2449;MICR DASH SYMBOL;correction +2B7A;LEFTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE VERTICAL STROKE;correction +2B7C;RIGHTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE VERTICAL STROKE;correction +A015;YI SYLLABLE ITERATION MARK;correction +AA6E;MYANMAR LETTER KHAMTI LLA;correction +FE00;VS1;abbreviation +FE01;VS2;abbreviation +FE02;VS3;abbreviation +FE03;VS4;abbreviation +FE04;VS5;abbreviation +FE05;VS6;abbreviation +FE06;VS7;abbreviation +FE07;VS8;abbreviation +FE08;VS9;abbreviation +FE09;VS10;abbreviation +FE0A;VS11;abbreviation +FE0B;VS12;abbreviation +FE0C;VS13;abbreviation +FE0D;VS14;abbreviation +FE0E;VS15;abbreviation +FE0F;VS16;abbreviation +FE18;PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRACKET;correction +FEFF;BYTE ORDER MARK;alternate +FEFF;BOM;abbreviation +FEFF;ZWNBSP;abbreviation +122D4;CUNEIFORM SIGN NU11 TENU;correction +122D5;CUNEIFORM SIGN NU11 OVER NU11 BUR OVER BUR;correction +16E56;MEDEFAIDRIN CAPITAL LETTER H;correction +16E57;MEDEFAIDRIN CAPITAL LETTER NG;correction +16E76;MEDEFAIDRIN SMALL LETTER H;correction +16E77;MEDEFAIDRIN SMALL LETTER NG;correction +1B001;HENTAIGANA LETTER E-1;correction +1D0C5;BYZANTINE MUSICAL SYMBOL FTHORA SKLIRON CHROMA VASIS;correction +E0100;VS17;abbreviation +E0101;VS18;abbreviation +E0102;VS19;abbreviation +E0103;VS20;abbreviation +E0104;VS21;abbreviation +E0105;VS22;abbreviation +E0106;VS23;abbreviation +E0107;VS24;abbreviation +E0108;VS25;abbreviation +E0109;VS26;abbreviation +E010A;VS27;abbreviation +E010B;VS28;abbreviation +E010C;VS29;abbreviation +E010D;VS30;abbreviation +E010E;VS31;abbreviation +E010F;VS32;abbreviation +E0110;VS33;abbreviation +E0111;VS34;abbreviation +E0112;VS35;abbreviation +E0113;VS36;abbreviation +E0114;VS37;abbreviation +E0115;VS38;abbreviation +E0116;VS39;abbreviation +E0117;VS40;abbreviation +E0118;VS41;abbreviation +E0119;VS42;abbreviation +E011A;VS43;abbreviation +E011B;VS44;abbreviation +E011C;VS45;abbreviation +E011D;VS46;abbreviation +E011E;VS47;abbreviation +E011F;VS48;abbreviation +E0120;VS49;abbreviation +E0121;VS50;abbreviation +E0122;VS51;abbreviation +E0123;VS52;abbreviation +E0124;VS53;abbreviation +E0125;VS54;abbreviation +E0126;VS55;abbreviation +E0127;VS56;abbreviation +E0128;VS57;abbreviation +E0129;VS58;abbreviation +E012A;VS59;abbreviation +E012B;VS60;abbreviation +E012C;VS61;abbreviation +E012D;VS62;abbreviation +E012E;VS63;abbreviation +E012F;VS64;abbreviation +E0130;VS65;abbreviation +E0131;VS66;abbreviation +E0132;VS67;abbreviation +E0133;VS68;abbreviation +E0134;VS69;abbreviation +E0135;VS70;abbreviation +E0136;VS71;abbreviation +E0137;VS72;abbreviation +E0138;VS73;abbreviation +E0139;VS74;abbreviation +E013A;VS75;abbreviation +E013B;VS76;abbreviation +E013C;VS77;abbreviation +E013D;VS78;abbreviation +E013E;VS79;abbreviation +E013F;VS80;abbreviation +E0140;VS81;abbreviation +E0141;VS82;abbreviation +E0142;VS83;abbreviation +E0143;VS84;abbreviation +E0144;VS85;abbreviation +E0145;VS86;abbreviation +E0146;VS87;abbreviation +E0147;VS88;abbreviation +E0148;VS89;abbreviation +E0149;VS90;abbreviation +E014A;VS91;abbreviation +E014B;VS92;abbreviation +E014C;VS93;abbreviation +E014D;VS94;abbreviation +E014E;VS95;abbreviation +E014F;VS96;abbreviation +E0150;VS97;abbreviation +E0151;VS98;abbreviation +E0152;VS99;abbreviation +E0153;VS100;abbreviation +E0154;VS101;abbreviation +E0155;VS102;abbreviation +E0156;VS103;abbreviation +E0157;VS104;abbreviation +E0158;VS105;abbreviation +E0159;VS106;abbreviation +E015A;VS107;abbreviation +E015B;VS108;abbreviation +E015C;VS109;abbreviation +E015D;VS110;abbreviation +E015E;VS111;abbreviation +E015F;VS112;abbreviation +E0160;VS113;abbreviation +E0161;VS114;abbreviation +E0162;VS115;abbreviation +E0163;VS116;abbreviation +E0164;VS117;abbreviation +E0165;VS118;abbreviation +E0166;VS119;abbreviation +E0167;VS120;abbreviation +E0168;VS121;abbreviation +E0169;VS122;abbreviation +E016A;VS123;abbreviation +E016B;VS124;abbreviation +E016C;VS125;abbreviation +E016D;VS126;abbreviation +E016E;VS127;abbreviation +E016F;VS128;abbreviation +E0170;VS129;abbreviation +E0171;VS130;abbreviation +E0172;VS131;abbreviation +E0173;VS132;abbreviation +E0174;VS133;abbreviation +E0175;VS134;abbreviation +E0176;VS135;abbreviation +E0177;VS136;abbreviation +E0178;VS137;abbreviation +E0179;VS138;abbreviation +E017A;VS139;abbreviation +E017B;VS140;abbreviation +E017C;VS141;abbreviation +E017D;VS142;abbreviation +E017E;VS143;abbreviation +E017F;VS144;abbreviation +E0180;VS145;abbreviation +E0181;VS146;abbreviation +E0182;VS147;abbreviation +E0183;VS148;abbreviation +E0184;VS149;abbreviation +E0185;VS150;abbreviation +E0186;VS151;abbreviation +E0187;VS152;abbreviation +E0188;VS153;abbreviation +E0189;VS154;abbreviation +E018A;VS155;abbreviation +E018B;VS156;abbreviation +E018C;VS157;abbreviation +E018D;VS158;abbreviation +E018E;VS159;abbreviation +E018F;VS160;abbreviation +E0190;VS161;abbreviation +E0191;VS162;abbreviation +E0192;VS163;abbreviation +E0193;VS164;abbreviation +E0194;VS165;abbreviation +E0195;VS166;abbreviation +E0196;VS167;abbreviation +E0197;VS168;abbreviation +E0198;VS169;abbreviation +E0199;VS170;abbreviation +E019A;VS171;abbreviation +E019B;VS172;abbreviation +E019C;VS173;abbreviation +E019D;VS174;abbreviation +E019E;VS175;abbreviation +E019F;VS176;abbreviation +E01A0;VS177;abbreviation +E01A1;VS178;abbreviation +E01A2;VS179;abbreviation +E01A3;VS180;abbreviation +E01A4;VS181;abbreviation +E01A5;VS182;abbreviation +E01A6;VS183;abbreviation +E01A7;VS184;abbreviation +E01A8;VS185;abbreviation +E01A9;VS186;abbreviation +E01AA;VS187;abbreviation +E01AB;VS188;abbreviation +E01AC;VS189;abbreviation +E01AD;VS190;abbreviation +E01AE;VS191;abbreviation +E01AF;VS192;abbreviation +E01B0;VS193;abbreviation +E01B1;VS194;abbreviation +E01B2;VS195;abbreviation +E01B3;VS196;abbreviation +E01B4;VS197;abbreviation +E01B5;VS198;abbreviation +E01B6;VS199;abbreviation +E01B7;VS200;abbreviation +E01B8;VS201;abbreviation +E01B9;VS202;abbreviation +E01BA;VS203;abbreviation +E01BB;VS204;abbreviation +E01BC;VS205;abbreviation +E01BD;VS206;abbreviation +E01BE;VS207;abbreviation +E01BF;VS208;abbreviation +E01C0;VS209;abbreviation +E01C1;VS210;abbreviation +E01C2;VS211;abbreviation +E01C3;VS212;abbreviation +E01C4;VS213;abbreviation +E01C5;VS214;abbreviation +E01C6;VS215;abbreviation +E01C7;VS216;abbreviation +E01C8;VS217;abbreviation +E01C9;VS218;abbreviation +E01CA;VS219;abbreviation +E01CB;VS220;abbreviation +E01CC;VS221;abbreviation +E01CD;VS222;abbreviation +E01CE;VS223;abbreviation +E01CF;VS224;abbreviation +E01D0;VS225;abbreviation +E01D1;VS226;abbreviation +E01D2;VS227;abbreviation +E01D3;VS228;abbreviation +E01D4;VS229;abbreviation +E01D5;VS230;abbreviation +E01D6;VS231;abbreviation +E01D7;VS232;abbreviation +E01D8;VS233;abbreviation +E01D9;VS234;abbreviation +E01DA;VS235;abbreviation +E01DB;VS236;abbreviation +E01DC;VS237;abbreviation +E01DD;VS238;abbreviation +E01DE;VS239;abbreviation +E01DF;VS240;abbreviation +E01E0;VS241;abbreviation +E01E1;VS242;abbreviation +E01E2;VS243;abbreviation +E01E3;VS244;abbreviation +E01E4;VS245;abbreviation +E01E5;VS246;abbreviation +E01E6;VS247;abbreviation +E01E7;VS248;abbreviation +E01E8;VS249;abbreviation +E01E9;VS250;abbreviation +E01EA;VS251;abbreviation +E01EB;VS252;abbreviation +E01EC;VS253;abbreviation +E01ED;VS254;abbreviation +E01EE;VS255;abbreviation +E01EF;VS256;abbreviation + +# EOF diff --git a/tools/data/NamedSequences-15.1.0.txt b/tools/data/NamedSequences-15.1.0.txt new file mode 100644 index 0000000..c00a17f --- /dev/null +++ b/tools/data/NamedSequences-15.1.0.txt @@ -0,0 +1,612 @@ +# NamedSequences-15.1.0.txt +# Date: 2023-01-05 +# © 2023 Unicode®, Inc. +# For terms of use, see https://www.unicode.org/terms_of_use.html +# +# Unicode Character Database +# For documentation, see https://www.unicode.org/reports/tr44/ +# +# Unicode Named Character Sequences +# +# This file is a normative contributory data file in the Unicode +# Character Database. +# +# Format: +# Name of Sequence; Code Point Sequence for USI +# +# Code point sequences in the Unicode Character Database +# use spaces as delimiters. The corresponding format for a +# UCS Sequence Identifier (USI) in ISO/IEC 10646 uses +# comma delimitation and angle brackets. Thus, a Unicode +# named character sequence of the form: +# +# EXAMPLE NAME;1000 1001 1002 +# +# in this data file, would correspond to an ISO/IEC 10646 USI +# as follows: +# +# <1000, 1001, 1002> +# +# For more information, see UAX #34: Unicode Named Character +# Sequences, at https://www.unicode.org/reports/tr34/ +# +# Note: The order of entries in this file is not significant. +# However, entries are generally in script order corresponding +# to block order in the Unicode Standard, to make it easier +# to find entries in the list. + +# ================================================ + +# Named keycap sequences for telephone keypad (used for emoji) +# Provisional, 2015-05-05 +# FE0F added to the sequences, 2016-05-11 +# Approved 2017-05-12 + +KEYCAP NUMBER SIGN;0023 FE0F 20E3 +KEYCAP ASTERISK;002A FE0F 20E3 +KEYCAP DIGIT ZERO;0030 FE0F 20E3 +KEYCAP DIGIT ONE;0031 FE0F 20E3 +KEYCAP DIGIT TWO;0032 FE0F 20E3 +KEYCAP DIGIT THREE;0033 FE0F 20E3 +KEYCAP DIGIT FOUR;0034 FE0F 20E3 +KEYCAP DIGIT FIVE;0035 FE0F 20E3 +KEYCAP DIGIT SIX;0036 FE0F 20E3 +KEYCAP DIGIT SEVEN;0037 FE0F 20E3 +KEYCAP DIGIT EIGHT;0038 FE0F 20E3 +KEYCAP DIGIT NINE;0039 FE0F 20E3 + +# Latin letter plus accent combinations. +# These are part of the original set of approved named sequences +# for Unicode 4.1. 2005. +# Subgroupings of this original set are identified here by +# purpose and source. + +# Subset 1: Originally requested for a Latin orthography +# of Hausa. See WG2 N1143 and UTC/1996-005. (6 total) + +LATIN CAPITAL LETTER A WITH MACRON AND GRAVE;0100 0300 +LATIN SMALL LETTER A WITH MACRON AND GRAVE;0101 0300 +LATIN CAPITAL LETTER I WITH MACRON AND GRAVE;012A 0300 +LATIN SMALL LETTER I WITH MACRON AND GRAVE;012B 0300 +LATIN CAPITAL LETTER U WITH MACRON AND GRAVE;016A 0300 +LATIN SMALL LETTER U WITH MACRON AND GRAVE;016B 0300 + +# Subset 2: Originally requested for a Latin orthography +# of Yoruba. See WG2 N1143 and UTC/1996-005. (14 total) + +LATIN CAPITAL LETTER E WITH VERTICAL LINE BELOW;0045 0329 +LATIN SMALL LETTER E WITH VERTICAL LINE BELOW;0065 0329 +LATIN CAPITAL LETTER E WITH VERTICAL LINE BELOW AND GRAVE;00C8 0329 +LATIN SMALL LETTER E WITH VERTICAL LINE BELOW AND GRAVE;00E8 0329 +LATIN CAPITAL LETTER E WITH VERTICAL LINE BELOW AND ACUTE;00C9 0329 +LATIN SMALL LETTER E WITH VERTICAL LINE BELOW AND ACUTE;00E9 0329 +LATIN CAPITAL LETTER O WITH VERTICAL LINE BELOW;004F 0329 +LATIN SMALL LETTER O WITH VERTICAL LINE BELOW;006F 0329 +LATIN CAPITAL LETTER O WITH VERTICAL LINE BELOW AND GRAVE;00D2 0329 +LATIN SMALL LETTER O WITH VERTICAL LINE BELOW AND GRAVE;00F2 0329 +LATIN CAPITAL LETTER O WITH VERTICAL LINE BELOW AND ACUTE;00D3 0329 +LATIN SMALL LETTER O WITH VERTICAL LINE BELOW AND ACUTE;00F3 0329 +LATIN CAPITAL LETTER S WITH VERTICAL LINE BELOW;0053 0329 +LATIN SMALL LETTER S WITH VERTICAL LINE BELOW;0073 0329 + +# Subset 3: Originally requested for Pinyin forms noted +# in HKSCS. See L2/02-423 and WG2 N2513. (4 total) + +LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND MACRON;00CA 0304 +LATIN SMALL LETTER E WITH CIRCUMFLEX AND MACRON;00EA 0304 +LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND CARON;00CA 030C +LATIN SMALL LETTER E WITH CIRCUMFLEX AND CARON;00EA 030C + +# Subset 4: Prominent use cases pulled from examples +# for Lithuanian and Tagalog in +# Unicode 4.0 and early drafts of UAX #34. (2 total) + +LATIN SMALL LETTER I WITH DOT ABOVE AND ACUTE;0069 0307 0301 +LATIN SMALL LETTER NG WITH TILDE ABOVE;006E 0360 0067 + +# Additions for Lithuanian. +# Provisional 2006-05-18, Approved 2007-10-19 + +LATIN CAPITAL LETTER A WITH OGONEK AND ACUTE;0104 0301 +LATIN SMALL LETTER A WITH OGONEK AND ACUTE;0105 0301 +LATIN CAPITAL LETTER A WITH OGONEK AND TILDE;0104 0303 +LATIN SMALL LETTER A WITH OGONEK AND TILDE;0105 0303 +LATIN CAPITAL LETTER E WITH OGONEK AND ACUTE;0118 0301 +LATIN SMALL LETTER E WITH OGONEK AND ACUTE;0119 0301 +LATIN CAPITAL LETTER E WITH OGONEK AND TILDE;0118 0303 +LATIN SMALL LETTER E WITH OGONEK AND TILDE;0119 0303 +LATIN CAPITAL LETTER E WITH DOT ABOVE AND ACUTE;0116 0301 +LATIN SMALL LETTER E WITH DOT ABOVE AND ACUTE;0117 0301 +LATIN CAPITAL LETTER E WITH DOT ABOVE AND TILDE;0116 0303 +LATIN SMALL LETTER E WITH DOT ABOVE AND TILDE;0117 0303 +LATIN SMALL LETTER I WITH DOT ABOVE AND GRAVE;0069 0307 0300 +LATIN SMALL LETTER I WITH DOT ABOVE AND TILDE;0069 0307 0303 +LATIN CAPITAL LETTER I WITH OGONEK AND ACUTE;012E 0301 +LATIN SMALL LETTER I WITH OGONEK AND DOT ABOVE AND ACUTE;012F 0307 0301 +LATIN CAPITAL LETTER I WITH OGONEK AND TILDE;012E 0303 +LATIN SMALL LETTER I WITH OGONEK AND DOT ABOVE AND TILDE;012F 0307 0303 +LATIN CAPITAL LETTER J WITH TILDE;004A 0303 +LATIN SMALL LETTER J WITH DOT ABOVE AND TILDE;006A 0307 0303 +LATIN CAPITAL LETTER L WITH TILDE;004C 0303 +LATIN SMALL LETTER L WITH TILDE;006C 0303 +LATIN CAPITAL LETTER M WITH TILDE;004D 0303 +LATIN SMALL LETTER M WITH TILDE;006D 0303 +LATIN CAPITAL LETTER R WITH TILDE;0052 0303 +LATIN SMALL LETTER R WITH TILDE;0072 0303 +LATIN CAPITAL LETTER U WITH OGONEK AND ACUTE;0172 0301 +LATIN SMALL LETTER U WITH OGONEK AND ACUTE;0173 0301 +LATIN CAPITAL LETTER U WITH OGONEK AND TILDE;0172 0303 +LATIN SMALL LETTER U WITH OGONEK AND TILDE;0173 0303 +LATIN CAPITAL LETTER U WITH MACRON AND ACUTE;016A 0301 +LATIN SMALL LETTER U WITH MACRON AND ACUTE;016B 0301 +LATIN CAPITAL LETTER U WITH MACRON AND TILDE;016A 0303 +LATIN SMALL LETTER U WITH MACRON AND TILDE;016B 0303 + +# Entries for JIS X 0213 compatibility mapping. +# Provisional 2008-11-07, Approved 2010-05-14 + +LATIN SMALL LETTER AE WITH GRAVE;00E6 0300 +LATIN SMALL LETTER OPEN O WITH GRAVE;0254 0300 +LATIN SMALL LETTER OPEN O WITH ACUTE;0254 0301 +LATIN SMALL LETTER TURNED V WITH GRAVE;028C 0300 +LATIN SMALL LETTER TURNED V WITH ACUTE;028C 0301 +LATIN SMALL LETTER SCHWA WITH GRAVE;0259 0300 +LATIN SMALL LETTER SCHWA WITH ACUTE;0259 0301 +LATIN SMALL LETTER HOOKED SCHWA WITH GRAVE;025A 0300 +LATIN SMALL LETTER HOOKED SCHWA WITH ACUTE;025A 0301 + +# Entries for Uyghur and Chagatai. +# Provisional N/A, Approved 2012-11-08 + +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH ALEF;0626 0627 +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH WAW;0626 0648 +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA;0626 0649 +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH OE;0626 06C6 +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH U;0626 06C7 +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH YU;0626 06C8 +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH E;0626 06D0 +ARABIC SEQUENCE YEH WITH HAMZA ABOVE WITH AE;0626 06D5 +ARABIC SEQUENCE NOON WITH KEHEH;0646 06A9 + +# Entries that correspond to Indic characters with nuktas +# that are also listed in CompositionExclusions.txt. +# These characters decompose for normalized text, even +# in NFC. Having named sequences for these helps in +# certain specifications, including Label Generation Rules (LGR) +# for Internationalized Domain Names (IDN). +# +# Provisional 2020-01-16, Approved 2021-07-27 + +DEVANAGARI SEQUENCE FOR LETTER QA; 0915 093C +DEVANAGARI SEQUENCE FOR LETTER KHHA; 0916 093C +DEVANAGARI SEQUENCE FOR LETTER GHHA; 0917 093C +DEVANAGARI SEQUENCE FOR LETTER ZA; 091C 093C +DEVANAGARI SEQUENCE FOR LETTER DDDHA; 0921 093C +DEVANAGARI SEQUENCE FOR LETTER RHA; 0922 093C +DEVANAGARI SEQUENCE FOR LETTER FA; 092B 093C +DEVANAGARI SEQUENCE FOR LETTER YYA; 092F 093C +BENGALI SEQUENCE FOR LETTER RRA; 09A1 09BC +BENGALI SEQUENCE FOR LETTER RHA; 09A2 09BC +BENGALI SEQUENCE FOR LETTER YYA; 09AF 09BC +GURMUKHI SEQUENCE FOR LETTER LLA; 0A32 0A3C +GURMUKHI SEQUENCE FOR LETTER SHA; 0A38 0A3C +GURMUKHI SEQUENCE FOR LETTER KHHA; 0A16 0A3C +GURMUKHI SEQUENCE FOR LETTER GHHA; 0A17 0A3C +GURMUKHI SEQUENCE FOR LETTER ZA; 0A1C 0A3C +GURMUKHI SEQUENCE FOR LETTER FA; 0A2B 0A3C +ORIYA SEQUENCE FOR LETTER RRA; 0B21 0B3C +ORIYA SEQUENCE FOR LETTER RHA; 0B22 0B3C + +# Entry for a Bangla entity. +# Provisional 2009-08-10, Approved 2010-05-14 +# +# Note that this same sequence is also used for the ASSAMESE LETTER KSSA. + +BENGALI LETTER KHINYA;0995 09CD 09B7 + +# Additions for Tamil. +# Provisional 2008-02-08, Approved 2009-08-14 +# +# A visual display of the Tamil named character sequences is available +# in the documentation for the Unicode Standard. See Section 12.6, Tamil in +# https://www.unicode.org/versions/latest/ + +TAMIL CONSONANT K; 0B95 0BCD +TAMIL CONSONANT NG; 0B99 0BCD +TAMIL CONSONANT C; 0B9A 0BCD +TAMIL CONSONANT NY; 0B9E 0BCD +TAMIL CONSONANT TT; 0B9F 0BCD +TAMIL CONSONANT NN; 0BA3 0BCD +TAMIL CONSONANT T; 0BA4 0BCD +TAMIL CONSONANT N; 0BA8 0BCD +TAMIL CONSONANT P; 0BAA 0BCD +TAMIL CONSONANT M; 0BAE 0BCD +TAMIL CONSONANT Y; 0BAF 0BCD +TAMIL CONSONANT R; 0BB0 0BCD +TAMIL CONSONANT L; 0BB2 0BCD +TAMIL CONSONANT V; 0BB5 0BCD +TAMIL CONSONANT LLL;0BB4 0BCD +TAMIL CONSONANT LL; 0BB3 0BCD +TAMIL CONSONANT RR; 0BB1 0BCD +TAMIL CONSONANT NNN;0BA9 0BCD +TAMIL CONSONANT J; 0B9C 0BCD +TAMIL CONSONANT SH; 0BB6 0BCD +TAMIL CONSONANT SS; 0BB7 0BCD +TAMIL CONSONANT S; 0BB8 0BCD +TAMIL CONSONANT H; 0BB9 0BCD +TAMIL CONSONANT KSS;0B95 0BCD 0BB7 0BCD + +TAMIL SYLLABLE KAA; 0B95 0BBE +TAMIL SYLLABLE KI; 0B95 0BBF +TAMIL SYLLABLE KII; 0B95 0BC0 +TAMIL SYLLABLE KU; 0B95 0BC1 +TAMIL SYLLABLE KUU; 0B95 0BC2 +TAMIL SYLLABLE KE; 0B95 0BC6 +TAMIL SYLLABLE KEE; 0B95 0BC7 +TAMIL SYLLABLE KAI; 0B95 0BC8 +TAMIL SYLLABLE KO; 0B95 0BCA +TAMIL SYLLABLE KOO; 0B95 0BCB +TAMIL SYLLABLE KAU; 0B95 0BCC + +TAMIL SYLLABLE NGAA; 0B99 0BBE +TAMIL SYLLABLE NGI; 0B99 0BBF +TAMIL SYLLABLE NGII; 0B99 0BC0 +TAMIL SYLLABLE NGU; 0B99 0BC1 +TAMIL SYLLABLE NGUU; 0B99 0BC2 +TAMIL SYLLABLE NGE; 0B99 0BC6 +TAMIL SYLLABLE NGEE; 0B99 0BC7 +TAMIL SYLLABLE NGAI; 0B99 0BC8 +TAMIL SYLLABLE NGO; 0B99 0BCA +TAMIL SYLLABLE NGOO; 0B99 0BCB +TAMIL SYLLABLE NGAU; 0B99 0BCC + +TAMIL SYLLABLE CAA; 0B9A 0BBE +TAMIL SYLLABLE CI; 0B9A 0BBF +TAMIL SYLLABLE CII; 0B9A 0BC0 +TAMIL SYLLABLE CU; 0B9A 0BC1 +TAMIL SYLLABLE CUU; 0B9A 0BC2 +TAMIL SYLLABLE CE; 0B9A 0BC6 +TAMIL SYLLABLE CEE; 0B9A 0BC7 +TAMIL SYLLABLE CAI; 0B9A 0BC8 +TAMIL SYLLABLE CO; 0B9A 0BCA +TAMIL SYLLABLE COO; 0B9A 0BCB +TAMIL SYLLABLE CAU; 0B9A 0BCC + +TAMIL SYLLABLE NYAA; 0B9E 0BBE +TAMIL SYLLABLE NYI; 0B9E 0BBF +TAMIL SYLLABLE NYII; 0B9E 0BC0 +TAMIL SYLLABLE NYU; 0B9E 0BC1 +TAMIL SYLLABLE NYUU; 0B9E 0BC2 +TAMIL SYLLABLE NYE; 0B9E 0BC6 +TAMIL SYLLABLE NYEE; 0B9E 0BC7 +TAMIL SYLLABLE NYAI; 0B9E 0BC8 +TAMIL SYLLABLE NYO; 0B9E 0BCA +TAMIL SYLLABLE NYOO; 0B9E 0BCB +TAMIL SYLLABLE NYAU; 0B9E 0BCC + +TAMIL SYLLABLE TTAA; 0B9F 0BBE +TAMIL SYLLABLE TTI; 0B9F 0BBF +TAMIL SYLLABLE TTII; 0B9F 0BC0 +TAMIL SYLLABLE TTU; 0B9F 0BC1 +TAMIL SYLLABLE TTUU; 0B9F 0BC2 +TAMIL SYLLABLE TTE; 0B9F 0BC6 +TAMIL SYLLABLE TTEE; 0B9F 0BC7 +TAMIL SYLLABLE TTAI; 0B9F 0BC8 +TAMIL SYLLABLE TTO; 0B9F 0BCA +TAMIL SYLLABLE TTOO; 0B9F 0BCB +TAMIL SYLLABLE TTAU; 0B9F 0BCC + +TAMIL SYLLABLE NNAA; 0BA3 0BBE +TAMIL SYLLABLE NNI; 0BA3 0BBF +TAMIL SYLLABLE NNII; 0BA3 0BC0 +TAMIL SYLLABLE NNU; 0BA3 0BC1 +TAMIL SYLLABLE NNUU; 0BA3 0BC2 +TAMIL SYLLABLE NNE; 0BA3 0BC6 +TAMIL SYLLABLE NNEE; 0BA3 0BC7 +TAMIL SYLLABLE NNAI; 0BA3 0BC8 +TAMIL SYLLABLE NNO; 0BA3 0BCA +TAMIL SYLLABLE NNOO; 0BA3 0BCB +TAMIL SYLLABLE NNAU; 0BA3 0BCC + +TAMIL SYLLABLE TAA; 0BA4 0BBE +TAMIL SYLLABLE TI; 0BA4 0BBF +TAMIL SYLLABLE TII; 0BA4 0BC0 +TAMIL SYLLABLE TU; 0BA4 0BC1 +TAMIL SYLLABLE TUU; 0BA4 0BC2 +TAMIL SYLLABLE TE; 0BA4 0BC6 +TAMIL SYLLABLE TEE; 0BA4 0BC7 +TAMIL SYLLABLE TAI; 0BA4 0BC8 +TAMIL SYLLABLE TO; 0BA4 0BCA +TAMIL SYLLABLE TOO; 0BA4 0BCB +TAMIL SYLLABLE TAU; 0BA4 0BCC + +TAMIL SYLLABLE NAA; 0BA8 0BBE +TAMIL SYLLABLE NI; 0BA8 0BBF +TAMIL SYLLABLE NII; 0BA8 0BC0 +TAMIL SYLLABLE NU; 0BA8 0BC1 +TAMIL SYLLABLE NUU; 0BA8 0BC2 +TAMIL SYLLABLE NE; 0BA8 0BC6 +TAMIL SYLLABLE NEE; 0BA8 0BC7 +TAMIL SYLLABLE NAI; 0BA8 0BC8 +TAMIL SYLLABLE NO; 0BA8 0BCA +TAMIL SYLLABLE NOO; 0BA8 0BCB +TAMIL SYLLABLE NAU; 0BA8 0BCC + +TAMIL SYLLABLE PAA; 0BAA 0BBE +TAMIL SYLLABLE PI; 0BAA 0BBF +TAMIL SYLLABLE PII; 0BAA 0BC0 +TAMIL SYLLABLE PU; 0BAA 0BC1 +TAMIL SYLLABLE PUU; 0BAA 0BC2 +TAMIL SYLLABLE PE; 0BAA 0BC6 +TAMIL SYLLABLE PEE; 0BAA 0BC7 +TAMIL SYLLABLE PAI; 0BAA 0BC8 +TAMIL SYLLABLE PO; 0BAA 0BCA +TAMIL SYLLABLE POO; 0BAA 0BCB +TAMIL SYLLABLE PAU; 0BAA 0BCC + +TAMIL SYLLABLE MAA; 0BAE 0BBE +TAMIL SYLLABLE MI; 0BAE 0BBF +TAMIL SYLLABLE MII; 0BAE 0BC0 +TAMIL SYLLABLE MU; 0BAE 0BC1 +TAMIL SYLLABLE MUU; 0BAE 0BC2 +TAMIL SYLLABLE ME; 0BAE 0BC6 +TAMIL SYLLABLE MEE; 0BAE 0BC7 +TAMIL SYLLABLE MAI; 0BAE 0BC8 +TAMIL SYLLABLE MO; 0BAE 0BCA +TAMIL SYLLABLE MOO; 0BAE 0BCB +TAMIL SYLLABLE MAU; 0BAE 0BCC + +TAMIL SYLLABLE YAA; 0BAF 0BBE +TAMIL SYLLABLE YI; 0BAF 0BBF +TAMIL SYLLABLE YII; 0BAF 0BC0 +TAMIL SYLLABLE YU; 0BAF 0BC1 +TAMIL SYLLABLE YUU; 0BAF 0BC2 +TAMIL SYLLABLE YE; 0BAF 0BC6 +TAMIL SYLLABLE YEE; 0BAF 0BC7 +TAMIL SYLLABLE YAI; 0BAF 0BC8 +TAMIL SYLLABLE YO; 0BAF 0BCA +TAMIL SYLLABLE YOO; 0BAF 0BCB +TAMIL SYLLABLE YAU; 0BAF 0BCC + +TAMIL SYLLABLE RAA; 0BB0 0BBE +TAMIL SYLLABLE RI; 0BB0 0BBF +TAMIL SYLLABLE RII; 0BB0 0BC0 +TAMIL SYLLABLE RU; 0BB0 0BC1 +TAMIL SYLLABLE RUU; 0BB0 0BC2 +TAMIL SYLLABLE RE; 0BB0 0BC6 +TAMIL SYLLABLE REE; 0BB0 0BC7 +TAMIL SYLLABLE RAI; 0BB0 0BC8 +TAMIL SYLLABLE RO; 0BB0 0BCA +TAMIL SYLLABLE ROO; 0BB0 0BCB +TAMIL SYLLABLE RAU; 0BB0 0BCC + +TAMIL SYLLABLE LAA; 0BB2 0BBE +TAMIL SYLLABLE LI; 0BB2 0BBF +TAMIL SYLLABLE LII; 0BB2 0BC0 +TAMIL SYLLABLE LU; 0BB2 0BC1 +TAMIL SYLLABLE LUU; 0BB2 0BC2 +TAMIL SYLLABLE LE; 0BB2 0BC6 +TAMIL SYLLABLE LEE; 0BB2 0BC7 +TAMIL SYLLABLE LAI; 0BB2 0BC8 +TAMIL SYLLABLE LO; 0BB2 0BCA +TAMIL SYLLABLE LOO; 0BB2 0BCB +TAMIL SYLLABLE LAU; 0BB2 0BCC + +TAMIL SYLLABLE VAA; 0BB5 0BBE +TAMIL SYLLABLE VI; 0BB5 0BBF +TAMIL SYLLABLE VII; 0BB5 0BC0 +TAMIL SYLLABLE VU; 0BB5 0BC1 +TAMIL SYLLABLE VUU; 0BB5 0BC2 +TAMIL SYLLABLE VE; 0BB5 0BC6 +TAMIL SYLLABLE VEE; 0BB5 0BC7 +TAMIL SYLLABLE VAI; 0BB5 0BC8 +TAMIL SYLLABLE VO; 0BB5 0BCA +TAMIL SYLLABLE VOO; 0BB5 0BCB +TAMIL SYLLABLE VAU; 0BB5 0BCC + +TAMIL SYLLABLE LLLAA; 0BB4 0BBE +TAMIL SYLLABLE LLLI; 0BB4 0BBF +TAMIL SYLLABLE LLLII; 0BB4 0BC0 +TAMIL SYLLABLE LLLU; 0BB4 0BC1 +TAMIL SYLLABLE LLLUU; 0BB4 0BC2 +TAMIL SYLLABLE LLLE; 0BB4 0BC6 +TAMIL SYLLABLE LLLEE; 0BB4 0BC7 +TAMIL SYLLABLE LLLAI; 0BB4 0BC8 +TAMIL SYLLABLE LLLO; 0BB4 0BCA +TAMIL SYLLABLE LLLOO; 0BB4 0BCB +TAMIL SYLLABLE LLLAU; 0BB4 0BCC + +TAMIL SYLLABLE LLAA; 0BB3 0BBE +TAMIL SYLLABLE LLI; 0BB3 0BBF +TAMIL SYLLABLE LLII; 0BB3 0BC0 +TAMIL SYLLABLE LLU; 0BB3 0BC1 +TAMIL SYLLABLE LLUU; 0BB3 0BC2 +TAMIL SYLLABLE LLE; 0BB3 0BC6 +TAMIL SYLLABLE LLEE; 0BB3 0BC7 +TAMIL SYLLABLE LLAI; 0BB3 0BC8 +TAMIL SYLLABLE LLO; 0BB3 0BCA +TAMIL SYLLABLE LLOO; 0BB3 0BCB +TAMIL SYLLABLE LLAU; 0BB3 0BCC + +TAMIL SYLLABLE RRAA; 0BB1 0BBE +TAMIL SYLLABLE RRI; 0BB1 0BBF +TAMIL SYLLABLE RRII; 0BB1 0BC0 +TAMIL SYLLABLE RRU; 0BB1 0BC1 +TAMIL SYLLABLE RRUU; 0BB1 0BC2 +TAMIL SYLLABLE RRE; 0BB1 0BC6 +TAMIL SYLLABLE RREE; 0BB1 0BC7 +TAMIL SYLLABLE RRAI; 0BB1 0BC8 +TAMIL SYLLABLE RRO; 0BB1 0BCA +TAMIL SYLLABLE RROO; 0BB1 0BCB +TAMIL SYLLABLE RRAU; 0BB1 0BCC + +TAMIL SYLLABLE NNNAA; 0BA9 0BBE +TAMIL SYLLABLE NNNI; 0BA9 0BBF +TAMIL SYLLABLE NNNII; 0BA9 0BC0 +TAMIL SYLLABLE NNNU; 0BA9 0BC1 +TAMIL SYLLABLE NNNUU; 0BA9 0BC2 +TAMIL SYLLABLE NNNE; 0BA9 0BC6 +TAMIL SYLLABLE NNNEE; 0BA9 0BC7 +TAMIL SYLLABLE NNNAI; 0BA9 0BC8 +TAMIL SYLLABLE NNNO; 0BA9 0BCA +TAMIL SYLLABLE NNNOO; 0BA9 0BCB +TAMIL SYLLABLE NNNAU; 0BA9 0BCC + +TAMIL SYLLABLE JAA; 0B9C 0BBE +TAMIL SYLLABLE JI; 0B9C 0BBF +TAMIL SYLLABLE JII; 0B9C 0BC0 +TAMIL SYLLABLE JU; 0B9C 0BC1 +TAMIL SYLLABLE JUU; 0B9C 0BC2 +TAMIL SYLLABLE JE; 0B9C 0BC6 +TAMIL SYLLABLE JEE; 0B9C 0BC7 +TAMIL SYLLABLE JAI; 0B9C 0BC8 +TAMIL SYLLABLE JO; 0B9C 0BCA +TAMIL SYLLABLE JOO; 0B9C 0BCB +TAMIL SYLLABLE JAU; 0B9C 0BCC + +TAMIL SYLLABLE SHAA; 0BB6 0BBE +TAMIL SYLLABLE SHI; 0BB6 0BBF +TAMIL SYLLABLE SHII; 0BB6 0BC0 +TAMIL SYLLABLE SHU; 0BB6 0BC1 +TAMIL SYLLABLE SHUU; 0BB6 0BC2 +TAMIL SYLLABLE SHE; 0BB6 0BC6 +TAMIL SYLLABLE SHEE; 0BB6 0BC7 +TAMIL SYLLABLE SHAI; 0BB6 0BC8 +TAMIL SYLLABLE SHO; 0BB6 0BCA +TAMIL SYLLABLE SHOO; 0BB6 0BCB +TAMIL SYLLABLE SHAU; 0BB6 0BCC + +TAMIL SYLLABLE SSAA; 0BB7 0BBE +TAMIL SYLLABLE SSI; 0BB7 0BBF +TAMIL SYLLABLE SSII; 0BB7 0BC0 +TAMIL SYLLABLE SSU; 0BB7 0BC1 +TAMIL SYLLABLE SSUU; 0BB7 0BC2 +TAMIL SYLLABLE SSE; 0BB7 0BC6 +TAMIL SYLLABLE SSEE; 0BB7 0BC7 +TAMIL SYLLABLE SSAI; 0BB7 0BC8 +TAMIL SYLLABLE SSO; 0BB7 0BCA +TAMIL SYLLABLE SSOO; 0BB7 0BCB +TAMIL SYLLABLE SSAU; 0BB7 0BCC + +TAMIL SYLLABLE SAA; 0BB8 0BBE +TAMIL SYLLABLE SI; 0BB8 0BBF +TAMIL SYLLABLE SII; 0BB8 0BC0 +TAMIL SYLLABLE SU; 0BB8 0BC1 +TAMIL SYLLABLE SUU; 0BB8 0BC2 +TAMIL SYLLABLE SE; 0BB8 0BC6 +TAMIL SYLLABLE SEE; 0BB8 0BC7 +TAMIL SYLLABLE SAI; 0BB8 0BC8 +TAMIL SYLLABLE SO; 0BB8 0BCA +TAMIL SYLLABLE SOO; 0BB8 0BCB +TAMIL SYLLABLE SAU; 0BB8 0BCC + +TAMIL SYLLABLE HAA; 0BB9 0BBE +TAMIL SYLLABLE HI; 0BB9 0BBF +TAMIL SYLLABLE HII; 0BB9 0BC0 +TAMIL SYLLABLE HU; 0BB9 0BC1 +TAMIL SYLLABLE HUU; 0BB9 0BC2 +TAMIL SYLLABLE HE; 0BB9 0BC6 +TAMIL SYLLABLE HEE; 0BB9 0BC7 +TAMIL SYLLABLE HAI; 0BB9 0BC8 +TAMIL SYLLABLE HO; 0BB9 0BCA +TAMIL SYLLABLE HOO; 0BB9 0BCB +TAMIL SYLLABLE HAU; 0BB9 0BCC + +TAMIL SYLLABLE KSSA; 0B95 0BCD 0BB7 +TAMIL SYLLABLE KSSAA; 0B95 0BCD 0BB7 0BBE +TAMIL SYLLABLE KSSI; 0B95 0BCD 0BB7 0BBF +TAMIL SYLLABLE KSSII; 0B95 0BCD 0BB7 0BC0 +TAMIL SYLLABLE KSSU; 0B95 0BCD 0BB7 0BC1 +TAMIL SYLLABLE KSSUU; 0B95 0BCD 0BB7 0BC2 +TAMIL SYLLABLE KSSE; 0B95 0BCD 0BB7 0BC6 +TAMIL SYLLABLE KSSEE; 0B95 0BCD 0BB7 0BC7 +TAMIL SYLLABLE KSSAI; 0B95 0BCD 0BB7 0BC8 +TAMIL SYLLABLE KSSO; 0B95 0BCD 0BB7 0BCA +TAMIL SYLLABLE KSSOO; 0B95 0BCD 0BB7 0BCB +TAMIL SYLLABLE KSSAU; 0B95 0BCD 0BB7 0BCC + +TAMIL SYLLABLE SHRII; 0BB6 0BCD 0BB0 0BC0 + +# Sinhala medial consonants and "reph" form. +# Provisional 2010-05-13, Approved 2011-08-05 + +SINHALA CONSONANT SIGN YANSAYA;0DCA 200D 0DBA +SINHALA CONSONANT SIGN RAKAARAANSAYA;0DCA 200D 0DBB +SINHALA CONSONANT SIGN REPAYA;0DBB 0DCA 200D + +# Georgian letter plus accent sequence. +# This is part of the original set of approved named sequences +# for Unicode 4.1. 2005. + +GEORGIAN LETTER U-BRJGU;10E3 0302 + +# Khmer subjoined forms and other sequences. +# These are part of the original set of approved named sequences +# for Unicode 4.1. 2005. + +KHMER CONSONANT SIGN COENG KA;17D2 1780 +KHMER CONSONANT SIGN COENG KHA;17D2 1781 +KHMER CONSONANT SIGN COENG KO;17D2 1782 +KHMER CONSONANT SIGN COENG KHO;17D2 1783 +KHMER CONSONANT SIGN COENG NGO;17D2 1784 +KHMER CONSONANT SIGN COENG CA;17D2 1785 +KHMER CONSONANT SIGN COENG CHA;17D2 1786 +KHMER CONSONANT SIGN COENG CO;17D2 1787 +KHMER CONSONANT SIGN COENG CHO;17D2 1788 +KHMER CONSONANT SIGN COENG NYO;17D2 1789 +KHMER CONSONANT SIGN COENG DA;17D2 178A +KHMER CONSONANT SIGN COENG TTHA;17D2 178B +KHMER CONSONANT SIGN COENG DO;17D2 178C +KHMER CONSONANT SIGN COENG TTHO;17D2 178D +KHMER CONSONANT SIGN COENG NA;17D2 178E +KHMER CONSONANT SIGN COENG TA;17D2 178F +KHMER CONSONANT SIGN COENG THA;17D2 1790 +KHMER CONSONANT SIGN COENG TO;17D2 1791 +KHMER CONSONANT SIGN COENG THO;17D2 1792 +KHMER CONSONANT SIGN COENG NO;17D2 1793 +KHMER CONSONANT SIGN COENG BA;17D2 1794 +KHMER CONSONANT SIGN COENG PHA;17D2 1795 +KHMER CONSONANT SIGN COENG PO;17D2 1796 +KHMER CONSONANT SIGN COENG PHO;17D2 1797 +KHMER CONSONANT SIGN COENG MO;17D2 1798 +KHMER CONSONANT SIGN COENG YO;17D2 1799 +KHMER CONSONANT SIGN COENG RO;17D2 179A +KHMER CONSONANT SIGN COENG LO;17D2 179B +KHMER CONSONANT SIGN COENG VO;17D2 179C +KHMER CONSONANT SIGN COENG SHA;17D2 179D +KHMER CONSONANT SIGN COENG SSA;17D2 179E +KHMER CONSONANT SIGN COENG SA;17D2 179F +KHMER CONSONANT SIGN COENG HA;17D2 17A0 +KHMER CONSONANT SIGN COENG LA;17D2 17A1 +KHMER VOWEL SIGN COENG QA;17D2 17A2 +KHMER INDEPENDENT VOWEL SIGN COENG QU;17D2 17A7 +KHMER INDEPENDENT VOWEL SIGN COENG RY;17D2 17AB +KHMER INDEPENDENT VOWEL SIGN COENG RYY;17D2 17AC +KHMER INDEPENDENT VOWEL SIGN COENG QE;17D2 17AF +KHMER VOWEL SIGN OM;17BB 17C6 +KHMER VOWEL SIGN AAM;17B6 17C6 + +# Entries for JIS X 0213 compatibility mapping. +# Provisional 2008-11-07, Approved 2010-05-14 +# +# Two of these were part of the original set of approved named sequences +# for Unicode 4.1. 2005. + +HIRAGANA LETTER BIDAKUON NGA;304B 309A +HIRAGANA LETTER BIDAKUON NGI;304D 309A +HIRAGANA LETTER BIDAKUON NGU;304F 309A +HIRAGANA LETTER BIDAKUON NGE;3051 309A +HIRAGANA LETTER BIDAKUON NGO;3053 309A +KATAKANA LETTER BIDAKUON NGA;30AB 309A +KATAKANA LETTER BIDAKUON NGI;30AD 309A +KATAKANA LETTER BIDAKUON NGU;30AF 309A +KATAKANA LETTER BIDAKUON NGE;30B1 309A +KATAKANA LETTER BIDAKUON NGO;30B3 309A +KATAKANA LETTER AINU CE;30BB 309A +KATAKANA LETTER AINU TU;30C4 309A +KATAKANA LETTER AINU TO;30C8 309A +KATAKANA LETTER AINU P;31F7 309A +MODIFIER LETTER EXTRA-HIGH EXTRA-LOW CONTOUR TONE BAR;02E5 02E9 +MODIFIER LETTER EXTRA-LOW EXTRA-HIGH CONTOUR TONE BAR;02E9 02E5 + +# EOF diff --git a/tools/gen_cjk_dbcs_tables.py b/tools/gen_cjk_dbcs_tables.py new file mode 100644 index 0000000..9ee17ef --- /dev/null +++ b/tools/gen_cjk_dbcs_tables.py @@ -0,0 +1,334 @@ +#!/usr/bin/env python3.13 +"""Generate `_cjk_tables.py` — packed mapping tables for the CJK DBCS codecs. + +Run with a real CPython 3.13 (`python3.13 tools/gen_cjk_dbcs_tables.py`); the +tables are *probed* from CPython's own cjkcodecs so WeavePy's pure-Python +ports (`_codec_cjk_dbcs.py`) reproduce the reference behaviour bit-for-bit, +including every NEC/IBM duplicate-row preference and decode-only cell. + +Table model (per codec): + +- decode grid: leads 0x81..0xFE x trails 0x40..0xFE, one u16 LE per cell + (0xFFFF = unmapped). big5hkscs uses u24 LE cells (0xFFFFFF = unmapped, + 0xFFFFFE = decodes-to-pair, pairs listed separately) because it decodes + into plane 2. +- euc_jp additionally carries a 94x94 u16 grid for the SS3 (0x8F) plane + (JIS X 0212). +- encode side: reconstructed at runtime as the *lowest (lead, trail)* + preimage of the decode grid, then patched by a small exceptions dict + {codepoint: bytes} and a rejects set (cells that decode but never + encode). Both are probed here by diffing `chr(cp).encode(codec)` against + the reconstruction rule for every BMP (+SMP where relevant) code point. +- gb18030's 4-byte forms are algorithmic over a BMP-range table probed from + encode results (runs of contiguous linear indices). + +Multi-byte-result encodes are *not* table entries: euc_kr's 8-byte jamo +make-up sequences, gb18030's 4-byte forms and big5hkscs's combining pairs +are reproduced algorithmically by the runtime module. +""" + +import base64 +import sys + +LEAD_LO, LEAD_HI = 0x81, 0xFE +TRAIL_LO, TRAIL_HI = 0x40, 0xFE +NLEAD = LEAD_HI - LEAD_LO + 1 # 126 +NTRAIL = TRAIL_HI - TRAIL_LO + 1 # 191 + +U16_UNDEF = 0xFFFF +U24_UNDEF = 0xFFFFFF +U24_PAIR = 0xFFFFFE + + +def probe_decode_grid(codec, u24=False): + """(grid bytearray, pairs dict {(lead, trail): (cp, cp)}).""" + cell = 3 if u24 else 2 + undef = U24_UNDEF if u24 else U16_UNDEF + grid = bytearray() + pairs = {} + # Leads that decode standalone (shift_jis/cp932 kana etc.) are handled + # algorithmically by the runtime; their grid rows stay unmapped. + single_leads = set() + for lead in range(LEAD_LO, LEAD_HI + 1): + try: + bytes((lead,)).decode(codec) + single_leads.add(lead) + except UnicodeDecodeError: + pass + for lead in range(LEAD_LO, LEAD_HI + 1): + if lead in single_leads: + grid += undef.to_bytes(cell, "little") * NTRAIL + continue + for trail in range(TRAIL_LO, TRAIL_HI + 1): + v = undef + try: + s = bytes((lead, trail)).decode(codec) + if len(s) == 1: + cp = ord(s) + assert cp <= (0x10FFFF if u24 else 0xFFFD), (codec, lead, trail, cp) + v = cp + elif len(s) == 2: + assert u24, (codec, lead, trail, s) + pairs[(lead, trail)] = (ord(s[0]), ord(s[1])) + v = U24_PAIR + else: + raise AssertionError((codec, lead, trail, s)) + except UnicodeDecodeError: + pass + grid += v.to_bytes(cell, "little") + return grid, pairs + + +def probe_ss3_grid(codec): + """euc_jp 0x8F plane: 94x94 u16 grid over (c2, c3) in 0xA1..0xFE.""" + grid = bytearray() + for c2 in range(0xA1, 0xFF): + for c3 in range(0xA1, 0xFF): + v = U16_UNDEF + try: + s = bytes((0x8F, c2, c3)).decode(codec) + assert len(s) == 1 and ord(s) <= 0xFFFD + v = ord(s) + except UnicodeDecodeError: + pass + grid += v.to_bytes(2, "little") + return grid + + +def grid_lowest_preimage(grid, u24=False): + """{cp: (lead, trail)} — first (lowest) cell wins, scanning in + (lead, trail) order. This is the runtime reconstruction rule.""" + cell = 3 if u24 else 2 + undef = U24_UNDEF if u24 else U16_UNDEF + inv = {} + idx = 0 + for lead in range(LEAD_LO, LEAD_HI + 1): + for trail in range(TRAIL_LO, TRAIL_HI + 1): + v = int.from_bytes(grid[idx : idx + cell], "little") + idx += cell + if v != undef and v != U24_PAIR and v not in inv: + inv[v] = (lead, trail) + return inv + + +def probe_encode(codec, cp_ranges): + """{cp: bytes or None}; None = raises. Multi-char results are skipped + (handled algorithmically).""" + out = {} + for lo, hi in cp_ranges: + for cp in range(lo, hi): + if 0xD800 <= cp <= 0xDFFF: + continue + try: + out[cp] = chr(cp).encode(codec) + except UnicodeEncodeError: + out[cp] = None + return out + + +def diff_encode(codec, enc_probe, inv, extra_rule=None): + """(exceptions {cp: bytes}, rejects set, algorithmic {cp: bytes}). + + `extra_rule(cp)` may return the bytes the runtime rule would produce for + code points outside the grid inverse (e.g. algorithmic layers); return + None for "rule says unencodable".""" + exceptions = {} + rejects = set() + algorithmic = {} + for cp, got in sorted(enc_probe.items()): + rule = None + if cp < 0x80: + rule = bytes((cp,)) + elif extra_rule is not None: + rule = extra_rule(cp) + if rule is None and cp in inv: + rule = bytes(inv[cp]) + if got == rule: + continue + if got is None: + if rule is not None: + rejects.add(cp) + continue + if len(got) > 2: + # euc_kr jamo (8), gb18030 4-byte: algorithmic in the runtime. + algorithmic[cp] = got + continue + exceptions[cp] = got + return exceptions, rejects, algorithmic + + +def gb18030_ranges(enc_probe): + """[(unicode_first, unicode_last, linear_base)] for BMP 4-byte forms, + probed from contiguous runs. Linear index over (b1-0x81, b2-0x30, + b3-0x81, b4-0x30) with mixed radix 10/1260.""" + ranges = [] + cur = None # (first, last, base) + for cp in range(0x80, 0x10000): + got = enc_probe.get(cp) + if got is None or len(got) != 4: + continue + b1, b2, b3, b4 = got + assert 0x81 <= b1 <= 0x84, hex(cp) + lin = ((b1 - 0x81) * 10 + (b2 - 0x30)) * 1260 + (b3 - 0x81) * 10 + (b4 - 0x30) + if cur is not None and cp == cur[1] + 1 and lin == cur[2] + (cp - cur[0]): + cur = (cur[0], cp, cur[2]) + else: + if cur is not None: + ranges.append(cur) + cur = (cp, cp, lin) + if cur is not None: + ranges.append(cur) + return ranges + + +def b64_lines(data, indent=" "): + enc = base64.b64encode(bytes(data)).decode("ascii") + lines = [enc[i : i + 96] for i in range(0, len(enc), 96)] + return "\n".join(f'{indent}"{line}"' for line in lines) + + +def fmt_dict_bytes(d): + items = ", ".join(f"0x{cp:X}: {v!r}" for cp, v in sorted(d.items())) + return "{" + items + "}" + + +def fmt_set(s): + if not s: + return "frozenset()" + return "frozenset((" + ", ".join(f"0x{cp:X}" for cp in sorted(s)) + ",))" + + +def main(): + out = [] + out.append('"""Packed CJK DBCS mapping tables (generated; do not edit).') + out.append("") + out.append("Generated by `tools/gen_cjk_dbcs_tables.py` by probing CPython") + out.append(f"{sys.version.split()[0]}'s cjkcodecs. See `_codec_cjk_dbcs` for the codec") + out.append('state machines that consume these tables."""') + out.append("") + out.append("import base64 as _b64") + out.append("") + out.append(f"LEAD_LO, TRAIL_LO, NTRAIL = 0x{LEAD_LO:X}, 0x{TRAIL_LO:X}, {NTRAIL}") + out.append("") + out.append("def _g(s):") + out.append(" return _b64.b64decode(s)") + out.append("") + + stats = [] + + def emit_codec(name, codec, u24=False, enc_ranges=((0x80, 0x10000),), extra_rule=None, + ss3=False): + grid, pairs = probe_decode_grid(codec, u24=u24) + inv = grid_lowest_preimage(grid, u24=u24) + ss3_grid = None + if ss3: + ss3_grid = probe_ss3_grid(codec) + # SS3 cells encode as 0x8F + cell; fold into the rule via extra_rule + ss3_inv = {} + idx = 0 + for c2 in range(0xA1, 0xFF): + for c3 in range(0xA1, 0xFF): + v = int.from_bytes(ss3_grid[idx : idx + 2], "little") + idx += 2 + if v != U16_UNDEF and v not in ss3_inv: + ss3_inv[v] = bytes((0x8F, c2, c3)) + prev_rule = extra_rule + + def rule(cp): + if prev_rule is not None: + r = prev_rule(cp) + if r is not None: + return r + if cp in inv: + return bytes(inv[cp]) + return ss3_inv.get(cp) + + extra_rule_eff = rule + else: + extra_rule_eff = extra_rule + + enc_probe = probe_encode(codec, enc_ranges) + exceptions, rejects, algorithmic = diff_encode(codec, enc_probe, inv, extra_rule_eff) + stats.append( + f"{name}: grid={len(grid)}B pairs={len(pairs)} exc={len(exceptions)} " + f"rej={len(rejects)} alg={len(algorithmic)}" + ) + up = name.upper() + out.append(f"# ---- {codec} ----") + out.append(f"{up}_DEC = _g(") + out.append(b64_lines(grid)) + out.append(")") + if ss3_grid is not None: + out.append(f"{up}_DEC_SS3 = _g(") + out.append(b64_lines(ss3_grid)) + out.append(")") + if pairs: + items = ", ".join( + f"(0x{l:X}, 0x{t:X}): (0x{a:X}, 0x{b:X})" for (l, t), (a, b) in sorted(pairs.items()) + ) + out.append(f"{up}_DEC_PAIRS = {{{items}}}") + out.append(f"{up}_ENC_EXC = {fmt_dict_bytes(exceptions)}") + out.append(f"{up}_ENC_REJECT = {fmt_set(rejects)}") + out.append("") + return enc_probe, algorithmic + + # --- kr --- + emit_codec("euc_kr", "euc_kr") # 8-byte jamo handled algorithmically + emit_codec("cp949", "cp949") + # johab reuses the euc_kr (ksx1001) grid algorithmically. + + # --- jp --- + emit_codec("euc_jp", "euc_jp", ss3=True) + + def sjis_kana_rule(cp): + if 0xFF61 <= cp <= 0xFF9F: + return bytes((cp - 0xFEC0,)) + return None + + emit_codec("shift_jis", "shift_jis", extra_rule=sjis_kana_rule) + + def cp932_rule(cp): + if 0xFF61 <= cp <= 0xFF9F: + return bytes((cp - 0xFEC0,)) + if cp == 0xF8F0: + return b"\xa0" + if 0xF8F1 <= cp <= 0xF8F3: + return bytes((cp - 0xF8F1 + 0xFD,)) + if 0xE000 <= cp < 0xE758: + c1 = (cp - 0xE000) // 188 + c2 = (cp - 0xE000) % 188 + return bytes((c1 + 0xF0, c2 + 0x40 if c2 < 0x3F else c2 + 0x41)) + return None + + emit_codec("cp932", "cp932", extra_rule=cp932_rule) + + # --- cn --- + emit_codec("gb2312", "gb2312") + emit_codec("gbk", "gbk") + enc_probe, alg = emit_codec( + "gb18030", "gb18030", enc_ranges=((0x80, 0x10000),) + ) + ranges = gb18030_ranges(enc_probe) + items = ", ".join(f"(0x{a:X}, 0x{b:X}, {c})" for a, b, c in ranges) + out.append(f"GB18030_RANGES = ({items})") + out.append("") + + # --- tw / hk --- + emit_codec("big5", "big5") + emit_codec("cp950", "cp950") + emit_codec( + "big5hkscs", "big5hkscs", u24=True, + enc_ranges=((0x80, 0x10000), (0x20000, 0x30000)), + ) + + text = "\n".join(out) + "\n" + dest = "crates/weavepy-vm/src/stdlib/python/_cjk_tables.py" + with open(dest, "w") as f: + f.write(text) + print(f"wrote {dest}: {len(text)} bytes") + for s in stats: + print(" ", s) + + +if __name__ == "__main__": + main() diff --git a/tools/gen_ucd_tables.py b/tools/gen_ucd_tables.py new file mode 100644 index 0000000..2db3a7c --- /dev/null +++ b/tools/gen_ucd_tables.py @@ -0,0 +1,553 @@ +#!/usr/bin/env python3.13 +"""Generate WeavePy's UCD 15.1.0 tables by probing host CPython 3.13. + +RFC 0050 WS4. CPython 3.13's `unicodedata` *is* UCD 15.1.0, so probing it +exhaustively (all 0x110000 code points, both the current database and the +`ucd_3_2_0` snapshot) reproduces `Modules/unicodedata_db.h` + +`Modules/unicodename_db.h` without re-implementing `makeunicodedata.py`. + +Outputs (packed binary blobs under +`crates/weavepy-vm/src/stdlib/ucd/`, loaded via `include_bytes!`): + +- `records.bin` unique per-code-point property records (12 bytes each) +- `index1.bin` block map: (0x110000 >> SHIFT) u16 block ids +- `index2.bin` per-block record ids: blocks * (1 << SHIFT) u16s +- `index1_32.bin`, + `index2_32.bin` the same two-level index for the UCD 3.2.0 snapshot + (sharing `records.bin`'s record pool) +- `numeric.bin` f64 numeric values (little-endian) +- `decomp.bin` decomposition strings: u8 prefix-idx, u8 len, len*u24 cps +- `names.bin` non-algorithmic names sorted by cp: u24 cp, u8 len, bytes +- `names32.bin` bitmap of "assigned in UCD 3.2.0" (0x110000 bits) +- `comp.bin` canonical composition pairs: u24 a, u24 b, u24 composed +- `case_records.bin` unique ctype/case records (14 bytes each: u16 flags + + 4 u24 pool refs for lower/upper/title/casefold; + 0xFFFFFF = identity) +- `case_index1.bin`, + `case_index2.bin` two-level index over the case records +- `case_pool.bin` case-mapping expansion pool: u8 len, len*u24 cps +- `aliases.bin` NameAliases.txt entries (lookup-only): u24 cp, u8 len, + name bytes +- `seqs.bin` NamedSequences.txt entries (lookup-only, multi-cp): + u8 n, n*u24 cps, u8 len, name bytes +- `meta.rs` generated Rust consts (category/bidi/eaw/prefix string + pools, SHIFT, record count) + +Record layout (12 bytes): + 0: category index (into CATEGORIES) + 1: bidirectional index (into BIDIRECTIONALS) + 2: combining class (0..=254) + 3: mirrored (0/1) + 4: east_asian_width idx (into EASTASIANWIDTHS) + 5: decimal (0xFF = none) + 6: digit (0xFF = none) + 7: numeric idx lo (u16 into numeric.bin / 8; 0xFFFF = none) + 8: numeric idx hi + 9: decomp idx lo (u24 byte offset into decomp.bin; 0xFFFFFF = none) + 10: decomp idx mid + 11: decomp idx hi +""" + +import os +import struct +import sys +import unicodedata + +assert sys.version_info[:2] == (3, 13), "must run under CPython 3.13" +assert unicodedata.unidata_version == "15.1.0", unicodedata.unidata_version + +OUT_DIR = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "crates", "weavepy-vm", "src", "stdlib", "ucd", +) +SHIFT = 7 +NCP = 0x110000 + +DB_CUR = unicodedata +DB_32 = unicodedata.ucd_3_2_0 + +# Decomposition tag prefixes (makeunicodedata.py DECOMPOSITION_PREFIXES). +DECOMP_PREFIXES = [ + "", "", "", "", "", "", "", + "", "", "", "", "", "", + "", "", "", "", +] + + +def probe_record(db, cp, pools): + ch = chr(cp) + cat = db.category(ch) + bidi = db.bidirectional(ch) + comb = db.combining(ch) + mirr = db.mirrored(ch) + eaw = db.east_asian_width(ch) + dec = db.decimal(ch, None) + dig = db.digit(ch, None) + num = db.numeric(ch, None) + decomp = db.decomposition(ch) + + cats, bidis, eaws, nums, decomps = pools + cat_i = intern_str(cats, cat) + bidi_i = intern_str(bidis, bidi) + eaw_i = intern_str(eaws, eaw) + + if num is None: + num_i = 0xFFFF + else: + num_i = intern_str(nums, num) + assert num_i < 0xFFFF + + if not decomp: + dcp_i = 0xFFFFFF + else: + dcp_i = intern_decomp(decomps, decomp) + assert dcp_i < 0xFFFFFF + + dec_b = 0xFF if dec is None else dec + dig_b = 0xFF if dig is None else dig + assert 0 <= comb <= 0xFF and mirr in (0, 1) + return struct.pack( + " 0020 0301' or '0041 0300'. Encode as (prefix_idx, cps).""" + key = decomp + idx = pool["map"].get(key) + if idx is not None: + return idx + parts = decomp.split() + if parts and parts[0].startswith("<"): + prefix = parts[0] + cps = [int(p, 16) for p in parts[1:]] + else: + prefix = "" + cps = [int(p, 16) for p in parts] + pfx_i = DECOMP_PREFIXES.index(prefix) + assert len(cps) <= 0xFF + blob = pool["blob"] + idx = len(blob) + blob.append(pfx_i) + blob.append(len(cps)) + for c in cps: + blob += c.to_bytes(3, "little") + pool["map"][key] = idx + return idx + + +def build_index(record_of_cp): + """splitbins: two-level index over 0x110000 entries.""" + block_size = 1 << SHIFT + blocks = {} + index1 = [] + index2 = bytearray() + for start in range(0, NCP, block_size): + block = tuple(record_of_cp[start:start + block_size]) + bid = blocks.get(block) + if bid is None: + bid = len(blocks) + blocks[block] = bid + for rid in block: + index2 += struct.pack(" is neither ignorable nor cased + # P2 = "AΣ": final iff is ignorable or not cased + # so ignorable ⟺ (P1 non-final and P2 final). + p1 = ("A\u03a3" + ch + "b").lower()[1] + p2 = ("A\u03a3" + ch).lower()[1] + assert p1 in "\u03c2\u03c3" and p2 in "\u03c2\u03c3", hex(cp) + if p1 == "\u03c3" and p2 == "\u03c2": + flags |= FLAG_CASE_IGNORABLE + return flags + + +def probe_case_tables(): + """case_records.bin / case_index1.bin / case_index2.bin / case_pool.bin. + + Record (14 bytes): u16 flags, then u24 lower/upper/title/casefold refs. + A ref < 0x110000 is a direct single code point; 0xFFFFFF means identity; + anything else is 0x110000 + byte offset into case_pool.bin (u8 len, + len*u24 cps) for multi-code-point expansions. + """ + pool = bytearray() + pool_map = {} + + def map_ref(cp, mapped): + if mapped == chr(cp): + return 0xFFFFFF + cps = [ord(c) for c in mapped] + if len(cps) == 1: + assert cps[0] < 0x110000 + return cps[0] + key = tuple(cps) + off = pool_map.get(key) + if off is None: + off = len(pool) + pool_map[key] = off + pool.append(len(cps)) + for c in cps: + pool.extend(c.to_bytes(3, "little")) + ref = 0x110000 + off + assert ref < 0xFFFFFF + return ref + + records = {} + record_list = [] + rids = [] + for cp in range(NCP): + ch = chr(cp) + rec = struct.pack("> 3] |= 1 << (cp & 7) + + print("probing canonical composition pairs...", flush=True) + comp = bytearray() + n_comp = 0 + for cp in range(NCP): + ch = chr(cp) + d = DB_CUR.decomposition(ch) + if not d or d.startswith("<"): + continue + parts = [int(p, 16) for p in d.split()] + if len(parts) != 2: + continue + # Primary composite iff NFC of the decomposition recomposes to it. + seq = "".join(map(chr, parts)) + if unicodedata.normalize("NFC", seq) == ch: + comp += parts[0].to_bytes(3, "little") + comp += parts[1].to_bytes(3, "little") + comp += cp.to_bytes(3, "little") + n_comp += 1 + + print("probing case/ctype tables...", flush=True) + case_records, case_i1, case_i2, case_pool = probe_case_tables() + + print("probing aliases + named sequences...", flush=True) + aliases_blob, seqs_blob = probe_aliases_and_sequences() + + print("probing lookup-only algorithmic ranges...", flush=True) + lookup_only_runs = probe_lookup_only_ranges() + + print("writing blobs...", flush=True) + numeric_blob = bytearray() + for s in pools[3]["list"]: + numeric_blob += struct.pack(" Date: Sun, 12 Jul 2026 14:23:48 -0700 Subject: [PATCH 2/2] fix: restore the C-locale _locale shim on non-Unix hosts --- crates/weavepy-vm/src/stdlib/locale_mod.rs | 133 ++++++++++++++++++++- 1 file changed, 132 insertions(+), 1 deletion(-) diff --git a/crates/weavepy-vm/src/stdlib/locale_mod.rs b/crates/weavepy-vm/src/stdlib/locale_mod.rs index 53fe6d3..71f01f3 100644 --- a/crates/weavepy-vm/src/stdlib/locale_mod.rs +++ b/crates/weavepy-vm/src/stdlib/locale_mod.rs @@ -7,7 +7,13 @@ //! reports the `LC_CTYPE` codeset. Strings coming back from libc are //! decoded with `mbstowcs` under the current `LC_CTYPE`, mirroring //! CPython's `PyUnicode_DecodeLocale`. +//! +//! On non-Unix hosts (Windows) the langinfo surface doesn't exist, so +//! we fall back to the pre-RFC-0050 C-locale shim: `setlocale` accepts +//! only `C`/`POSIX`, `localeconv` serves POSIX defaults, and the +//! codeset is always UTF-8. +#[cfg(unix)] use std::ffi::{CStr, CString}; use crate::sync::Rc; @@ -18,6 +24,7 @@ use crate::import::ModuleCache; use crate::object::{BuiltinFn, DictData, DictKey, Object, PyModule}; // Wide-char/multibyte libc entry points the `libc` crate doesn't bind. +#[cfg(unix)] unsafe extern "C" { fn mbstowcs( dest: *mut libc::wchar_t, @@ -34,19 +41,44 @@ unsafe extern "C" { // Category constants — the host libc's values (CPython exports these // verbatim from `locale.h`). +#[cfg(unix)] pub const LC_ALL: i64 = libc::LC_ALL as i64; +#[cfg(unix)] pub const LC_CTYPE: i64 = libc::LC_CTYPE as i64; +#[cfg(unix)] pub const LC_NUMERIC: i64 = libc::LC_NUMERIC as i64; +#[cfg(unix)] pub const LC_TIME: i64 = libc::LC_TIME as i64; +#[cfg(unix)] pub const LC_COLLATE: i64 = libc::LC_COLLATE as i64; +#[cfg(unix)] pub const LC_MONETARY: i64 = libc::LC_MONETARY as i64; +#[cfg(unix)] pub const LC_MESSAGES: i64 = libc::LC_MESSAGES as i64; + +// Non-Unix fallback: the POSIX-ish values the pre-RFC-0050 shim used. +#[cfg(not(unix))] +pub const LC_ALL: i64 = 6; +#[cfg(not(unix))] +pub const LC_CTYPE: i64 = 0; +#[cfg(not(unix))] +pub const LC_NUMERIC: i64 = 1; +#[cfg(not(unix))] +pub const LC_TIME: i64 = 2; +#[cfg(not(unix))] +pub const LC_COLLATE: i64 = 3; +#[cfg(not(unix))] +pub const LC_MONETARY: i64 = 4; +#[cfg(not(unix))] +pub const LC_MESSAGES: i64 = 5; + pub const CHAR_MAX: i64 = 127; /// `setlocale(LC_CTYPE, "")` — adopt the environment's `LC_CTYPE` locale, /// as CPython's pre-init does (`_Py_SetLocaleFromEnv`). Called once at /// interpreter start so `nl_langinfo(CODESET)`/`localeconv` and the /// `locale` module observe the user's locale rather than plain `"C"`. +#[cfg(unix)] pub fn init_from_env() { let empty = CString::new("").expect("static"); // SAFETY: `setlocale` with a valid category and NUL-terminated string. @@ -55,6 +87,10 @@ pub fn init_from_env() { } } +/// Non-Unix: nothing to adopt — the shim always serves the C locale. +#[cfg(not(unix))] +pub fn init_from_env() {} + pub fn build(_cache: &ModuleCache) -> Rc { let dict = Rc::new(RefCell::new(DictData::default())); { @@ -76,7 +112,9 @@ pub fn build(_cache: &ModuleCache) -> Rc { d.insert(DictKey(Object::from_static(name)), Object::Int(val)); } // `nl_langinfo` item constants (langinfo.h). Grouped exactly like - // CPython's `langinfo_constants` table. + // CPython's `langinfo_constants` table. Windows has no langinfo.h, + // matching CPython's `_locale` there. + #[cfg(unix)] for &(name, val) in langinfo_constants() { d.insert(DictKey(Object::from_static(name)), Object::Int(val)); } @@ -100,6 +138,8 @@ pub fn build(_cache: &ModuleCache) -> Rc { DictKey(Object::from_static("strxfrm")), builtin("strxfrm", l_strxfrm), ); + // Windows CPython's `_locale` has no `nl_langinfo`; mirror that. + #[cfg(unix)] d.insert( DictKey(Object::from_static("nl_langinfo")), builtin("nl_langinfo", l_nl_langinfo), @@ -128,6 +168,7 @@ fn builtin(name: &'static str, body: fn(&[Object]) -> Result String { if ptr.is_null() { return String::new(); @@ -159,6 +200,7 @@ fn decode_locale_cstr(ptr: *const libc::c_char) -> String { bytes.iter().map(|&b| b as char).collect() } +#[cfg(unix)] fn arg_category(args: &[Object], fname: &str) -> Result { let cat = match args.first() { Some(Object::Int(n)) => *n, @@ -183,6 +225,7 @@ fn arg_category(args: &[Object], fname: &str) -> Result Result { let category = arg_category(args, "setlocale")?; match args.get(1) { @@ -213,6 +256,7 @@ fn l_setlocale(args: &[Object]) -> Result { /// CPython's `copy_grouping`: the lconv grouping byte string becomes a list /// of ints, keeping a trailing `CHAR_MAX` terminator and stopping there. +#[cfg(unix)] fn copy_grouping(ptr: *const libc::c_char) -> Object { if ptr.is_null() { return Object::new_list(vec![]); @@ -229,6 +273,7 @@ fn copy_grouping(ptr: *const libc::c_char) -> Object { Object::new_list(out) } +#[cfg(unix)] fn l_localeconv(_args: &[Object]) -> Result { let mut d = DictData::default(); // SAFETY: `localeconv` returns a pointer to static libc storage, valid @@ -270,6 +315,7 @@ fn l_localeconv(_args: &[Object]) -> Result { } /// A NUL-terminated wide-char copy of `s` for `wcscoll`/`wcsxfrm`. +#[cfg(unix)] fn to_wide(s: &str) -> Vec { let mut v: Vec = s.chars().map(|c| c as u32 as libc::wchar_t).collect(); v.push(0); @@ -285,6 +331,7 @@ fn arg_str(args: &[Object], idx: usize, fname: &str) -> Result Result { let a = to_wide(&arg_str(args, 0, "strcoll")?); let b = to_wide(&arg_str(args, 1, "strcoll")?); @@ -293,6 +340,7 @@ fn l_strcoll(args: &[Object]) -> Result { Ok(Object::Int(i64::from(r))) } +#[cfg(unix)] fn l_strxfrm(args: &[Object]) -> Result { let s = arg_str(args, 0, "strxfrm")?; let src = to_wide(&s); @@ -317,6 +365,7 @@ fn l_strxfrm(args: &[Object]) -> Result { } } +#[cfg(unix)] fn l_nl_langinfo(args: &[Object]) -> Result { let item = match args.first() { Some(Object::Int(n)) => *n, @@ -337,6 +386,7 @@ fn l_nl_langinfo(args: &[Object]) -> Result { /// The current `LC_CTYPE` codeset (`nl_langinfo(CODESET)`), with the /// UTF-8 fallback CPython's `_Py_GetLocaleEncoding` applies when the /// codeset is empty. +#[cfg(unix)] pub fn current_codeset() -> String { // SAFETY: CODESET is a valid langinfo item on all supported hosts. let ptr = unsafe { libc::nl_langinfo(libc::CODESET) }; @@ -348,6 +398,12 @@ pub fn current_codeset() -> String { } } +/// Non-Unix: no langinfo — the shim's codeset is always UTF-8. +#[cfg(not(unix))] +pub fn current_codeset() -> String { + "UTF-8".to_owned() +} + /// `_locale.getencoding()` — the current `LC_CTYPE` codeset. fn l_getencoding(_args: &[Object]) -> Result { Ok(Object::from_str(current_codeset())) @@ -355,6 +411,7 @@ fn l_getencoding(_args: &[Object]) -> Result { /// The `nl_langinfo` item constants exported on this platform, mirroring /// CPython's `langinfo_constants` table in `_localemodule.c`. +#[cfg(unix)] fn langinfo_constants() -> &'static [(&'static str, i64)] { static CONSTANTS: std::sync::OnceLock> = std::sync::OnceLock::new(); CONSTANTS @@ -419,3 +476,77 @@ fn langinfo_constants() -> &'static [(&'static str, i64)] { }) .as_slice() } + +// --------------------------------------------------------------------------- +// Non-Unix fallbacks — the pre-RFC-0050 C-locale shim, kept so the module +// builds on hosts without POSIX locale APIs (Windows). +// --------------------------------------------------------------------------- + +#[cfg(not(unix))] +fn l_setlocale(args: &[Object]) -> Result { + let loc = match args.get(1) { + Some(Object::Str(s)) => s.to_string(), + Some(Object::None) | None => "C".to_owned(), + _ => { + return Err(crate::error::type_error( + "setlocale: locale must be str or None", + )) + } + }; + if loc == "C" || loc == "POSIX" || loc.is_empty() { + return Ok(Object::from_static("C")); + } + Err(value_error("unsupported locale setting")) +} + +#[cfg(not(unix))] +fn l_localeconv(_args: &[Object]) -> Result { + let mut d = DictData::default(); + let mut ins = |k: &'static str, v: Object| { + d.insert(DictKey(Object::from_static(k)), v); + }; + for k in [ + "thousands_sep", + "int_curr_symbol", + "currency_symbol", + "mon_decimal_point", + "mon_thousands_sep", + "positive_sign", + "negative_sign", + ] { + ins(k, Object::from_static("")); + } + ins("decimal_point", Object::from_static(".")); + ins("grouping", Object::new_list(vec![])); + ins("mon_grouping", Object::new_list(vec![])); + for k in [ + "int_frac_digits", + "frac_digits", + "p_cs_precedes", + "p_sep_by_space", + "n_cs_precedes", + "n_sep_by_space", + "p_sign_posn", + "n_sign_posn", + ] { + ins(k, Object::Int(CHAR_MAX)); + } + Ok(Object::Dict(Rc::new(RefCell::new(d)))) +} + +#[cfg(not(unix))] +fn l_strcoll(args: &[Object]) -> Result { + let a = arg_str(args, 0, "strcoll")?; + let b = arg_str(args, 1, "strcoll")?; + use std::cmp::Ordering; + Ok(Object::Int(match a.cmp(&b) { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1, + })) +} + +#[cfg(not(unix))] +fn l_strxfrm(args: &[Object]) -> Result { + Ok(Object::from_str(arg_str(args, 0, "strxfrm")?)) +}